Skip to content

Commit b857d4d

Browse files
committed
add tests for emissions w/ subs
1 parent 6bddb56 commit b857d4d

File tree

1 file changed

+350
-0
lines changed

1 file changed

+350
-0
lines changed

pallets/subtensor/src/tests/coinbase.rs

Lines changed: 350 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2928,3 +2928,353 @@ fn test_zero_shares_zero_emission() {
29282928
assert_eq!(SubnetAlphaIn::<Test>::get(netuid2), initial.into());
29292929
});
29302930
}
2931+
2932+
#[test]
2933+
fn test_mining_emission_distribution_with_subsidy() {
2934+
new_test_ext(1).execute_with(|| {
2935+
let validator_coldkey = U256::from(1);
2936+
let validator_hotkey = U256::from(2);
2937+
let validator_miner_coldkey = U256::from(3);
2938+
let validator_miner_hotkey = U256::from(4);
2939+
let miner_coldkey = U256::from(5);
2940+
let miner_hotkey = U256::from(6);
2941+
let netuid = NetUid::from(1);
2942+
let subnet_tempo = 10;
2943+
let stake: u64 = 100_000_000_000;
2944+
let root_stake: u64 = 200_000_000_000; // 200 TAO
2945+
2946+
// Create root network
2947+
SubtensorModule::set_tao_weight(0); // Start tao weight at 0
2948+
SubtokenEnabled::<Test>::insert(NetUid::ROOT, true);
2949+
NetworksAdded::<Test>::insert(NetUid::ROOT, true);
2950+
2951+
// Add network, register hotkeys, and setup network parameters
2952+
add_network(netuid, subnet_tempo, 0);
2953+
SubnetMechanism::<Test>::insert(netuid, 1); // Set mechanism to 1
2954+
2955+
// Setup large LPs to prevent slippage
2956+
SubnetTAO::<Test>::insert(netuid, TaoCurrency::from(1_000_000_000_000_000));
2957+
SubnetAlphaIn::<Test>::insert(netuid, AlphaCurrency::from(1_000_000_000_000_000));
2958+
2959+
register_ok_neuron(netuid, validator_hotkey, validator_coldkey, 0);
2960+
register_ok_neuron(netuid, validator_miner_hotkey, validator_miner_coldkey, 1);
2961+
register_ok_neuron(netuid, miner_hotkey, miner_coldkey, 2);
2962+
SubtensorModule::add_balance_to_coldkey_account(
2963+
&validator_coldkey,
2964+
stake + ExistentialDeposit::get(),
2965+
);
2966+
SubtensorModule::add_balance_to_coldkey_account(
2967+
&validator_miner_coldkey,
2968+
stake + ExistentialDeposit::get(),
2969+
);
2970+
SubtensorModule::add_balance_to_coldkey_account(
2971+
&miner_coldkey,
2972+
stake + ExistentialDeposit::get(),
2973+
);
2974+
SubtensorModule::set_weights_set_rate_limit(netuid, 0);
2975+
step_block(subnet_tempo);
2976+
SubnetOwnerCut::<Test>::set(u16::MAX / 10);
2977+
// There are two validators and three neurons
2978+
MaxAllowedUids::<Test>::set(netuid, 3);
2979+
SubtensorModule::set_max_allowed_validators(netuid, 2);
2980+
2981+
// Setup stakes:
2982+
// Stake from validator
2983+
// Stake from valiminer
2984+
assert_ok!(SubtensorModule::add_stake(
2985+
RuntimeOrigin::signed(validator_coldkey),
2986+
validator_hotkey,
2987+
netuid,
2988+
stake.into()
2989+
));
2990+
assert_ok!(SubtensorModule::add_stake(
2991+
RuntimeOrigin::signed(validator_miner_coldkey),
2992+
validator_miner_hotkey,
2993+
netuid,
2994+
stake.into()
2995+
));
2996+
2997+
// Setup YUMA so that it creates emissions
2998+
Weights::<Test>::insert(NetUidStorageIndex::from(netuid), 0, vec![(1, 0xFFFF)]);
2999+
Weights::<Test>::insert(NetUidStorageIndex::from(netuid), 1, vec![(2, 0xFFFF)]);
3000+
BlockAtRegistration::<Test>::set(netuid, 0, 1);
3001+
BlockAtRegistration::<Test>::set(netuid, 1, 1);
3002+
BlockAtRegistration::<Test>::set(netuid, 2, 1);
3003+
LastUpdate::<Test>::set(NetUidStorageIndex::from(netuid), vec![2, 2, 2]);
3004+
Kappa::<Test>::set(netuid, u16::MAX / 5);
3005+
ActivityCutoff::<Test>::set(netuid, u16::MAX); // makes all stake active
3006+
ValidatorPermit::<Test>::insert(netuid, vec![true, true, false]);
3007+
3008+
// Run run_coinbase until emissions are drained
3009+
step_block(subnet_tempo);
3010+
3011+
// Add stake to validator so it has root stake
3012+
SubtensorModule::add_balance_to_coldkey_account(&validator_coldkey, root_stake.into());
3013+
// init root
3014+
assert_ok!(SubtensorModule::add_stake(
3015+
RuntimeOrigin::signed(validator_coldkey),
3016+
validator_hotkey,
3017+
NetUid::ROOT,
3018+
root_stake.into()
3019+
));
3020+
// Set tao weight non zero
3021+
SubtensorModule::set_tao_weight(u64::MAX / 10);
3022+
3023+
// Make subsidy happen
3024+
// set price very low, e.g. a lot of alpha in
3025+
//SubnetAlphaIn::<Test>::insert(netuid, AlphaCurrency::from(1_000_000_000_000_000));
3026+
pallet_subtensor_swap::AlphaSqrtPrice::<Test>::insert(
3027+
netuid,
3028+
U64F64::saturating_from_num(0.01),
3029+
);
3030+
3031+
// Run run_coinbase until emissions are drained
3032+
step_block(subnet_tempo);
3033+
3034+
log::info!("is_sub: Running epoch with subsidy");
3035+
3036+
let old_root_alpha_divs = PendingRootAlphaDivs::<Test>::get(netuid);
3037+
let per_block_emission = SubtensorModule::get_block_emission_for_issuance(
3038+
SubtensorModule::get_alpha_issuance(netuid).into(),
3039+
)
3040+
.unwrap_or(0);
3041+
3042+
// step by one block
3043+
step_block(1);
3044+
// Verify that root alpha divs
3045+
let new_root_alpha_divs = PendingRootAlphaDivs::<Test>::get(netuid);
3046+
// Check that we are indeed being subsidized, i.e. that root alpha divs are NOT increasing
3047+
assert_eq!(
3048+
new_root_alpha_divs, old_root_alpha_divs,
3049+
"Root alpha divs should not increase"
3050+
);
3051+
// Check root divs are zero
3052+
assert_eq!(
3053+
new_root_alpha_divs,
3054+
AlphaCurrency::ZERO,
3055+
"Root alpha divs should be zero"
3056+
);
3057+
let miner_stake_before_epoch = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
3058+
&miner_hotkey,
3059+
&miner_coldkey,
3060+
netuid,
3061+
);
3062+
// Run again but with some root stake
3063+
step_block(subnet_tempo - 2);
3064+
assert_abs_diff_eq!(
3065+
PendingEmission::<Test>::get(netuid).to_u64(),
3066+
U96F32::saturating_from_num(per_block_emission)
3067+
.saturating_mul(U96F32::saturating_from_num(subnet_tempo as u64))
3068+
.saturating_mul(U96F32::saturating_from_num(0.90))
3069+
.saturating_to_num::<u64>(),
3070+
epsilon = 100_000_u64.into()
3071+
);
3072+
step_block(1);
3073+
assert!(
3074+
BlocksSinceLastStep::<Test>::get(netuid) == 0,
3075+
"Blocks since last step should be 0"
3076+
);
3077+
3078+
let miner_uid = Uids::<Test>::get(netuid, miner_hotkey).unwrap_or(0);
3079+
log::info!("Miner uid: {miner_uid:?}");
3080+
let miner_incentive: AlphaCurrency =
3081+
(*Incentive::<Test>::get(NetUidStorageIndex::from(netuid))
3082+
.get(miner_uid as usize)
3083+
.expect("Miner uid should be present") as u64)
3084+
.into();
3085+
log::info!("Miner incentive: {miner_incentive:?}");
3086+
3087+
// Miner emissions
3088+
let miner_emission_1: u64 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
3089+
&miner_hotkey,
3090+
&miner_coldkey,
3091+
netuid,
3092+
)
3093+
.to_u64()
3094+
- miner_stake_before_epoch.to_u64();
3095+
3096+
assert_abs_diff_eq!(
3097+
Incentive::<Test>::get(NetUidStorageIndex::from(netuid))
3098+
.iter()
3099+
.sum::<u16>(),
3100+
u16::MAX,
3101+
epsilon = 10
3102+
);
3103+
3104+
assert_abs_diff_eq!(
3105+
miner_emission_1,
3106+
U96F32::saturating_from_num(miner_incentive)
3107+
.saturating_div(u16::MAX.into())
3108+
.saturating_mul(U96F32::saturating_from_num(per_block_emission))
3109+
.saturating_mul(U96F32::saturating_from_num(subnet_tempo + 1))
3110+
.saturating_mul(U96F32::saturating_from_num(0.45)) // miner cut
3111+
.saturating_to_num::<u64>(),
3112+
epsilon = 1_000_000_u64
3113+
);
3114+
});
3115+
}
3116+
3117+
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_mining_emission_distribution_with_no_subsidy --exact --show-output --nocapture
3118+
#[test]
3119+
fn test_mining_emission_distribution_with_no_subsidy() {
3120+
new_test_ext(1).execute_with(|| {
3121+
let validator_coldkey = U256::from(1);
3122+
let validator_hotkey = U256::from(2);
3123+
let validator_miner_coldkey = U256::from(3);
3124+
let validator_miner_hotkey = U256::from(4);
3125+
let miner_coldkey = U256::from(5);
3126+
let miner_hotkey = U256::from(6);
3127+
let netuid = NetUid::from(1);
3128+
let subnet_tempo = 10;
3129+
let stake: u64 = 100_000_000_000;
3130+
let root_stake: u64 = 200_000_000_000; // 200 TAO
3131+
3132+
// Create root network
3133+
SubtensorModule::set_tao_weight(0); // Start tao weight at 0
3134+
SubtokenEnabled::<Test>::insert(NetUid::ROOT, true);
3135+
NetworksAdded::<Test>::insert(NetUid::ROOT, true);
3136+
3137+
// Add network, register hotkeys, and setup network parameters
3138+
add_network(netuid, subnet_tempo, 0);
3139+
SubnetMechanism::<Test>::insert(netuid, 1); // Set mechanism to 1
3140+
3141+
// Setup large LPs to prevent slippage
3142+
SubnetTAO::<Test>::insert(netuid, TaoCurrency::from(1_000_000_000_000_000));
3143+
SubnetAlphaIn::<Test>::insert(netuid, AlphaCurrency::from(1_000_000_000_000_000));
3144+
3145+
register_ok_neuron(netuid, validator_hotkey, validator_coldkey, 0);
3146+
register_ok_neuron(netuid, validator_miner_hotkey, validator_miner_coldkey, 1);
3147+
register_ok_neuron(netuid, miner_hotkey, miner_coldkey, 2);
3148+
SubtensorModule::add_balance_to_coldkey_account(
3149+
&validator_coldkey,
3150+
stake + ExistentialDeposit::get(),
3151+
);
3152+
SubtensorModule::add_balance_to_coldkey_account(
3153+
&validator_miner_coldkey,
3154+
stake + ExistentialDeposit::get(),
3155+
);
3156+
SubtensorModule::add_balance_to_coldkey_account(
3157+
&miner_coldkey,
3158+
stake + ExistentialDeposit::get(),
3159+
);
3160+
SubtensorModule::set_weights_set_rate_limit(netuid, 0);
3161+
step_block(subnet_tempo);
3162+
SubnetOwnerCut::<Test>::set(u16::MAX / 10);
3163+
// There are two validators and three neurons
3164+
MaxAllowedUids::<Test>::set(netuid, 3);
3165+
SubtensorModule::set_max_allowed_validators(netuid, 2);
3166+
3167+
// Setup stakes:
3168+
// Stake from validator
3169+
// Stake from valiminer
3170+
assert_ok!(SubtensorModule::add_stake(
3171+
RuntimeOrigin::signed(validator_coldkey),
3172+
validator_hotkey,
3173+
netuid,
3174+
stake.into()
3175+
));
3176+
assert_ok!(SubtensorModule::add_stake(
3177+
RuntimeOrigin::signed(validator_miner_coldkey),
3178+
validator_miner_hotkey,
3179+
netuid,
3180+
stake.into()
3181+
));
3182+
3183+
// Setup YUMA so that it creates emissions
3184+
Weights::<Test>::insert(NetUidStorageIndex::from(netuid), 0, vec![(1, 0xFFFF)]);
3185+
Weights::<Test>::insert(NetUidStorageIndex::from(netuid), 1, vec![(2, 0xFFFF)]);
3186+
BlockAtRegistration::<Test>::set(netuid, 0, 1);
3187+
BlockAtRegistration::<Test>::set(netuid, 1, 1);
3188+
BlockAtRegistration::<Test>::set(netuid, 2, 1);
3189+
LastUpdate::<Test>::set(NetUidStorageIndex::from(netuid), vec![2, 2, 2]);
3190+
Kappa::<Test>::set(netuid, u16::MAX / 5);
3191+
ActivityCutoff::<Test>::set(netuid, u16::MAX); // makes all stake active
3192+
ValidatorPermit::<Test>::insert(netuid, vec![true, true, false]);
3193+
3194+
// Run run_coinbase until emissions are drained
3195+
step_block(subnet_tempo);
3196+
3197+
// Add stake to validator so it has root stake
3198+
SubtensorModule::add_balance_to_coldkey_account(&validator_coldkey, root_stake.into());
3199+
// init root
3200+
assert_ok!(SubtensorModule::add_stake(
3201+
RuntimeOrigin::signed(validator_coldkey),
3202+
validator_hotkey,
3203+
NetUid::ROOT,
3204+
root_stake.into()
3205+
));
3206+
// Set tao weight non zero
3207+
SubtensorModule::set_tao_weight(u64::MAX / 10);
3208+
3209+
// Make subsidy not happen
3210+
// set price very high
3211+
// e.g. very little alpha in pool
3212+
//SubnetAlphaIn::<Test>::insert(netuid, AlphaCurrency::from(5));
3213+
pallet_subtensor_swap::AlphaSqrtPrice::<Test>::insert(
3214+
netuid,
3215+
U64F64::saturating_from_num(10.0),
3216+
);
3217+
3218+
// Run run_coinbase until emissions are drained
3219+
step_block(subnet_tempo);
3220+
3221+
log::info!("is_sub: Running epoch with no subsidy");
3222+
3223+
let old_root_alpha_divs = PendingRootAlphaDivs::<Test>::get(netuid);
3224+
let miner_stake_before_epoch = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
3225+
&miner_hotkey,
3226+
&miner_coldkey,
3227+
netuid,
3228+
);
3229+
3230+
// step by one block
3231+
step_block(1);
3232+
// Verify that root alpha divs
3233+
let new_root_alpha_divs = PendingRootAlphaDivs::<Test>::get(netuid);
3234+
// Check that we are NOT being subsidized, i.e. that root alpha divs are are changing
3235+
assert_ne!(
3236+
new_root_alpha_divs, old_root_alpha_divs,
3237+
"Root alpha divs should be changing"
3238+
);
3239+
assert!(
3240+
new_root_alpha_divs > AlphaCurrency::ZERO,
3241+
"Root alpha divs should be greater than 0"
3242+
);
3243+
3244+
// Run again but with some root stake
3245+
step_block(subnet_tempo - 1);
3246+
3247+
let miner_uid = Uids::<Test>::get(netuid, miner_hotkey).unwrap_or(0);
3248+
let miner_incentive: AlphaCurrency =
3249+
(*Incentive::<Test>::get(NetUidStorageIndex::from(netuid))
3250+
.get(miner_uid as usize)
3251+
.expect("Miner uid should be present") as u64)
3252+
.into();
3253+
log::info!("Miner incentive: {miner_incentive:?}");
3254+
3255+
let per_block_emission = SubtensorModule::get_block_emission_for_issuance(
3256+
SubtensorModule::get_alpha_issuance(netuid).into(),
3257+
)
3258+
.unwrap_or(0);
3259+
3260+
// Miner emissions
3261+
let miner_emission_1: u64 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
3262+
&miner_hotkey,
3263+
&miner_coldkey,
3264+
netuid,
3265+
)
3266+
.to_u64()
3267+
- miner_stake_before_epoch.to_u64();
3268+
3269+
assert_abs_diff_eq!(
3270+
miner_emission_1,
3271+
U96F32::saturating_from_num(miner_incentive)
3272+
.saturating_div(u16::MAX.into())
3273+
.saturating_mul(U96F32::saturating_from_num(per_block_emission))
3274+
.saturating_mul(U96F32::saturating_from_num(subnet_tempo + 1))
3275+
.saturating_mul(U96F32::saturating_from_num(0.45)) // miner cut
3276+
.saturating_to_num::<u64>(),
3277+
epsilon = 1_000_000_u64
3278+
);
3279+
});
3280+
}

0 commit comments

Comments
 (0)