Skip to content

Commit 32982b7

Browse files
committed
Change type of flow cutoff to I64F64, add tests for negative cutoff, cleanup tests
1 parent 9cd2b14 commit 32982b7

File tree

5 files changed

+112
-79
lines changed

5 files changed

+112
-79
lines changed

pallets/admin-utils/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub mod pallet {
3131
utils::rate_limiting::{Hyperparameter, TransactionType},
3232
};
3333
use sp_runtime::BoundedVec;
34-
use substrate_fixed::types::{I96F32, U64F64};
34+
use substrate_fixed::types::{I64F64, I96F32, U64F64};
3535
use subtensor_runtime_common::{MechId, NetUid, TaoCurrency};
3636

3737
/// The main data structure of the module.
@@ -2111,7 +2111,7 @@ pub mod pallet {
21112111
))]
21122112
pub fn sudo_set_tao_flow_cutoff(
21132113
origin: OriginFor<T>,
2114-
flow_cutoff: TaoCurrency,
2114+
flow_cutoff: I64F64,
21152115
) -> DispatchResult {
21162116
ensure_root(origin)?;
21172117
pallet_subtensor::Pallet::<T>::set_tao_flow_cutoff(flow_cutoff);

pallets/subtensor/src/coinbase/subnet_emissions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ impl<T: Config> Pallet<T> {
9090
.map(|flow| flow.min(&zero))
9191
.min()
9292
.unwrap_or(&zero);
93-
let flow_cutoff = I64F64::saturating_from_num(u64::from(TaoFlowCutoff::<T>::get()));
93+
let flow_cutoff = TaoFlowCutoff::<T>::get();
9494
flow_cutoff.max(*min_flow)
9595
}
9696

pallets/subtensor/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1218,9 +1218,14 @@ pub mod pallet {
12181218
#[pallet::storage] // --- MAP ( netuid ) --> subnet_ema_tao_flow | Returns the EMA of TAO inflow-outflow balance.
12191219
pub type SubnetEmaTaoFlow<T: Config> =
12201220
StorageMap<_, Identity, NetUid, (u64, I64F64), OptionQuery>;
1221+
#[pallet::type_value]
1222+
/// Default value for flow cutoff.
1223+
pub fn DefaultFlowCutoff<T: Config>() -> I64F64 {
1224+
I64F64::saturating_from_num(0)
1225+
}
12211226
#[pallet::storage]
12221227
/// --- ITEM --> TAO Flow Cutoff
1223-
pub type TaoFlowCutoff<T: Config> = StorageValue<_, TaoCurrency, ValueQuery, DefaultZeroTao<T>>;
1228+
pub type TaoFlowCutoff<T: Config> = StorageValue<_, I64F64, ValueQuery, DefaultFlowCutoff<T>>;
12241229
#[pallet::type_value]
12251230
/// Default value for flow normalization exponent.
12261231
pub fn DefaultFlowNormExponent<T: Config>() -> U64F64 {

pallets/subtensor/src/tests/subnet_emissions.rs

Lines changed: 101 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,9 @@ fn get_shares_normal_flows_three_subnets() {
191191
}
192192

193193
// Monotonicity with the flows: share(n3) > share(n2) > share(n1)
194-
let s1 = shares.get(&NetUid::from(n1)).unwrap().to_num::<f64>();
195-
let s2 = shares.get(&NetUid::from(n2)).unwrap().to_num::<f64>();
196-
let s3 = shares.get(&NetUid::from(n3)).unwrap().to_num::<f64>();
194+
let s1 = shares.get(&n1).unwrap().to_num::<f64>();
195+
let s2 = shares.get(&n2).unwrap().to_num::<f64>();
196+
let s3 = shares.get(&n3).unwrap().to_num::<f64>();
197197
assert!(
198198
s3 > s2 && s2 > s1,
199199
"expected s3 > s2 > s1; got {s1}, {s2}, {s3}"
@@ -236,8 +236,8 @@ fn get_shares_low_flows_sum_one_and_ordering() {
236236
);
237237
}
238238

239-
let s1 = shares.get(&NetUid::from(n1)).unwrap().to_num::<f64>();
240-
let s2 = shares.get(&NetUid::from(n2)).unwrap().to_num::<f64>();
239+
let s1 = shares.get(&n1).unwrap().to_num::<f64>();
240+
let s2 = shares.get(&n2).unwrap().to_num::<f64>();
241241
assert!(
242242
s2 > s1,
243243
"expected s2 > s1 with higher flow; got s1={s1}, s2={s2}"
@@ -265,7 +265,7 @@ fn get_shares_high_flows_sum_one_and_ordering() {
265265
SubnetEmaTaoFlow::<Test>::insert(n1, (block_num, i64f64(9.0e11)));
266266
SubnetEmaTaoFlow::<Test>::insert(n2, (block_num, i64f64(1.8e12)));
267267

268-
let subnets = vec![NetUid::from(n1), NetUid::from(n2)];
268+
let subnets = vec![n1, n2];
269269
let shares = SubtensorModule::get_shares(&subnets);
270270

271271
let sum: f64 = shares.values().map(|v| v.to_num::<f64>()).sum();
@@ -280,8 +280,8 @@ fn get_shares_high_flows_sum_one_and_ordering() {
280280
);
281281
}
282282

283-
let s1 = shares.get(&NetUid::from(n1)).unwrap().to_num::<f64>();
284-
let s2 = shares.get(&NetUid::from(n2)).unwrap().to_num::<f64>();
283+
let s1 = shares.get(&n1).unwrap().to_num::<f64>();
284+
let s2 = shares.get(&n2).unwrap().to_num::<f64>();
285285
assert!(
286286
s2 > s1,
287287
"expected s2 > s1 with higher flow; got s1={s1}, s2={s2}"
@@ -306,8 +306,6 @@ fn get_shares_price_flow_blend_1v3_price_and_3v1_flow() {
306306
let owner_coldkey = U256::from(43);
307307
let n1 = add_dynamic_network(&owner_hotkey, &owner_coldkey);
308308
let n2 = add_dynamic_network(&owner_hotkey, &owner_coldkey);
309-
let net1 = NetUid::from(n1);
310-
let net2 = NetUid::from(n2);
311309

312310
// define "window" length half_life blocks and set first block to 0
313311
let half_life: u64 = FlowHalfLife::<Test>::get();
@@ -316,30 +314,30 @@ fn get_shares_price_flow_blend_1v3_price_and_3v1_flow() {
316314

317315
// t = 0: expect (0.25, 0.75)
318316
frame_system::Pallet::<Test>::set_block_number(0);
319-
seed_price_and_flow(net1, net2, /*price*/ 1.0, 3.0, /*flow*/ 3.0, 1.0);
320-
let shares = SubtensorModule::get_shares(&[net1, net2]);
321-
let s1 = shares.get(&net1).unwrap().to_num::<f64>();
322-
let s2 = shares.get(&net2).unwrap().to_num::<f64>();
317+
seed_price_and_flow(n1, n2, /*price*/ 1.0, 3.0, /*flow*/ 3.0, 1.0);
318+
let shares = SubtensorModule::get_shares(&[n1, n2]);
319+
let s1 = shares.get(&n1).unwrap().to_num::<f64>();
320+
let s2 = shares.get(&n2).unwrap().to_num::<f64>();
323321
assert_abs_diff_eq!(s1 + s2, 1.0_f64, epsilon = 1e-9);
324322
assert_abs_diff_eq!(s1, 0.25_f64, epsilon = 1e-6);
325323
assert_abs_diff_eq!(s2, 0.75_f64, epsilon = 1e-6);
326324

327325
// t = half_life/2: expect (0.5, 0.5)
328326
frame_system::Pallet::<Test>::set_block_number(half_life / 2);
329-
seed_price_and_flow(net1, net2, 1.0, 3.0, 3.0, 1.0);
330-
let shares = SubtensorModule::get_shares(&[net1, net2]);
331-
let s1 = shares.get(&net1).unwrap().to_num::<f64>();
332-
let s2 = shares.get(&net2).unwrap().to_num::<f64>();
327+
seed_price_and_flow(n1, n2, 1.0, 3.0, 3.0, 1.0);
328+
let shares = SubtensorModule::get_shares(&[n1, n2]);
329+
let s1 = shares.get(&n1).unwrap().to_num::<f64>();
330+
let s2 = shares.get(&n2).unwrap().to_num::<f64>();
333331
assert_abs_diff_eq!(s1 + s2, 1.0_f64, epsilon = 1e-9);
334332
assert_abs_diff_eq!(s1, 0.5_f64, epsilon = 1e-6);
335333
assert_abs_diff_eq!(s2, 0.5_f64, epsilon = 1e-6);
336334

337335
// t = half_life: expect (0.75, 0.25)
338336
frame_system::Pallet::<Test>::set_block_number(half_life);
339-
seed_price_and_flow(net1, net2, 1.0, 3.0, 3.0, 1.0);
340-
let shares = SubtensorModule::get_shares(&[net1, net2]);
341-
let s1 = shares.get(&net1).unwrap().to_num::<f64>();
342-
let s2 = shares.get(&net2).unwrap().to_num::<f64>();
337+
seed_price_and_flow(n1, n2, 1.0, 3.0, 3.0, 1.0);
338+
let shares = SubtensorModule::get_shares(&[n1, n2]);
339+
let s1 = shares.get(&n1).unwrap().to_num::<f64>();
340+
let s2 = shares.get(&n2).unwrap().to_num::<f64>();
343341
assert_abs_diff_eq!(s1 + s2, 1.0_f64, epsilon = 1e-9);
344342
assert_abs_diff_eq!(s1, 0.75_f64, epsilon = 1e-6);
345343
assert_abs_diff_eq!(s2, 0.25_f64, epsilon = 1e-6);
@@ -353,8 +351,6 @@ fn get_shares_price_flow_blend_3v1_price_and_1v3_flow() {
353351
let owner_coldkey = U256::from(51);
354352
let n1 = add_dynamic_network(&owner_hotkey, &owner_coldkey);
355353
let n2 = add_dynamic_network(&owner_hotkey, &owner_coldkey);
356-
let net1 = NetUid::from(n1);
357-
let net2 = NetUid::from(n2);
358354

359355
// window half_life and anchor at 0
360356
let half_life: u64 = FlowHalfLife::<Test>::get();
@@ -363,29 +359,29 @@ fn get_shares_price_flow_blend_3v1_price_and_1v3_flow() {
363359

364360
// t = 0: prices dominate → (0.75, 0.25)
365361
frame_system::Pallet::<Test>::set_block_number(0);
366-
seed_price_and_flow(net1, net2, /*price*/ 3.0, 1.0, /*flow*/ 1.0, 3.0);
367-
let shares = SubtensorModule::get_shares(&[net1, net2]);
368-
let s1 = shares.get(&net1).unwrap().to_num::<f64>();
369-
let s2 = shares.get(&net2).unwrap().to_num::<f64>();
362+
seed_price_and_flow(n1, n2, /*price*/ 3.0, 1.0, /*flow*/ 1.0, 3.0);
363+
let shares = SubtensorModule::get_shares(&[n1, n2]);
364+
let s1 = shares.get(&n1).unwrap().to_num::<f64>();
365+
let s2 = shares.get(&n2).unwrap().to_num::<f64>();
370366
assert_abs_diff_eq!(s1 + s2, 1.0_f64, epsilon = 1e-9);
371367
assert_abs_diff_eq!(s1, 0.75_f64, epsilon = 1e-6);
372368
assert_abs_diff_eq!(s2, 0.25_f64, epsilon = 1e-6);
373369

374370
// t = half_life/2: equal → (0.5, 0.5)
375371
frame_system::Pallet::<Test>::set_block_number(half_life / 2);
376-
seed_price_and_flow(net1, net2, 3.0, 1.0, 1.0, 3.0);
377-
let shares = SubtensorModule::get_shares(&[net1, net2]);
378-
let s1 = shares.get(&net1).unwrap().to_num::<f64>();
379-
let s2 = shares.get(&net2).unwrap().to_num::<f64>();
372+
seed_price_and_flow(n1, n2, 3.0, 1.0, 1.0, 3.0);
373+
let shares = SubtensorModule::get_shares(&[n1, n2]);
374+
let s1 = shares.get(&n1).unwrap().to_num::<f64>();
375+
let s2 = shares.get(&n2).unwrap().to_num::<f64>();
380376
assert_abs_diff_eq!(s1, 0.5_f64, epsilon = 1e-6);
381377
assert_abs_diff_eq!(s2, 0.5_f64, epsilon = 1e-6);
382378

383379
// t = half_life: flows dominate → (0.25, 0.75)
384380
frame_system::Pallet::<Test>::set_block_number(half_life);
385-
seed_price_and_flow(net1, net2, 3.0, 1.0, 1.0, 3.0);
386-
let shares = SubtensorModule::get_shares(&[net1, net2]);
387-
let s1 = shares.get(&net1).unwrap().to_num::<f64>();
388-
let s2 = shares.get(&net2).unwrap().to_num::<f64>();
381+
seed_price_and_flow(n1, n2, 3.0, 1.0, 1.0, 3.0);
382+
let shares = SubtensorModule::get_shares(&[n1, n2]);
383+
let s1 = shares.get(&n1).unwrap().to_num::<f64>();
384+
let s2 = shares.get(&n2).unwrap().to_num::<f64>();
389385
assert_abs_diff_eq!(s1, 0.25_f64, epsilon = 1e-6);
390386
assert_abs_diff_eq!(s2, 0.75_f64, epsilon = 1e-6);
391387
});
@@ -402,28 +398,26 @@ fn get_shares_negative_vs_positive_flow() {
402398
let owner_coldkey = U256::from(61);
403399
let n1 = add_dynamic_network(&owner_hotkey, &owner_coldkey);
404400
let n2 = add_dynamic_network(&owner_hotkey, &owner_coldkey);
405-
let net1 = NetUid::from(n1);
406-
let net2 = NetUid::from(n2);
407401

408402
// Configure blending window and current block
409403
let half_life: u64 = FlowHalfLife::<Test>::get();
410404
FlowFirstBlock::<Test>::set(Some(0_u64));
411405
FlowNormExponent::<Test>::set(u64f64(1.0));
412406
frame_system::Pallet::<Test>::set_block_number(half_life);
413-
TaoFlowCutoff::<Test>::set(TaoCurrency::from(0));
407+
TaoFlowCutoff::<Test>::set(I64F64::from_num(0));
414408

415409
// Equal EMA prices so price side doesn't bias
416-
SubnetMovingPrice::<Test>::insert(net1, i96f32(1.0));
417-
SubnetMovingPrice::<Test>::insert(net2, i96f32(1.0));
410+
SubnetMovingPrice::<Test>::insert(n1, i96f32(1.0));
411+
SubnetMovingPrice::<Test>::insert(n2, i96f32(1.0));
418412

419413
// Set flows: n1 negative, n2 positive
420414
let now = frame_system::Pallet::<Test>::block_number();
421415
SubnetEmaTaoFlow::<Test>::insert(n1, (now, i64f64(-100.0)));
422416
SubnetEmaTaoFlow::<Test>::insert(n2, (now, i64f64(500.0)));
423417

424-
let shares = SubtensorModule::get_shares(&[net1, net2]);
425-
let s1 = shares.get(&net1).unwrap().to_num::<f64>();
426-
let s2 = shares.get(&net2).unwrap().to_num::<f64>();
418+
let shares = SubtensorModule::get_shares(&[n1, n2]);
419+
let s1 = shares.get(&n1).unwrap().to_num::<f64>();
420+
let s2 = shares.get(&n2).unwrap().to_num::<f64>();
427421

428422
// Sum ~ 1
429423
assert_abs_diff_eq!(s1 + s2, 1.0_f64, epsilon = 1e-9);
@@ -445,28 +439,26 @@ fn get_shares_both_negative_flows_zero_emission() {
445439
let owner_coldkey = U256::from(61);
446440
let n1 = add_dynamic_network(&owner_hotkey, &owner_coldkey);
447441
let n2 = add_dynamic_network(&owner_hotkey, &owner_coldkey);
448-
let net1 = NetUid::from(n1);
449-
let net2 = NetUid::from(n2);
450442

451443
// Configure blending window and current block
452444
let half_life: u64 = FlowHalfLife::<Test>::get();
453445
FlowFirstBlock::<Test>::set(Some(0_u64));
454446
FlowNormExponent::<Test>::set(u64f64(1.0));
455447
frame_system::Pallet::<Test>::set_block_number(half_life);
456-
TaoFlowCutoff::<Test>::set(TaoCurrency::from(0));
448+
TaoFlowCutoff::<Test>::set(I64F64::from_num(0));
457449

458450
// Equal EMA prices so price side doesn't bias
459-
SubnetMovingPrice::<Test>::insert(net1, i96f32(1.0));
460-
SubnetMovingPrice::<Test>::insert(net2, i96f32(1.0));
451+
SubnetMovingPrice::<Test>::insert(n1, i96f32(1.0));
452+
SubnetMovingPrice::<Test>::insert(n2, i96f32(1.0));
461453

462-
// Set flows: n1 negative, n2 positive
454+
// Set flows
463455
let now = frame_system::Pallet::<Test>::block_number();
464456
SubnetEmaTaoFlow::<Test>::insert(n1, (now, i64f64(-100.0)));
465457
SubnetEmaTaoFlow::<Test>::insert(n2, (now, i64f64(-200.0)));
466458

467-
let shares = SubtensorModule::get_shares(&[net1, net2]);
468-
let s1 = shares.get(&net1).unwrap().to_num::<f64>();
469-
let s2 = shares.get(&net2).unwrap().to_num::<f64>();
459+
let shares = SubtensorModule::get_shares(&[n1, n2]);
460+
let s1 = shares.get(&n1).unwrap().to_num::<f64>();
461+
let s2 = shares.get(&n2).unwrap().to_num::<f64>();
470462

471463
assert!(
472464
s1 < 1e-20 && s2 < 1e-20,
@@ -484,28 +476,26 @@ fn get_shares_both_below_cutoff_zero_emission() {
484476
let owner_coldkey = U256::from(61);
485477
let n1 = add_dynamic_network(&owner_hotkey, &owner_coldkey);
486478
let n2 = add_dynamic_network(&owner_hotkey, &owner_coldkey);
487-
let net1 = NetUid::from(n1);
488-
let net2 = NetUid::from(n2);
489479

490480
// Configure blending window and current block
491481
let half_life: u64 = FlowHalfLife::<Test>::get();
492482
FlowFirstBlock::<Test>::set(Some(0_u64));
493483
FlowNormExponent::<Test>::set(u64f64(1.0));
494484
frame_system::Pallet::<Test>::set_block_number(half_life);
495-
TaoFlowCutoff::<Test>::set(TaoCurrency::from(2_000));
485+
TaoFlowCutoff::<Test>::set(I64F64::from_num(2_000));
496486

497487
// Equal EMA prices so price side doesn't bias
498-
SubnetMovingPrice::<Test>::insert(net1, i96f32(1.0));
499-
SubnetMovingPrice::<Test>::insert(net2, i96f32(1.0));
488+
SubnetMovingPrice::<Test>::insert(n1, i96f32(1.0));
489+
SubnetMovingPrice::<Test>::insert(n2, i96f32(1.0));
500490

501-
// Set flows: n1 negative, n2 positive
491+
// Set flows
502492
let now = frame_system::Pallet::<Test>::block_number();
503493
SubnetEmaTaoFlow::<Test>::insert(n1, (now, i64f64(1000.0)));
504494
SubnetEmaTaoFlow::<Test>::insert(n2, (now, i64f64(2000.0)));
505495

506-
let shares = SubtensorModule::get_shares(&[net1, net2]);
507-
let s1 = shares.get(&net1).unwrap().to_num::<f64>();
508-
let s2 = shares.get(&net2).unwrap().to_num::<f64>();
496+
let shares = SubtensorModule::get_shares(&[n1, n2]);
497+
let s1 = shares.get(&n1).unwrap().to_num::<f64>();
498+
let s2 = shares.get(&n2).unwrap().to_num::<f64>();
509499

510500
assert!(
511501
s1 < 1e-20 && s2 < 1e-20,
@@ -526,37 +516,75 @@ fn get_shares_one_below_cutoff_other_full_emission() {
526516
let owner_coldkey = U256::from(61);
527517
let n1 = add_dynamic_network(&owner_hotkey, &owner_coldkey);
528518
let n2 = add_dynamic_network(&owner_hotkey, &owner_coldkey);
529-
let net1 = NetUid::from(n1);
530-
let net2 = NetUid::from(n2);
531519

532520
// Configure blending window and current block
533521
let half_life: u64 = FlowHalfLife::<Test>::get();
534522
FlowFirstBlock::<Test>::set(Some(0_u64));
535523
FlowNormExponent::<Test>::set(u64f64(1.0));
536524
frame_system::Pallet::<Test>::set_block_number(half_life);
537-
TaoFlowCutoff::<Test>::set(TaoCurrency::from(2_000));
525+
TaoFlowCutoff::<Test>::set(I64F64::from_num(2_000));
538526

539527
// Equal EMA prices (price side doesn't bias)
540-
SubnetMovingPrice::<Test>::insert(net1, i96f32(1.0));
541-
SubnetMovingPrice::<Test>::insert(net2, i96f32(1.0));
528+
SubnetMovingPrice::<Test>::insert(n1, i96f32(1.0));
529+
SubnetMovingPrice::<Test>::insert(n2, i96f32(1.0));
542530

543-
// Set flows: n1 negative, n2 positive
531+
// Set flows
544532
let now = frame_system::Pallet::<Test>::block_number();
545533
SubnetEmaTaoFlow::<Test>::insert(n1, (now, i64f64(flow1)));
546534
SubnetEmaTaoFlow::<Test>::insert(n2, (now, i64f64(flow2)));
547535

548-
let shares = SubtensorModule::get_shares(&[net1, net2]);
549-
let s1 = shares.get(&net1).unwrap().to_num::<f64>();
550-
let s2 = shares.get(&net2).unwrap().to_num::<f64>();
536+
let shares = SubtensorModule::get_shares(&[n1, n2]);
537+
let s1 = shares.get(&n1).unwrap().to_num::<f64>();
538+
let s2 = shares.get(&n2).unwrap().to_num::<f64>();
551539

552540
// Sum ~ 1
553541
assert_abs_diff_eq!(s1 + s2, 1.0_f64, epsilon = 1e-9);
554-
// Negative flow subnet should not get weight from flow; with equal prices mid-window,
555-
// positive-flow subnet should dominate and get all the allocation.
556542
assert!(
557543
s2 > 0.999_999 && s1 < 1e-6,
558544
"expected s2≈1, s1≈0; got s1={s1}, s2={s2}"
559545
);
560546
});
561547
});
562548
}
549+
550+
/// If subnets have negative EMA flows, but they are above the cut-off, emissions are proportional
551+
/// for all except the bottom one, which gets nothing
552+
#[test]
553+
fn get_shares_both_negative_above_cutoff() {
554+
new_test_ext(1).execute_with(|| {
555+
// 2 subnets
556+
let owner_hotkey = U256::from(60);
557+
let owner_coldkey = U256::from(61);
558+
let n1 = add_dynamic_network(&owner_hotkey, &owner_coldkey);
559+
let n2 = add_dynamic_network(&owner_hotkey, &owner_coldkey);
560+
let n3 = add_dynamic_network(&owner_hotkey, &owner_coldkey);
561+
562+
// Configure blending window and current block
563+
let half_life: u64 = FlowHalfLife::<Test>::get();
564+
FlowFirstBlock::<Test>::set(Some(0_u64));
565+
FlowNormExponent::<Test>::set(u64f64(1.0));
566+
frame_system::Pallet::<Test>::set_block_number(half_life);
567+
TaoFlowCutoff::<Test>::set(I64F64::from_num(-1000.0));
568+
569+
// Equal EMA prices so price side doesn't bias
570+
SubnetMovingPrice::<Test>::insert(n1, i96f32(1.0));
571+
SubnetMovingPrice::<Test>::insert(n2, i96f32(1.0));
572+
SubnetMovingPrice::<Test>::insert(n3, i96f32(1.0));
573+
574+
// Set flows
575+
let now = frame_system::Pallet::<Test>::block_number();
576+
SubnetEmaTaoFlow::<Test>::insert(n1, (now, i64f64(-100.0)));
577+
SubnetEmaTaoFlow::<Test>::insert(n2, (now, i64f64(-300.0)));
578+
SubnetEmaTaoFlow::<Test>::insert(n3, (now, i64f64(-400.0)));
579+
580+
let shares = SubtensorModule::get_shares(&[n1, n2, n3]);
581+
let s1 = shares.get(&n1).unwrap().to_num::<f64>();
582+
let s2 = shares.get(&n2).unwrap().to_num::<f64>();
583+
let s3 = shares.get(&n3).unwrap().to_num::<f64>();
584+
585+
assert_abs_diff_eq!(s1, 0.75, epsilon = s1 / 100.0);
586+
assert_abs_diff_eq!(s2, 0.25, epsilon = s2 / 100.0);
587+
assert_abs_diff_eq!(s3, 0.0, epsilon = 1e-9);
588+
assert_abs_diff_eq!(s1 + s2 + s3, 1.0, epsilon = 1e-9);
589+
});
590+
}

0 commit comments

Comments
 (0)