Skip to content

Commit

Permalink
Merge branch 'devnet-ready' into subnet-identities
Browse files Browse the repository at this point in the history
  • Loading branch information
unconst authored Aug 23, 2024
2 parents 979d46d + 3496c34 commit 2c2a15d
Show file tree
Hide file tree
Showing 15 changed files with 636 additions and 37 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

**/*.lock

*.ipynb

# Generated by code coverage
*.profraw
*.profdata
Expand Down
3 changes: 0 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ repository = "https://github.com/opentensor/subtensor"

[dependencies]
node-subtensor = { path = "node", version = "4.0.0-dev" }
pallet-commitments = { path = "pallets/commitments", version = "4.0.0-dev" }
pallet-subtensor = { path = "pallets/subtensor", version = "4.0.0-dev" }
node-subtensor-runtime = { path = "runtime", version = "4.0.0-dev" }
subtensor-macros = { path = "support/macros", version = "0.1.0" }

[build-dependencies]
subtensor-linting = { path = "support/linting", version = "0.1.0" }
Expand Down Expand Up @@ -167,3 +164,8 @@ opt-level = 3
inherits = "release"
lto = true
codegen-units = 1

[features]
default = []
try-runtime = ["node-subtensor/try-runtime", "node-subtensor-runtime/try-runtime"]
runtime-benchmarks = ["node-subtensor/runtime-benchmarks", "node-subtensor-runtime/runtime-benchmarks"]
14 changes: 14 additions & 0 deletions docs/delegate-info.json
Original file line number Diff line number Diff line change
Expand Up @@ -390,5 +390,19 @@
"url": "https://cortex.foundation/",
"description": "Cortex Foundation is committed to advancing the integration of decentralized AI. Our validator is designed for transparency, reliability, and community engagement.",
"signature": "7a6274ff6b0f7ddca97e37ef4a9b90781012ff3cf7baa3159f6feaafc43c557975aad324ea608d6b8abeb21f8f3ca2595e54b81a7564574d0242b803d969618a"
},
{
"address":"5F27Eqz2PhyMtGMEce898x31DokNqRVxkm5AhDDe6rDGNvoY",
"name": "Love",
"url": "https://love.cosimo.fund",
"description": "Love validator exists to accelerate open source AI and be good stewards of the Bittensorr network",
"signature": "c221a3de3be031c149a7be912b3b75e0355605f041dc975153302b23b4d93e45e9cc7453532491e92076ccd333a4c1f95f4a2229aae8f4fcfb88e5dec3f14c87"
},
{
"address": "5Hb63SvXBXqZ8zw6mwW1A39fHdqUrJvohXgepyhp2jgWedSB",
"name": "TAO Miner's Union",
"url": "https://minersunion.ai",
"description": "The first Bittensor validator that empowers you to choose which subnets to incentivize. Committed to transparency and integrity, we ensure fair and honest validation processes that contribute to the growth and strength of the network.",
"signature": "e8c68bc766a06f36c633e1f68d5aca4c4090a26e394372f64d5b00cc13621f361ec9df85fc9f0d247dbc1fe452bd53ffc0224dee2bc85c9d82cb250e4ac10984"
}
]
68 changes: 68 additions & 0 deletions pallets/admin-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub use pallet::*;
pub mod weights;
pub use weights::WeightInfo;

use frame_system::pallet_prelude::BlockNumberFor;
use sp_runtime::{traits::Member, RuntimeAppPublic};

mod benchmarking;
Expand Down Expand Up @@ -1128,6 +1129,73 @@ pub mod pallet {

Ok(())
}

/// Sets the duration of the coldkey swap schedule.
///
/// This extrinsic allows the root account to set the duration for the coldkey swap schedule.
/// The coldkey swap schedule determines how long it takes for a coldkey swap operation to complete.
///
/// # Arguments
/// * `origin` - The origin of the call, which must be the root account.
/// * `duration` - The new duration for the coldkey swap schedule, in number of blocks.
///
/// # Errors
/// * `BadOrigin` - If the caller is not the root account.
///
/// # Weight
/// Weight is handled by the `#[pallet::weight]` attribute.
#[pallet::call_index(54)]
#[pallet::weight((0, DispatchClass::Operational, Pays::No))]
pub fn sudo_set_coldkey_swap_schedule_duration(
origin: OriginFor<T>,
duration: BlockNumberFor<T>,
) -> DispatchResult {
// Ensure the call is made by the root account
ensure_root(origin)?;

// Set the new duration of schedule coldkey swap
pallet_subtensor::Pallet::<T>::set_coldkey_swap_schedule_duration(duration);

// Log the change
log::trace!("ColdkeySwapScheduleDurationSet( duration: {:?} )", duration);

Ok(())
}

/// Sets the duration of the dissolve network schedule.
///
/// This extrinsic allows the root account to set the duration for the dissolve network schedule.
/// The dissolve network schedule determines how long it takes for a network dissolution operation to complete.
///
/// # Arguments
/// * `origin` - The origin of the call, which must be the root account.
/// * `duration` - The new duration for the dissolve network schedule, in number of blocks.
///
/// # Errors
/// * `BadOrigin` - If the caller is not the root account.
///
/// # Weight
/// Weight is handled by the `#[pallet::weight]` attribute.
#[pallet::call_index(55)]
#[pallet::weight((0, DispatchClass::Operational, Pays::No))]
pub fn sudo_set_dissolve_network_schedule_duration(
origin: OriginFor<T>,
duration: BlockNumberFor<T>,
) -> DispatchResult {
// Ensure the call is made by the root account
ensure_root(origin)?;

// Set the duration of schedule dissolve network
pallet_subtensor::Pallet::<T>::set_dissolve_network_schedule_duration(duration);

// Log the change
log::trace!(
"DissolveNetworkScheduleDurationSet( duration: {:?} )",
duration
);

Ok(())
}
}
}

Expand Down
76 changes: 75 additions & 1 deletion pallets/admin-utils/tests/tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use frame_support::sp_runtime::DispatchError;
use frame_support::{
assert_err, assert_ok,
assert_err, assert_noop, assert_ok,
dispatch::{DispatchClass, GetDispatchInfo, Pays},
};
use frame_system::Config;
Expand Down Expand Up @@ -1361,3 +1361,77 @@ fn test_sudo_get_set_alpha() {
));
});
}

#[test]
fn test_sudo_set_coldkey_swap_schedule_duration() {
new_test_ext().execute_with(|| {
// Arrange
let root = RuntimeOrigin::root();
let non_root = RuntimeOrigin::signed(U256::from(1));
let new_duration = 100u32.into();

// Act & Assert: Non-root account should fail
assert_noop!(
AdminUtils::sudo_set_coldkey_swap_schedule_duration(non_root, new_duration),
DispatchError::BadOrigin
);

// Act: Root account should succeed
assert_ok!(AdminUtils::sudo_set_coldkey_swap_schedule_duration(
root.clone(),
new_duration
));

// Assert: Check if the duration was actually set
assert_eq!(
pallet_subtensor::ColdkeySwapScheduleDuration::<Test>::get(),
new_duration
);

// Act & Assert: Setting the same value again should succeed (idempotent operation)
assert_ok!(AdminUtils::sudo_set_coldkey_swap_schedule_duration(
root,
new_duration
));

// You might want to check for events here if your pallet emits them
System::assert_last_event(Event::ColdkeySwapScheduleDurationSet(new_duration).into());
});
}

#[test]
fn test_sudo_set_dissolve_network_schedule_duration() {
new_test_ext().execute_with(|| {
// Arrange
let root = RuntimeOrigin::root();
let non_root = RuntimeOrigin::signed(U256::from(1));
let new_duration = 200u32.into();

// Act & Assert: Non-root account should fail
assert_noop!(
AdminUtils::sudo_set_dissolve_network_schedule_duration(non_root, new_duration),
DispatchError::BadOrigin
);

// Act: Root account should succeed
assert_ok!(AdminUtils::sudo_set_dissolve_network_schedule_duration(
root.clone(),
new_duration
));

// Assert: Check if the duration was actually set
assert_eq!(
pallet_subtensor::DissolveNetworkScheduleDuration::<Test>::get(),
new_duration
);

// Act & Assert: Setting the same value again should succeed (idempotent operation)
assert_ok!(AdminUtils::sudo_set_dissolve_network_schedule_duration(
root,
new_duration
));

// You might want to check for events here if your pallet emits them
System::assert_last_event(Event::DissolveNetworkScheduleDurationSet(new_duration).into());
});
}
61 changes: 60 additions & 1 deletion pallets/subtensor/src/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ benchmarks! {
assert_ok!(Subtensor::<T>::register_network(RawOrigin::Signed(coldkey.clone()).into(), None));
}: dissolve_network(RawOrigin::Signed(coldkey), 1)


// swap_hotkey {
// let seed: u32 = 1;
// let coldkey: T::AccountId = account("Alice", 0, seed);
Expand Down Expand Up @@ -444,7 +445,7 @@ reveal_weights {
let new_rate_limit: u64 = 100;
}: sudo_set_tx_childkey_take_rate_limit(RawOrigin::Root, new_rate_limit)

benchmark_set_childkey_take {
benchmark_set_childkey_take {
// Setup
let netuid: u16 = 1;
let tempo: u16 = 1;
Expand All @@ -462,4 +463,62 @@ benchmark_set_childkey_take {
Subtensor::<T>::add_balance_to_coldkey_account(&coldkey, amount_to_be_staked);
assert_ok!(Subtensor::<T>::do_burned_registration(RawOrigin::Signed(coldkey.clone()).into(), netuid, hotkey.clone()));
}: set_childkey_take(RawOrigin::Signed(coldkey), hotkey, netuid, take)

swap_coldkey {
// Set up initial state
let old_coldkey: T::AccountId = account("old_coldkey", 0, 0);
let new_coldkey: T::AccountId = account("new_coldkey", 0, 0);
let hotkey1: T::AccountId = account("hotkey1", 0, 0);
let netuid = 1u16;
let stake_amount1 = 1000u64;
let stake_amount2 = 2000u64;
let swap_cost = Subtensor::<T>::get_key_swap_cost();
let free_balance_old = 12345u64 + swap_cost;
let tempo: u16 = 1;

// Setup initial state
Subtensor::<T>::init_new_network(netuid, tempo);
Subtensor::<T>::set_network_registration_allowed(netuid, true);
Subtensor::<T>::set_network_pow_registration_allowed(netuid, true);

let block_number: u64 = Subtensor::<T>::get_current_block_as_u64();
let (nonce, work): (u64, Vec<u8>) = Subtensor::<T>::create_work_for_block_number(
netuid,
block_number,
3,
&hotkey1,
);

let _ = Subtensor::<T>::register(
<T as frame_system::Config>::RuntimeOrigin::from(RawOrigin::Signed(old_coldkey.clone())),
netuid,
block_number,
nonce,
work.clone(),
hotkey1.clone(),
old_coldkey.clone(),
);

// Add balance to old coldkey
Subtensor::<T>::add_balance_to_coldkey_account(
&old_coldkey,
stake_amount1 + stake_amount2 + free_balance_old,
);

// Insert an Identity
let name: Vec<u8> = b"The fourth Coolest Identity".to_vec();
let identity: ChainIdentity = ChainIdentity {
name: name.clone(),
url: vec![],
image: vec![],
discord: vec![],
description: vec![],
additional: vec![],
};

Identities::<T>::insert(&old_coldkey, identity);

// Benchmark setup complete, now execute the extrinsic
}: swap_coldkey(RawOrigin::Signed(old_coldkey.clone()), old_coldkey.clone(), new_coldkey.clone())

}
9 changes: 3 additions & 6 deletions pallets/subtensor/src/coinbase/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1015,17 +1015,14 @@ impl<T: Config> Pallet<T> {
/// * 'SubNetworkDoesNotExist': If the specified network does not exist.
/// * 'NotSubnetOwner': If the caller does not own the specified subnet.
///
pub fn user_remove_network(origin: T::RuntimeOrigin, netuid: u16) -> dispatch::DispatchResult {
// --- 1. Ensure the function caller is a signed user.
let coldkey = ensure_signed(origin)?;

// --- 2. Ensure this subnet exists.
pub fn user_remove_network(coldkey: T::AccountId, netuid: u16) -> dispatch::DispatchResult {
// --- 1. Ensure this subnet exists.
ensure!(
Self::if_subnet_exist(netuid),
Error::<T>::SubNetworkDoesNotExist
);

// --- 3. Ensure the caller owns this subnet.
// --- 2. Ensure the caller owns this subnet.
ensure!(
SubnetOwner::<T>::get(netuid) == coldkey,
Error::<T>::NotSubnetOwner
Expand Down
25 changes: 17 additions & 8 deletions pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -672,16 +672,17 @@ mod dispatches {
///
/// Weight is calculated based on the number of database reads and writes.
#[pallet::call_index(71)]
#[pallet::weight((Weight::from_parts(1_940_000_000, 0)
.saturating_add(T::DbWeight::get().reads(272))
.saturating_add(T::DbWeight::get().writes(527)), DispatchClass::Operational, Pays::No))]
#[pallet::weight((Weight::from_parts(127_713_000, 0)
.saturating_add(Weight::from_parts(0, 11645))
.saturating_add(T::DbWeight::get().reads(18))
.saturating_add(T::DbWeight::get().writes(12)), DispatchClass::Operational, Pays::No))]
pub fn swap_coldkey(
origin: OriginFor<T>,
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)?;
log::info!("swap_coldkey: {:?} -> {:?}", old_coldkey, new_coldkey);

Self::do_swap_coldkey(&old_coldkey, &new_coldkey)
Expand Down Expand Up @@ -933,8 +934,13 @@ mod dispatches {
#[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::No))]
pub fn dissolve_network(origin: OriginFor<T>, netuid: u16) -> DispatchResult {
Self::user_remove_network(origin, netuid)
pub fn dissolve_network(
origin: OriginFor<T>,
coldkey: T::AccountId,
netuid: u16,
) -> DispatchResult {
ensure_root(origin)?;
Self::user_remove_network(coldkey, netuid)
}

/// Set a single child for a given hotkey on a specified network.
Expand Down Expand Up @@ -1103,7 +1109,10 @@ mod dispatches {
let duration: BlockNumberFor<T> = DissolveNetworkScheduleDuration::<T>::get();
let when: BlockNumberFor<T> = current_block.saturating_add(duration);

let call = Call::<T>::dissolve_network { netuid };
let call = Call::<T>::dissolve_network {
coldkey: who.clone(),
netuid,
};

let bound_call = T::Preimages::bound(LocalCallOf::<T>::from(call.clone()))
.map_err(|_| Error::<T>::FailedToSchedule)?;
Expand All @@ -1112,7 +1121,7 @@ mod dispatches {
DispatchTime::At(when),
None,
63,
frame_system::RawOrigin::Signed(who.clone()).into(),
frame_system::RawOrigin::Root.into(),
bound_call,
)
.map_err(|_| Error::<T>::FailedToSchedule)?;
Expand Down
Loading

0 comments on commit 2c2a15d

Please sign in to comment.