Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

devnet deploy 2/24/2025 number 2 #1339

Merged
merged 12 commits into from
Feb 24, 2025
2 changes: 1 addition & 1 deletion docs/rust-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Use a terminal shell to execute the following commands:
```bash
sudo apt update
# May prompt for location information
sudo apt install -y git clang curl libssl-dev llvm libudev-dev
sudo apt install -y git clang curl libssl-dev llvm libudev-dev make pkg-config protobuf-compiler
```

### Arch Linux
Expand Down
3 changes: 1 addition & 2 deletions pallets/admin-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1383,8 +1383,7 @@ pub mod pallet {
///
/// # Arguments
/// * `origin` - The origin of the call, which must be the root account.
/// * `precompile_id` - The identifier of the EVM precompile to toggle.
/// * `enabled` - The new enablement state of the precompile.
/// * `alpha` - The new moving alpha value for the SubnetMovingAlpha.
///
/// # Errors
/// * `BadOrigin` - If the caller is not the root account.
Expand Down
25 changes: 25 additions & 0 deletions pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1882,5 +1882,30 @@ mod dispatches {
allow_partial,
)
}

/// Attempts to associate a hotkey with a coldkey.
///
/// # Arguments
/// * `origin` - The origin of the transaction, which must be signed by the coldkey that owns the `hotkey`.
/// * `hotkey` - The hotkey to associate with the coldkey.
///
/// # Note
/// Will charge based on the weight even if the hotkey is already associated with a coldkey.
#[pallet::call_index(91)]
#[pallet::weight((
Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().reads_writes(3, 3)),
DispatchClass::Operational,
Pays::Yes
))]
pub fn try_associate_hotkey(
origin: T::RuntimeOrigin,
hotkey: T::AccountId,
) -> DispatchResult {
let coldkey = ensure_signed(origin)?;

let _ = Self::do_try_associate_hotkey(&coldkey, &hotkey);

Ok(())
}
}
}
13 changes: 13 additions & 0 deletions pallets/subtensor/src/staking/account.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use super::*;

impl<T: Config> Pallet<T> {
pub fn do_try_associate_hotkey(
coldkey: &T::AccountId,
hotkey: &T::AccountId,
) -> DispatchResult {
// Ensure the hotkey is not already associated with a coldkey
Self::create_account_if_non_existent(coldkey, hotkey);

Ok(())
}
}
6 changes: 5 additions & 1 deletion pallets/subtensor/src/staking/decrease_take.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ impl<T: Config> Pallet<T> {
// --- 4. Set the new take value.
Delegates::<T>::insert(hotkey.clone(), take);

// --- 5. Emit the take value.
// --- 5. Set last block for rate limiting
let block: u64 = Self::get_current_block_as_u64();
Self::set_last_tx_block_delegate_take(&hotkey, block);

// --- 6. Emit the take value.
log::debug!(
"TakeDecreased( coldkey:{:?}, hotkey:{:?}, take:{:?} )",
coldkey,
Expand Down
4 changes: 2 additions & 2 deletions pallets/subtensor/src/staking/increase_take.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ impl<T: Config> Pallet<T> {
let block: u64 = Self::get_current_block_as_u64();
ensure!(
!Self::exceeds_tx_delegate_take_rate_limit(
Self::get_last_tx_block_delegate_take(&coldkey),
Self::get_last_tx_block_delegate_take(&hotkey),
block
),
Error::<T>::DelegateTxRateLimitExceeded
);

// Set last block for rate limiting
Self::set_last_tx_block_delegate_take(&coldkey, block);
Self::set_last_tx_block_delegate_take(&hotkey, block);

// --- 6. Set the new take value.
Delegates::<T>::insert(hotkey.clone(), take);
Expand Down
1 change: 1 addition & 0 deletions pallets/subtensor/src/staking/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::*;
pub mod account;
pub mod add_stake;
pub mod decrease_take;
pub mod helpers;
Expand Down
64 changes: 64 additions & 0 deletions pallets/subtensor/src/tests/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1671,6 +1671,70 @@ fn test_rate_limits_enforced_on_increase_take() {
});
}

// Test rate-limiting on an increase take just after a decrease take
// Prevents a Validator from decreasing take and then increasing it immediately after.
#[test]
fn test_rate_limits_enforced_on_decrease_before_increase_take() {
new_test_ext(1).execute_with(|| {
// Make account
let hotkey0 = U256::from(1);
let coldkey0 = U256::from(3);

// Add balance
SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000);

// Register the neuron to a new network
let netuid = 1;
add_network(netuid, 1, 0);
register_ok_neuron(netuid, hotkey0, coldkey0, 124124);

// Coldkey / hotkey 0 become delegates with 9% take
Delegates::<Test>::insert(hotkey0, SubtensorModule::get_min_delegate_take() + 1);
assert_eq!(
SubtensorModule::get_hotkey_take(&hotkey0),
SubtensorModule::get_min_delegate_take() + 1
);

// Decrease take
assert_ok!(SubtensorModule::do_decrease_take(
RuntimeOrigin::signed(coldkey0),
hotkey0,
SubtensorModule::get_min_delegate_take()
)); // Verify decrease
assert_eq!(
SubtensorModule::get_hotkey_take(&hotkey0),
SubtensorModule::get_min_delegate_take()
);

// Increase take immediately after
assert_eq!(
SubtensorModule::do_increase_take(
RuntimeOrigin::signed(coldkey0),
hotkey0,
SubtensorModule::get_min_delegate_take() + 1
),
Err(Error::<Test>::DelegateTxRateLimitExceeded.into())
); // Verify no change
assert_eq!(
SubtensorModule::get_hotkey_take(&hotkey0),
SubtensorModule::get_min_delegate_take()
);

step_block(1 + InitialTxDelegateTakeRateLimit::get() as u16);

// Can increase after waiting
assert_ok!(SubtensorModule::do_increase_take(
RuntimeOrigin::signed(coldkey0),
hotkey0,
SubtensorModule::get_min_delegate_take() + 1
)); // Verify increase
assert_eq!(
SubtensorModule::get_hotkey_take(&hotkey0),
SubtensorModule::get_min_delegate_take() + 1
);
});
}

#[test]
fn test_get_total_delegated_stake_after_unstaking() {
new_test_ext(1).execute_with(|| {
Expand Down
66 changes: 66 additions & 0 deletions pallets/subtensor/src/tests/staking2.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use super::mock::*;
use crate::*;
use frame_support::{
assert_ok,
dispatch::{GetDispatchInfo, Pays},
weights::Weight,
};
use sp_core::U256;
use substrate_fixed::types::I96F32;

Expand Down Expand Up @@ -557,3 +562,64 @@ fn test_share_based_staking_stake_inject_stake_new() {
});
});
}

// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::staking2::test_try_associate_hotkey --exact --show-output --nocapture
#[test]
fn test_try_associate_hotkey() {
new_test_ext(1).execute_with(|| {
let hotkey1 = U256::from(1);
let coldkey1 = U256::from(2);
let coldkey2 = U256::from(3);

// Check initial association
assert!(!SubtensorModule::hotkey_account_exists(&hotkey1));

// Associate hotkey1 with coldkey1
assert_ok!(SubtensorModule::try_associate_hotkey(
RuntimeOrigin::signed(coldkey1),
hotkey1
));

// Check that hotkey1 is associated with coldkey1
assert!(SubtensorModule::hotkey_account_exists(&hotkey1));
assert_eq!(
SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey1),
coldkey1
);
assert_ne!(SubtensorModule::get_owned_hotkeys(&coldkey1).len(), 0);
assert!(SubtensorModule::get_owned_hotkeys(&coldkey1).contains(&hotkey1));

// Verify this tx requires a fee
let call =
RuntimeCall::SubtensorModule(crate::Call::try_associate_hotkey { hotkey: hotkey1 });
let dispatch_info = call.get_dispatch_info();
// Verify tx weight > 0
assert!(dispatch_info.weight.all_gte(Weight::from_all(0)));
// Verify pays Yes is set
assert_eq!(dispatch_info.pays_fee, Pays::Yes);

// Check that coldkey2 is not associated with any hotkey
assert!(!SubtensorModule::get_owned_hotkeys(&coldkey2).contains(&hotkey1));
assert_eq!(SubtensorModule::get_owned_hotkeys(&coldkey2).len(), 0);

// Try to associate hotkey1 with coldkey2
// Should have no effect because coldkey1 is already associated with hotkey1
assert_ok!(SubtensorModule::try_associate_hotkey(
RuntimeOrigin::signed(coldkey2),
hotkey1
));

// Check that hotkey1 is still associated with coldkey1
assert!(SubtensorModule::hotkey_account_exists(&hotkey1));
assert_eq!(
SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey1),
coldkey1
);
assert_ne!(SubtensorModule::get_owned_hotkeys(&coldkey1).len(), 0);
assert!(SubtensorModule::get_owned_hotkeys(&coldkey1).contains(&hotkey1));

// Check that coldkey2 is still not associated with any hotkey
assert!(!SubtensorModule::get_owned_hotkeys(&coldkey2).contains(&hotkey1));
assert_eq!(SubtensorModule::get_owned_hotkeys(&coldkey2).len(), 0);
});
}
2 changes: 1 addition & 1 deletion runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,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: 243,
spec_version: 244,
impl_version: 1,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
Expand Down
Loading