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
4 changes: 2 additions & 2 deletions pallets/subtensor/src/coinbase/run_coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ impl<T: Config> Pallet<T> {
// --- 8 Iterate over each nominator and get all viable stake.
let mut total_viable_nominator_stake: u64 = total_hotkey_stake;
for (nominator, nominator_stake) in Stake::<T>::iter_prefix(hotkey) {
if LastAddStakeIncrease::<T>::get(hotkey, nominator) > last_emission_drain {
if false && LastAddStakeIncrease::<T>::get(hotkey, nominator) > last_emission_drain {
total_viable_nominator_stake =
total_viable_nominator_stake.saturating_sub(nominator_stake);
}
Expand All @@ -303,7 +303,7 @@ impl<T: Config> Pallet<T> {
for (nominator, nominator_stake) in Stake::<T>::iter_prefix(hotkey) {
// --- 10 Check if the stake was manually increased by the user since the last emission drain for this hotkey.
// If it was, skip this nominator as they will not receive their proportion of the emission.
if LastAddStakeIncrease::<T>::get(hotkey, nominator.clone()) > last_emission_drain {
if false && LastAddStakeIncrease::<T>::get(hotkey, nominator.clone()) > last_emission_drain {
continue;
}

Expand Down
144 changes: 143 additions & 1 deletion pallets/subtensor/tests/coinbase.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#![allow(unused, clippy::indexing_slicing, clippy::panic, clippy::unwrap_used)]
use crate::mock::*;
mod mock;
// use frame_support::{assert_err, assert_ok};
use frame_support::{assert_err, assert_ok};
use frame_system::Config;
use sp_core::U256;

// Test the ability to hash all sorts of hotkeys.
Expand Down Expand Up @@ -154,3 +155,144 @@ fn test_set_and_get_hotkey_emission_tempo() {
assert_eq!(updated_tempo, new_tempo);
});
}

#[test]
fn test_coinbase_nominator_drainage() {
new_test_ext(1).execute_with(|| {
// 1. Set up the network and accounts
let netuid: u16 = 1;
let hotkey = U256::from(0);
let coldkey = U256::from(3);
let nominator1 = U256::from(1);
let nominator2 = U256::from(2);

log::debug!("Setting up network with netuid: {}", netuid);
log::debug!("Hotkey: {:?}, Coldkey: {:?}", hotkey, coldkey);
log::debug!("Nominators: {:?}, {:?}", nominator1, nominator2);

// 2. Create network and register neuron
add_network(netuid, 1, 0);
register_ok_neuron(netuid, hotkey, coldkey, 100000);
SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey);

log::debug!("Network created and neuron registered");

// 3. Set up balances and stakes
SubtensorModule::add_balance_to_coldkey_account(&coldkey, 1000);
SubtensorModule::add_balance_to_coldkey_account(&nominator1, 1500);
SubtensorModule::add_balance_to_coldkey_account(&nominator2, 1500);

log::debug!("Balances added to accounts");

// 4. Make the hotkey a delegate
assert_ok!(SubtensorModule::do_become_delegate(
<<Test as Config>::RuntimeOrigin>::signed(coldkey),
hotkey,
(u16::MAX as u64 / 10) as u16
));

log::debug!("Hotkey became a delegate with minimum take");

// Add stakes for nominators
SubtensorModule::add_stake(
<<Test as Config>::RuntimeOrigin>::signed(nominator1),
hotkey,
100,
);

SubtensorModule::add_stake(
<<Test as Config>::RuntimeOrigin>::signed(nominator2),
hotkey,
100,
);

// Log the stakes for hotkey, nominator1, and nominator2
log::debug!(
"Initial stakes - Hotkey: {}, Nominator1: {}, Nominator2: {}",
SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey, &hotkey),
SubtensorModule::get_stake_for_coldkey_and_hotkey(&nominator1, &hotkey),
SubtensorModule::get_stake_for_coldkey_and_hotkey(&nominator2, &hotkey)
);
log::debug!("Stakes added for nominators");

// 5. Set emission and verify initial states
SubtensorModule::set_emission_values(&[netuid], vec![10]).unwrap();
assert_eq!(SubtensorModule::get_subnet_emission_value(netuid), 10);
assert_eq!(SubtensorModule::get_pending_hotkey_emission(&hotkey), 0);
assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey), 200);
assert_eq!(SubtensorModule::get_pending_emission(netuid), 0);

log::debug!("Emission set and initial states verified");

// 6. Set hotkey emission tempo
SubtensorModule::set_hotkey_emission_tempo(1);
log::debug!("Hotkey emission tempo set to 1");

// 7. Simulate blocks and check emissions
next_block();
assert_eq!(SubtensorModule::get_pending_emission(netuid), 10);
log::debug!(
"After first block, pending emission: {}",
SubtensorModule::get_pending_emission(netuid)
);

next_block();
assert_eq!(SubtensorModule::get_pending_emission(netuid), 0);
assert_eq!(SubtensorModule::get_pending_hotkey_emission(&hotkey), 0);
log::debug!("After second block, pending emission drained");

// 8. Check final stakes
let hotkey_stake = SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey, &hotkey);
let nominator1_stake =
SubtensorModule::get_stake_for_coldkey_and_hotkey(&nominator1, &hotkey);
let nominator2_stake =
SubtensorModule::get_stake_for_coldkey_and_hotkey(&nominator2, &hotkey);

log::debug!(
"Final stakes - Hotkey: {}, Nominator1: {}, Nominator2: {}",
hotkey_stake,
nominator1_stake,
nominator2_stake
);

// 9. Verify distribution
let min_take = SubtensorModule::get_min_delegate_take() as u64;
let total_emission = 20; // 10 per block for 2 blocks
let hotkey_emission = total_emission * min_take / u16::MAX as u64;
let remaining_emission = total_emission - hotkey_emission;
let nominator_emission = remaining_emission / 2;

log::debug!(
"Calculated emissions - Hotkey: {}, Each Nominator: {}",
hotkey_emission,
nominator_emission
);

// Debug: Print the actual stakes
log::debug!("Actual hotkey stake: {}", hotkey_stake);
log::debug!("Actual nominator1 stake: {}", nominator1_stake);
log::debug!("Actual nominator2 stake: {}", nominator2_stake);

// Debug: Check the total stake for the hotkey
let total_stake = SubtensorModule::get_total_stake_for_hotkey(&hotkey);
log::debug!("Total stake for hotkey: {}", total_stake);

// Assertions
assert_eq!(hotkey_stake, 2, "Hotkey stake mismatch");
assert_eq!(
nominator1_stake,
100 + nominator_emission,
"Nominator1 stake mismatch"
);
assert_eq!(
nominator2_stake,
100 + nominator_emission,
"Nominator2 stake mismatch"
);

// 10. Check total stake
assert_eq!(total_stake, 200 + total_emission, "Total stake mismatch");

log::debug!("Test completed");
});
}
2 changes: 1 addition & 1 deletion runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,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: 196,
spec_version: 199,
impl_version: 1,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
Expand Down
Loading