Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions pallets/admin-utils/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,5 +280,18 @@ mod benchmarks {
_(RawOrigin::Root, 1u16/*netuid*/, 1_000_000_000_000_000u64/*max_stake*/)/*sudo_set_network_max_stake*/;
}

#[benchmark]
fn sudo_enable_alpha_transfer() {
pallet_subtensor::Pallet::<T>::init_new_network(
1u16, /*netuid*/
1u16, /*sudo_tempo*/
);
let owner: T::AccountId = account("Alice", 0, 1);
pallet_subtensor::SubnetOwner::<T>::insert(1u16, owner.clone());

#[extrinsic_call]
_(RawOrigin::Signed(owner.clone()), 1u16/*netuid*/)/*sudo_enable_alpha_transfer*/;
}

//impl_benchmark_test_suite!(AdminUtils, crate::mock::new_test_ext(), crate::mock::Test);
}
42 changes: 41 additions & 1 deletion pallets/admin-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ pub mod pallet {
}

#[pallet::event]
pub enum Event<T: Config> {}
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// Alpha transfer was enabled on a subnet.
AlphaTransferEnabled(u16, bool),
}

// Errors inform users that something went wrong.
#[pallet::error]
Expand Down Expand Up @@ -1287,6 +1291,42 @@ pub mod pallet {
ensure_root(origin)?;
T::Grandpa::schedule_change(next_authorities, in_blocks, forced)
}

/// Enables alpha transfer for a specific subnet.
///
/// This extrinsic allows the subnet owner to enable alpha transfer for a specific subnet.
///
/// # Arguments
/// * `origin` - The origin of the call, which must be the subnet owner.
/// * `netuid` - The unique identifier of the subnet for which the periods are being set.
///
/// # Errors
/// * `BadOrigin` - If the caller is neither the subnet owner nor the root account.
/// * `SubnetDoesNotExist` - If the specified subnet does not exist.
///
/// # Weight
/// Weight is handled by the `#[pallet::weight]` attribute.
#[pallet::call_index(61)]
#[pallet::weight(<T as Config>::WeightInfo::sudo_enable_alpha_transfer())]
pub fn sudo_enable_alpha_transfer(origin: OriginFor<T>, netuid: u16) -> DispatchResult {
pallet_subtensor::Pallet::<T>::ensure_subnet_owner(origin, netuid)?;

ensure!(
pallet_subtensor::Pallet::<T>::if_subnet_exist(netuid),
Error::<T>::SubnetDoesNotExist
);

if pallet_subtensor::Pallet::<T>::get_alpha_transfer_enabled(netuid) {
return Ok(()); // exit early if already enabled
}

pallet_subtensor::Pallet::<T>::set_alpha_transfer_enabled(netuid, true);
// Log and emit event
log::debug!("AlphaTransferEnabled( netuid: {:?} ) ", netuid);
Self::deposit_event(Event::AlphaTransferEnabled(netuid, true));

Ok(())
}
}
}

Expand Down
16 changes: 16 additions & 0 deletions pallets/admin-utils/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pub trait WeightInfo {
fn sudo_set_commit_reveal_weights_enabled() -> Weight;
fn sudo_set_evm_chain_id() -> Weight;
fn schedule_grandpa_change(a: u32) -> Weight;
fn sudo_enable_alpha_transfer() -> Weight;
}

/// Weights for `pallet_admin_utils` using the Substrate node and recommended hardware.
Expand Down Expand Up @@ -456,6 +457,14 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// TODO should be replaced by benchmarked weights
Weight::default()
}

fn sudo_enable_alpha_transfer() -> Weight {
// TODO benchmark
// 1 read for check subnet owner
// 1 read for check alpha transfer enabled
// 1 write for set alpha transfer enabled
Weight::default().saturating_add(RocksDbWeight::get().reads_writes(2_u64, 1_u64))
}
}

// For backwards compatibility and tests.
Expand Down Expand Up @@ -851,4 +860,11 @@ impl WeightInfo for () {
// TODO should be replaced by benchmarked weights
Weight::default()
}
fn sudo_enable_alpha_transfer() -> Weight {
// TODO benchmark
// 1 read for check subnet owner
// 1 read for check alpha transfer enabled
// 1 write for set alpha transfer enabled
Weight::default().saturating_add(RocksDbWeight::get().reads_writes(2_u64, 1_u64))
}
}
17 changes: 16 additions & 1 deletion pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,11 @@ pub mod pallet {
false
}
#[pallet::type_value]
/// Default value for alpha transfer enabled.
pub fn DefaultAlphaTransferEnabled<T: Config>() -> bool {
false
}
#[pallet::type_value]
/// Senate requirements
pub fn DefaultSenateRequiredStakePercentage<T: Config>() -> u64 {
T::InitialSenateRequiredStakePercentage::get()
Expand Down Expand Up @@ -1227,6 +1232,10 @@ pub mod pallet {
pub type CommitRevealWeightsEnabled<T> =
StorageMap<_, Identity, u16, bool, ValueQuery, DefaultCommitRevealWeightsEnabled<T>>;
#[pallet::storage]
/// --- MAP ( netuid ) --> alpha transfer enabled if true
pub type AlphaTransferEnabled<T> =
StorageMap<_, Identity, u16, bool, ValueQuery, DefaultAlphaTransferEnabled<T>>;
#[pallet::storage]
/// --- MAP ( netuid ) --> Burn
pub type Burn<T> = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultBurn<T>>;
#[pallet::storage]
Expand Down Expand Up @@ -1570,6 +1579,7 @@ pub enum CustomTransactionError {
RateLimitExceeded,
InsufficientLiquidity,
BadRequest,
AlphaTransferNotEnabled,
}

impl From<CustomTransactionError> for u8 {
Expand All @@ -1583,6 +1593,7 @@ impl From<CustomTransactionError> for u8 {
CustomTransactionError::NotEnoughStakeToWithdraw => 5,
CustomTransactionError::RateLimitExceeded => 6,
CustomTransactionError::InsufficientLiquidity => 7,
CustomTransactionError::AlphaTransferNotEnabled => 8,
CustomTransactionError::BadRequest => 255,
}
}
Expand Down Expand Up @@ -1654,6 +1665,10 @@ where
CustomTransactionError::InsufficientLiquidity.into(),
)
.into()),
Error::<T>::AlphaTransferNotEnabled => Err(InvalidTransaction::Custom(
CustomTransactionError::AlphaTransferNotEnabled.into(),
)
.into()),
_ => Err(
InvalidTransaction::Custom(CustomTransactionError::BadRequest.into()).into(),
),
Expand Down Expand Up @@ -1842,7 +1857,7 @@ where
alpha_amount,
}) => {
// Fully validate the user input
Self::result_to_validity(Pallet::<T>::validate_stake_transition(
Self::result_to_validity(Pallet::<T>::validate_alpha_transfer(
who,
destination_coldkey,
hotkey,
Expand Down
2 changes: 2 additions & 0 deletions pallets/subtensor/src/macros/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ mod errors {
CommittingWeightsTooFast,
/// Stake amount is too low.
AmountTooLow,
/// Alpha transfer is not enabled on this subnet.
AlphaTransferNotEnabled,
/// Not enough liquidity.
InsufficientLiquidity,
}
Expand Down
6 changes: 6 additions & 0 deletions pallets/subtensor/src/staking/move_stake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ impl<T: Config> Pallet<T> {
alpha_amount,
)?;

// Ensure alpha transfer is enabled on the origin subnet
ensure!(
Pallet::<T>::get_alpha_transfer_enabled(origin_netuid),
Error::<T>::AlphaTransferNotEnabled
);

// 9. Emit an event for logging/monitoring.
log::info!(
"StakeTransferred(origin_coldkey: {:?}, destination_coldkey: {:?}, hotkey: {:?}, origin_netuid: {:?}, destination_netuid: {:?}, amount: {:?})",
Expand Down
25 changes: 25 additions & 0 deletions pallets/subtensor/src/staking/stake_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,31 @@ impl<T: Config> Pallet<T> {

Ok(())
}

pub fn validate_alpha_transfer(
origin_coldkey: &T::AccountId,
destination_coldkey: &T::AccountId,
origin_hotkey: &T::AccountId,
destination_hotkey: &T::AccountId,
origin_netuid: u16,
destination_netuid: u16,
alpha_amount: u64,
) -> Result<(), Error<T>> {
ensure!(
Self::get_alpha_transfer_enabled(origin_netuid),
Error::<T>::AlphaTransferNotEnabled
);

Self::validate_stake_transition(
origin_coldkey,
destination_coldkey,
origin_hotkey,
destination_hotkey,
origin_netuid,
destination_netuid,
alpha_amount,
)
}
}

///////////////////////////////////////////
Expand Down
52 changes: 52 additions & 0 deletions pallets/subtensor/src/tests/move_stake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,9 @@ fn test_do_transfer_success() {
let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey);
let fee = DefaultStakingFee::<Test>::get();

// Enable alpha transfer on this subnet
SubtensorModule::set_alpha_transfer_enabled(netuid, true);

// 2. Define the origin coldkey, destination coldkey, and hotkey to be used.
let origin_coldkey = U256::from(1);
let destination_coldkey = U256::from(2);
Expand Down Expand Up @@ -906,6 +909,9 @@ fn test_do_transfer_nonexistent_hotkey() {
let subnet_owner_hotkey = U256::from(1002);
let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey);

// Enable alpha transfer on this subnet
SubtensorModule::set_alpha_transfer_enabled(netuid, true);

let origin_coldkey = U256::from(1);
let destination_coldkey = U256::from(2);
let nonexistent_hotkey = U256::from(999);
Expand All @@ -931,6 +937,9 @@ fn test_do_transfer_insufficient_stake() {
let subnet_owner_hotkey = U256::from(1002);
let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey);

// Enable alpha transfer on this subnet
SubtensorModule::set_alpha_transfer_enabled(netuid, true);

let origin_coldkey = U256::from(1);
let destination_coldkey = U256::from(2);
let hotkey = U256::from(3);
Expand Down Expand Up @@ -961,6 +970,9 @@ fn test_do_transfer_wrong_origin() {
let subnet_owner_hotkey = U256::from(1011);
let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey);

// Enable alpha transfer on this subnet
SubtensorModule::set_alpha_transfer_enabled(netuid, true);

let origin_coldkey = U256::from(1);
let wrong_coldkey = U256::from(9999);
let destination_coldkey = U256::from(2);
Expand Down Expand Up @@ -993,6 +1005,9 @@ fn test_do_transfer_minimum_stake_check() {
let subnet_owner_hotkey = U256::from(1002);
let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey);

// Enable alpha transfer on this subnet
SubtensorModule::set_alpha_transfer_enabled(netuid, true);

let origin_coldkey = U256::from(1);
let destination_coldkey = U256::from(2);
let hotkey = U256::from(3);
Expand Down Expand Up @@ -1024,6 +1039,9 @@ fn test_do_transfer_different_subnets() {
let origin_netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey);
let destination_netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey);

// Enable alpha transfer on origin subnet
SubtensorModule::set_alpha_transfer_enabled(origin_netuid, true);

// 2. Define origin/destination coldkeys and hotkey.
let origin_coldkey = U256::from(1);
let destination_coldkey = U256::from(2);
Expand Down Expand Up @@ -1088,6 +1106,40 @@ fn test_do_transfer_different_subnets() {
});
}

/// RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::move_stake::test_do_transfer_alpha_transfer_not_enabled --show-output
#[test]
fn test_do_transfer_alpha_transfer_not_enabled() {
new_test_ext(1).execute_with(|| {
let subnet_owner_coldkey = U256::from(1001);
let subnet_owner_hotkey = U256::from(1002);
let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey);

let origin_coldkey = U256::from(1);
let destination_coldkey = U256::from(2);
let hotkey = U256::from(3);
let stake_amount = DefaultMinStake::<Test>::get() * 10;

SubtensorModule::create_account_if_non_existent(&origin_coldkey, &hotkey);
SubtensorModule::stake_into_subnet(&hotkey, &origin_coldkey, netuid, stake_amount, 0);

// Verify alpha transfer is not enabled
assert!(!SubtensorModule::get_alpha_transfer_enabled(netuid));

let alpha = stake_amount - 10_000;
assert_err!(
SubtensorModule::do_transfer_stake(
RuntimeOrigin::signed(origin_coldkey),
destination_coldkey,
hotkey,
netuid,
netuid,
alpha
),
Error::<Test>::AlphaTransferNotEnabled
);
});
}

#[test]
fn test_do_swap_success() {
new_test_ext(1).execute_with(|| {
Expand Down
20 changes: 19 additions & 1 deletion pallets/subtensor/src/utils/misc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;
use crate::{
system::{ensure_root, ensure_signed_or_root, pallet_prelude::BlockNumberFor},
system::{ensure_root, ensure_signed, ensure_signed_or_root, pallet_prelude::BlockNumberFor},
Error,
};
use safe_math::*;
Expand All @@ -23,6 +23,17 @@ impl<T: Config> Pallet<T> {
}
}

/// Ensure that the caller is the owner of the subnet.
/// Note: this is *not* true for the root account.
pub fn ensure_subnet_owner(o: T::RuntimeOrigin, netuid: u16) -> Result<(), DispatchError> {
let coldkey = ensure_signed(o);
match coldkey {
Ok(who) if SubnetOwner::<T>::get(netuid) == who => Ok(()),
Ok(_) => Err(DispatchError::BadOrigin),
Err(x) => Err(x.into()),
}
}

// ========================
// ==== Global Setters ====
// ========================
Expand Down Expand Up @@ -471,6 +482,13 @@ impl<T: Config> Pallet<T> {
CommitRevealWeightsEnabled::<T>::set(netuid, enabled);
}

pub fn get_alpha_transfer_enabled(netuid: u16) -> bool {
AlphaTransferEnabled::<T>::get(netuid)
}
pub fn set_alpha_transfer_enabled(netuid: u16, enabled: bool) {
AlphaTransferEnabled::<T>::set(netuid, enabled);
}

pub fn get_rho(netuid: u16) -> u16 {
Rho::<T>::get(netuid)
}
Expand Down