subtensor
subtensor copied to clipboard
Running STAO and DTAO concurrently
- change the emission calculation to the following:
sum_tao = sum([p.tao_in for p in pools])
sum_prices = sum([p.price for p in pools])
emission = [p.tao_in/sum_tao for p in pools]
for i, p in enumerate(pools):
if sum_prices > 1.0:
p.inject( tao_in = 0, alpha_in = 1, alpha_out = 1 )
else:
p.inject( tao_in = emission[i], alpha_in = 0, alpha_out = 1 )
Note that the emission is now p.tao_in/sum_tao which is the ratio of TAO in the pool to the total TAO in the pools. This is the exact same calculation for STAO, where the emission for the subnet is tao_in_network/sum_tao_in_networks
TotalSubnetStake and DynamicTAOReserve are the same values in an STAO/DTAO environment
- When we migrate from STAO --> DTAO we will need to unstake everyone
// --- 5. Iterate over all stakes and unstake them if they are in
// this subnet. The subnet is not dynamic so this is all clean unstakes.
SubStake::<T>::iter().for_each(|((cold_i, hot_i, subnet_i), stake_amount_i)| {
if subnet_i == netuid {
// Unstake everyone from this subnet.
Self::decrease_stake_on_coldkey_hotkey_account( cold_i, hot_i, subnet_i, stake_amount_i );
}
});
TotalSubnetStake::<T>::insert( netuid, 0 ); // We have cleared all the stake on this subnet.
- Prices no longer are required except here:
if sum_prices > 1.0:
p.inject( tao_in = 0, alpha_in = 1, alpha_out = 1 )
else:
p.inject( tao_in = emission[i], alpha_in = 0, alpha_out = 1 )
For STAO subnets we just always emit TAO (as if prices were > 1)
Test plan
Definition: Price threshold = SUM( Emission( subnet ) for subnet in DTAO_SUBNETS )/ SUM( Emission( subnet ) for subnet in ALL_SUBNETS )
For STAO subnets:
- DynamicTAOReserve gets increased by stake amount on
add stake - DynamicTAOReserve gets decreased by stake amount on
remove stake - DynamicTAOReserve gets increased by proportion of this subnet's DynamicTAOReserve to total stake in block_step in every block, no matter what the sub of prices is (greater or lower than threshold)
- PendingEmission gets increased by the same value on every block (within an epoch)
- At the end of every epoch PendingEmission gets distributed to delegates' and delegators' stake, and is reset to 0
- Delegates and delegators can then turn their stake into TAO by removing stake, which will be converted to TAO 1:1.
For DTAO subnets
- DynamicTAOReserve gets increased by stake amount on
add stake - DynamicTAOReserve gets decreased by stake amount on
remove stake - DynamicTAOReserve gets increased by proportion of this subnet's DynamicTAOReserve to total stake in block_step in every block, if the sum of dynamic prices is greater than or equal to threshold, by 0 otherwise
- DynamicAlphaReserve gets increased by proportion of this subnet's DynamicTAOReserve to total stake in block_step in every block, if the sum of dynamic prices is lower than threshold, by 0 otherwise
- PendingAlphaEmission gets increased by the same value on every block (within an epoch)
Corner cases
- If there are no DTAO subnets, STAO subnets keep working as above
- If there is no stake in DTAO subnets (sum of prices == 0), the sum of DTAO emissions is 0, so the threshold is 0, so all DTAO subnets get nothing in DynamicTAOReserve and DynamicAlphaReserve
- If there is zero total stake, everybody gets punished and emissions just go drained and burned
Sanity checks
- After epoch emission, the common wealth (total balance on all coldkeys of delegates and delegators + total stake) gets increased by sum of what get_block_emission function returns for every block in the epoch.
Converting a subnet from STAO to DTAO
- Only subnet owner can do it
- A conversion job is scheduled to run in
on_initializehook to avoid block overweighing. It performs all following steps. - Wait until the end of subnet tempo so that
PendingEmissionis drained (set to 0) - Halt all operations on this subnet that increase stake, which includes:
- Staking
- Epoch emissions
- Increasing
PendingEmissionin run_coinbase block handling
- Own stake of subnet owner key is converted to dynamic pool as if it was the creation of the dynamic subnet.
- "If the staked balance is lower than the current subnet lock cost, the difference will be taken from the subnet owner free balance (already reserved/withdrawn by now)" - this is questionable because Subnet already exists and has been locked for a while.
- Because of slippage, if we add existing delegators' stakes to the pool, the alpha amount granted to stakers will depend on the order, which will not be fair. So, all delegators will be forcefully unstaked and welcomed to stake back after conversion.
- After all stakers are unstaked, the
StaoToDtaoConversionUnstakeCompletedevent will be emitted.
- After all stakers are unstaked, the
- Subnet tempo is set to default value
TotalSubnetTAOwill be reduced by the amount of forcefully unstaked TAO (test)DynamicTAOReservewill be set to equal the new value ofTotalSubnetTAO(test)
Branch: feat/stao-dtao-transition
Transition check list:
- [ ] Benchmark for starting extrinsic
- [ ] Add Events as needed
closed as no longer required