Skip to content

Commit 3eaea00

Browse files
authored
Merge pull request #1042 from opentensor/merge-devnet-to-devnet-ready
Merge devnet to devnet ready with conflicts resolved
2 parents c9109ac + b639263 commit 3eaea00

File tree

7 files changed

+50850
-50793
lines changed

7 files changed

+50850
-50793
lines changed

Diff for: chainspecs/plain_spec_finney.json

+50,759-50,759
Large diffs are not rendered by default.

Diff for: chainspecs/plain_spec_testfinney.json

+1-1
Large diffs are not rendered by default.

Diff for: pallets/subtensor/src/coinbase/run_coinbase.rs

+25-25
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,28 @@ use substrate_fixed::types::I96F32;
55
impl<T: Config> Pallet<T> {
66
/// The `coinbase` function performs a four-part emission distribution process involving
77
/// subnets, epochs, hotkeys, and nominators.
8-
// It is divided into several steps, each handling a specific part of the distribution:
9-
10-
// Step 1: Compute the block-wise emission for each subnet.
11-
// This involves calculating how much (TAO) should be emitted into each subnet using the
12-
// root epoch function.
13-
14-
// Step 2: Accumulate the subnet block emission.
15-
// After calculating the block-wise emission, these values are accumulated to keep track
16-
// of how much each subnet should emit before the next distribution phase. This accumulation
17-
// is a running total that gets updated each block.
18-
19-
// Step 3: Distribute the accumulated emissions through epochs.
20-
// Subnets periodically distribute their accumulated emissions to hotkeys (active validators/miners)
21-
// in the network on a `tempo` --- the time between epochs. This step runs Yuma consensus to
22-
// determine how emissions are split among hotkeys based on their contributions and roles.
23-
// The accumulation of hotkey emissions is done through the `accumulate_hotkey_emission` function.
24-
// The function splits the rewards for a hotkey amongst itself and its `parents`. The parents are
25-
// the hotkeys that are delegating their stake to the hotkey.
26-
27-
// Step 4: Further distribute emissions from hotkeys to nominators.
28-
// Finally, the emissions received by hotkeys are further distributed to their nominators,
29-
// who are stakeholders that support the hotkeys.
8+
/// It is divided into several steps, each handling a specific part of the distribution:
9+
///
10+
/// Step 1: Compute the block-wise emission for each subnet.
11+
/// This involves calculating how much (TAO) should be emitted into each subnet using the
12+
/// root epoch function.
13+
///
14+
/// Step 2: Accumulate the subnet block emission.
15+
/// After calculating the block-wise emission, these values are accumulated to keep track
16+
/// of how much each subnet should emit before the next distribution phase. This accumulation
17+
/// is a running total that gets updated each block.
18+
///
19+
/// Step 3: Distribute the accumulated emissions through epochs.
20+
/// Subnets periodically distribute their accumulated emissions to hotkeys (active validators/miners)
21+
/// in the network on a `tempo` --- the time between epochs. This step runs Yuma consensus to
22+
/// determine how emissions are split among hotkeys based on their contributions and roles.
23+
/// The accumulation of hotkey emissions is done through the `accumulate_hotkey_emission` function.
24+
/// The function splits the rewards for a hotkey amongst itself and its `parents`. The parents are
25+
/// the hotkeys that are delegating their stake to the hotkey.
26+
///
27+
/// Step 4: Further distribute emissions from hotkeys to nominators.
28+
/// Finally, the emissions received by hotkeys are further distributed to their nominators,
29+
/// who are stakeholders that support the hotkeys.
3030
pub fn run_coinbase() {
3131
// --- 0. Get current block.
3232
let current_block: u64 = Self::get_current_block_as_u64();
@@ -48,7 +48,7 @@ impl<T: Config> Pallet<T> {
4848
// --- 3. Drain the subnet block emission and accumulate it as subnet emission, which increases until the tempo is reached in #4.
4949
// subnet_blockwise_emission -> subnet_pending_emission
5050
for netuid in subnets.clone().iter() {
51-
if *netuid == 0 {
51+
if *netuid == 0 || !Self::is_registration_allowed(*netuid) {
5252
continue;
5353
}
5454
// --- 3.1 Get the network's block-wise emission amount.
@@ -90,7 +90,7 @@ impl<T: Config> Pallet<T> {
9090
Self::set_blocks_since_last_step(*netuid, 0);
9191
Self::set_last_mechanism_step_block(*netuid, current_block);
9292

93-
if *netuid == 0 {
93+
if *netuid == 0 || !Self::is_registration_allowed(*netuid) {
9494
// Skip netuid 0 payouts
9595
continue;
9696
}
@@ -134,7 +134,7 @@ impl<T: Config> Pallet<T> {
134134
&hotkey,
135135
*netuid,
136136
validator_emission, // Amount received from validating
137-
mining_emission, // Amount recieved from mining.
137+
mining_emission, // Amount received from mining.
138138
);
139139
log::debug!("Accumulated emissions on hotkey {:?} for netuid {:?}: mining {:?}, validator {:?}", hotkey, *netuid, mining_emission, validator_emission);
140140
}

Diff for: pallets/subtensor/src/epoch/math.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -113,26 +113,24 @@ pub fn vec_max_upscale_to_u16(vec: &[I32F32]) -> Vec<u16> {
113113
})
114114
.collect();
115115
}
116-
return vec
117-
.iter()
116+
vec.iter()
118117
.map(|e: &I32F32| {
119118
e.saturating_mul(u16_max)
120119
.saturating_div(*val)
121120
.round()
122121
.to_num::<u16>()
123122
})
124-
.collect();
123+
.collect()
125124
}
126125
None => {
127126
let sum: I32F32 = vec.iter().sum();
128-
return vec
129-
.iter()
127+
vec.iter()
130128
.map(|e: &I32F32| {
131129
e.saturating_mul(u16_max)
132130
.saturating_div(sum)
133131
.to_num::<u16>()
134132
})
135-
.collect();
133+
.collect()
136134
}
137135
}
138136
}
@@ -246,7 +244,7 @@ pub fn is_topk(vector: &[I32F32], k: usize) -> Vec<bool> {
246244
pub fn normalize(x: &[I32F32]) -> Vec<I32F32> {
247245
let x_sum: I32F32 = sum(x);
248246
if x_sum != I32F32::from_num(0.0_f32) {
249-
return x.iter().map(|xi| xi.saturating_div(x_sum)).collect();
247+
x.iter().map(|xi| xi.saturating_div(x_sum)).collect()
250248
} else {
251249
x.to_vec()
252250
}

Diff for: pallets/subtensor/src/tests/coinbase.rs

+55
Original file line numberDiff line numberDiff line change
@@ -1448,3 +1448,58 @@ fn test_coinbase_nominator_drainage_with_net_negative_delta() {
14481448
log::debug!("Test completed");
14491449
});
14501450
}
1451+
1452+
/// Tests that emission rewards are not distributed when subnet registration is disabled
1453+
/// This test verifies that:
1454+
/// 1. A subnet with registration disabled does not distribute emissions
1455+
/// 2. Pending emissions remain at 0 even after multiple blocks
1456+
/// 3. Total stake remains unchanged when registration is disabled
1457+
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --test coinbase test_emission_with_registration_disabled_subnet -- --nocapture
1458+
1459+
#[test]
1460+
fn test_emission_with_registration_disabled_subnet() {
1461+
new_test_ext(1).execute_with(|| {
1462+
// Initialize test network and accounts
1463+
let netuid: u16 = 1;
1464+
let hotkey = U256::from(0); // Validator hotkey
1465+
let coldkey = U256::from(1); // Validator coldkey
1466+
1467+
// Create network and disable registration
1468+
add_network(netuid, 1, 0); // Creates subnet with netuid=1, tempo=1, modality=0
1469+
SubtensorModule::set_network_registration_allowed(netuid, false); // Disable registration
1470+
1471+
// Set up validator accounts and stake
1472+
// This simulates an existing validator before registration was disabled
1473+
SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey);
1474+
SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey, &hotkey, 1000);
1475+
1476+
// Configure emission rate for the subnet
1477+
SubtensorModule::set_emission_values(&[netuid], vec![10]).unwrap();
1478+
assert_eq!(SubtensorModule::get_subnet_emission_value(netuid), 10);
1479+
1480+
// Verify initial emission state is zero
1481+
assert_eq!(SubtensorModule::get_pending_emission(netuid), 0);
1482+
assert_eq!(SubtensorModule::get_pending_hotkey_emission(&hotkey), 0);
1483+
1484+
// Advance chain by 100 blocks
1485+
step_block(100);
1486+
1487+
// Verify no emissions were distributed after 100 blocks
1488+
assert_eq!(
1489+
SubtensorModule::get_pending_hotkey_emission(&hotkey),
1490+
0,
1491+
"Hotkey pending emission should remain zero"
1492+
);
1493+
1494+
// Advance chain by 1000 more blocks
1495+
step_block(1000);
1496+
1497+
// Verify total stake remains unchanged after many blocks
1498+
// This confirms no emissions were added to stake
1499+
let total_stake = SubtensorModule::get_total_stake_for_hotkey(&hotkey);
1500+
assert_eq!(
1501+
total_stake, 1000,
1502+
"Total stake should not increase when registration is disabled"
1503+
);
1504+
});
1505+
}

Diff for: pallets/subtensor/src/tests/epoch.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2736,6 +2736,7 @@ fn test_blocks_since_last_step() {
27362736
assert_eq!(SubtensorModule::get_blocks_since_last_step(netuid), 27);
27372737
});
27382738
}
2739+
27392740
// // Map the retention graph for consensus guarantees with an single epoch on a graph with 512 nodes, of which the first 64 are validators, the graph is split into a major and minor set, each setting specific weight on itself and the complement on the other.
27402741
// //
27412742
// // ```import torch
@@ -2835,7 +2836,7 @@ fn test_blocks_since_last_step() {
28352836
// println!("]");
28362837
// }
28372838

2838-
/// Helpers
2839+
// Helpers
28392840

28402841
/// Asserts that two I32F32 values are approximately equal within a given epsilon.
28412842
///

Diff for: runtime/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1867,7 +1867,10 @@ impl_runtime_apis! {
18671867
use frame_system_benchmarking::Pallet as SystemBench;
18681868
use baseline::Pallet as BaselineBench;
18691869

1870+
#[allow(non_local_definitions)]
18701871
impl frame_system_benchmarking::Config for Runtime {}
1872+
1873+
#[allow(non_local_definitions)]
18711874
impl baseline::Config for Runtime {}
18721875

18731876
use frame_support::traits::WhitelistedStorageKeys;

0 commit comments

Comments
 (0)