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

set miner/ validator cut percentage #960

Closed
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
58 changes: 57 additions & 1 deletion pallets/admin-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -707,17 +707,73 @@ pub mod pallet {
))]
pub fn sudo_set_subnet_owner_cut(
origin: OriginFor<T>,
netuid: u16,
subnet_owner_cut: u16,
) -> DispatchResult {
ensure_root(origin)?;
pallet_subtensor::Pallet::<T>::set_subnet_owner_cut(subnet_owner_cut);
ensure!(
pallet_subtensor::Pallet::<T>::if_subnet_exist(netuid),
Error::<T>::SubnetDoesNotExist
);
pallet_subtensor::Pallet::<T>::set_subnet_owner_cut(netuid, subnet_owner_cut);
log::debug!(
"SubnetOwnerCut( subnet_owner_cut: {:?} ) ",
subnet_owner_cut
);
Ok(())
}

/// The extrinsic sets the subnet miner cut for a subnet.
/// It is only callable by the root account.
/// The extrinsic will call the Subtensor pallet to set the subnet miner cut.
#[pallet::call_index(58)]
#[pallet::weight((0, DispatchClass::Operational, Pays::No))]
pub fn sudo_set_subnet_miner_cut(
origin: OriginFor<T>,
netuid: u16,
subnet_miner_cut: u16,
) -> DispatchResult {
pallet_subtensor::Pallet::<T>::ensure_subnet_owner_or_root(origin, netuid)?;
ensure!(
pallet_subtensor::Pallet::<T>::if_subnet_exist(netuid),
Error::<T>::SubnetDoesNotExist
);

match pallet_subtensor::Pallet::<T>::ensure_subnet_miner_cut(netuid, subnet_miner_cut)
{
Ok(cut) => pallet_subtensor::Pallet::<T>::set_subnet_burn_cut(netuid, cut),
Err(_) => return Ok(()),
};
pallet_subtensor::Pallet::<T>::set_subnet_miner_cut(netuid, subnet_miner_cut);
Ok(())
}

/// The extrinsic sets the subnet validator cut for a subnet.
/// It is only callable by the root account.
/// The extrinsic will call the Subtensor pallet to set the subnet validator cut.
#[pallet::call_index(59)]
#[pallet::weight((0, DispatchClass::Operational, Pays::No))]
pub fn sudo_set_subnet_validator_cut(
origin: OriginFor<T>,
netuid: u16,
subnet_validator_cut: u16,
) -> DispatchResult {
pallet_subtensor::Pallet::<T>::ensure_subnet_owner_or_root(origin, netuid)?;
ensure!(
pallet_subtensor::Pallet::<T>::if_subnet_exist(netuid),
Error::<T>::SubnetDoesNotExist
);
match pallet_subtensor::Pallet::<T>::ensure_subnet_miner_cut(
netuid,
subnet_validator_cut,
) {
Ok(cut) => pallet_subtensor::Pallet::<T>::set_subnet_burn_cut(netuid, cut),
Err(_) => return Ok(()),
};
pallet_subtensor::Pallet::<T>::set_subnet_validator_cut(netuid, subnet_validator_cut);
Ok(())
}

/// The extrinsic sets the network rate limit for the network.
/// It is only callable by the root account.
/// The extrinsic will call the Subtensor pallet to set the network rate limit.
Expand Down
8 changes: 7 additions & 1 deletion pallets/admin-utils/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,10 @@ parameter_types! {
pub const InitialNetworkImmunityPeriod: u64 = 7200 * 7;
pub const InitialNetworkMinAllowedUids: u16 = 128;
pub const InitialNetworkMinLockCost: u64 = 100_000_000_000;
pub const InitialSubnetOwnerCut: u16 = 0; // 0%. 100% of rewards go to validators + miners.
pub const InitialSubnetOwnerCut: u16 = 11_796; // 18%
pub const InitialSubnetMinerCut: u16 = 30_146; // 41%
pub const InitialSubnetValidatorCut: u16 = 30_146; // 41%
pub const InitialSubnetBurnCut: u16 = 0; // 0%
pub const InitialNetworkLockReductionInterval: u64 = 2; // 2 blocks.
pub const InitialSubnetLimit: u16 = 10; // Max 10 subnets.
pub const InitialNetworkRateLimit: u64 = 0;
Expand Down Expand Up @@ -177,6 +180,9 @@ impl pallet_subtensor::Config for Test {
type InitialNetworkMinAllowedUids = InitialNetworkMinAllowedUids;
type InitialNetworkMinLockCost = InitialNetworkMinLockCost;
type InitialSubnetOwnerCut = InitialSubnetOwnerCut;
type InitialSubnetMinerCut = InitialSubnetMinerCut;
type InitialSubnetValidatorCut = InitialSubnetValidatorCut;
type InitialSubnetBurnCut = InitialSubnetBurnCut;
type InitialNetworkLockReductionInterval = InitialNetworkLockReductionInterval;
type InitialSubnetLimit = InitialSubnetLimit;
type InitialNetworkRateLimit = InitialNetworkRateLimit;
Expand Down
115 changes: 112 additions & 3 deletions pallets/admin-utils/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,20 +265,129 @@ fn test_sudo_set_adjustment_alpha() {
fn test_sudo_subnet_owner_cut() {
new_test_ext().execute_with(|| {
let to_be_set: u16 = 10;
let init_value: u16 = SubtensorModule::get_subnet_owner_cut();
let netuid: u16 = 1;
add_network(netuid, 10);
let init_value: u16 = SubtensorModule::get_subnet_owner_cut(netuid);
assert_eq!(
AdminUtils::sudo_set_subnet_owner_cut(
<<Test as Config>::RuntimeOrigin>::signed(U256::from(0)),
netuid,
to_be_set
),
Err(DispatchError::BadOrigin)
);
assert_eq!(SubtensorModule::get_subnet_owner_cut(), init_value);
assert_eq!(SubtensorModule::get_subnet_owner_cut(netuid), init_value);
assert_ok!(AdminUtils::sudo_set_subnet_owner_cut(
<<Test as Config>::RuntimeOrigin>::root(),
netuid,
to_be_set
));
assert_eq!(SubtensorModule::get_subnet_owner_cut(netuid), to_be_set);
});
}

#[test]
fn test_sudo_subnet_miner_cut() {
new_test_ext().execute_with(|| {
let to_be_set: u16 = 1000;
let netuid: u16 = 1;
add_network(netuid, 10);

let init_value: u16 = SubtensorModule::get_subnet_miner_cut(netuid);

// Test non-root access (should fail)
assert_eq!(
AdminUtils::sudo_set_subnet_miner_cut(
<<Test as Config>::RuntimeOrigin>::signed(U256::from(1)),
netuid,
to_be_set
),
Err(DispatchError::BadOrigin)
);

// Test non-existent subnet (should fail)
assert_eq!(
AdminUtils::sudo_set_subnet_miner_cut(
<<Test as Config>::RuntimeOrigin>::root(),
netuid + 1,
to_be_set
),
Err(Error::<Test>::SubnetDoesNotExist.into())
);

// Verify value hasn't changed
assert_eq!(SubtensorModule::get_subnet_miner_cut(netuid), init_value);

// Test successful update
assert_ok!(AdminUtils::sudo_set_subnet_miner_cut(
<<Test as Config>::RuntimeOrigin>::root(),
netuid,
to_be_set
));

// Verify new value
assert_eq!(SubtensorModule::get_subnet_miner_cut(netuid), to_be_set);

let sum = SubtensorModule::get_subnet_owner_cut(netuid)
+ SubtensorModule::get_subnet_miner_cut(netuid)
+ SubtensorModule::get_subnet_validator_cut(netuid)
+ SubtensorModule::get_subnet_burn_cut(netuid);

// Verify total cut sum is 100%
assert_eq!(sum, u16::MAX);
});
}

#[test]
fn test_sudo_subnet_validator_cut() {
new_test_ext().execute_with(|| {
let to_be_set: u16 = 10;
let netuid: u16 = 1;
add_network(netuid, 10);
let init_value: u16 = SubtensorModule::get_subnet_validator_cut(netuid);

// Test non-root access (should fail)
assert_eq!(
AdminUtils::sudo_set_subnet_validator_cut(
<<Test as Config>::RuntimeOrigin>::signed(U256::from(1)),
netuid,
to_be_set
),
Err(DispatchError::BadOrigin)
);

// Test non-existent subnet (should fail)
assert_eq!(
AdminUtils::sudo_set_subnet_validator_cut(
<<Test as Config>::RuntimeOrigin>::root(),
netuid + 1,
to_be_set
),
Err(Error::<Test>::SubnetDoesNotExist.into())
);

// Verify value hasn't changed
assert_eq!(
SubtensorModule::get_subnet_validator_cut(netuid),
init_value
);

// Test successful update
assert_ok!(AdminUtils::sudo_set_subnet_validator_cut(
<<Test as Config>::RuntimeOrigin>::root(),
netuid,
to_be_set
));
assert_eq!(SubtensorModule::get_subnet_owner_cut(), to_be_set);

// Verify new value
assert_eq!(SubtensorModule::get_subnet_validator_cut(netuid), to_be_set);

let sum = SubtensorModule::get_subnet_owner_cut(netuid)
+ SubtensorModule::get_subnet_miner_cut(netuid)
+ SubtensorModule::get_subnet_validator_cut(netuid)
+ SubtensorModule::get_subnet_burn_cut(netuid);
// Verify total cut sum is 100%
assert_eq!(sum, u16::MAX);
});
}

Expand Down
10 changes: 9 additions & 1 deletion pallets/subtensor/src/coinbase/run_coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,21 @@ impl<T: Config> Pallet<T> {

// --- 4.4.1 Compute the subnet owner cut.
let owner_cut: I96F32 = I96F32::from_num(subnet_emission).saturating_mul(
I96F32::from_num(Self::get_subnet_owner_cut())
I96F32::from_num(Self::get_subnet_owner_cut(*netuid))
.saturating_div(I96F32::from_num(u16::MAX)),
);

// --- 4.4.2 Remove the cut from the subnet emission
subnet_emission = subnet_emission.saturating_sub(owner_cut.to_num::<u64>());

let subnet_burn_cut: I96F32 = I96F32::from_num(subnet_emission).saturating_mul(
I96F32::from_num(Self::get_subnet_burn_cut(*netuid))
.saturating_div(I96F32::from_num(u16::MAX)),
);
subnet_emission =
subnet_emission.saturating_sub(subnet_burn_cut.to_num::<u64>());
Self::burn_tokens(subnet_burn_cut.to_num::<u64>());

// --- 4.4.3 Add the cut to the balance of the owner
Self::add_balance_to_coldkey_account(
&Self::get_subnet_owner(*netuid),
Expand Down
18 changes: 15 additions & 3 deletions pallets/subtensor/src/epoch/run_epoch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,19 @@ impl<T: Config> Pallet<T> {

// Compute rao based emission scores. range: I96F32(0, rao_emission)
let float_rao_emission: I96F32 = I96F32::from_num(rao_emission);
// Apply server and validator cuts to their respective emissions.
let server_cut: I96F32 = I96F32::from_num(Self::get_subnet_miner_cut(netuid))
.saturating_div(I96F32::from_num(u16::MAX));
let validator_cut: I96F32 = I96F32::from_num(Self::get_subnet_validator_cut(netuid))
.saturating_div(I96F32::from_num(u16::MAX));

let server_emission: Vec<I96F32> = normalized_server_emission
.iter()
.map(|se: &I32F32| I96F32::from_num(*se).saturating_mul(float_rao_emission))
.map(|se: &I32F32| {
I96F32::from_num(*se)
.saturating_mul(float_rao_emission)
.saturating_mul(server_cut)
})
.collect();
let server_emission: Vec<u64> = server_emission
.iter()
Expand All @@ -315,13 +324,16 @@ impl<T: Config> Pallet<T> {

let validator_emission: Vec<I96F32> = normalized_validator_emission
.iter()
.map(|ve: &I32F32| I96F32::from_num(*ve).saturating_mul(float_rao_emission))
.map(|ve: &I32F32| {
I96F32::from_num(*ve)
.saturating_mul(float_rao_emission)
.saturating_mul(validator_cut)
})
.collect();
let validator_emission: Vec<u64> = validator_emission
.iter()
.map(|e: &I96F32| e.to_num::<u64>())
.collect();

// Used only to track combined emission in the storage.
let combined_emission: Vec<I96F32> = normalized_combined_emission
.iter()
Expand Down
41 changes: 39 additions & 2 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,25 @@ pub mod pallet {
pub fn DefaultSubnetOwnerCut<T: Config>() -> u16 {
T::InitialSubnetOwnerCut::get()
}

#[pallet::type_value]
/// Default value for subnet miner cut.
pub fn DefaultSubnetMinerCut<T: Config>() -> u16 {
T::InitialSubnetMinerCut::get()
}

#[pallet::type_value]
/// Default value for subnet validator cut.
pub fn DefaultSubnetValidatorCut<T: Config>() -> u16 {
T::InitialSubnetValidatorCut::get()
}

#[pallet::type_value]
/// Default value for subnet burn cut.
pub fn DefaultSubnetBurnCut<T: Config>() -> u16 {
T::InitialSubnetBurnCut::get()
}

#[pallet::type_value]
/// Default value for subnet limit.
pub fn DefaultSubnetLimit<T: Config>() -> u16 {
Expand Down Expand Up @@ -881,9 +900,27 @@ pub mod pallet {
/// ITEM( network_lock_reduction_interval )
pub type NetworkLockReductionInterval<T> =
StorageValue<_, u64, ValueQuery, DefaultNetworkLockReductionInterval<T>>;

#[pallet::storage]
/// ITEM( subnet_owner_cut )
pub type SubnetOwnerCut<T> = StorageValue<_, u16, ValueQuery, DefaultSubnetOwnerCut<T>>;
/// MAP ( netuid ) --> subnet_owner_cut
pub type SubnetOwnerCut<T> =
StorageMap<_, Identity, u16, u16, ValueQuery, DefaultSubnetOwnerCut<T>>;

#[pallet::storage]
/// MAP ( netuid ) --> subnet_miner_cut
pub type SubnetMinerCut<T> =
StorageMap<_, Identity, u16, u16, ValueQuery, DefaultSubnetMinerCut<T>>;

#[pallet::storage]
/// MAP ( netuid ) --> subnet_validator_cut
pub type SubnetValidatorCut<T> =
StorageMap<_, Identity, u16, u16, ValueQuery, DefaultSubnetValidatorCut<T>>;

#[pallet::storage]
/// MAP ( netuid ) --> subnet_burn_cut
pub type SubnetBurnCut<T> =
StorageMap<_, Identity, u16, u16, ValueQuery, DefaultSubnetBurnCut<T>>;

#[pallet::storage]
/// ITEM( network_rate_limit )
pub type NetworkRateLimit<T> = StorageValue<_, u64, ValueQuery, DefaultNetworkRateLimit<T>>;
Expand Down
9 changes: 9 additions & 0 deletions pallets/subtensor/src/macros/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,15 @@ mod config {
/// Initial network subnet cut.
#[pallet::constant]
type InitialSubnetOwnerCut: Get<u16>;
/// Initial subnet miner cut.
#[pallet::constant]
type InitialSubnetMinerCut: Get<u16>;
/// Initial subnet validator cut.
#[pallet::constant]
type InitialSubnetValidatorCut: Get<u16>;
/// Initial subnet burn cut.
#[pallet::constant]
type InitialSubnetBurnCut: Get<u16>;
/// Initial lock reduction interval.
#[pallet::constant]
type InitialNetworkLockReductionInterval: Get<u64>;
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 @@ -190,5 +190,7 @@ mod errors {
InputLengthsUnequal,
/// A transactor exceeded the rate limit for setting weights.
CommittingWeightsTooFast,
/// Invalid cut normalization.
InvalidCut,
}
}
8 changes: 7 additions & 1 deletion pallets/subtensor/src/macros/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,13 @@ mod events {
/// the faucet it called on the test net.
Faucet(T::AccountId, u64),
/// the subnet owner cut is set.
SubnetOwnerCutSet(u16),
SubnetOwnerCutSet(u16, u16),
/// the subnet miner cut is set.
SubnetMinerCutSet(u16, u16),
/// the subnet validator cut is set.
SubnetValidatorCutSet(u16, u16),
/// the subnet burn cut is set.
SubnetBurnCutSet(u16, u16),
/// the network creation rate limit is set.
NetworkRateLimitSet(u64),
/// the network immunity period is set.
Expand Down
Loading
Loading