From cb78f39dea933e7510bc34701044b5691b046240 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Fri, 26 Jul 2024 20:59:56 +0400 Subject: [PATCH 01/44] clippy --- pallets/collective/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/collective/src/lib.rs b/pallets/collective/src/lib.rs index 96040f99c..c6552b036 100644 --- a/pallets/collective/src/lib.rs +++ b/pallets/collective/src/lib.rs @@ -951,8 +951,8 @@ impl, I: 'static> Pallet { /// /// If not `approved`: /// - one event deposited. - /// Two removals, one mutation. - /// Computation and i/o `O(P)` where: + /// Two removals, one mutation. + /// Computation and i/o `O(P)` where: /// - `P` is number of active proposals fn do_approve_proposal( seats: MemberCount, From d9b8eb9570641c65118b974520fb59e79ea5f79f Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Mon, 29 Jul 2024 20:06:11 +0400 Subject: [PATCH 02/44] stash --- Cargo.toml | 2 +- pallets/subtensor/src/lib.rs | 1 + pallets/subtensor/src/macros/config.rs | 13 +++- pallets/subtensor/src/macros/dispatches.rs | 87 +++++++++++++++++++++- runtime/Cargo.toml | 6 +- runtime/src/lib.rs | 24 +++++- runtime/tests/pallet_proxy.rs | 2 +- 7 files changed, 127 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4a7565a01..2db7ce1d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,7 @@ subtensor-macros = { path = "support/macros" } frame-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } frame-benchmarking-cli = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } frame-executive = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } -frame-metadata-hash-extension = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" , default-features = false } +frame-metadata-hash-extension = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } frame-support = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } frame-system = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } frame-system-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index abf6a8613..3f9004167 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -19,6 +19,7 @@ use codec::{Decode, Encode}; use frame_support::sp_runtime::transaction_validity::InvalidTransaction; use frame_support::sp_runtime::transaction_validity::ValidTransaction; use pallet_balances::Call as BalancesCall; +// use pallet_scheduler as Scheduler; use scale_info::TypeInfo; use sp_runtime::{ traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension}, diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index e59eac5ca..fb1ad5415 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -1,7 +1,6 @@ #![allow(clippy::crate_in_macro_def)] use frame_support::pallet_macros::pallet_section; - /// A [`pallet_section`] that defines the errors for a pallet. /// This can later be imported into the pallet using [`import_section`]. #[pallet_section] @@ -31,6 +30,18 @@ mod config { /// Interface to allow other pallets to control who can register identities type TriumvirateInterface: crate::CollectiveInterface; + /// The scheduler type used for scheduling delayed calls. + type Scheduler: ScheduleNamed, Call, Self::RuntimeOrigin>; + + /// The hashing system (algorithm) being used in the runtime, matching the Scheduler's Hasher. + type Hasher: Hash< + Output = <, + Call, + Self::RuntimeOrigin, + >>::Hasher as Hash>::Output, + >; + /// ================================= /// ==== Initial Value Constants ==== /// ================================= diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 293dc0238..a84c5964d 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -4,6 +4,12 @@ use frame_support::pallet_macros::pallet_section; /// This can later be imported into the pallet using [`import_section`]. #[pallet_section] mod dispatches { + use frame_support::traits::schedule::v3::Named as ScheduleNamed; + use frame_support::traits::schedule::DispatchTime; + use frame_support::traits::Bounded; + use frame_system::pallet_prelude::BlockNumberFor; + use sp_runtime::traits::Hash; + use sp_runtime::traits::Saturating; /// Dispatchable functions allow users to interact with the pallet and invoke state changes. /// These functions materialize as "extrinsics", which are often compared to transactions. /// Dispatchable functions must be annotated with a weight and must return a DispatchResult. @@ -675,7 +681,11 @@ mod dispatches { origin: OriginFor, new_coldkey: T::AccountId, ) -> DispatchResultWithPostInfo { - Self::do_swap_coldkey(origin, &new_coldkey) + // Ensure it's called with root privileges (scheduler has root privileges) + ensure_root(origin.clone())?; + + let who = ensure_signed(origin)?; + Self::do_swap_coldkey(frame_system::RawOrigin::Signed(who).into(), &new_coldkey) } /// Unstakes all tokens associated with a hotkey and transfers them to a new coldkey. @@ -901,5 +911,80 @@ mod dispatches { Self::do_set_children(origin, hotkey, netuid, children)?; Ok(().into()) } + + /// Schedules a coldkey swap operation to be executed at a future block. + /// + /// This function allows a user to schedule the swapping of their coldkey to a new one + /// at a specified future block. The swap is not executed immediately but is scheduled + /// to occur at the specified block number. + /// + /// # Arguments + /// + /// * `origin` - The origin of the call, which should be signed by the current coldkey owner. + /// * `new_coldkey` - The account ID of the new coldkey that will replace the current one. + /// * `when` - The block number at which the coldkey swap should be executed. + /// + /// # Returns + /// + /// Returns a `DispatchResultWithPostInfo` indicating whether the scheduling was successful. + /// + /// # Errors + /// + /// This function may return an error if: + /// * The origin is not signed. + /// * The scheduling fails due to conflicts or system constraints. + /// + /// # Notes + /// + /// - The actual swap is not performed by this function. It merely schedules the swap operation. + /// - The weight of this call is set to a fixed value and may need adjustment based on benchmarking. + /// + /// # TODO + /// + /// - Implement proper weight calculation based on the complexity of the operation. + /// - Consider adding checks to prevent scheduling too far into the future. + /// TODO: Benchmark this call + #[pallet::call_index(73)] + #[pallet::weight((Weight::from_parts(119_000_000, 0) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(31)), DispatchClass::Operational, Pays::Yes))] + pub fn schedule_swap_coldkey( + origin: OriginFor, + new_coldkey: T::AccountId, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + + // Calculate the number of blocks in 5 days + let blocks_in_5_days: u32 = 5 * 24 * 60 * 60 / 12; + + let current_block = >::block_number(); + let when = current_block.saturating_add(BlockNumberFor::::from(blocks_in_5_days)); + + let call = Call::::swap_coldkey { + new_coldkey: new_coldkey.clone(), + }; + + let unique_id = ( + b"schedule_swap_coldkey", + who.clone(), + new_coldkey.clone(), + when, + ) + .using_encoded(sp_io::hashing::blake2_256); + + let hash = T::Hasher::hash(&call.encode()); + let len = call.using_encoded(|e| e.len() as u32); + + T::Scheduler::schedule_named( + unique_id, + DispatchTime::At(when), + None, + 63, + frame_system::RawOrigin::Root.into(), + Bounded::Lookup { hash, len }, + )?; + + Ok(().into()) + } } } diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 042d0337c..c8fac478b 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -155,7 +155,7 @@ std = [ "sp-tracing/std", "log/std", "sp-storage/std", - "sp-genesis-builder/std" + "sp-genesis-builder/std", ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", @@ -178,7 +178,7 @@ runtime-benchmarks = [ "pallet-multisig/runtime-benchmarks", "pallet-preimage/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", - "pallet-sudo/runtime-benchmarks" + "pallet-sudo/runtime-benchmarks", ] try-runtime = [ "frame-try-runtime/try-runtime", @@ -204,6 +204,6 @@ try-runtime = [ "sp-runtime/try-runtime", "pallet-admin-utils/try-runtime", "pallet-commitments/try-runtime", - "pallet-registry/try-runtime" + "pallet-registry/try-runtime", ] metadata-hash = ["substrate-wasm-builder/metadata-hash"] diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 61f3a3c85..1d2236dc3 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -12,6 +12,7 @@ pub mod check_nonce; mod migrations; use codec::{Decode, Encode, MaxEncodedLen}; +use frame_support::traits::schedule::v3::Named as ScheduleNamed; use frame_support::{ dispatch::DispatchResultWithPostInfo, genesis_builder_helper::{build_config, create_default_config}, @@ -68,6 +69,7 @@ pub use sp_runtime::BuildStorage; pub use sp_runtime::{Perbill, Permill}; // Subtensor module +pub use pallet_scheduler; pub use pallet_subtensor; // An index to a block. @@ -94,6 +96,10 @@ type MemberCount = u32; pub type Nonce = u32; +/// The scheduler type used for scheduling delayed calls. +// With something like this: +// type Scheduler = pallet_subtensor::Scheduler; + // 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; @@ -834,6 +840,19 @@ impl pallet_commitments::Config for Runtime { type RateLimit = CommitmentRateLimit; } +impl pallet_scheduler::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type MaximumWeight = MaximumSchedulerWeight; + type ScheduleOrigin = EnsureRoot; + type MaxScheduledPerBlock = ConstU32<50>; + type WeightInfo = pallet_scheduler::weights::SubstrateWeight; + type OriginPrivilegeCmp = EqualPrivilegeOnly; + type Preimages = Preimage; +} + // Configure the pallet subtensor. parameter_types! { pub const SubtensorInitialRho: u16 = 10; @@ -883,6 +902,7 @@ parameter_types! { pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn pub const SubtensorInitialHotkeyEmissionTempo: u64 = 7200; // Drain every day. pub const SubtensorInitialNetworkMaxStake: u64 = 500_000_000_000_000; // 500_000 TAO + } impl pallet_subtensor::Config for Runtime { @@ -892,6 +912,8 @@ impl pallet_subtensor::Config for Runtime { type CouncilOrigin = EnsureMajoritySenate; type SenateMembers = ManageSenateMembers; type TriumvirateInterface = TriumvirateVotes; + type Scheduler = pallet_scheduler::Pallet; + type Hasher = BlakeTwo256; type InitialRho = SubtensorInitialRho; type InitialKappa = SubtensorInitialKappa; @@ -1266,12 +1288,12 @@ construct_runtime!( Sudo: pallet_sudo, Multisig: pallet_multisig, Preimage: pallet_preimage, - Scheduler: pallet_scheduler, Proxy: pallet_proxy, Registry: pallet_registry, Commitments: pallet_commitments, AdminUtils: pallet_admin_utils, SafeMode: pallet_safe_mode, + Scheduler: pallet_scheduler, } ); diff --git a/runtime/tests/pallet_proxy.rs b/runtime/tests/pallet_proxy.rs index 796dfc471..192893c1e 100644 --- a/runtime/tests/pallet_proxy.rs +++ b/runtime/tests/pallet_proxy.rs @@ -4,7 +4,7 @@ use codec::Encode; use frame_support::{assert_ok, traits::InstanceFilter, BoundedVec}; use node_subtensor_runtime::{ AccountId, BalancesCall, BuildStorage, Proxy, ProxyType, Runtime, RuntimeCall, RuntimeEvent, - RuntimeGenesisConfig, RuntimeOrigin, SubtensorModule, System, SystemCall, + RuntimeGenesisConfig, RuntimeOrigin, SchedulerCall, SubtensorModule, System, SystemCall, }; const ACCOUNT: [u8; 32] = [1_u8; 32]; From d7ef0586047420de51651782678150a20bf5168a Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 30 Jul 2024 18:57:04 +0800 Subject: [PATCH 03/44] fix compile error --- pallets/subtensor/src/lib.rs | 9 ++++++++- pallets/subtensor/src/macros/config.rs | 11 +---------- pallets/subtensor/src/macros/dispatches.rs | 19 ++++++++++--------- runtime/src/lib.rs | 18 +----------------- 4 files changed, 20 insertions(+), 37 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 3f9004167..f5febb0aa 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -65,7 +65,7 @@ pub mod pallet { use frame_support::{ dispatch::GetDispatchInfo, pallet_prelude::{DispatchResult, StorageMap, ValueQuery, *}, - traits::{tokens::fungible, UnfilteredDispatchable}, + traits::{tokens::fungible, OriginTrait, UnfilteredDispatchable}, }; use frame_system::pallet_prelude::*; use sp_core::H256; @@ -78,6 +78,13 @@ pub mod pallet { #[cfg(feature = "std")] use sp_std::prelude::Box; + /// Origin for the pallet + pub type PalletsOriginOf = + <::RuntimeOrigin as OriginTrait>::PalletsOrigin; + + /// Call type for the pallet + pub type CallOf = ::RuntimeCall; + /// Tracks version for migrations. Should be monotonic with respect to the /// order of migrations. (i.e. always increasing) const STORAGE_VERSION: StorageVersion = StorageVersion::new(7); diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index fb1ad5415..d2504eb4e 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -31,16 +31,7 @@ mod config { type TriumvirateInterface: crate::CollectiveInterface; /// The scheduler type used for scheduling delayed calls. - type Scheduler: ScheduleNamed, Call, Self::RuntimeOrigin>; - - /// The hashing system (algorithm) being used in the runtime, matching the Scheduler's Hasher. - type Hasher: Hash< - Output = <, - Call, - Self::RuntimeOrigin, - >>::Hasher as Hash>::Output, - >; + type Scheduler: ScheduleNamed, CallOf, PalletsOriginOf>; /// ================================= /// ==== Initial Value Constants ==== diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index a84c5964d..43eeb4105 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -972,17 +972,18 @@ mod dispatches { ) .using_encoded(sp_io::hashing::blake2_256); - let hash = T::Hasher::hash(&call.encode()); + let hash = sp_runtime::traits::BlakeTwo256::hash_of(&call); + let len = call.using_encoded(|e| e.len() as u32); - T::Scheduler::schedule_named( - unique_id, - DispatchTime::At(when), - None, - 63, - frame_system::RawOrigin::Root.into(), - Bounded::Lookup { hash, len }, - )?; + // T::Scheduler::schedule_named( + // unique_id, + // DispatchTime::At(when), + // None, + // 63, + // frame_system::RawOrigin::Root.into(), + // Bounded::Lookup { hash, len }, + // )?; Ok(().into()) } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 1d2236dc3..289e9effe 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -12,7 +12,6 @@ pub mod check_nonce; mod migrations; use codec::{Decode, Encode, MaxEncodedLen}; -use frame_support::traits::schedule::v3::Named as ScheduleNamed; use frame_support::{ dispatch::DispatchResultWithPostInfo, genesis_builder_helper::{build_config, create_default_config}, @@ -840,19 +839,6 @@ impl pallet_commitments::Config for Runtime { type RateLimit = CommitmentRateLimit; } -impl pallet_scheduler::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type RuntimeOrigin = RuntimeOrigin; - type PalletsOrigin = OriginCaller; - type RuntimeCall = RuntimeCall; - type MaximumWeight = MaximumSchedulerWeight; - type ScheduleOrigin = EnsureRoot; - type MaxScheduledPerBlock = ConstU32<50>; - type WeightInfo = pallet_scheduler::weights::SubstrateWeight; - type OriginPrivilegeCmp = EqualPrivilegeOnly; - type Preimages = Preimage; -} - // Configure the pallet subtensor. parameter_types! { pub const SubtensorInitialRho: u16 = 10; @@ -912,9 +898,7 @@ impl pallet_subtensor::Config for Runtime { type CouncilOrigin = EnsureMajoritySenate; type SenateMembers = ManageSenateMembers; type TriumvirateInterface = TriumvirateVotes; - type Scheduler = pallet_scheduler::Pallet; - type Hasher = BlakeTwo256; - + type Scheduler = Scheduler; type InitialRho = SubtensorInitialRho; type InitialKappa = SubtensorInitialKappa; type InitialMaxAllowedUids = SubtensorInitialMaxAllowedUids; From 2260fa0340dbb6f15991068314f79503e6db6446 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 30 Jul 2024 20:15:19 +0800 Subject: [PATCH 04/44] fix error --- pallets/subtensor/src/macros/dispatches.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 43eeb4105..f5599adae 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -972,18 +972,22 @@ mod dispatches { ) .using_encoded(sp_io::hashing::blake2_256); - let hash = sp_runtime::traits::BlakeTwo256::hash_of(&call); + let hash = , + CallOf, + PalletsOriginOf, + >>::Hasher::hash_of(&call); let len = call.using_encoded(|e| e.len() as u32); - // T::Scheduler::schedule_named( - // unique_id, - // DispatchTime::At(when), - // None, - // 63, - // frame_system::RawOrigin::Root.into(), - // Bounded::Lookup { hash, len }, - // )?; + T::Scheduler::schedule_named( + unique_id, + DispatchTime::At(when), + None, + 63, + frame_system::RawOrigin::Root.into(), + Bounded::Lookup { hash, len }, + )?; Ok(().into()) } From ed345c5428ce858b18211179592079cf410538a9 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 30 Jul 2024 22:10:34 +0800 Subject: [PATCH 05/44] fix clippy --- pallets/collective/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pallets/collective/src/lib.rs b/pallets/collective/src/lib.rs index c6552b036..e3c64f1a7 100644 --- a/pallets/collective/src/lib.rs +++ b/pallets/collective/src/lib.rs @@ -951,9 +951,9 @@ impl, I: 'static> Pallet { /// /// If not `approved`: /// - one event deposited. - /// Two removals, one mutation. - /// Computation and i/o `O(P)` where: - /// - `P` is number of active proposals + /// - Two removals, one mutation. + /// - Computation and i/o `O(P)` where: + /// - `P` is number of active proposals fn do_approve_proposal( seats: MemberCount, yes_votes: MemberCount, From 3e6d1af7375cca6adc82241f5d838c398cd694b6 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 30 Jul 2024 22:19:07 +0800 Subject: [PATCH 06/44] fix clippy --- pallets/collective/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/collective/src/lib.rs b/pallets/collective/src/lib.rs index e3c64f1a7..0ce5e3e08 100644 --- a/pallets/collective/src/lib.rs +++ b/pallets/collective/src/lib.rs @@ -951,8 +951,8 @@ impl, I: 'static> Pallet { /// /// If not `approved`: /// - one event deposited. - /// - Two removals, one mutation. - /// - Computation and i/o `O(P)` where: + /// - Two removals, one mutation. + /// - Computation and i/o `O(P)` where: /// - `P` is number of active proposals fn do_approve_proposal( seats: MemberCount, From 8dda65de145547fd050b34a99fd58d3177cded80 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 30 Jul 2024 22:51:56 +0800 Subject: [PATCH 07/44] fix unit test --- pallets/admin-utils/Cargo.toml | 3 ++- pallets/admin-utils/tests/mock.rs | 40 +++++++++++++++++++++++++++---- pallets/subtensor/Cargo.toml | 2 ++ pallets/subtensor/tests/mock.rs | 34 ++++++++++++++++++++++++-- 4 files changed, 71 insertions(+), 8 deletions(-) diff --git a/pallets/admin-utils/Cargo.toml b/pallets/admin-utils/Cargo.toml index 859972fce..97371a79f 100644 --- a/pallets/admin-utils/Cargo.toml +++ b/pallets/admin-utils/Cargo.toml @@ -37,7 +37,8 @@ sp-io = { workspace = true } sp-tracing = { workspace = true } sp-consensus-aura = { workspace = true } pallet-balances = { workspace = true, features = ["std"] } - +pallet-scheduler = { workspace = true } +sp-std = { workspace = true } [features] default = ["std"] diff --git a/pallets/admin-utils/tests/mock.rs b/pallets/admin-utils/tests/mock.rs index 7ae11b6fb..4b08c578b 100644 --- a/pallets/admin-utils/tests/mock.rs +++ b/pallets/admin-utils/tests/mock.rs @@ -2,19 +2,20 @@ use frame_support::{ assert_ok, derive_impl, parameter_types, - traits::{Everything, Hooks}, + traits::{Everything, Hooks, PrivilegeCmp}, weights, }; use frame_system as system; -use frame_system::{limits, EnsureNever}; +use frame_system::{limits, EnsureNever, EnsureRoot}; use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_core::U256; use sp_core::{ConstU64, H256}; use sp_runtime::{ traits::{BlakeTwo256, ConstU32, IdentityLookup}, - BuildStorage, DispatchError, + BuildStorage, DispatchError, Perbill, }; - +use sp_std::cmp::Ordering; +use sp_weights::Weight; type Block = frame_system::mocking::MockBlock; // Configure a mock runtime to test the pallet. @@ -25,6 +26,7 @@ frame_support::construct_runtime!( Balances: pallet_balances, AdminUtils: pallet_admin_utils, SubtensorModule: pallet_subtensor::{Pallet, Call, Storage, Event, Error}, + Scheduler: pallet_scheduler, } ); @@ -126,7 +128,7 @@ impl pallet_subtensor::Config for Test { type CouncilOrigin = EnsureNever; type SenateMembers = (); type TriumvirateInterface = (); - + type Scheduler = Scheduler; type InitialMinAllowedWeights = InitialMinAllowedWeights; type InitialEmissionValue = InitialEmissionValue; type InitialMaxWeightsLimit = InitialMaxWeightsLimit; @@ -218,6 +220,34 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); } +pub struct OriginPrivilegeCmp; + +impl PrivilegeCmp for OriginPrivilegeCmp { + fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option { + None + } +} + +parameter_types! { + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * + BlockWeights::get().max_block; + pub const MaxScheduledPerBlock: u32 = 50; + pub const NoPreimagePostponement: Option = Some(10); +} + +impl pallet_scheduler::Config for Test { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type MaximumWeight = MaximumSchedulerWeight; + type ScheduleOrigin = EnsureRoot; + type MaxScheduledPerBlock = MaxScheduledPerBlock; + type WeightInfo = pallet_scheduler::weights::SubstrateWeight; + type OriginPrivilegeCmp = OriginPrivilegeCmp; + type Preimages = (); +} + pub struct SubtensorIntrf; impl pallet_admin_utils::SubtensorInterface for SubtensorIntrf { diff --git a/pallets/subtensor/Cargo.toml b/pallets/subtensor/Cargo.toml index a0835008f..b002c2371 100644 --- a/pallets/subtensor/Cargo.toml +++ b/pallets/subtensor/Cargo.toml @@ -48,12 +48,14 @@ num-traits = { version = "0.2.19", default-features = false, features = ["libm"] [dev-dependencies] pallet-balances = { workspace = true, features = ["std"] } +pallet-scheduler = { workspace = true } sp-version = { workspace = true } # Substrate sp-tracing = { workspace = true } parity-util-mem = { workspace = true, features = ["primitive-types"] } rand = { workspace = true } sp-core = { workspace = true } +sp-std = { workspace = true } [features] default = ["std"] diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 27d11eb13..6f75fcb1a 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -6,7 +6,7 @@ use frame_support::weights::constants::RocksDbWeight; use frame_support::weights::Weight; use frame_support::{ assert_ok, parameter_types, - traits::{Everything, Hooks}, + traits::{Everything, Hooks, PrivilegeCmp}, }; use frame_system as system; use frame_system::{limits, EnsureNever, EnsureRoot, RawOrigin}; @@ -17,6 +17,7 @@ use sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, BuildStorage, }; +use sp_std::cmp::Ordering; type Block = frame_system::mocking::MockBlock; @@ -32,6 +33,7 @@ frame_support::construct_runtime!( SenateMembers: pallet_membership::::{Pallet, Call, Storage, Event, Config}, SubtensorModule: pallet_subtensor::{Pallet, Call, Storage, Event}, Utility: pallet_utility::{Pallet, Call, Storage, Event}, + Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event}, } ); @@ -336,7 +338,7 @@ impl pallet_subtensor::Config for Test { type CouncilOrigin = frame_system::EnsureSigned; type SenateMembers = ManageSenateMembers; type TriumvirateInterface = TriumvirateVotes; - + type Scheduler = Scheduler; type InitialMinAllowedWeights = InitialMinAllowedWeights; type InitialEmissionValue = InitialEmissionValue; type InitialMaxWeightsLimit = InitialMaxWeightsLimit; @@ -385,6 +387,34 @@ impl pallet_subtensor::Config for Test { type InitialNetworkMaxStake = InitialNetworkMaxStake; } +pub struct OriginPrivilegeCmp; + +impl PrivilegeCmp for OriginPrivilegeCmp { + fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option { + None + } +} + +parameter_types! { + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * + BlockWeights::get().max_block; + pub const MaxScheduledPerBlock: u32 = 50; + pub const NoPreimagePostponement: Option = Some(10); +} + +impl pallet_scheduler::Config for Test { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type MaximumWeight = MaximumSchedulerWeight; + type ScheduleOrigin = EnsureRoot; + type MaxScheduledPerBlock = MaxScheduledPerBlock; + type WeightInfo = pallet_scheduler::weights::SubstrateWeight; + type OriginPrivilegeCmp = OriginPrivilegeCmp; + type Preimages = (); +} + impl pallet_utility::Config for Test { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; From 0b5e24d0687d7a1aaef277208cae81b77a18b883 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Wed, 31 Jul 2024 00:16:42 +0400 Subject: [PATCH 08/44] chore: scheduler tests --- Cargo.lock | 3 + pallets/subtensor/src/macros/dispatches.rs | 9 +- pallets/subtensor/src/macros/errors.rs | 6 + pallets/subtensor/src/macros/events.rs | 2 +- pallets/subtensor/tests/swap_coldkey.rs | 194 +++++++++++++++++++++ runtime/src/lib.rs | 2 +- runtime/tests/pallet_proxy.rs | 2 +- 7 files changed, 214 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a50f8a12..ea30f4e25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4976,6 +4976,7 @@ dependencies = [ "frame-system", "log", "pallet-balances", + "pallet-scheduler", "pallet-subtensor", "parity-scale-codec", "scale-info", @@ -4983,6 +4984,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-weights", "substrate-fixed", @@ -5264,6 +5266,7 @@ dependencies = [ "pallet-balances", "pallet-collective", "pallet-membership", + "pallet-scheduler", "pallet-transaction-payment", "pallet-utility", "parity-scale-codec", diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index f5599adae..6a88d44ca 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -987,7 +987,14 @@ mod dispatches { 63, frame_system::RawOrigin::Root.into(), Bounded::Lookup { hash, len }, - )?; + ) + .map_err(|_| Error::::FailedToSchedule)?; + // Emit the SwapScheduled event + Self::deposit_event(Event::ColdkeySwapScheduled { + old_coldkey: who.clone(), + new_coldkey: new_coldkey.clone(), + execution_block: when, + }); Ok(().into()) } diff --git a/pallets/subtensor/src/macros/errors.rs b/pallets/subtensor/src/macros/errors.rs index 156cbea56..d51469482 100644 --- a/pallets/subtensor/src/macros/errors.rs +++ b/pallets/subtensor/src/macros/errors.rs @@ -168,5 +168,11 @@ mod errors { TooManyChildren, /// Default transaction rate limit exceeded. TxRateLimitExceeded, + /// Swap coldkey only callable by root. + SwapColdkeyOnlyCallableByRoot, + /// Swap already scheduled. + SwapAlreadyScheduled, + /// failed to swap coldkey + FailedToSchedule, } } diff --git a/pallets/subtensor/src/macros/events.rs b/pallets/subtensor/src/macros/events.rs index b93b8296b..b2c14ae76 100644 --- a/pallets/subtensor/src/macros/events.rs +++ b/pallets/subtensor/src/macros/events.rs @@ -164,7 +164,7 @@ mod events { /// The account ID of the new coldkey new_coldkey: T::AccountId, /// The arbitration block for the coldkey swap - arbitration_block: u64, + execution_block: BlockNumberFor, }, /// The arbitration period has been extended ArbitrationPeriodExtended { diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index 9203e2b3f..6ea0bb542 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -4,10 +4,16 @@ use frame_support::weights::Weight; use frame_support::{assert_err, assert_noop, assert_ok}; use frame_system::{Config, RawOrigin}; mod mock; +use frame_support::error::BadOrigin; +use frame_support::traits::schedule::v3::Named as ScheduleNamed; +use frame_support::traits::schedule::DispatchTime; +use frame_support::traits::OnInitialize; use mock::*; use pallet_subtensor::*; +use pallet_subtensor::{Call, Error}; use sp_core::H256; use sp_core::U256; +use sp_runtime::DispatchError; // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_total_hotkey_coldkey_stakes_this_interval --exact --nocapture #[test] @@ -1286,3 +1292,191 @@ fn test_coldkey_delegations() { assert_eq!(Stake::::get(delegate, coldkey), 0); }); } + +#[test] +fn test_schedule_swap_coldkey_success() { + new_test_ext(1).execute_with(|| { + // Initialize test accounts + let old_coldkey: U256 = U256::from(1); + let new_coldkey: U256 = U256::from(2); + + // Add balance to the old coldkey account + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 1000); + + // Schedule the coldkey swap + assert_ok!(SubtensorModule::schedule_swap_coldkey( + <::RuntimeOrigin>::signed(old_coldkey), + new_coldkey + )); + + // Get the current block number + let current_block: u64 = System::block_number(); + + // Calculate the expected execution block (5 days from now) + let expected_execution_block: u64 = current_block + 5 * 24 * 60 * 60 / 12; + + // Check for the SwapScheduled event + System::assert_last_event( + Event::ColdkeySwapScheduled { + old_coldkey, + new_coldkey, + execution_block: expected_execution_block, + } + .into(), + ); + + // TODO: Add additional checks to ensure the swap is correctly scheduled in the system + // For example, verify that the swap is present in the appropriate storage or scheduler + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_schedule_swap_coldkey_duplicate --exact --nocapture +#[test] +fn test_schedule_swap_coldkey_duplicate() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 2000); + + assert_ok!(SubtensorModule::schedule_swap_coldkey( + <::RuntimeOrigin>::signed(old_coldkey), + new_coldkey + )); + + // Attempt to schedule again + assert_noop!( + SubtensorModule::schedule_swap_coldkey( + <::RuntimeOrigin>::signed(old_coldkey), + new_coldkey + ), + Error::::FailedToSchedule + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_schedule_swap_coldkey_execution --exact --nocapture +#[test] +fn test_schedule_swap_coldkey_execution() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let hotkey = U256::from(3); + let netuid = 1u16; + let stake_amount = 100; + + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, old_coldkey, 0); + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 1000); + assert_ok!(SubtensorModule::add_stake( + <::RuntimeOrigin>::signed(old_coldkey), + hotkey, + stake_amount + )); + + // Check initial ownership + assert_eq!( + Owner::::get(hotkey), + old_coldkey, + "Initial ownership check failed" + ); + + // Schedule the swap + assert_ok!(SubtensorModule::schedule_swap_coldkey( + <::RuntimeOrigin>::signed(old_coldkey), + new_coldkey + )); + + // Get the scheduled execution block + let current_block = System::block_number(); + let blocks_in_5_days = 5 * 24 * 60 * 60 / 12; + let execution_block = current_block + blocks_in_5_days; + + println!("Current block: {}", current_block); + println!("Execution block: {}", execution_block); + + // Fast forward to the execution block + // System::set_block_number(execution_block); + run_to_block(execution_block); + + // Run on_initialize for the execution block + SubtensorModule::on_initialize(execution_block); + + // // Also run Scheduler's on_initialize + // as OnInitialize>::on_initialize( + // execution_block, + // ); + + // // Check if the swap has occurred + // let new_owner = Owner::::get(hotkey); + // println!("New owner after swap: {:?}", new_owner); + // assert_eq!( + // new_owner, new_coldkey, + // "Ownership was not updated as expected" + // ); + + // assert_eq!( + // Stake::::get(hotkey, new_coldkey), + // stake_amount, + // "Stake was not transferred to new coldkey" + // ); + // assert_eq!( + // Stake::::get(hotkey, old_coldkey), + // 0, + // "Old coldkey still has stake" + // ); + + // Check for the SwapExecuted event + System::assert_last_event( + Event::ColdkeySwapScheduled { + old_coldkey, + new_coldkey, + execution_block, + } + .into(), + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_direct_swap_coldkey_call_fails --exact --nocapture +#[test] +fn test_direct_swap_coldkey_call_fails() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + + assert_noop!( + SubtensorModule::swap_coldkey( + <::RuntimeOrigin>::signed(old_coldkey), + new_coldkey + ), + BadOrigin + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_schedule_swap_coldkey_with_pending_swap --exact --nocapture +#[test] +fn test_schedule_swap_coldkey_with_pending_swap() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey1 = U256::from(2); + let new_coldkey2 = U256::from(3); + + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 2000); + + assert_ok!(SubtensorModule::schedule_swap_coldkey( + <::RuntimeOrigin>::signed(old_coldkey), + new_coldkey1 + )); + + // Attempt to schedule another swap before the first one executes + assert_noop!( + SubtensorModule::schedule_swap_coldkey( + <::RuntimeOrigin>::signed(old_coldkey), + new_coldkey2 + ), + Error::::SwapAlreadyScheduled + ); + }); +} diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 289e9effe..d6699e759 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -144,7 +144,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 191, + spec_version: 192, impl_version: 1, apis: RUNTIME_API_VERSIONS, diff --git a/runtime/tests/pallet_proxy.rs b/runtime/tests/pallet_proxy.rs index 192893c1e..796dfc471 100644 --- a/runtime/tests/pallet_proxy.rs +++ b/runtime/tests/pallet_proxy.rs @@ -4,7 +4,7 @@ use codec::Encode; use frame_support::{assert_ok, traits::InstanceFilter, BoundedVec}; use node_subtensor_runtime::{ AccountId, BalancesCall, BuildStorage, Proxy, ProxyType, Runtime, RuntimeCall, RuntimeEvent, - RuntimeGenesisConfig, RuntimeOrigin, SchedulerCall, SubtensorModule, System, SystemCall, + RuntimeGenesisConfig, RuntimeOrigin, SubtensorModule, System, SystemCall, }; const ACCOUNT: [u8; 32] = [1_u8; 32]; From 850caf681d85e3bb4f7b32eee0c496392dcf160f Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Wed, 31 Jul 2024 01:29:29 +0400 Subject: [PATCH 09/44] chore: lints --- pallets/subtensor/tests/children.rs | 1 - pallets/subtensor/tests/coinbase.rs | 8 ++++---- pallets/subtensor/tests/difficulty.rs | 2 +- pallets/subtensor/tests/epoch.rs | 2 +- pallets/subtensor/tests/mock.rs | 4 ++++ pallets/subtensor/tests/neuron_info.rs | 2 +- pallets/subtensor/tests/registration.rs | 2 +- pallets/subtensor/tests/serving.rs | 4 ++-- pallets/subtensor/tests/staking.rs | 4 ++-- pallets/subtensor/tests/weights.rs | 6 +++--- runtime/src/lib.rs | 1 + 11 files changed, 20 insertions(+), 16 deletions(-) diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index 9ad07e1e7..e834baa85 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -297,7 +297,6 @@ fn test_do_set_child_singular_multiple_children() { // SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_add_singular_child --exact --nocapture #[test] -#[cfg(not(tarpaulin))] fn test_add_singular_child() { new_test_ext(1).execute_with(|| { let netuid: u16 = 1; diff --git a/pallets/subtensor/tests/coinbase.rs b/pallets/subtensor/tests/coinbase.rs index 8fd963dff..a6c1acde1 100644 --- a/pallets/subtensor/tests/coinbase.rs +++ b/pallets/subtensor/tests/coinbase.rs @@ -6,7 +6,7 @@ use sp_core::U256; // Test the ability to hash all sorts of hotkeys. #[test] -#[cfg(not(tarpaulin))] + fn test_hotkey_hashing() { new_test_ext(1).execute_with(|| { for i in 0..10000 { @@ -18,7 +18,7 @@ fn test_hotkey_hashing() { // Test drain tempo on hotkeys. // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test coinbase test_hotkey_drain_time -- --nocapture #[test] -#[cfg(not(tarpaulin))] + fn test_hotkey_drain_time() { new_test_ext(1).execute_with(|| { // Block 0 @@ -46,7 +46,7 @@ fn test_hotkey_drain_time() { // To run this test specifically, use the following command: // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test coinbase test_coinbase_basic -- --nocapture #[test] -#[cfg(not(tarpaulin))] + fn test_coinbase_basic() { new_test_ext(1).execute_with(|| { // Define network ID @@ -138,7 +138,7 @@ fn test_coinbase_basic() { // Test getting and setting hotkey emission tempo // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test coinbase test_set_and_get_hotkey_emission_tempo -- --nocapture #[test] -#[cfg(not(tarpaulin))] + fn test_set_and_get_hotkey_emission_tempo() { new_test_ext(1).execute_with(|| { // Get the default hotkey emission tempo diff --git a/pallets/subtensor/tests/difficulty.rs b/pallets/subtensor/tests/difficulty.rs index 05238bc43..b9524de57 100644 --- a/pallets/subtensor/tests/difficulty.rs +++ b/pallets/subtensor/tests/difficulty.rs @@ -5,7 +5,7 @@ mod mock; use sp_core::U256; #[test] -#[cfg(not(tarpaulin))] + fn test_registration_difficulty_adjustment() { new_test_ext(1).execute_with(|| { // Create Net 1 diff --git a/pallets/subtensor/tests/epoch.rs b/pallets/subtensor/tests/epoch.rs index 526a58b4e..53a825fee 100644 --- a/pallets/subtensor/tests/epoch.rs +++ b/pallets/subtensor/tests/epoch.rs @@ -2107,7 +2107,7 @@ fn test_zero_weights() { // Test that epoch assigns validator permits to highest stake uids, varies uid interleaving and stake values. #[test] -#[cfg(not(tarpaulin))] + fn test_validator_permits() { let netuid: u16 = 1; let tempo: u16 = u16::MAX - 1; // high tempo to skip automatic epochs in on_initialize, use manual epochs instead diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 6f75fcb1a..5503b8190 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -266,6 +266,7 @@ impl CollectiveInterface for TriumvirateVotes { } // We call pallet_collective TriumvirateCollective +#[allow(dead_code)] type TriumvirateCollective = pallet_collective::Instance1; impl pallet_collective::Config for Test { type RuntimeOrigin = RuntimeOrigin; @@ -283,6 +284,7 @@ impl pallet_collective::Config for Test { } // We call council members Triumvirate +#[allow(dead_code)] type TriumvirateMembership = pallet_membership::Instance1; impl pallet_membership::Config for Test { type RuntimeEvent = RuntimeEvent; @@ -299,6 +301,7 @@ impl pallet_membership::Config for Test { // This is a dummy collective instance for managing senate members // Probably not the best solution, but fastest implementation +#[allow(dead_code)] type SenateCollective = pallet_collective::Instance2; impl pallet_collective::Config for Test { type RuntimeOrigin = RuntimeOrigin; @@ -316,6 +319,7 @@ impl pallet_collective::Config for Test { } // We call our top K delegates membership Senate +#[allow(dead_code)] type SenateMembership = pallet_membership::Instance2; impl pallet_membership::Config for Test { type RuntimeEvent = RuntimeEvent; diff --git a/pallets/subtensor/tests/neuron_info.rs b/pallets/subtensor/tests/neuron_info.rs index 10df1c07d..4375979bd 100644 --- a/pallets/subtensor/tests/neuron_info.rs +++ b/pallets/subtensor/tests/neuron_info.rs @@ -15,7 +15,7 @@ fn test_get_neuron_none() { } #[test] -#[cfg(not(tarpaulin))] + fn test_get_neuron_some() { new_test_ext(1).execute_with(|| { let netuid: u16 = 1; diff --git a/pallets/subtensor/tests/registration.rs b/pallets/subtensor/tests/registration.rs index bd95ae3b1..f951971f5 100644 --- a/pallets/subtensor/tests/registration.rs +++ b/pallets/subtensor/tests/registration.rs @@ -539,7 +539,7 @@ fn test_burn_adjustment() { } #[test] -#[cfg(not(tarpaulin))] + fn test_registration_too_many_registrations_per_block() { new_test_ext(1).execute_with(|| { let netuid: u16 = 1; diff --git a/pallets/subtensor/tests/serving.rs b/pallets/subtensor/tests/serving.rs index 41e9888cc..8232a936d 100644 --- a/pallets/subtensor/tests/serving.rs +++ b/pallets/subtensor/tests/serving.rs @@ -161,7 +161,7 @@ fn test_serving_set_metadata_update() { } #[test] -#[cfg(not(tarpaulin))] + fn test_axon_serving_rate_limit_exceeded() { new_test_ext(1).execute_with(|| { let hotkey_account_id = U256::from(1); @@ -379,7 +379,7 @@ fn test_prometheus_serving_set_metadata_update() { } #[test] -#[cfg(not(tarpaulin))] + fn test_prometheus_serving_rate_limit_exceeded() { new_test_ext(1).execute_with(|| { let hotkey_account_id = U256::from(1); diff --git a/pallets/subtensor/tests/staking.rs b/pallets/subtensor/tests/staking.rs index 2952426a9..409348180 100644 --- a/pallets/subtensor/tests/staking.rs +++ b/pallets/subtensor/tests/staking.rs @@ -15,7 +15,7 @@ use sp_core::{H256, U256}; ************************************************************/ #[test] -#[cfg(not(tarpaulin))] + fn test_add_stake_dispatch_info_ok() { new_test_ext(1).execute_with(|| { let hotkey = U256::from(0); @@ -521,7 +521,7 @@ fn test_remove_stake_rate_limit_exceeded() { } #[test] -#[cfg(not(tarpaulin))] + fn test_remove_stake_dispatch_info_ok() { new_test_ext(1).execute_with(|| { let hotkey = U256::from(0); diff --git a/pallets/subtensor/tests/weights.rs b/pallets/subtensor/tests/weights.rs index 2344bd425..f56b5e038 100644 --- a/pallets/subtensor/tests/weights.rs +++ b/pallets/subtensor/tests/weights.rs @@ -21,7 +21,7 @@ use substrate_fixed::types::I32F32; // Test the call passes through the subtensor module. #[test] -#[cfg(not(tarpaulin))] + fn test_set_weights_dispatch_info_ok() { new_test_ext(0).execute_with(|| { let dests = vec![1, 1]; @@ -41,7 +41,7 @@ fn test_set_weights_dispatch_info_ok() { }); } #[test] -#[cfg(not(tarpaulin))] + fn test_set_rootweights_dispatch_info_ok() { new_test_ext(0).execute_with(|| { let dests = vec![1, 1]; @@ -404,7 +404,7 @@ fn test_weights_err_no_validator_permit() { // To execute this test: cargo test --package pallet-subtensor --test weights test_set_weights_min_stake_failed -- --nocapture` #[test] -#[cfg(not(tarpaulin))] + fn test_set_weights_min_stake_failed() { new_test_ext(0).execute_with(|| { let dests = vec![0]; diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index d6699e759..000e3d7a1 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -522,6 +522,7 @@ impl pallet_collective::Config for Runtime { } // We call council members Triumvirate +#[allow(dead_code)] type TriumvirateMembership = pallet_membership::Instance1; impl pallet_membership::Config for Runtime { type RuntimeEvent = RuntimeEvent; From d790ab394446f41086417e0ab8489c747b529290 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Wed, 31 Jul 2024 02:58:47 +0400 Subject: [PATCH 10/44] fix: hotkey swap delegates --- pallets/subtensor/src/swap/swap_hotkey.rs | 11 +++---- pallets/subtensor/tests/swap_hotkey.rs | 35 +++++++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/pallets/subtensor/src/swap/swap_hotkey.rs b/pallets/subtensor/src/swap/swap_hotkey.rs index fb3c33e4d..f39948339 100644 --- a/pallets/subtensor/src/swap/swap_hotkey.rs +++ b/pallets/subtensor/src/swap/swap_hotkey.rs @@ -200,11 +200,12 @@ impl Pallet { // 8. Swap delegates. // Delegates( hotkey ) -> take value -- the hotkey delegate take value. - let old_delegate_take = Delegates::::get(old_hotkey); - Delegates::::remove(old_hotkey); // Remove the old delegate take. - Delegates::::insert(new_hotkey, old_delegate_take); // Insert the new delegate take. - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - + if Delegates::::contains_key(old_hotkey) { + let old_delegate_take = Delegates::::get(old_hotkey); + Delegates::::remove(old_hotkey); + Delegates::::insert(new_hotkey, old_delegate_take); + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + } // 9. Swap all subnet specific info. let all_netuids: Vec = Self::get_all_subnet_netuids(); for netuid in all_netuids { diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs index c6a05f2b6..94abf73ea 100644 --- a/pallets/subtensor/tests/swap_hotkey.rs +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -959,3 +959,38 @@ fn test_swap_hotkey_error_cases() { assert_eq!(Balances::free_balance(coldkey), initial_balance - swap_cost); }); } + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_becomes_delegate --exact --nocapture +#[test] +fn test_swap_hotkey_becomes_delegate() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let tempo: u16 = 13; + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let swap_cost = 1_000_000_000u64 * 2; + let delegate_take = 10u16; + + // Setup initial state + add_network(netuid, tempo, 0); + register_ok_neuron(netuid, old_hotkey, coldkey, 0); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, swap_cost); + + // Ensure old_hotkey is not a delegate + assert!(!Delegates::::contains_key(old_hotkey)); + + // Perform the swap + assert_ok!(SubtensorModule::do_swap_hotkey( + <::RuntimeOrigin>::signed(coldkey), + &old_hotkey, + &new_hotkey + )); + + // Check that old_hotkey is no longer a delegate + assert!(!Delegates::::contains_key(old_hotkey)); + + // Check that new_hotkey is now a delegate with the correct take value + assert!(!Delegates::::contains_key(new_hotkey)); + }); +} From 50179b5604b91e6be6f9f131c9a9b7bdc1600494 Mon Sep 17 00:00:00 2001 From: distributedstatemachine <112424909+distributedstatemachine@users.noreply.github.com> Date: Wed, 31 Jul 2024 03:12:42 +0400 Subject: [PATCH 11/44] Update pallets/subtensor/tests/swap_hotkey.rs Co-authored-by: Cameron Fairchild --- pallets/subtensor/tests/swap_hotkey.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs index 94abf73ea..417917af4 100644 --- a/pallets/subtensor/tests/swap_hotkey.rs +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -987,7 +987,7 @@ fn test_swap_hotkey_becomes_delegate() { &new_hotkey )); - // Check that old_hotkey is no longer a delegate + // Check that old_hotkey is still not a delegate assert!(!Delegates::::contains_key(old_hotkey)); // Check that new_hotkey is now a delegate with the correct take value From 6cbd4d07d9baff5cbe6ced6e3c95b00d2b11c833 Mon Sep 17 00:00:00 2001 From: distributedstatemachine <112424909+distributedstatemachine@users.noreply.github.com> Date: Wed, 31 Jul 2024 03:12:51 +0400 Subject: [PATCH 12/44] Update pallets/subtensor/tests/swap_hotkey.rs Co-authored-by: Cameron Fairchild --- pallets/subtensor/tests/swap_hotkey.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs index 417917af4..83ee58c2b 100644 --- a/pallets/subtensor/tests/swap_hotkey.rs +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -960,9 +960,9 @@ fn test_swap_hotkey_error_cases() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_becomes_delegate --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_does_not_become_delegate --exact --nocapture #[test] -fn test_swap_hotkey_becomes_delegate() { +fn test_swap_hotkey_does_not_become_delegate() { new_test_ext(1).execute_with(|| { let netuid: u16 = 1; let tempo: u16 = 13; From bdb3e176b8f8ddeada52197edcdbdaca1273069d Mon Sep 17 00:00:00 2001 From: distributedstatemachine <112424909+distributedstatemachine@users.noreply.github.com> Date: Wed, 31 Jul 2024 03:12:59 +0400 Subject: [PATCH 13/44] Update pallets/subtensor/tests/swap_hotkey.rs Co-authored-by: Cameron Fairchild --- pallets/subtensor/tests/swap_hotkey.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs index 83ee58c2b..2cadc01fe 100644 --- a/pallets/subtensor/tests/swap_hotkey.rs +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -990,7 +990,7 @@ fn test_swap_hotkey_does_not_become_delegate() { // Check that old_hotkey is still not a delegate assert!(!Delegates::::contains_key(old_hotkey)); - // Check that new_hotkey is now a delegate with the correct take value + // Check that new_hotkey is NOT a delegate either assert!(!Delegates::::contains_key(new_hotkey)); }); } From 883799fb0dd23c3bc1a33ff0c120a7fbc8993cda Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Wed, 31 Jul 2024 10:02:33 +0400 Subject: [PATCH 14/44] chore: additional tests --- pallets/subtensor/tests/swap_hotkey.rs | 127 +++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs index 2cadc01fe..ab8f08302 100644 --- a/pallets/subtensor/tests/swap_hotkey.rs +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -994,3 +994,130 @@ fn test_swap_hotkey_does_not_become_delegate() { assert!(!Delegates::::contains_key(new_hotkey)); }); } + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_with_delegate_and_stakes --exact --nocapture +#[test] +fn test_swap_hotkey_with_delegate_and_stakes() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let tempo: u16 = 13; + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let staker1 = U256::from(4); + let staker2 = U256::from(5); + let swap_cost = 1_000_000_000u64; + let delegate_take = 11_796; + let stake_amount1 = 100u64; + let stake_amount2 = 200u64; + + // Setup initial state + add_network(netuid, tempo, 0); + register_ok_neuron(netuid, old_hotkey, coldkey, 0); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, swap_cost); + SubtensorModule::add_balance_to_coldkey_account(&staker1, stake_amount1); + SubtensorModule::add_balance_to_coldkey_account(&staker2, stake_amount2); + + // Make old_hotkey a delegate + assert_ok!(SubtensorModule::become_delegate( + RuntimeOrigin::signed(coldkey), + old_hotkey, + )); + + // Add stakes to the delegate + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(staker1), + old_hotkey, + stake_amount1 + )); + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(staker2), + old_hotkey, + stake_amount2 + )); + + // Assert initial stake amounts + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&old_hotkey), + stake_amount1 + stake_amount2 - (ExistentialDeposit::get() * 2) + ); + + // Print entire staking hotkeys map + log::info!( + "StakingHotkeys before swap: {:?}", + StakingHotkeys::::iter().collect::>() + ); + + // Perform the swap + assert_ok!(SubtensorModule::do_swap_hotkey( + <::RuntimeOrigin>::signed(coldkey), + &old_hotkey, + &new_hotkey + )); + + // Check that new_hotkey is now a delegate with the same take + assert_eq!(Delegates::::get(new_hotkey), delegate_take); + assert!(!Delegates::::contains_key(old_hotkey)); + + // Check that stakes have been transferred to the new hotkey + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&new_hotkey), + stake_amount1 + stake_amount2 - (ExistentialDeposit::get() * 2) + ); + + assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&old_hotkey), 0); + + // Check that the total stake for the new hotkey is correct + assert_eq!( + TotalHotkeyStake::::get(new_hotkey), + stake_amount1 + stake_amount2 - (ExistentialDeposit::get() * 2) + ); + assert!(!TotalHotkeyStake::::contains_key(old_hotkey)); + + // Print entire staking hotkeys map + log::info!( + "StakingHotkeys after swap: {:?}", + StakingHotkeys::::iter().collect::>() + ); + + // Check that the staking hotkeys for the stakers have been updated + assert!(StakingHotkeys::::get(staker1).contains(&new_hotkey)); + assert!(StakingHotkeys::::get(staker2).contains(&new_hotkey)); + assert!(!StakingHotkeys::::get(staker1).contains(&old_hotkey)); + assert!(!StakingHotkeys::::get(staker2).contains(&old_hotkey)); + + // Check staking hotkeys for new hotkey + // Retrieve all stakers associated with the new hotkey + let new_hotkey_stakers = StakingHotkeys::::iter() + // Iterate through all entries in the StakingHotkeys storage map + .filter(|(_, hotkeys)| hotkeys.contains(&new_hotkey)) + // Keep only entries where the new_hotkey is in the list of hotkeys + .map(|(staker, _)| staker) + // Extract just the staker (coldkey) from each matching entry + .collect::>(); + // Collect the results into a vector + + log::info!("new_hotkey_stakers: {:?}", new_hotkey_stakers); + + assert_eq!(new_hotkey_stakers.len(), 2); + assert!(new_hotkey_stakers.contains(&staker1)); + assert!(new_hotkey_stakers.contains(&staker2)); + + // Verify that old_hotkey is not in any staker's StakingHotkeys + let old_hotkey_stakers = StakingHotkeys::::iter() + .filter(|(_, hotkeys)| hotkeys.contains(&old_hotkey)) + .count(); + + assert_eq!(old_hotkey_stakers, 0); + + // Check that the total balances of stakers haven't changed + assert_eq!( + SubtensorModule::get_coldkey_balance(&staker1), + ExistentialDeposit::get() + ); + assert_eq!( + SubtensorModule::get_coldkey_balance(&staker2), + ExistentialDeposit::get() + ); + }); +} From c61782ffd7828d4eb44a3bd59f2477fc7c57d265 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Wed, 31 Jul 2024 10:04:56 +0400 Subject: [PATCH 15/44] chore: bump spec version --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 66951b7fc..49c9bb786 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -139,7 +139,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 191, + spec_version: 193, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 3d4d57155c7a0a996cc32912b72a40b375ea5947 Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 31 Jul 2024 15:18:19 +0800 Subject: [PATCH 16/44] start the unit test fix --- pallets/subtensor/src/lib.rs | 4 ++++ pallets/subtensor/src/macros/dispatches.rs | 6 ++++++ pallets/subtensor/src/swap/swap_coldkey.rs | 5 ++++- pallets/subtensor/tests/swap_coldkey.rs | 17 +++++++++-------- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index f5febb0aa..321e58b4a 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -691,6 +691,10 @@ pub mod pallet { pub type OwnedHotkeys = StorageMap<_, Blake2_128Concat, T::AccountId, Vec, ValueQuery>; + #[pallet::storage] // --- DMAP ( cold ) --> () | Maps coldkey to if a coldkey swap is scheduled. + pub type ColdkeySwapScheduled = + StorageMap<_, Blake2_128Concat, T::AccountId, (), ValueQuery>; + /// ============================ /// ==== Global Parameters ===== /// ============================ diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 6a88d44ca..348f57f73 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -953,6 +953,10 @@ mod dispatches { new_coldkey: T::AccountId, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; + ensure!( + !ColdkeySwapScheduled::::contains_key(&who), + Error::::SwapAlreadyScheduled + ); // Calculate the number of blocks in 5 days let blocks_in_5_days: u32 = 5 * 24 * 60 * 60 / 12; @@ -989,6 +993,8 @@ mod dispatches { Bounded::Lookup { hash, len }, ) .map_err(|_| Error::::FailedToSchedule)?; + + ColdkeySwapScheduled::::insert(&who, ()); // Emit the SwapScheduled event Self::deposit_event(Event::ColdkeySwapScheduled { old_coldkey: who.clone(), diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index bd8a11fa1..b47b0ac95 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -74,7 +74,10 @@ impl Pallet { Self::set_last_tx_block(new_coldkey, Self::get_current_block_as_u64()); weight.saturating_accrue(T::DbWeight::get().writes(1)); - // 10. Emit the ColdkeySwapped event + // 10. Remove the coldkey swap scheduled record + ColdkeySwapScheduled::::remove(&old_coldkey); + + // 11. Emit the ColdkeySwapped event Self::deposit_event(Event::ColdkeySwapped { old_coldkey: old_coldkey.clone(), new_coldkey: new_coldkey.clone(), diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index 6ea0bb542..8c2bb2330 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -1395,6 +1395,15 @@ fn test_schedule_swap_coldkey_execution() { println!("Current block: {}", current_block); println!("Execution block: {}", execution_block); + System::assert_last_event( + Event::ColdkeySwapScheduled { + old_coldkey, + new_coldkey, + execution_block, + } + .into(), + ); + // Fast forward to the execution block // System::set_block_number(execution_block); run_to_block(execution_block); @@ -1427,14 +1436,6 @@ fn test_schedule_swap_coldkey_execution() { // ); // Check for the SwapExecuted event - System::assert_last_event( - Event::ColdkeySwapScheduled { - old_coldkey, - new_coldkey, - execution_block, - } - .into(), - ); }); } From cab0fc34f19d184aed8ff548b4f8d01dc18e3ade Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Wed, 31 Jul 2024 22:18:58 +0400 Subject: [PATCH 17/44] chore: fix tests --- pallets/subtensor/tests/swap_hotkey.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs index ab8f08302..b416e6b4d 100644 --- a/pallets/subtensor/tests/swap_hotkey.rs +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -1099,7 +1099,7 @@ fn test_swap_hotkey_with_delegate_and_stakes() { log::info!("new_hotkey_stakers: {:?}", new_hotkey_stakers); - assert_eq!(new_hotkey_stakers.len(), 2); + assert_eq!(new_hotkey_stakers.len(), 3); assert!(new_hotkey_stakers.contains(&staker1)); assert!(new_hotkey_stakers.contains(&staker2)); From a125856bb4aec20ab968c8dd3b6460a8c589ff50 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 11:19:24 +0800 Subject: [PATCH 18/44] fix unit test --- pallets/subtensor/Cargo.toml | 4 +- pallets/subtensor/src/macros/config.rs | 2 +- pallets/subtensor/src/macros/dispatches.rs | 29 ++++++-- pallets/subtensor/src/swap/swap_coldkey.rs | 1 + pallets/subtensor/tests/mock.rs | 81 ++++++++++++++++++++-- pallets/subtensor/tests/swap_coldkey.rs | 57 ++++++++------- 6 files changed, 138 insertions(+), 36 deletions(-) diff --git a/pallets/subtensor/Cargo.toml b/pallets/subtensor/Cargo.toml index b002c2371..37c579db0 100644 --- a/pallets/subtensor/Cargo.toml +++ b/pallets/subtensor/Cargo.toml @@ -24,7 +24,7 @@ sp-core = { workspace = true } pallet-balances = { workspace = true } scale-info = { workspace = true, features = ["derive"] } frame-benchmarking = { workspace = true, optional = true } -frame-support = { workspace = true } +frame-support = { workspace = true , features = ["experimental", "tuples-96"]} frame-system = { workspace = true } sp-io = { workspace = true } serde = { workspace = true, features = ["derive"] } @@ -56,6 +56,8 @@ parity-util-mem = { workspace = true, features = ["primitive-types"] } rand = { workspace = true } sp-core = { workspace = true } sp-std = { workspace = true } +pallet-preimage = { workspace = true } +pallet-parameters = { workspace = true } [features] default = ["std"] diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index d2504eb4e..82e3f5afc 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -31,7 +31,7 @@ mod config { type TriumvirateInterface: crate::CollectiveInterface; /// The scheduler type used for scheduling delayed calls. - type Scheduler: ScheduleNamed, CallOf, PalletsOriginOf>; + type Scheduler: ScheduleAnon, CallOf, PalletsOriginOf>; /// ================================= /// ==== Initial Value Constants ==== diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 348f57f73..3b1aa4418 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -4,6 +4,7 @@ use frame_support::pallet_macros::pallet_section; /// This can later be imported into the pallet using [`import_section`]. #[pallet_section] mod dispatches { + use frame_support::traits::schedule::v3::Anon as ScheduleAnon; use frame_support::traits::schedule::v3::Named as ScheduleNamed; use frame_support::traits::schedule::DispatchTime; use frame_support::traits::Bounded; @@ -959,7 +960,7 @@ mod dispatches { ); // Calculate the number of blocks in 5 days - let blocks_in_5_days: u32 = 5 * 24 * 60 * 60 / 12; + let blocks_in_5_days: u32 = 2; let current_block = >::block_number(); let when = current_block.saturating_add(BlockNumberFor::::from(blocks_in_5_days)); @@ -976,7 +977,7 @@ mod dispatches { ) .using_encoded(sp_io::hashing::blake2_256); - let hash = , CallOf, PalletsOriginOf, @@ -984,16 +985,34 @@ mod dispatches { let len = call.using_encoded(|e| e.len() as u32); - T::Scheduler::schedule_named( - unique_id, + // fn schedule( + // when: DispatchTime, + // maybe_periodic: Option>, + // priority: Priority, + // origin: Origin, + // call: Bounded, + // ) -> Result; + + T::Scheduler::schedule( DispatchTime::At(when), None, - 63, + 0, + // T::RuntimeOrigin::root(), frame_system::RawOrigin::Root.into(), Bounded::Lookup { hash, len }, ) .map_err(|_| Error::::FailedToSchedule)?; + // T::Scheduler::schedule_named( + // unique_id, + // DispatchTime::At(when), + // None, + // 63, + // frame_system::RawOrigin::Root.into(), + // Bounded::Lookup { hash, len }, + // ) + // .map_err(|_| Error::::FailedToSchedule)?; + ColdkeySwapScheduled::::insert(&who, ()); // Emit the SwapScheduled event Self::deposit_event(Event::ColdkeySwapScheduled { diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index b47b0ac95..5c866e663 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -33,6 +33,7 @@ impl Pallet { origin: T::RuntimeOrigin, new_coldkey: &T::AccountId, ) -> DispatchResultWithPostInfo { + log::info!("+++ do_swap_coldkey +++"); // 1. Ensure the origin is signed and get the old coldkey let old_coldkey = ensure_signed(origin)?; diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 5503b8190..62deba782 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -5,12 +5,17 @@ use frame_support::weights::constants::RocksDbWeight; // use frame_support::weights::constants::WEIGHT_PER_SECOND; use frame_support::weights::Weight; use frame_support::{ - assert_ok, parameter_types, - traits::{Everything, Hooks, PrivilegeCmp}, + assert_ok, + dynamic_params::{dynamic_pallet_params, dynamic_params}, + parameter_types, + traits::fungible::HoldConsideration, + traits::{Everything, Hooks, LinearStoragePrice, PrivilegeCmp}, }; use frame_system as system; use frame_system::{limits, EnsureNever, EnsureRoot, RawOrigin}; use pallet_collective::MemberCount; +use pallet_parameters; +use pallet_preimage; use sp_core::{Get, H256, U256}; use sp_runtime::Perbill; use sp_runtime::{ @@ -34,6 +39,8 @@ frame_support::construct_runtime!( SubtensorModule: pallet_subtensor::{Pallet, Call, Storage, Event}, Utility: pallet_utility::{Pallet, Call, Storage, Event}, Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event}, + Preimage: pallet_preimage::{Pallet, Call, Storage, Event}, + Parameters: pallet_parameters::{Pallet, Call, Storage, Event}, } ); @@ -69,6 +76,36 @@ pub type Balance = u64; #[allow(dead_code)] pub type BlockNumber = u64; +#[dynamic_params(RuntimeParameters, pallet_parameters::Parameters::)] +pub mod dynamic_params { + use super::*; + + #[dynamic_pallet_params] + #[codec(index = 0)] + pub mod storage { + /// Configures the base deposit of storing some data. + #[codec(index = 0)] + pub static BaseDeposit: Balance = 1; + + /// Configures the per-byte deposit of storing some data. + #[codec(index = 1)] + pub static ByteDeposit: Balance = 1; + } + + #[dynamic_pallet_params] + #[codec(index = 1)] + pub mod contracts { + #[codec(index = 0)] + pub static DepositPerItem: Balance = 1; + + #[codec(index = 1)] + pub static DepositPerByte: Balance = 1; + + #[codec(index = 2)] + pub static DefaultDepositLimit: Balance = 1; + } +} + #[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] impl pallet_balances::Config for Test { type Balance = Balance; @@ -395,7 +432,7 @@ pub struct OriginPrivilegeCmp; impl PrivilegeCmp for OriginPrivilegeCmp { fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option { - None + Some(Ordering::Less) } } @@ -416,7 +453,7 @@ impl pallet_scheduler::Config for Test { type MaxScheduledPerBlock = MaxScheduledPerBlock; type WeightInfo = pallet_scheduler::weights::SubstrateWeight; type OriginPrivilegeCmp = OriginPrivilegeCmp; - type Preimages = (); + type Preimages = Preimage; } impl pallet_utility::Config for Test { @@ -426,6 +463,34 @@ impl pallet_utility::Config for Test { type WeightInfo = pallet_utility::weights::SubstrateWeight; } +parameter_types! { + pub const PreimageMaxSize: u32 = 4096 * 1024; + pub const PreimageBaseDeposit: Balance = 1; + pub const PreimageByteDeposit: Balance = 1; + // pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage); +} + +impl pallet_preimage::Config for Test { + type WeightInfo = pallet_preimage::weights::SubstrateWeight; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type ManagerOrigin = EnsureRoot; + type Consideration = (); + // HoldConsideration< + // AccountId, + // Balances, + // PreimageHoldReason, + // LinearStoragePrice, + // >; +} + +impl pallet_parameters::Config for Test { + type RuntimeParameters = RuntimeParameters; + type RuntimeEvent = RuntimeEvent; + type AdminOrigin = EnsureRoot; + type WeightInfo = (); +} + #[allow(dead_code)] // Build genesis storage according to the mock runtime. pub fn new_test_ext(block_number: BlockNumber) -> sp_io::TestExternalities { @@ -460,22 +525,30 @@ pub fn test_ext_with_balances(balances: Vec<(U256, u128)>) -> sp_io::TestExterna #[allow(dead_code)] pub(crate) fn step_block(n: u16) { for _ in 0..n { + Scheduler::on_finalize(System::block_number()); SubtensorModule::on_finalize(System::block_number()); System::on_finalize(System::block_number()); System::set_block_number(System::block_number() + 1); System::on_initialize(System::block_number()); SubtensorModule::on_initialize(System::block_number()); + Scheduler::on_initialize(System::block_number()); } } #[allow(dead_code)] pub(crate) fn run_to_block(n: u64) { while System::block_number() < n { + Scheduler::on_finalize(System::block_number()); SubtensorModule::on_finalize(System::block_number()); System::on_finalize(System::block_number()); System::set_block_number(System::block_number() + 1); System::on_initialize(System::block_number()); + System::events().iter().for_each(|event| { + log::info!("Event: {:?}", event.event); + }); + System::reset_events(); SubtensorModule::on_initialize(System::block_number()); + Scheduler::on_initialize(System::block_number()); } } diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index 8c2bb2330..3ba9a0468 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -1389,7 +1389,7 @@ fn test_schedule_swap_coldkey_execution() { // Get the scheduled execution block let current_block = System::block_number(); - let blocks_in_5_days = 5 * 24 * 60 * 60 / 12; + let blocks_in_5_days = 2; let execution_block = current_block + blocks_in_5_days; println!("Current block: {}", current_block); @@ -1406,34 +1406,41 @@ fn test_schedule_swap_coldkey_execution() { // Fast forward to the execution block // System::set_block_number(execution_block); - run_to_block(execution_block); + for block_number in current_block..(execution_block + 3) { + log::info!("+++++ Block number: {}", block_number); + // System::events().iter().for_each(|event| { + // log::info!("Event: {:?}", event.event); + // }); + // Preimage::len(); + run_to_block(block_number + 1); + } // Run on_initialize for the execution block SubtensorModule::on_initialize(execution_block); - // // Also run Scheduler's on_initialize - // as OnInitialize>::on_initialize( - // execution_block, - // ); - - // // Check if the swap has occurred - // let new_owner = Owner::::get(hotkey); - // println!("New owner after swap: {:?}", new_owner); - // assert_eq!( - // new_owner, new_coldkey, - // "Ownership was not updated as expected" - // ); - - // assert_eq!( - // Stake::::get(hotkey, new_coldkey), - // stake_amount, - // "Stake was not transferred to new coldkey" - // ); - // assert_eq!( - // Stake::::get(hotkey, old_coldkey), - // 0, - // "Old coldkey still has stake" - // ); + // Also run Scheduler's on_initialize + as OnInitialize>::on_initialize( + execution_block, + ); + + // Check if the swap has occurred + let new_owner = Owner::::get(hotkey); + println!("New owner after swap: {:?}", new_owner); + assert_eq!( + new_owner, new_coldkey, + "Ownership was not updated as expected" + ); + + assert_eq!( + Stake::::get(hotkey, new_coldkey), + stake_amount, + "Stake was not transferred to new coldkey" + ); + assert_eq!( + Stake::::get(hotkey, old_coldkey), + 0, + "Old coldkey still has stake" + ); // Check for the SwapExecuted event }); From 0c1816cfd7b705dd17ffe0902d48b79384f4a361 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 15:41:50 +0800 Subject: [PATCH 19/44] fixed the config level issue --- pallets/subtensor/src/lib.rs | 20 ++++--- pallets/subtensor/src/macros/config.rs | 18 ++++++- pallets/subtensor/src/macros/dispatches.rs | 61 +++++++++++++++------- pallets/subtensor/src/swap/swap_coldkey.rs | 5 +- pallets/subtensor/tests/mock.rs | 2 + pallets/subtensor/tests/swap_coldkey.rs | 6 ++- runtime/src/lib.rs | 2 + 7 files changed, 83 insertions(+), 31 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 321e58b4a..34b4ab5b2 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -65,11 +65,13 @@ pub mod pallet { use frame_support::{ dispatch::GetDispatchInfo, pallet_prelude::{DispatchResult, StorageMap, ValueQuery, *}, - traits::{tokens::fungible, OriginTrait, UnfilteredDispatchable}, + traits::{ + tokens::fungible, OriginTrait, QueryPreimage, StorePreimage, UnfilteredDispatchable, + }, }; use frame_system::pallet_prelude::*; use sp_core::H256; - use sp_runtime::traits::TrailingZeroInput; + use sp_runtime::traits::{Dispatchable, TrailingZeroInput}; use sp_std::vec; use sp_std::vec::Vec; @@ -103,6 +105,9 @@ pub mod pallet { /// Struct for Axon. pub type AxonInfoOf = AxonInfo; + /// local one + pub type LocalCallOf = ::RuntimeCall; + /// Data structure for Axon information. #[derive(Encode, Decode, Default, TypeInfo, Clone, PartialEq, Eq, Debug)] pub struct AxonInfo { @@ -1189,7 +1194,8 @@ pub struct SubtensorSignedExtension(pub Phan impl Default for SubtensorSignedExtension where - T::RuntimeCall: Dispatchable, + ::RuntimeCall: + Dispatchable, ::RuntimeCall: IsSubType>, { fn default() -> Self { @@ -1199,7 +1205,8 @@ where impl SubtensorSignedExtension where - T::RuntimeCall: Dispatchable, + ::RuntimeCall: + Dispatchable, ::RuntimeCall: IsSubType>, { pub fn new() -> Self { @@ -1230,14 +1237,15 @@ impl sp_std::fmt::Debug for SubtensorSignedE impl SignedExtension for SubtensorSignedExtension where - T::RuntimeCall: Dispatchable, + ::RuntimeCall: + Dispatchable, ::RuntimeCall: IsSubType>, ::RuntimeCall: IsSubType>, { const IDENTIFIER: &'static str = "SubtensorSignedExtension"; type AccountId = T::AccountId; - type Call = T::RuntimeCall; + type Call = ::RuntimeCall; type AdditionalSigned = (); type Pre = (CallType, u64, Self::AccountId); diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index 82e3f5afc..c333dfed6 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -9,6 +9,13 @@ mod config { /// Configure the pallet by specifying the parameters and types on which it depends. #[pallet::config] pub trait Config: frame_system::Config { + /// call type + type RuntimeCall: Parameter + + Dispatchable + + From> + + IsType<::RuntimeCall> + + From>; + /// Because this pallet emits events, it depends on the runtime's definition of an event. type RuntimeEvent: From> + IsType<::RuntimeEvent>; @@ -31,7 +38,16 @@ mod config { type TriumvirateInterface: crate::CollectiveInterface; /// The scheduler type used for scheduling delayed calls. - type Scheduler: ScheduleAnon, CallOf, PalletsOriginOf>; + type Scheduler: ScheduleNamed, LocalCallOf, PalletsOriginOf> + + ScheduleAnon< + BlockNumberFor, + LocalCallOf, + PalletsOriginOf, + Hasher = Self::Hashing, + >; + + /// the preimage to store the call data. + type Preimages: QueryPreimage + StorePreimage; /// ================================= /// ==== Initial Value Constants ==== diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 3b1aa4418..3e3590bf9 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -683,10 +683,10 @@ mod dispatches { new_coldkey: T::AccountId, ) -> DispatchResultWithPostInfo { // Ensure it's called with root privileges (scheduler has root privileges) - ensure_root(origin.clone())?; + // ensure_root(origin.clone())?; let who = ensure_signed(origin)?; - Self::do_swap_coldkey(frame_system::RawOrigin::Signed(who).into(), &new_coldkey) + Self::do_swap_coldkey(&who, &new_coldkey) } /// Unstakes all tokens associated with a hotkey and transfers them to a new coldkey. @@ -969,21 +969,24 @@ mod dispatches { new_coldkey: new_coldkey.clone(), }; - let unique_id = ( - b"schedule_swap_coldkey", - who.clone(), - new_coldkey.clone(), - when, - ) - .using_encoded(sp_io::hashing::blake2_256); + let bound_call = T::Preimages::bound(LocalCallOf::::from(call.clone())) + .map_err(|_| Error::::FailedToSchedule)?; + + // let unique_id = ( + // b"schedule_swap_coldkey", + // who.clone(), + // new_coldkey.clone(), + // when, + // ) + // .using_encoded(sp_io::hashing::blake2_256); - let hash = , - CallOf, - PalletsOriginOf, - >>::Hasher::hash_of(&call); + // let hash = , + // CallOf, + // PalletsOriginOf, + // >>::Hasher::hash_of(&call); - let len = call.using_encoded(|e| e.len() as u32); + // let len = call.using_encoded(|e| e.len() as u32); // fn schedule( // when: DispatchTime, @@ -993,13 +996,33 @@ mod dispatches { // call: Bounded, // ) -> Result; + // T::Scheduler::schedule_named( + // unique_id, + // DispatchTime::At(when), + // None, + // 63, + // frame_system::RawOrigin::Root.into(), + // // bound_call, + // Bounded::Lookup { hash, len }, + // ) + // .map_err(|_| Error::::FailedToSchedule)?; + + // let result = T::Scheduler::schedule( + // DispatchTime::At(when), + // None, + // 128u8, + // frame_system::RawOrigin::Root.into(), + // call, + // ); + T::Scheduler::schedule( DispatchTime::At(when), None, - 0, - // T::RuntimeOrigin::root(), - frame_system::RawOrigin::Root.into(), - Bounded::Lookup { hash, len }, + 63, + // frame_system::RawOrigin::Root.into(), + frame_system::RawOrigin::Signed(who.clone()).into(), + // frame_system::RawOrigin::Signed(&who).into(), + bound_call, ) .map_err(|_| Error::::FailedToSchedule)?; diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index 5c866e663..1b87b386b 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -30,12 +30,11 @@ impl Pallet { /// /// Weight is tracked and updated throughout the function execution. pub fn do_swap_coldkey( - origin: T::RuntimeOrigin, + old_coldkey: &T::AccountId, new_coldkey: &T::AccountId, ) -> DispatchResultWithPostInfo { - log::info!("+++ do_swap_coldkey +++"); // 1. Ensure the origin is signed and get the old coldkey - let old_coldkey = ensure_signed(origin)?; + // let old_coldkey = ensure_signed(origin)?; // 2. Initialize the weight for this operation let mut weight: Weight = T::DbWeight::get().reads(2); diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 62deba782..c357e0948 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -373,6 +373,7 @@ impl pallet_membership::Config for Test { impl pallet_subtensor::Config for Test { type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; type Currency = Balances; type InitialIssuance = InitialIssuance; type SudoRuntimeCall = TestRuntimeCall; @@ -426,6 +427,7 @@ impl pallet_subtensor::Config for Test { type LiquidAlphaOn = InitialLiquidAlphaOn; type InitialHotkeyEmissionTempo = InitialHotkeyEmissionTempo; type InitialNetworkMaxStake = InitialNetworkMaxStake; + type Preimages = Preimage; } pub struct OriginPrivilegeCmp; diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index 3ba9a0468..b27549a8f 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -548,7 +548,8 @@ fn test_do_swap_coldkey_success() { // Perform the swap assert_ok!(SubtensorModule::do_swap_coldkey( - <::RuntimeOrigin>::signed(old_coldkey), + // <::RuntimeOrigin>::signed(old_coldkey), + &old_coldkey, &new_coldkey )); @@ -889,7 +890,8 @@ fn test_do_swap_coldkey_with_subnet_ownership() { // Perform the swap assert_ok!(SubtensorModule::do_swap_coldkey( - <::RuntimeOrigin>::signed(old_coldkey), + // <::RuntimeOrigin>::signed(old_coldkey), + &old_coldkey, &new_coldkey )); diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 000e3d7a1..12fb55586 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -894,6 +894,7 @@ parameter_types! { impl pallet_subtensor::Config for Runtime { type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; type SudoRuntimeCall = RuntimeCall; type Currency = Balances; type CouncilOrigin = EnsureMajoritySenate; @@ -947,6 +948,7 @@ impl pallet_subtensor::Config for Runtime { type LiquidAlphaOn = InitialLiquidAlphaOn; type InitialHotkeyEmissionTempo = SubtensorInitialHotkeyEmissionTempo; type InitialNetworkMaxStake = SubtensorInitialNetworkMaxStake; + type Preimages = Preimage; } use sp_runtime::BoundedVec; From aad89d88aeb8c701f609562ba03b7b22c225cdc0 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 18:35:26 +0800 Subject: [PATCH 20/44] fix compilation --- pallets/subtensor/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pallets/subtensor/Cargo.toml b/pallets/subtensor/Cargo.toml index 37c579db0..c05b12b2e 100644 --- a/pallets/subtensor/Cargo.toml +++ b/pallets/subtensor/Cargo.toml @@ -57,7 +57,6 @@ rand = { workspace = true } sp-core = { workspace = true } sp-std = { workspace = true } pallet-preimage = { workspace = true } -pallet-parameters = { workspace = true } [features] default = ["std"] From 53ccd943faa6038dfab66dc0bd6cb81370dfa65c Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 19:15:53 +0800 Subject: [PATCH 21/44] all unit test passed --- pallets/subtensor/src/macros/dispatches.rs | 69 +++------------------- pallets/subtensor/src/swap/swap_coldkey.rs | 7 +++ pallets/subtensor/tests/mock.rs | 64 ++++++++++---------- pallets/subtensor/tests/swap_coldkey.rs | 29 ++++----- 4 files changed, 58 insertions(+), 111 deletions(-) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 3e3590bf9..9105dc0ea 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -7,9 +7,7 @@ mod dispatches { use frame_support::traits::schedule::v3::Anon as ScheduleAnon; use frame_support::traits::schedule::v3::Named as ScheduleNamed; use frame_support::traits::schedule::DispatchTime; - use frame_support::traits::Bounded; use frame_system::pallet_prelude::BlockNumberFor; - use sp_runtime::traits::Hash; use sp_runtime::traits::Saturating; /// Dispatchable functions allow users to interact with the pallet and invoke state changes. /// These functions materialize as "extrinsics", which are often compared to transactions. @@ -680,13 +678,14 @@ mod dispatches { .saturating_add(T::DbWeight::get().writes(527)), DispatchClass::Operational, Pays::No))] pub fn swap_coldkey( origin: OriginFor, + old_coldkey: T::AccountId, new_coldkey: T::AccountId, ) -> DispatchResultWithPostInfo { // Ensure it's called with root privileges (scheduler has root privileges) - // ensure_root(origin.clone())?; + ensure_root(origin.clone())?; + log::info!("swap_coldkey: {:?} -> {:?}", old_coldkey, new_coldkey); - let who = ensure_signed(origin)?; - Self::do_swap_coldkey(&who, &new_coldkey) + Self::do_swap_coldkey(&old_coldkey, &new_coldkey) } /// Unstakes all tokens associated with a hotkey and transfers them to a new coldkey. @@ -960,82 +959,28 @@ mod dispatches { ); // Calculate the number of blocks in 5 days - let blocks_in_5_days: u32 = 2; + let blocks_in_5_days: u32 = 5 * 24 * 60 * 60 / 12; let current_block = >::block_number(); let when = current_block.saturating_add(BlockNumberFor::::from(blocks_in_5_days)); let call = Call::::swap_coldkey { + old_coldkey: who.clone(), new_coldkey: new_coldkey.clone(), }; let bound_call = T::Preimages::bound(LocalCallOf::::from(call.clone())) .map_err(|_| Error::::FailedToSchedule)?; - // let unique_id = ( - // b"schedule_swap_coldkey", - // who.clone(), - // new_coldkey.clone(), - // when, - // ) - // .using_encoded(sp_io::hashing::blake2_256); - - // let hash = , - // CallOf, - // PalletsOriginOf, - // >>::Hasher::hash_of(&call); - - // let len = call.using_encoded(|e| e.len() as u32); - - // fn schedule( - // when: DispatchTime, - // maybe_periodic: Option>, - // priority: Priority, - // origin: Origin, - // call: Bounded, - // ) -> Result; - - // T::Scheduler::schedule_named( - // unique_id, - // DispatchTime::At(when), - // None, - // 63, - // frame_system::RawOrigin::Root.into(), - // // bound_call, - // Bounded::Lookup { hash, len }, - // ) - // .map_err(|_| Error::::FailedToSchedule)?; - - // let result = T::Scheduler::schedule( - // DispatchTime::At(when), - // None, - // 128u8, - // frame_system::RawOrigin::Root.into(), - // call, - // ); - T::Scheduler::schedule( DispatchTime::At(when), None, 63, - // frame_system::RawOrigin::Root.into(), - frame_system::RawOrigin::Signed(who.clone()).into(), - // frame_system::RawOrigin::Signed(&who).into(), + frame_system::RawOrigin::Root.into(), bound_call, ) .map_err(|_| Error::::FailedToSchedule)?; - // T::Scheduler::schedule_named( - // unique_id, - // DispatchTime::At(when), - // None, - // 63, - // frame_system::RawOrigin::Root.into(), - // Bounded::Lookup { hash, len }, - // ) - // .map_err(|_| Error::::FailedToSchedule)?; - ColdkeySwapScheduled::::insert(&who, ()); // Emit the SwapScheduled event Self::deposit_event(Event::ColdkeySwapScheduled { diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index 1b87b386b..c76da4ef2 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -39,17 +39,22 @@ impl Pallet { // 2. Initialize the weight for this operation let mut weight: Weight = T::DbWeight::get().reads(2); + log::info!("do_swap_coldkey old_coldkey: {:?}", old_coldkey); + // 3. Ensure the new coldkey is not associated with any hotkeys ensure!( StakingHotkeys::::get(new_coldkey).is_empty(), Error::::ColdKeyAlreadyAssociated ); + log::info!("do_swap_coldkey ColdKeyAlreadyAssociated"); + // 4. Ensure the new coldkey is not a hotkey ensure!( !Self::hotkey_account_exists(new_coldkey), Error::::ColdKeyAlreadyAssociated ); + log::info!("do_swap_coldkey ColdKeyAlreadyAssociated 2"); // 5. Calculate the swap cost and ensure sufficient balance let swap_cost = Self::get_key_swap_cost(); @@ -58,6 +63,7 @@ impl Pallet { Self::can_remove_balance_from_coldkey_account(&old_coldkey, swap_cost), Error::::NotEnoughBalanceToPaySwapColdKey ); + log::info!("do_swap_coldkey NotEnoughBalanceToPaySwapColdKey"); // 6. Remove and burn the swap cost from the old coldkey's account let actual_burn_amount = @@ -69,6 +75,7 @@ impl Pallet { // 8. Perform the actual coldkey swap let _ = Self::perform_swap_coldkey(&old_coldkey, new_coldkey, &mut weight); + log::info!("do_swap_coldkey perform_swap_coldkey"); // 9. Update the last transaction block for the new coldkey Self::set_last_tx_block(new_coldkey, Self::get_current_block_as_u64()); diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index c357e0948..e1c5f07d7 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -14,7 +14,7 @@ use frame_support::{ use frame_system as system; use frame_system::{limits, EnsureNever, EnsureRoot, RawOrigin}; use pallet_collective::MemberCount; -use pallet_parameters; +// use pallet_parameters; use pallet_preimage; use sp_core::{Get, H256, U256}; use sp_runtime::Perbill; @@ -40,7 +40,7 @@ frame_support::construct_runtime!( Utility: pallet_utility::{Pallet, Call, Storage, Event}, Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event}, Preimage: pallet_preimage::{Pallet, Call, Storage, Event}, - Parameters: pallet_parameters::{Pallet, Call, Storage, Event}, + // Parameters: pallet_parameters::{Pallet, Call, Storage, Event}, } ); @@ -76,35 +76,35 @@ pub type Balance = u64; #[allow(dead_code)] pub type BlockNumber = u64; -#[dynamic_params(RuntimeParameters, pallet_parameters::Parameters::)] -pub mod dynamic_params { - use super::*; +// #[dynamic_params(RuntimeParameters, pallet_parameters::Parameters::)] +// pub mod dynamic_params { +// use super::*; - #[dynamic_pallet_params] - #[codec(index = 0)] - pub mod storage { - /// Configures the base deposit of storing some data. - #[codec(index = 0)] - pub static BaseDeposit: Balance = 1; +// #[dynamic_pallet_params] +// #[codec(index = 0)] +// pub mod storage { +// /// Configures the base deposit of storing some data. +// #[codec(index = 0)] +// pub static BaseDeposit: Balance = 1; - /// Configures the per-byte deposit of storing some data. - #[codec(index = 1)] - pub static ByteDeposit: Balance = 1; - } +// /// Configures the per-byte deposit of storing some data. +// #[codec(index = 1)] +// pub static ByteDeposit: Balance = 1; +// } - #[dynamic_pallet_params] - #[codec(index = 1)] - pub mod contracts { - #[codec(index = 0)] - pub static DepositPerItem: Balance = 1; +// #[dynamic_pallet_params] +// #[codec(index = 1)] +// pub mod contracts { +// #[codec(index = 0)] +// pub static DepositPerItem: Balance = 1; - #[codec(index = 1)] - pub static DepositPerByte: Balance = 1; +// #[codec(index = 1)] +// pub static DepositPerByte: Balance = 1; - #[codec(index = 2)] - pub static DefaultDepositLimit: Balance = 1; - } -} +// #[codec(index = 2)] +// pub static DefaultDepositLimit: Balance = 1; +// } +// } #[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] impl pallet_balances::Config for Test { @@ -486,12 +486,12 @@ impl pallet_preimage::Config for Test { // >; } -impl pallet_parameters::Config for Test { - type RuntimeParameters = RuntimeParameters; - type RuntimeEvent = RuntimeEvent; - type AdminOrigin = EnsureRoot; - type WeightInfo = (); -} +// impl pallet_parameters::Config for Test { +// type RuntimeParameters = RuntimeParameters; +// type RuntimeEvent = RuntimeEvent; +// type AdminOrigin = EnsureRoot; +// type WeightInfo = (); +// } #[allow(dead_code)] // Build genesis storage according to the mock runtime. diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index b27549a8f..cfc2d0098 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -1352,7 +1352,7 @@ fn test_schedule_swap_coldkey_duplicate() { <::RuntimeOrigin>::signed(old_coldkey), new_coldkey ), - Error::::FailedToSchedule + Error::::SwapAlreadyScheduled ); }); } @@ -1369,7 +1369,7 @@ fn test_schedule_swap_coldkey_execution() { add_network(netuid, 13, 0); register_ok_neuron(netuid, hotkey, old_coldkey, 0); - SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 1000); + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 1000000000000000); assert_ok!(SubtensorModule::add_stake( <::RuntimeOrigin>::signed(old_coldkey), hotkey, @@ -1391,12 +1391,9 @@ fn test_schedule_swap_coldkey_execution() { // Get the scheduled execution block let current_block = System::block_number(); - let blocks_in_5_days = 2; + let blocks_in_5_days = 5 * 24 * 60 * 60 / 12; let execution_block = current_block + blocks_in_5_days; - println!("Current block: {}", current_block); - println!("Execution block: {}", execution_block); - System::assert_last_event( Event::ColdkeySwapScheduled { old_coldkey, @@ -1406,16 +1403,7 @@ fn test_schedule_swap_coldkey_execution() { .into(), ); - // Fast forward to the execution block - // System::set_block_number(execution_block); - for block_number in current_block..(execution_block + 3) { - log::info!("+++++ Block number: {}", block_number); - // System::events().iter().for_each(|event| { - // log::info!("Event: {:?}", event.event); - // }); - // Preimage::len(); - run_to_block(block_number + 1); - } + run_to_block(execution_block); // Run on_initialize for the execution block SubtensorModule::on_initialize(execution_block); @@ -1427,7 +1415,6 @@ fn test_schedule_swap_coldkey_execution() { // Check if the swap has occurred let new_owner = Owner::::get(hotkey); - println!("New owner after swap: {:?}", new_owner); assert_eq!( new_owner, new_coldkey, "Ownership was not updated as expected" @@ -1445,6 +1432,13 @@ fn test_schedule_swap_coldkey_execution() { ); // Check for the SwapExecuted event + System::assert_last_event( + Event::ColdkeySwapped { + old_coldkey, + new_coldkey, + } + .into(), + ); }); } @@ -1458,6 +1452,7 @@ fn test_direct_swap_coldkey_call_fails() { assert_noop!( SubtensorModule::swap_coldkey( <::RuntimeOrigin>::signed(old_coldkey), + old_coldkey, new_coldkey ), BadOrigin From 2f83b84e726b22e5171d6bfcacc211db4bcf2dbf Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 19:19:19 +0800 Subject: [PATCH 22/44] clean up code --- pallets/subtensor/src/swap/swap_coldkey.rs | 20 ++-------- pallets/subtensor/tests/mock.rs | 45 ---------------------- 2 files changed, 4 insertions(+), 61 deletions(-) diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index c76da4ef2..2b54d4313 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -33,56 +33,44 @@ impl Pallet { old_coldkey: &T::AccountId, new_coldkey: &T::AccountId, ) -> DispatchResultWithPostInfo { - // 1. Ensure the origin is signed and get the old coldkey - // let old_coldkey = ensure_signed(origin)?; - // 2. Initialize the weight for this operation let mut weight: Weight = T::DbWeight::get().reads(2); - log::info!("do_swap_coldkey old_coldkey: {:?}", old_coldkey); - // 3. Ensure the new coldkey is not associated with any hotkeys ensure!( StakingHotkeys::::get(new_coldkey).is_empty(), Error::::ColdKeyAlreadyAssociated ); - log::info!("do_swap_coldkey ColdKeyAlreadyAssociated"); - // 4. Ensure the new coldkey is not a hotkey ensure!( !Self::hotkey_account_exists(new_coldkey), Error::::ColdKeyAlreadyAssociated ); - log::info!("do_swap_coldkey ColdKeyAlreadyAssociated 2"); // 5. Calculate the swap cost and ensure sufficient balance let swap_cost = Self::get_key_swap_cost(); - log::debug!("Coldkey swap cost: {:?}", swap_cost); ensure!( - Self::can_remove_balance_from_coldkey_account(&old_coldkey, swap_cost), + Self::can_remove_balance_from_coldkey_account(old_coldkey, swap_cost), Error::::NotEnoughBalanceToPaySwapColdKey ); - log::info!("do_swap_coldkey NotEnoughBalanceToPaySwapColdKey"); // 6. Remove and burn the swap cost from the old coldkey's account - let actual_burn_amount = - Self::remove_balance_from_coldkey_account(&old_coldkey, swap_cost)?; + let actual_burn_amount = Self::remove_balance_from_coldkey_account(old_coldkey, swap_cost)?; Self::burn_tokens(actual_burn_amount); // 7. Update the weight for the balance operations weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); // 8. Perform the actual coldkey swap - let _ = Self::perform_swap_coldkey(&old_coldkey, new_coldkey, &mut weight); - log::info!("do_swap_coldkey perform_swap_coldkey"); + let _ = Self::perform_swap_coldkey(old_coldkey, new_coldkey, &mut weight); // 9. Update the last transaction block for the new coldkey Self::set_last_tx_block(new_coldkey, Self::get_current_block_as_u64()); weight.saturating_accrue(T::DbWeight::get().writes(1)); // 10. Remove the coldkey swap scheduled record - ColdkeySwapScheduled::::remove(&old_coldkey); + ColdkeySwapScheduled::::remove(old_coldkey); // 11. Emit the ColdkeySwapped event Self::deposit_event(Event::ColdkeySwapped { diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index e1c5f07d7..d6b45c63f 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -40,7 +40,6 @@ frame_support::construct_runtime!( Utility: pallet_utility::{Pallet, Call, Storage, Event}, Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event}, Preimage: pallet_preimage::{Pallet, Call, Storage, Event}, - // Parameters: pallet_parameters::{Pallet, Call, Storage, Event}, } ); @@ -76,36 +75,6 @@ pub type Balance = u64; #[allow(dead_code)] pub type BlockNumber = u64; -// #[dynamic_params(RuntimeParameters, pallet_parameters::Parameters::)] -// pub mod dynamic_params { -// use super::*; - -// #[dynamic_pallet_params] -// #[codec(index = 0)] -// pub mod storage { -// /// Configures the base deposit of storing some data. -// #[codec(index = 0)] -// pub static BaseDeposit: Balance = 1; - -// /// Configures the per-byte deposit of storing some data. -// #[codec(index = 1)] -// pub static ByteDeposit: Balance = 1; -// } - -// #[dynamic_pallet_params] -// #[codec(index = 1)] -// pub mod contracts { -// #[codec(index = 0)] -// pub static DepositPerItem: Balance = 1; - -// #[codec(index = 1)] -// pub static DepositPerByte: Balance = 1; - -// #[codec(index = 2)] -// pub static DefaultDepositLimit: Balance = 1; -// } -// } - #[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] impl pallet_balances::Config for Test { type Balance = Balance; @@ -117,7 +86,6 @@ impl pallet_balances::Config for Test { type WeightInfo = (); type MaxReserves = (); type ReserveIdentifier = (); - type RuntimeHoldReason = (); type FreezeIdentifier = (); type MaxFreezes = (); @@ -478,21 +446,8 @@ impl pallet_preimage::Config for Test { type Currency = Balances; type ManagerOrigin = EnsureRoot; type Consideration = (); - // HoldConsideration< - // AccountId, - // Balances, - // PreimageHoldReason, - // LinearStoragePrice, - // >; } -// impl pallet_parameters::Config for Test { -// type RuntimeParameters = RuntimeParameters; -// type RuntimeEvent = RuntimeEvent; -// type AdminOrigin = EnsureRoot; -// type WeightInfo = (); -// } - #[allow(dead_code)] // Build genesis storage according to the mock runtime. pub fn new_test_ext(block_number: BlockNumber) -> sp_io::TestExternalities { From d80a92889adc893716440250c7ee48e3197b7c96 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 19:31:18 +0800 Subject: [PATCH 23/44] fix clippy --- pallets/subtensor/tests/mock.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index d6b45c63f..328b6e5c7 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -2,20 +2,14 @@ use frame_support::derive_impl; use frame_support::dispatch::DispatchResultWithPostInfo; use frame_support::weights::constants::RocksDbWeight; -// use frame_support::weights::constants::WEIGHT_PER_SECOND; use frame_support::weights::Weight; use frame_support::{ - assert_ok, - dynamic_params::{dynamic_pallet_params, dynamic_params}, - parameter_types, - traits::fungible::HoldConsideration, - traits::{Everything, Hooks, LinearStoragePrice, PrivilegeCmp}, + assert_ok, parameter_types, + traits::{Everything, Hooks, PrivilegeCmp}, }; use frame_system as system; use frame_system::{limits, EnsureNever, EnsureRoot, RawOrigin}; use pallet_collective::MemberCount; -// use pallet_parameters; -use pallet_preimage; use sp_core::{Get, H256, U256}; use sp_runtime::Perbill; use sp_runtime::{ From 1633b6c98b7d037c1ead9cff69ad90a041a6cd54 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 19:40:17 +0800 Subject: [PATCH 24/44] fix admin test --- pallets/admin-utils/tests/mock.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pallets/admin-utils/tests/mock.rs b/pallets/admin-utils/tests/mock.rs index 4b08c578b..3f3ef843d 100644 --- a/pallets/admin-utils/tests/mock.rs +++ b/pallets/admin-utils/tests/mock.rs @@ -122,6 +122,7 @@ parameter_types! { impl pallet_subtensor::Config for Test { type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; type Currency = Balances; type InitialIssuance = InitialIssuance; type SudoRuntimeCall = TestRuntimeCall; @@ -175,6 +176,7 @@ impl pallet_subtensor::Config for Test { type LiquidAlphaOn = InitialLiquidAlphaOn; type InitialHotkeyEmissionTempo = InitialHotkeyEmissionTempo; type InitialNetworkMaxStake = InitialNetworkMaxStake; + type Preimages = (); } #[derive_impl(frame_system::config_preludes::TestDefaultConfig)] From 49bd0c553702f6b3e7e9b9654bd5103806c78efd Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 20:08:33 +0800 Subject: [PATCH 25/44] fix test --- pallets/subtensor/tests/swap_coldkey.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index cfc2d0098..5a576fd2d 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -1432,7 +1432,7 @@ fn test_schedule_swap_coldkey_execution() { ); // Check for the SwapExecuted event - System::assert_last_event( + System::assert_has_event( Event::ColdkeySwapped { old_coldkey, new_coldkey, From 0f2fa057419a7a726df656b0da29699010034f52 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 20:46:29 +0800 Subject: [PATCH 26/44] remove unneeded feature --- pallets/subtensor/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/Cargo.toml b/pallets/subtensor/Cargo.toml index c05b12b2e..d7a9bc06c 100644 --- a/pallets/subtensor/Cargo.toml +++ b/pallets/subtensor/Cargo.toml @@ -24,7 +24,7 @@ sp-core = { workspace = true } pallet-balances = { workspace = true } scale-info = { workspace = true, features = ["derive"] } frame-benchmarking = { workspace = true, optional = true } -frame-support = { workspace = true , features = ["experimental", "tuples-96"]} +frame-support = { workspace = true } frame-system = { workspace = true } sp-io = { workspace = true } serde = { workspace = true, features = ["derive"] } From 59dc95cf5a189dc7dafef622ce4986dc7656ffe9 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 20:52:46 +0800 Subject: [PATCH 27/44] clean up code --- pallets/subtensor/src/macros/config.rs | 13 ++++++------- pallets/subtensor/src/macros/dispatches.rs | 1 - pallets/subtensor/tests/mock.rs | 1 - pallets/subtensor/tests/swap_coldkey.rs | 6 +----- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index c333dfed6..2f924905d 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -38,13 +38,12 @@ mod config { type TriumvirateInterface: crate::CollectiveInterface; /// The scheduler type used for scheduling delayed calls. - type Scheduler: ScheduleNamed, LocalCallOf, PalletsOriginOf> - + ScheduleAnon< - BlockNumberFor, - LocalCallOf, - PalletsOriginOf, - Hasher = Self::Hashing, - >; + type Scheduler: ScheduleAnon< + BlockNumberFor, + LocalCallOf, + PalletsOriginOf, + Hasher = Self::Hashing, + >; /// the preimage to store the call data. type Preimages: QueryPreimage + StorePreimage; diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 9105dc0ea..011fdfe83 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -5,7 +5,6 @@ use frame_support::pallet_macros::pallet_section; #[pallet_section] mod dispatches { use frame_support::traits::schedule::v3::Anon as ScheduleAnon; - use frame_support::traits::schedule::v3::Named as ScheduleNamed; use frame_support::traits::schedule::DispatchTime; use frame_system::pallet_prelude::BlockNumberFor; use sp_runtime::traits::Saturating; diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 328b6e5c7..3497b6d67 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -431,7 +431,6 @@ parameter_types! { pub const PreimageMaxSize: u32 = 4096 * 1024; pub const PreimageBaseDeposit: Balance = 1; pub const PreimageByteDeposit: Balance = 1; - // pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage); } impl pallet_preimage::Config for Test { diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index 5a576fd2d..48168addc 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -889,11 +889,7 @@ fn test_do_swap_coldkey_with_subnet_ownership() { OwnedHotkeys::::insert(old_coldkey, vec![hotkey]); // Perform the swap - assert_ok!(SubtensorModule::do_swap_coldkey( - // <::RuntimeOrigin>::signed(old_coldkey), - &old_coldkey, - &new_coldkey - )); + assert_ok!(SubtensorModule::do_swap_coldkey(&old_coldkey, &new_coldkey)); // Verify subnet ownership transfer assert_eq!(SubnetOwner::::get(netuid), new_coldkey); From 9250464572a049778042d391b9c695f8766414f7 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 2 Aug 2024 13:44:36 +0800 Subject: [PATCH 28/44] update feature dependency --- Cargo.lock | 36 ++++++++++++++++++---------------- pallets/admin-utils/Cargo.toml | 4 +++- pallets/subtensor/Cargo.toml | 6 +++++- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea30f4e25..d8959b99b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1198,7 +1198,7 @@ dependencies = [ [[package]] name = "common" version = "0.1.0" -source = "git+https://github.com/w3f/ring-proof#b273d33f9981e2bb3375ab45faeb537f7ee35224" +source = "git+https://github.com/w3f/ring-proof#665f5f51af5734c7b6d90b985dd6861d4c5b4752" dependencies = [ "ark-ec", "ark-ff", @@ -4150,9 +4150,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru" @@ -5266,6 +5266,7 @@ dependencies = [ "pallet-balances", "pallet-collective", "pallet-membership", + "pallet-preimage", "pallet-scheduler", "pallet-transaction-payment", "pallet-utility", @@ -6433,13 +6434,14 @@ dependencies = [ [[package]] name = "ring" version = "0.1.0" -source = "git+https://github.com/w3f/ring-proof#b273d33f9981e2bb3375ab45faeb537f7ee35224" +source = "git+https://github.com/w3f/ring-proof#665f5f51af5734c7b6d90b985dd6861d4c5b4752" dependencies = [ "ark-ec", "ark-ff", "ark-poly", "ark-serialize", "ark-std", + "arrayvec", "blake2 0.10.6", "common", "fflonk", @@ -7908,9 +7910,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] @@ -7935,9 +7937,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", @@ -8408,7 +8410,7 @@ dependencies = [ [[package]] name = "sp-crypto-ec-utils" version = "0.10.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -8470,7 +8472,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" dependencies = [ "proc-macro2", "quote", @@ -8490,7 +8492,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.25.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" dependencies = [ "environmental", "parity-scale-codec", @@ -8673,7 +8675,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "24.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -8705,7 +8707,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" dependencies = [ "Inflector", "expander", @@ -8794,7 +8796,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2 [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" [[package]] name = "sp-storage" @@ -8811,7 +8813,7 @@ dependencies = [ [[package]] name = "sp-storage" version = "19.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" dependencies = [ "impl-serde", "parity-scale-codec", @@ -8846,7 +8848,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "16.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" dependencies = [ "parity-scale-codec", "tracing", @@ -8943,7 +8945,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "20.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" dependencies = [ "impl-trait-for-tuples", "log", diff --git a/pallets/admin-utils/Cargo.toml b/pallets/admin-utils/Cargo.toml index 97371a79f..ff54989cd 100644 --- a/pallets/admin-utils/Cargo.toml +++ b/pallets/admin-utils/Cargo.toml @@ -65,12 +65,14 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "sp-runtime/runtime-benchmarks", - "pallet-subtensor/runtime-benchmarks" + "pallet-subtensor/runtime-benchmarks", + "pallet-scheduler/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", "pallet-balances/try-runtime", + "pallet-scheduler/try-runtime", "sp-runtime/try-runtime", "pallet-subtensor/try-runtime" ] diff --git a/pallets/subtensor/Cargo.toml b/pallets/subtensor/Cargo.toml index d7a9bc06c..2baee6127 100644 --- a/pallets/subtensor/Cargo.toml +++ b/pallets/subtensor/Cargo.toml @@ -95,13 +95,17 @@ runtime-benchmarks = [ "pallet-membership/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "sp-runtime/runtime-benchmarks", - "pallet-collective/runtime-benchmarks" + "pallet-collective/runtime-benchmarks", + "pallet-preimage/runtime-benchmarks", + "pallet-scheduler/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", "pallet-balances/try-runtime", "pallet-membership/try-runtime", + "pallet-preimage/try-runtime", + "pallet-scheduler/try-runtime", "pallet-transaction-payment/try-runtime", "pallet-utility/try-runtime", "sp-runtime/try-runtime", From af4bf3527fcea4fd8586f0c37039d12e8758d614 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 2 Aug 2024 15:20:51 +0800 Subject: [PATCH 29/44] fix zepter --- pallets/admin-utils/Cargo.toml | 2 ++ pallets/subtensor/Cargo.toml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/pallets/admin-utils/Cargo.toml b/pallets/admin-utils/Cargo.toml index ff54989cd..c67c00914 100644 --- a/pallets/admin-utils/Cargo.toml +++ b/pallets/admin-utils/Cargo.toml @@ -51,12 +51,14 @@ std = [ "pallet-subtensor/std", "sp-consensus-aura/std", "pallet-balances/std", + "pallet-scheduler/std", "sp-runtime/std", "sp-tracing/std", "sp-weights/std", "log/std", "sp-core/std", "sp-io/std", + "sp-std/std", "substrate-fixed/std", ] runtime-benchmarks = [ diff --git a/pallets/subtensor/Cargo.toml b/pallets/subtensor/Cargo.toml index 2baee6127..3c0bd71c1 100644 --- a/pallets/subtensor/Cargo.toml +++ b/pallets/subtensor/Cargo.toml @@ -70,6 +70,8 @@ std = [ "pallet-membership/std", "substrate-fixed/std", "pallet-balances/std", + "pallet-preimage/std", + "pallet-scheduler/std", "pallet-transaction-payment/std", "pallet-utility/std", "sp-core/std", From 0bce83eaeb2a0d4de86dfab4cf68bf431c7625c1 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 2 Aug 2024 15:25:41 +0800 Subject: [PATCH 30/44] fix clippy --- runtime/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 12fb55586..b606d2eb1 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -538,6 +538,7 @@ impl pallet_membership::Config for Runtime { } // We call our top K delegates membership Senate +#[allow(dead_code)] type SenateMembership = pallet_membership::Instance2; impl pallet_membership::Config for Runtime { type RuntimeEvent = RuntimeEvent; From 22cc4b5f664bfd1d611fff79f2cfdaf8126feb51 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Wed, 31 Jul 2024 11:40:56 +0400 Subject: [PATCH 31/44] chore: skip wasm builds on test scripts --- scripts/test_specific.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/test_specific.sh b/scripts/test_specific.sh index 018872d33..85f3ebe30 100755 --- a/scripts/test_specific.sh +++ b/scripts/test_specific.sh @@ -1,6 +1,4 @@ pallet="${3:-pallet-subtensor}" features="${4:-pow-faucet}" -# RUST_LOG="pallet_subtensor=info" cargo test --release --features=$features -p $pallet --test $1 -- $2 --nocapture --exact - -RUST_LOG=INFO cargo test --release --features=$features -p $pallet --test $1 -- $2 --nocapture --exact \ No newline at end of file +SKIP_WASM_BUILD=1 RUST_LOG=DEBUG cargo test --release --features=$features -p $pallet --test $1 -- $2 --nocapture --exact \ No newline at end of file From 21e3c26a5f64c0dd135343c1277a3f19c4e62684 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Sun, 4 Aug 2024 13:37:53 +0400 Subject: [PATCH 32/44] feat: patch errors and assertions --- pallets/subtensor/src/macros/errors.rs | 4 ++++ pallets/subtensor/src/swap/swap_coldkey.rs | 13 +++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/pallets/subtensor/src/macros/errors.rs b/pallets/subtensor/src/macros/errors.rs index d51469482..9c344ab8d 100644 --- a/pallets/subtensor/src/macros/errors.rs +++ b/pallets/subtensor/src/macros/errors.rs @@ -174,5 +174,9 @@ mod errors { SwapAlreadyScheduled, /// failed to swap coldkey FailedToSchedule, + /// New coldkey is hotkey + NewColdKeyIsHotkey, + /// New coldkey is in arbitration + NewColdkeyIsInArbitration, } } diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index 2b54d4313..5b02d49b5 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -35,18 +35,27 @@ impl Pallet { ) -> DispatchResultWithPostInfo { // 2. Initialize the weight for this operation let mut weight: Weight = T::DbWeight::get().reads(2); - // 3. Ensure the new coldkey is not associated with any hotkeys ensure!( StakingHotkeys::::get(new_coldkey).is_empty(), Error::::ColdKeyAlreadyAssociated ); + weight = weight.saturating_add(T::DbWeight::get().reads(1)); // 4. Ensure the new coldkey is not a hotkey ensure!( !Self::hotkey_account_exists(new_coldkey), - Error::::ColdKeyAlreadyAssociated + Error::::NewColdKeyIsHotkey ); + weight = weight.saturating_add(T::DbWeight::get().reads(1)); + + // TODO: Consider adding a check to ensure the new coldkey is not in arbitration + // ensure!( + // !Self::coldkey_in_arbitration(new_coldkey), + // Error::::NewColdkeyIsInArbitration + // ); + + // Note: We might want to add a cooldown period for coldkey swaps to prevent abuse // 5. Calculate the swap cost and ensure sufficient balance let swap_cost = Self::get_key_swap_cost(); From 67de45c584cc6bcd077329613ff882b03b2293b2 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 6 Aug 2024 15:33:55 +0800 Subject: [PATCH 33/44] add schedule dissolve network --- pallets/admin-utils/tests/mock.rs | 5 + pallets/subtensor/src/benchmarks.rs | 19 ++++ pallets/subtensor/src/lib.rs | 69 +++++++++++-- pallets/subtensor/src/macros/config.rs | 7 +- pallets/subtensor/src/macros/dispatches.rs | 62 +++++++++++- pallets/subtensor/src/macros/events.rs | 9 ++ pallets/subtensor/tests/mock.rs | 5 +- pallets/subtensor/tests/networks.rs | 107 ++++++++++++++++++--- pallets/subtensor/tests/swap_coldkey.rs | 5 +- 9 files changed, 259 insertions(+), 29 deletions(-) diff --git a/pallets/admin-utils/tests/mock.rs b/pallets/admin-utils/tests/mock.rs index 3f3ef843d..077f07804 100644 --- a/pallets/admin-utils/tests/mock.rs +++ b/pallets/admin-utils/tests/mock.rs @@ -118,6 +118,9 @@ parameter_types! { pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn pub const InitialHotkeyEmissionTempo: u64 = 1; pub const InitialNetworkMaxStake: u64 = 500_000_000_000_000; // 500_000 TAO + pub const InitialColdkeySwapScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // 5 days + pub const InitialDissolveNetworkScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // 5 days + } impl pallet_subtensor::Config for Test { @@ -177,6 +180,8 @@ impl pallet_subtensor::Config for Test { type InitialHotkeyEmissionTempo = InitialHotkeyEmissionTempo; type InitialNetworkMaxStake = InitialNetworkMaxStake; type Preimages = (); + type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration; + type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration; } #[derive_impl(frame_system::config_preludes::TestDefaultConfig)] diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index 03e087a92..eaa4821ad 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -429,4 +429,23 @@ reveal_weights { }: reveal_weights(RawOrigin::Signed(hotkey.clone()), netuid, uids, weight_values, salt, version_key) + schedule_swap_coldkey { + let old_coldkey: T::AccountId = account("old_cold", 0, 1); + let new_coldkey: T::AccountId = account("new_cold", 1, 2); + let _ = Subtensor::::schedule_swap_coldkey( + ::RuntimeOrigin::from(RawOrigin::Signed(old_coldkey.clone())), + new_coldkey.clone(), + ); + + }: schedule_swap_coldkey(RawOrigin::Signed(old_coldkey.clone()), new_coldkey.clone()) + + schedule_dissolve_network { + let coldkey: T::AccountId = account("old_cold", 0, 1); + let netuid = 1; + let _ = Subtensor::::schedule_dissolve_network( + ::RuntimeOrigin::from(RawOrigin::Signed(coldkey.clone())), + netuid, + ); + + }: schedule_dissolve_network(RawOrigin::Signed(coldkey.clone()), netuid) } diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index a1002bf66..d77a87b37 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -588,6 +588,26 @@ pub mod pallet { T::InitialNetworkMaxStake::get() } + #[pallet::type_value] + /// Default value for coldkey swap schedule duration + pub fn DefaultColdkeySwapScheduleDuration() -> BlockNumberFor { + T::InitialColdkeySwapScheduleDuration::get() + } + + #[pallet::storage] + pub type ColdkeySwapScheduleDuration = + StorageValue<_, BlockNumberFor, ValueQuery, DefaultColdkeySwapScheduleDuration>; + + #[pallet::type_value] + /// Default value for coldkey swap schedule duration + pub fn DefaultDissolveNetworkScheduleDuration() -> BlockNumberFor { + T::InitialDissolveNetworkScheduleDuration::get() + } + + #[pallet::storage] + pub type DissolveNetworkScheduleDuration = + StorageValue<_, BlockNumberFor, ValueQuery, DefaultDissolveNetworkScheduleDuration>; + #[pallet::storage] pub type SenateRequiredStakePercentage = StorageValue<_, u64, ValueQuery, DefaultSenateRequiredStakePercentage>; @@ -1219,6 +1239,19 @@ pub enum CallType { Other, } +#[derive(Debug, PartialEq)] +pub enum CustomTransactionError { + ColdkeyInSwapSchedule, +} + +impl From for u8 { + fn from(variant: CustomTransactionError) -> u8 { + match variant { + CustomTransactionError::ColdkeyInSwapSchedule => 0, + } + } +} + #[freeze_struct("61e2b893d5ce6701")] #[derive(Encode, Decode, Clone, Eq, PartialEq, TypeInfo)] pub struct SubtensorSignedExtension(pub PhantomData); @@ -1367,14 +1400,34 @@ where priority: Self::get_priority_vanilla(), ..Default::default() }), - Some(Call::dissolve_network { .. }) => Ok(ValidTransaction { - priority: Self::get_priority_vanilla(), - ..Default::default() - }), - _ => Ok(ValidTransaction { - priority: Self::get_priority_vanilla(), - ..Default::default() - }), + Some(Call::dissolve_network { .. }) => { + InvalidTransaction::Custom(CustomTransactionError::ColdkeyInSwapSchedule.into()) + .into() + } + _ => { + if let Some(balances_call) = call.is_sub_type() { + match balances_call { + BalancesCall::transfer_keep_alive { .. } + | BalancesCall::transfer_all { .. } + | BalancesCall::transfer_allow_death { .. } => { + if ColdkeySwapScheduled::::contains_key(who) { + return InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into(), + ) + .into(); + } + } + // Add other Balances call validations if needed + _ => {} + } + } + + // Default validation for other calls + Ok(ValidTransaction { + priority: Self::get_priority_vanilla(), + ..Default::default() + }) + } } } diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index 2f924905d..c5c5ac737 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -5,7 +5,6 @@ use frame_support::pallet_macros::pallet_section; /// This can later be imported into the pallet using [`import_section`]. #[pallet_section] mod config { - /// Configure the pallet by specifying the parameters and types on which it depends. #[pallet::config] pub trait Config: frame_system::Config { @@ -193,5 +192,11 @@ mod config { /// Initial hotkey emission tempo. #[pallet::constant] type InitialHotkeyEmissionTempo: Get; + /// Coldkey swap schedule duartion. + #[pallet::constant] + type InitialColdkeySwapScheduleDuration: Get>; + /// Dissolve network schedule duration + #[pallet::constant] + type InitialDissolveNetworkScheduleDuration: Get>; } } diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 48874fb1b..68d2d70ee 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -957,11 +957,9 @@ mod dispatches { Error::::SwapAlreadyScheduled ); - // Calculate the number of blocks in 5 days - let blocks_in_5_days: u32 = 5 * 24 * 60 * 60 / 12; - - let current_block = >::block_number(); - let when = current_block.saturating_add(BlockNumberFor::::from(blocks_in_5_days)); + let current_block: BlockNumberFor = >::block_number(); + let duration: BlockNumberFor = ColdkeySwapScheduleDuration::::get(); + let when: BlockNumberFor = current_block.saturating_add(duration); let call = Call::::swap_coldkey { old_coldkey: who.clone(), @@ -991,6 +989,60 @@ mod dispatches { Ok(().into()) } + /// Schedule the dissolution of a network at a specified block number. + /// + /// # Arguments + /// + /// * `origin` - The origin of the call, must be signed by the sender. + /// * `netuid` - The u16 network identifier to be dissolved. + /// + /// # Returns + /// + /// Returns a `DispatchResultWithPostInfo` indicating success or failure of the operation. + /// + /// # Weight + /// + /// Weight is calculated based on the number of database reads and writes. + + #[pallet::call_index(74)] + #[pallet::weight((Weight::from_parts(119_000_000, 0) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(31)), DispatchClass::Operational, Pays::Yes))] + pub fn schedule_dissolve_network( + origin: OriginFor, + netuid: u16, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + + let current_block: BlockNumberFor = >::block_number(); + let duration: BlockNumberFor = DissolveNetworkScheduleDuration::::get(); + let when: BlockNumberFor = current_block.saturating_add(duration); + + let call = Call::::dissolve_network { netuid }; + + let bound_call = T::Preimages::bound(LocalCallOf::::from(call.clone())) + .map_err(|_| Error::::FailedToSchedule)?; + + T::Scheduler::schedule( + DispatchTime::At(when), + None, + 63, + frame_system::RawOrigin::Signed(who.clone()).into(), + bound_call, + ) + .map_err(|_| Error::::FailedToSchedule)?; + + ColdkeySwapScheduled::::insert(&who, ()); + // Emit the SwapScheduled event + Self::deposit_event(Event::DissolveNetworkScheduled { + account: who.clone(), + netuid: netuid, + execution_block: when, + }); + + Ok(().into()) + } + /// ---- Set prometheus information for the neuron. /// # Args: /// * 'origin': (Origin): diff --git a/pallets/subtensor/src/macros/events.rs b/pallets/subtensor/src/macros/events.rs index 9d771e3e2..2fbffdb7c 100644 --- a/pallets/subtensor/src/macros/events.rs +++ b/pallets/subtensor/src/macros/events.rs @@ -179,5 +179,14 @@ mod events { NetworkMaxStakeSet(u16, u64), /// The identity of a coldkey has been set ChainIdentitySet(T::AccountId), + /// A dissolve network extrinsic scheduled. + DissolveNetworkScheduled { + /// The account ID schedule the dissolve network extrisnic + account: T::AccountId, + /// network ID will be dissolved + netuid: u16, + /// extrinsic execution block number + execution_block: BlockNumberFor, + }, } } diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 3497b6d67..17ccfc87d 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -171,7 +171,8 @@ parameter_types! { pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn pub const InitialHotkeyEmissionTempo: u64 = 0; // Defaults to draining every block. pub const InitialNetworkMaxStake: u64 = 500_000_000_000_000; // 500,000 TAO - + pub const InitialColdkeySwapScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days + pub const InitialDissolveNetworkScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days } // Configure collective pallet for council @@ -390,6 +391,8 @@ impl pallet_subtensor::Config for Test { type InitialHotkeyEmissionTempo = InitialHotkeyEmissionTempo; type InitialNetworkMaxStake = InitialNetworkMaxStake; type Preimages = Preimage; + type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration; + type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration; } pub struct OriginPrivilegeCmp; diff --git a/pallets/subtensor/tests/networks.rs b/pallets/subtensor/tests/networks.rs index 93e563683..1929ff543 100644 --- a/pallets/subtensor/tests/networks.rs +++ b/pallets/subtensor/tests/networks.rs @@ -1,14 +1,99 @@ -// DEPRECATED mod mock; -// use frame_support::{ -// assert_ok, -// dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, Pays}, -// sp_std::vec, -// }; -// use frame_system::Config; -// use frame_system::{EventRecord, Phase}; -// use mock::*; -// use pallet_subtensor::Error; -// use sp_core::{H256, U256}; +use crate::mock::*; +use frame_support::assert_ok; +use frame_system::Config; +use pallet_subtensor::{DissolveNetworkScheduleDuration, Event}; +use sp_core::U256; + +mod mock; + +#[test] +fn test_registration_ok() { + new_test_ext(1).execute_with(|| { + let block_number: u64 = 0; + let netuid: u16 = 2; + let tempo: u16 = 13; + let hotkey_account_id: U256 = U256::from(1); + let coldkey_account_id = U256::from(0); // Neighbour of the beast, har har + let (nonce, work): (u64, Vec) = SubtensorModule::create_work_for_block_number( + netuid, + block_number, + 129123813, + &hotkey_account_id, + ); + + //add network + add_network(netuid, tempo, 0); + + assert_ok!(SubtensorModule::register( + <::RuntimeOrigin>::signed(hotkey_account_id), + netuid, + block_number, + nonce, + work.clone(), + hotkey_account_id, + coldkey_account_id + )); + + assert_ok!(SubtensorModule::user_remove_network( + <::RuntimeOrigin>::signed(coldkey_account_id), + netuid + )); + + assert!(!SubtensorModule::if_subnet_exist(netuid)) + }) +} + +#[test] +fn test_schedule_dissolve_network_execution() { + new_test_ext(1).execute_with(|| { + let block_number: u64 = 0; + let netuid: u16 = 2; + let tempo: u16 = 13; + let hotkey_account_id: U256 = U256::from(1); + let coldkey_account_id = U256::from(0); // Neighbour of the beast, har har + let (nonce, work): (u64, Vec) = SubtensorModule::create_work_for_block_number( + netuid, + block_number, + 129123813, + &hotkey_account_id, + ); + + //add network + add_network(netuid, tempo, 0); + + assert_ok!(SubtensorModule::register( + <::RuntimeOrigin>::signed(hotkey_account_id), + netuid, + block_number, + nonce, + work.clone(), + hotkey_account_id, + coldkey_account_id + )); + + assert!(SubtensorModule::if_subnet_exist(netuid)); + + assert_ok!(SubtensorModule::schedule_dissolve_network( + <::RuntimeOrigin>::signed(coldkey_account_id), + netuid + )); + + let current_block = System::block_number(); + let execution_block = current_block + DissolveNetworkScheduleDuration::::get(); + + System::assert_last_event( + Event::DissolveNetworkScheduled { + account: coldkey_account_id, + netuid, + execution_block, + } + .into(), + ); + + run_to_block(execution_block); + assert!(!SubtensorModule::if_subnet_exist(netuid)); + }) +} // #[allow(dead_code)] // fn record(event: RuntimeEvent) -> EventRecord { diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index 48168addc..ec030ebee 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -10,7 +10,7 @@ use frame_support::traits::schedule::DispatchTime; use frame_support::traits::OnInitialize; use mock::*; use pallet_subtensor::*; -use pallet_subtensor::{Call, Error}; +use pallet_subtensor::{Call, ColdkeySwapScheduleDuration, Error}; use sp_core::H256; use sp_core::U256; use sp_runtime::DispatchError; @@ -1387,8 +1387,7 @@ fn test_schedule_swap_coldkey_execution() { // Get the scheduled execution block let current_block = System::block_number(); - let blocks_in_5_days = 5 * 24 * 60 * 60 / 12; - let execution_block = current_block + blocks_in_5_days; + let execution_block = current_block + ColdkeySwapScheduleDuration::::get(); System::assert_last_event( Event::ColdkeySwapScheduled { From 106df9e84abcd2c31df5c9e3d2dc4b78cb03a54f Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 6 Aug 2024 15:52:09 +0800 Subject: [PATCH 34/44] fix clippy --- pallets/subtensor/src/lib.rs | 11 +++++++++-- pallets/subtensor/src/macros/dispatches.rs | 2 +- runtime/src/lib.rs | 4 ++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index d77a87b37..22fa0514e 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1401,8 +1401,15 @@ where ..Default::default() }), Some(Call::dissolve_network { .. }) => { - InvalidTransaction::Custom(CustomTransactionError::ColdkeyInSwapSchedule.into()) - .into() + if ColdkeySwapScheduled::::contains_key(who) { + InvalidTransaction::Custom(CustomTransactionError::ColdkeyInSwapSchedule.into()) + .into() + } else { + Ok(ValidTransaction { + priority: Self::get_priority_vanilla(), + ..Default::default() + }) + } } _ => { if let Some(balances_call) = call.is_sub_type() { diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 68d2d70ee..112ef10b5 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1036,7 +1036,7 @@ mod dispatches { // Emit the SwapScheduled event Self::deposit_event(Event::DissolveNetworkScheduled { account: who.clone(), - netuid: netuid, + netuid, execution_block: when, }); diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index f042c449a..20d565f9a 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -902,6 +902,8 @@ parameter_types! { pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn pub const SubtensorInitialHotkeyEmissionTempo: u64 = 7200; // Drain every day. pub const SubtensorInitialNetworkMaxStake: u64 = 500_000_000_000_000; // 500_000 TAO + pub const InitialColdkeySwapScheduleDuration: BlockNumber = 5 * 24 * 60 * 60 / 12; // 5 days + pub const InitialDissolveNetworkScheduleDuration: BlockNumber = 5 * 24 * 60 * 60 / 12; // 5 days } @@ -962,6 +964,8 @@ impl pallet_subtensor::Config for Runtime { type InitialHotkeyEmissionTempo = SubtensorInitialHotkeyEmissionTempo; type InitialNetworkMaxStake = SubtensorInitialNetworkMaxStake; type Preimages = Preimage; + type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration; + type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration; } use sp_runtime::BoundedVec; From cc036e55b1daa35a5d7b5b6777e3ea77d57e3133 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 6 Aug 2024 16:10:49 +0800 Subject: [PATCH 35/44] fix clippy --- pallets/subtensor/src/lib.rs | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 22fa0514e..f92f1102c 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1412,24 +1412,19 @@ where } } _ => { - if let Some(balances_call) = call.is_sub_type() { - match balances_call { - BalancesCall::transfer_keep_alive { .. } - | BalancesCall::transfer_all { .. } - | BalancesCall::transfer_allow_death { .. } => { - if ColdkeySwapScheduled::::contains_key(who) { - return InvalidTransaction::Custom( - CustomTransactionError::ColdkeyInSwapSchedule.into(), - ) - .into(); - } - } - // Add other Balances call validations if needed - _ => {} + if let Some( + BalancesCall::transfer_keep_alive { .. } + | BalancesCall::transfer_all { .. } + | BalancesCall::transfer_allow_death { .. }, + ) = call.is_sub_type() + { + if ColdkeySwapScheduled::::contains_key(who) { + return InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into(), + ) + .into(); } } - - // Default validation for other calls Ok(ValidTransaction { priority: Self::get_priority_vanilla(), ..Default::default() From 70f624fad7c5a5eddcc56c6c44c64f45cdc8629e Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 6 Aug 2024 22:17:18 +0800 Subject: [PATCH 36/44] udpate comments --- pallets/subtensor/src/benchmarks.rs | 2 +- pallets/subtensor/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index eaa4821ad..05d006ab0 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -440,7 +440,7 @@ reveal_weights { }: schedule_swap_coldkey(RawOrigin::Signed(old_coldkey.clone()), new_coldkey.clone()) schedule_dissolve_network { - let coldkey: T::AccountId = account("old_cold", 0, 1); + let coldkey: T::AccountId = account("coldkey", 0, 1); let netuid = 1; let _ = Subtensor::::schedule_dissolve_network( ::RuntimeOrigin::from(RawOrigin::Signed(coldkey.clone())), diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index f92f1102c..09f1446e7 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -599,7 +599,7 @@ pub mod pallet { StorageValue<_, BlockNumberFor, ValueQuery, DefaultColdkeySwapScheduleDuration>; #[pallet::type_value] - /// Default value for coldkey swap schedule duration + /// Default value for dissolve network schedule duration pub fn DefaultDissolveNetworkScheduleDuration() -> BlockNumberFor { T::InitialDissolveNetworkScheduleDuration::get() } From 771b120fc783a737f3b82c97c8dbcf59967f0ba8 Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 7 Aug 2024 09:30:38 +0800 Subject: [PATCH 37/44] fix bechmarks --- pallets/subtensor/src/benchmarks.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index 05d006ab0..2cb53e62c 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -432,20 +432,10 @@ reveal_weights { schedule_swap_coldkey { let old_coldkey: T::AccountId = account("old_cold", 0, 1); let new_coldkey: T::AccountId = account("new_cold", 1, 2); - let _ = Subtensor::::schedule_swap_coldkey( - ::RuntimeOrigin::from(RawOrigin::Signed(old_coldkey.clone())), - new_coldkey.clone(), - ); - }: schedule_swap_coldkey(RawOrigin::Signed(old_coldkey.clone()), new_coldkey.clone()) schedule_dissolve_network { let coldkey: T::AccountId = account("coldkey", 0, 1); let netuid = 1; - let _ = Subtensor::::schedule_dissolve_network( - ::RuntimeOrigin::from(RawOrigin::Signed(coldkey.clone())), - netuid, - ); - - }: schedule_dissolve_network(RawOrigin::Signed(coldkey.clone()), netuid) + }: schedule_dissolve_network(RawOrigin::Signed(coldkey.clone()), netuid) } From 03a85f191dcebe6c107a4016e570fa5db8ea471c Mon Sep 17 00:00:00 2001 From: Keith Date: Wed, 7 Aug 2024 03:00:46 +0900 Subject: [PATCH 38/44] Create publish script to publish crates in the correct order --- publish.sh | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 publish.sh diff --git a/publish.sh b/publish.sh new file mode 100644 index 000000000..0e8b75520 --- /dev/null +++ b/publish.sh @@ -0,0 +1,30 @@ +#!/bin/bash +set -ex +cargo doc --all-features +cargo test --all-features --workspace +cd support/macros +cargo publish +cd ../.. +cd pallets/commitments +cargo publish +cd .. +cd collective +cargo publish +cd .. +cd registry +cargo publish +cd .. +cd subtensor +cargo publish +cd runtime-api +cargo publish +cd ../.. +cd admin-utils +cargo publish +cd ../.. +cd runtime +cargo publish +cd .. +cd node +cargo publish +echo "published successfully." From c4eeca1fabe75d8a31e16335f6512ec9614a6f60 Mon Sep 17 00:00:00 2001 From: Keith Date: Wed, 7 Aug 2024 13:32:46 +0900 Subject: [PATCH 39/44] Put publish.sh inside scripts/ --- publish.sh => scripts/publish.sh | 2 -- 1 file changed, 2 deletions(-) rename publish.sh => scripts/publish.sh (85%) diff --git a/publish.sh b/scripts/publish.sh similarity index 85% rename from publish.sh rename to scripts/publish.sh index 0e8b75520..3eb0fc6a5 100644 --- a/publish.sh +++ b/scripts/publish.sh @@ -1,7 +1,5 @@ #!/bin/bash set -ex -cargo doc --all-features -cargo test --all-features --workspace cd support/macros cargo publish cd ../.. From 63666075ee7c71aa0d2045ec9164aa31e5d02291 Mon Sep 17 00:00:00 2001 From: Keith Date: Thu, 8 Aug 2024 17:30:36 +0900 Subject: [PATCH 40/44] Add bump-version binary to help with bumping all crate versions --- Cargo.lock | 9 ++++++ Cargo.toml | 1 + VERSION | 1 + pallets/subtensor/rpc/Cargo.toml | 4 +-- runtime/Cargo.toml | 2 +- support/tools/Cargo.toml | 18 ++++++++++++ support/tools/src/bump_version.rs | 49 +++++++++++++++++++++++++++++++ 7 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 VERSION create mode 100644 support/tools/Cargo.toml create mode 100644 support/tools/src/bump_version.rs diff --git a/Cargo.lock b/Cargo.lock index 4a50f8a12..28f3f212c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9216,6 +9216,15 @@ dependencies = [ "syn 2.0.67", ] +[[package]] +name = "subtensor-tools" +version = "0.1.0" +dependencies = [ + "anyhow", + "semver 1.0.23", + "toml_edit 0.22.14", +] + [[package]] name = "subtle" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index 4a7565a01..e8d94e157 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "pallets/commitments", "pallets/subtensor", "runtime", + "support/tools", "support/macros", ] resolver = "2" diff --git a/VERSION b/VERSION new file mode 100644 index 000000000..0c89fc927 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +4.0.0 \ No newline at end of file diff --git a/pallets/subtensor/rpc/Cargo.toml b/pallets/subtensor/rpc/Cargo.toml index db2f5f147..861c313d8 100644 --- a/pallets/subtensor/rpc/Cargo.toml +++ b/pallets/subtensor/rpc/Cargo.toml @@ -26,8 +26,8 @@ sp-runtime = { workspace = true } # local packages -subtensor-custom-rpc-runtime-api = { version = "0.0.2", path = "../runtime-api", default-features = false } -pallet-subtensor = { version = "4.0.0-dev", path = "../../subtensor", default-features = false } +subtensor-custom-rpc-runtime-api = { path = "../runtime-api", default-features = false } +pallet-subtensor = { path = "../../subtensor", default-features = false } [features] default = ["std"] diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 042d0337c..60c8fa22e 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -21,7 +21,7 @@ path = "src/spec_version.rs" [dependencies] subtensor-macros.workspace = true -subtensor-custom-rpc-runtime-api = { version = "0.0.2", path = "../pallets/subtensor/runtime-api", default-features = false } +subtensor-custom-rpc-runtime-api = { path = "../pallets/subtensor/runtime-api", default-features = false } smallvec = { workspace = true } log = { workspace = true } codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ diff --git a/support/tools/Cargo.toml b/support/tools/Cargo.toml new file mode 100644 index 000000000..a640fde54 --- /dev/null +++ b/support/tools/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "subtensor-tools" +version = "0.1.0" +edition = "2021" +license = "MIT" + +description = "support tools for Subtensor" +repository = "https://github.com/opentensor/subtensor" +homepage = "https://bittensor.com" + +[[bin]] +name = "bump-version" +path = "src/bump_version.rs" + +[dependencies] +anyhow = "1.0" +semver = "1.0" +toml_edit = "0.22" diff --git a/support/tools/src/bump_version.rs b/support/tools/src/bump_version.rs new file mode 100644 index 000000000..a806e7f36 --- /dev/null +++ b/support/tools/src/bump_version.rs @@ -0,0 +1,49 @@ +use semver::Version; +use std::{ + fs, + io::{Read, Seek, Write}, + str::FromStr, +}; +use toml_edit::{DocumentMut, Item, Value}; + +const TOML_PATHS: [&str; 9] = [ + "support/macros", + "pallets/commitments", + "pallets/collective", + "pallets/registry", + "pallets/subtensor", + "pallets/subtensor/runtime-api", + "pallets/admin-utils", + "runtime", + "node", +]; + +fn main() -> anyhow::Result<()> { + let mut version_file = fs::File::options().read(true).write(true).open("VERSION")?; + let mut version_str = String::new(); + version_file.read_to_string(&mut version_str)?; + let mut version = Version::parse(&version_str)?; + version.minor = version.minor.saturating_add(1); + + for path in TOML_PATHS { + let cargo_toml_path = format!("{path}/Cargo.toml"); + let mut toml_file = fs::File::options() + .read(true) + .write(true) + .open(&cargo_toml_path)?; + let mut toml_str = String::new(); + toml_file.read_to_string(&mut toml_str)?; + let mut modified_toml_doc = DocumentMut::from_str(&toml_str)?; + + modified_toml_doc["package"]["version"] = Item::Value(Value::from(version.to_string())); + toml_file.set_len(0)?; + toml_file.rewind()?; + toml_file.write_all(modified_toml_doc.to_string().as_bytes())?; + } + + version_file.set_len(0)?; + version_file.rewind()?; + version_file.write_all(version.to_string().as_bytes())?; + + Ok(()) +} From 9e98762c89fb78a73c76de0880aa4fc6c7c0b186 Mon Sep 17 00:00:00 2001 From: Keith Date: Wed, 14 Aug 2024 11:06:34 -0400 Subject: [PATCH 41/44] Remove VERSION file and instead pass version as an argument --- Cargo.lock | 1 + VERSION | 1 - support/tools/Cargo.toml | 1 + support/tools/src/bump_version.rs | 18 +++++++++--------- 4 files changed, 11 insertions(+), 10 deletions(-) delete mode 100644 VERSION diff --git a/Cargo.lock b/Cargo.lock index 28f3f212c..5e46fa1a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9221,6 +9221,7 @@ name = "subtensor-tools" version = "0.1.0" dependencies = [ "anyhow", + "clap", "semver 1.0.23", "toml_edit 0.22.14", ] diff --git a/VERSION b/VERSION deleted file mode 100644 index 0c89fc927..000000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -4.0.0 \ No newline at end of file diff --git a/support/tools/Cargo.toml b/support/tools/Cargo.toml index a640fde54..fa3e1fd50 100644 --- a/support/tools/Cargo.toml +++ b/support/tools/Cargo.toml @@ -14,5 +14,6 @@ path = "src/bump_version.rs" [dependencies] anyhow = "1.0" +clap = { version = "4.5", features = ["derive"] } semver = "1.0" toml_edit = "0.22" diff --git a/support/tools/src/bump_version.rs b/support/tools/src/bump_version.rs index a806e7f36..a16293c30 100644 --- a/support/tools/src/bump_version.rs +++ b/support/tools/src/bump_version.rs @@ -1,3 +1,4 @@ +use clap::Parser; use semver::Version; use std::{ fs, @@ -18,12 +19,15 @@ const TOML_PATHS: [&str; 9] = [ "node", ]; +#[derive(Parser)] +struct CliArgs { + #[arg(required = true)] + version: Version, +} + fn main() -> anyhow::Result<()> { - let mut version_file = fs::File::options().read(true).write(true).open("VERSION")?; - let mut version_str = String::new(); - version_file.read_to_string(&mut version_str)?; - let mut version = Version::parse(&version_str)?; - version.minor = version.minor.saturating_add(1); + let args = CliArgs::parse(); + let version = args.version; for path in TOML_PATHS { let cargo_toml_path = format!("{path}/Cargo.toml"); @@ -41,9 +45,5 @@ fn main() -> anyhow::Result<()> { toml_file.write_all(modified_toml_doc.to_string().as_bytes())?; } - version_file.set_len(0)?; - version_file.rewind()?; - version_file.write_all(version.to_string().as_bytes())?; - Ok(()) } From 74fcd80bf535b51ef2b8851d57a7d45a32cc46f8 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Mon, 19 Aug 2024 08:12:14 +0400 Subject: [PATCH 42/44] chore: tidy --- pallets/subtensor/src/swap/swap_coldkey.rs | 8 -------- runtime/src/lib.rs | 4 ---- 2 files changed, 12 deletions(-) diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index 5b02d49b5..498549e5c 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -49,14 +49,6 @@ impl Pallet { ); weight = weight.saturating_add(T::DbWeight::get().reads(1)); - // TODO: Consider adding a check to ensure the new coldkey is not in arbitration - // ensure!( - // !Self::coldkey_in_arbitration(new_coldkey), - // Error::::NewColdkeyIsInArbitration - // ); - - // Note: We might want to add a cooldown period for coldkey swaps to prevent abuse - // 5. Calculate the swap cost and ensure sufficient balance let swap_cost = Self::get_key_swap_cost(); ensure!( diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 20d565f9a..f644d8a2a 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -97,10 +97,6 @@ type MemberCount = u32; pub type Nonce = u32; -/// The scheduler type used for scheduling delayed calls. -// With something like this: -// type Scheduler = pallet_subtensor::Scheduler; - // 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; From 8ab4573e79a18f39f7c5251e11c67a6504e7c2b6 Mon Sep 17 00:00:00 2001 From: open-junius Date: Mon, 19 Aug 2024 13:14:51 +0800 Subject: [PATCH 43/44] clean code and fix a bug --- pallets/subtensor/src/macros/dispatches.rs | 31 -- pallets/subtensor/tests/networks.rs | 409 --------------------- 2 files changed, 440 deletions(-) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 112ef10b5..21668c922 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -687,36 +687,6 @@ mod dispatches { Self::do_swap_coldkey(&old_coldkey, &new_coldkey) } - /// Unstakes all tokens associated with a hotkey and transfers them to a new coldkey. - /// - /// # Arguments - /// - /// * `origin` - The origin of the call, must be signed by the current coldkey. - /// * `hotkey` - The hotkey associated with the stakes to be unstaked. - /// * `new_coldkey` - The new coldkey to receive the unstaked tokens. - /// - /// # Returns - /// - /// Returns a `DispatchResult` indicating success or failure of the operation. - /// - /// # Weight - /// - /// Weight is calculated based on the number of database reads and writes. - #[cfg(test)] - #[pallet::call_index(72)] - #[pallet::weight((Weight::from_parts(21_000_000, 0) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(3)), DispatchClass::Operational, Pays::No))] - pub fn schedule_coldkey_swap( - _origin: OriginFor, - _new_coldkey: T::AccountId, - _work: Vec, - _block_number: u64, - _nonce: u64, - ) -> DispatchResult { - Ok(()) - } - // ---- SUDO ONLY FUNCTIONS ------------------------------------------------------------ // ================================== @@ -1032,7 +1002,6 @@ mod dispatches { ) .map_err(|_| Error::::FailedToSchedule)?; - ColdkeySwapScheduled::::insert(&who, ()); // Emit the SwapScheduled event Self::deposit_event(Event::DissolveNetworkScheduled { account: who.clone(), diff --git a/pallets/subtensor/tests/networks.rs b/pallets/subtensor/tests/networks.rs index 1929ff543..b41ff985d 100644 --- a/pallets/subtensor/tests/networks.rs +++ b/pallets/subtensor/tests/networks.rs @@ -94,412 +94,3 @@ fn test_schedule_dissolve_network_execution() { assert!(!SubtensorModule::if_subnet_exist(netuid)); }) } - -// #[allow(dead_code)] -// fn record(event: RuntimeEvent) -> EventRecord { -// EventRecord { -// phase: Phase::Initialization, -// event, -// topics: vec![], -// } -// } - -// /*TO DO SAM: write test for LatuUpdate after it is set */ -// // --- add network tests ---- -// #[test] -// fn test_add_network_dispatch_info_ok() { -// new_test_ext().execute_with(|| { -// let netuid: u16 = 1; -// let modality = 0; -// let tempo: u16 = 13; -// let call = RuntimeCall::SubtensorModule(SubtensorCall::sudo_add_network { -// netuid, -// tempo, -// modality, -// }); -// assert_eq!( -// call.get_dispatch_info(), -// DispatchInfo { -// weight: frame_support::weights::Weight::from_parts(50000000, 0), -// class: DispatchClass::Operational, -// pays_fee: Pays::No -// } -// ); -// }); -// } - -// #[test] -// fn test_add_network() { -// new_test_ext().execute_with(|| { -// let modality = 0; -// let tempo: u16 = 13; -// add_network(10, tempo, modality); -// assert_eq!(SubtensorModule::get_number_of_subnets(), 1); -// add_network(20, tempo, modality); -// assert_eq!(SubtensorModule::get_number_of_subnets(), 2); -// }); -// } - -// #[test] -// fn test_add_network_check_tempo() { -// new_test_ext().execute_with(|| { -// let modality = 0; -// let tempo: u16 = 13; -// assert_eq!(SubtensorModule::get_tempo(1), 0); -// add_network(1, tempo, modality); -// assert_eq!(SubtensorModule::get_tempo(1), 13); -// }); -// } - -// #[test] -// fn test_clear_min_allowed_weight_for_network() { -// new_test_ext().execute_with(|| { -// let netuid: u16 = 1; -// let min_allowed_weight = 2; -// let tempo: u16 = 13; -// add_network(netuid, tempo, 0); -// register_ok_neuron(1, U256::from(55), U256::from(66), 0); -// SubtensorModule::set_min_allowed_weights(netuid, min_allowed_weight); -// assert_eq!(SubtensorModule::get_min_allowed_weights(netuid), 2); -// assert_ok!(SubtensorModule::do_remove_network( -// <::RuntimeOrigin>::root(), -// netuid -// )); -// assert_eq!(SubtensorModule::get_min_allowed_weights(netuid), 0); -// }); -// } - -// #[test] -// fn test_remove_uid_for_network() { -// new_test_ext().execute_with(|| { -// let netuid: u16 = 1; -// let tempo: u16 = 13; -// add_network(netuid, tempo, 0); -// register_ok_neuron(1, U256::from(55), U256::from(66), 0); -// let neuron_id; -// match SubtensorModule::get_uid_for_net_and_hotkey(netuid, &U256::from(55)) { -// Ok(k) => neuron_id = k, -// Err(e) => panic!("Error: {:?}", e), -// } -// assert!(SubtensorModule::get_uid_for_net_and_hotkey(netuid, &U256::from(55)).is_ok()); -// assert_eq!(neuron_id, 0); -// register_ok_neuron(1, U256::from(56), U256::from(67), 300000); -// let neuron_uid = -// SubtensorModule::get_uid_for_net_and_hotkey(netuid, &U256::from(56)).unwrap(); -// assert_eq!(neuron_uid, 1); -// assert_ok!(SubtensorModule::do_remove_network( -// <::RuntimeOrigin>::root(), -// netuid -// )); -// assert!(SubtensorModule::get_uid_for_net_and_hotkey(netuid, &U256::from(55)).is_err()); -// }); -// } - -// #[test] -// fn test_remove_difficulty_for_network() { -// new_test_ext().execute_with(|| { -// let netuid: u16 = 1; -// let difficulty: u64 = 10; -// let tempo: u16 = 13; -// add_network(netuid, tempo, 0); -// register_ok_neuron(1, U256::from(55), U256::from(66), 0); -// assert_ok!(SubtensorModule::sudo_set_difficulty( -// <::RuntimeOrigin>::root(), -// netuid, -// difficulty -// )); -// assert_eq!(SubtensorModule::get_difficulty_as_u64(netuid), difficulty); -// assert_ok!(SubtensorModule::do_remove_network( -// <::RuntimeOrigin>::root(), -// netuid -// )); -// assert_eq!(SubtensorModule::get_difficulty_as_u64(netuid), 10000); -// }); -// } - -// #[test] -// fn test_remove_network_for_all_hotkeys() { -// new_test_ext().execute_with(|| { -// let netuid: u16 = 1; -// let tempo: u16 = 13; -// add_network(netuid, tempo, 0); -// register_ok_neuron(1, U256::from(55), U256::from(66), 0); -// register_ok_neuron(1, U256::from(77), U256::from(88), 65536); -// assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 2); -// assert_ok!(SubtensorModule::do_remove_network( -// <::RuntimeOrigin>::root(), -// netuid -// )); -// assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 0); -// }); -// } - -// #[test] -// fn test_network_set_default_value_for_other_parameters() { -// new_test_ext().execute_with(|| { -// let netuid: u16 = 1; -// let tempo: u16 = 13; -// add_network(netuid, tempo, 0); -// assert_eq!(SubtensorModule::get_min_allowed_weights(netuid), 0); -// assert_eq!(SubtensorModule::get_emission_value(netuid), 0); -// assert_eq!(SubtensorModule::get_max_weight_limit(netuid), u16::MAX); -// assert_eq!(SubtensorModule::get_difficulty_as_u64(netuid), 10000); -// assert_eq!(SubtensorModule::get_immunity_period(netuid), 2); -// }); -// } - -// // --- Set Emission Ratios Tests -// #[test] -// fn test_network_set_emission_ratios_dispatch_info_ok() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// let emission: Vec = vec![100000000, 900000000]; -// let call = RuntimeCall::SubtensorModule(SubtensorCall::sudo_set_emission_values { -// netuids, -// emission, -// }); -// assert_eq!( -// call.get_dispatch_info(), -// DispatchInfo { -// weight: frame_support::weights::Weight::from_parts(28000000, 0), -// class: DispatchClass::Operational, -// pays_fee: Pays::No -// } -// ); -// }); -// } - -// #[test] -// fn test_network_set_emission_ratios_ok() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// let emission: Vec = vec![100000000, 900000000]; -// add_network(1, 0, 0); -// add_network(2, 0, 0); -// assert_ok!(SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// )); -// }); -// } - -// #[test] -// fn test_network_set_emission_ratios_fail_summation() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// let emission: Vec = vec![100000000, 910000000]; -// add_network(1, 0, 0); -// add_network(2, 0, 0); -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Err(Error::::InvalidEmissionValues.into()) -// ); -// }); -// } - -// #[test] -// fn test_network_set_emission_invalid_netuids() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// let emission: Vec = vec![100000000, 900000000]; -// add_network(1, 0, 0); -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Err(Error::::IncorrectNetuidsLength.into()) -// ); -// }); -// } - -// #[test] -// fn test_network_set_emission_ratios_fail_net() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// let emission: Vec = vec![100000000, 900000000]; -// add_network(1, 0, 0); -// add_network(3, 0, 0); -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Err(Error::::UidVecContainInvalidOne.into()) -// ); -// }); -// } - -// #[test] -// fn test_add_difficulty_fail() { -// new_test_ext().execute_with(|| { -// let netuid: u16 = 1; -// assert_eq!( -// SubtensorModule::sudo_set_difficulty( -// <::RuntimeOrigin>::root(), -// netuid, -// 120000 -// ), -// Err(Error::::NetworkDoesNotExist.into()) -// ); -// }); -// } - -// #[test] -// fn test_multi_tempo_with_emission() { -// new_test_ext().execute_with(|| { -// let netuid: u16 = 1; -// assert_eq!( -// SubtensorModule::sudo_set_difficulty( -// <::RuntimeOrigin>::root(), -// netuid, -// 120000 -// ), -// Err(Error::::NetworkDoesNotExist.into()) -// ); -// }); -// } - -// #[test] -// // Required by the test otherwise it would panic if compiled in debug mode -// #[allow(arithmetic_overflow)] -// fn test_set_emission_values_errors_on_emission_sum_overflow() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// // u64(u64::MAX + 1..000..1) equals to 1_000_000_000 which is the same as -// // the value of Self::get_block_emission() expected by the extrinsic -// let emission: Vec = vec![u64::MAX, 1_000_000_001]; -// add_network(1, 0, 0); -// add_network(2, 0, 0); -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Err(Error::::InvalidEmissionValues.into()) -// ); -// }); -// } - -// #[test] -// #[allow(arithmetic_overflow)] -// fn test_set_emission_values_no_errors() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// let emission: Vec = vec![600_000_000, 400_000_000]; - -// add_network(1, 0, 0); -// add_network(2, 0, 0); -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Ok(()) -// ); -// }); -// } - -// #[test] -// // Required by the test otherwise it would panic if compiled in debug mode -// #[allow(arithmetic_overflow)] -// fn test_set_emission_values_sum_too_large() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// // u64(1_000_000_000 + 1) equals to 1_000_000_001 which is more than -// // the value of Self::get_block_emission() expected by the extrinsic -// let emission: Vec = vec![1_000_000_000, 1]; -// add_network(1, 0, 0); -// add_network(2, 0, 0); -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Err(Error::::InvalidEmissionValues.into()) -// ); -// }); -// } - -// #[test] -// // Required by the test otherwise it would panic if compiled in debug mode -// #[allow(arithmetic_overflow)] -// fn test_set_emission_values_sum_too_small() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// // u64(1 + 2_000) equals to 2_001 which is LESS than -// // the value of Self::get_block_emission() expected by the extrinsic -// let emission: Vec = vec![1, 2_000]; -// add_network(1, 0, 0); -// add_network(2, 0, 0); -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Err(Error::::InvalidEmissionValues.into()) -// ); -// }); -// } - -// #[test] -// fn test_set_emission_values_too_many_netuids() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - -// // Sums to 1_000_000_000 and has 10 elements -// let emission: Vec = vec![1_000_000_000, 0, 0, 0, 0, 0, 0, 0, 0, 0]; -// add_network(1, 0, 0); -// add_network(2, 0, 0); -// // We only add 2 networks, so this should fail -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Err(Error::::IncorrectNetuidsLength.into()) -// ); -// }); -// } - -// #[test] -// fn test_set_emission_values_over_u16_max_values() { -// new_test_ext().execute_with(|| { -// // Make vec of u16 with length 2^16 + 2 -// let netuids: Vec = vec![0; 0x10002]; -// // This is greater than u16::MAX -// assert!(netuids.len() > u16::MAX as usize); -// // On cast to u16, this will be 2 -// assert!(netuids.len() as u16 == 2); - -// // Sums to 1_000_000_000 and the length is 65536 -// let mut emission: Vec = vec![0; netuids.len()]; -// emission[0] = 1_000_000_000; - -// add_network(1, 0, 0); -// add_network(2, 0, 0); -// // We only add 2 networks, so this should fail -// // but if we cast to u16 during length comparison, -// // the length will be 2 and the check will pass -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Err(Error::::IncorrectNetuidsLength.into()) -// ); -// }); -// } From e2f372bc33ec9b4b7a1c9ee69cccd542739abc09 Mon Sep 17 00:00:00 2001 From: open-junius Date: Mon, 19 Aug 2024 13:37:45 +0800 Subject: [PATCH 44/44] remove unused dispatch --- pallets/subtensor/src/macros/dispatches.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 21668c922..b1eda9ea6 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -811,17 +811,6 @@ mod dispatches { Self::user_remove_network(origin, netuid) } - /// Sets values for liquid alpha - #[pallet::call_index(64)] - #[pallet::weight((0, DispatchClass::Operational, Pays::No))] - pub fn sudo_hotfix_swap_coldkey_delegates( - _origin: OriginFor, - _old_coldkey: T::AccountId, - _new_coldkey: T::AccountId, - ) -> DispatchResult { - Ok(()) - } - /// Set a single child for a given hotkey on a specified network. /// /// This function allows a coldkey to set a single child for a given hotkey on a specified network.