Skip to content

Commit 0399af2

Browse files
committed
fix: merge duplicate UIDs in weight computation
If WASM returns the same hotkey multiple times, their weights are now summed on the same UID instead of pushing duplicate UID entries. Uses BTreeMap for deterministic UID ordering. Applied to both CommitWindowOpen handler and RPC pre-compute at 70s.
1 parent 6a3d17e commit 0399af2

File tree

1 file changed

+25
-12
lines changed

1 file changed

+25
-12
lines changed

bins/validator-node/src/main.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,16 +1571,22 @@ async fn main() -> Result<()> {
15711571
if assignments.is_empty() { continue; }
15721572
let total: f64 = assignments.iter().map(|a| a.weight).sum();
15731573
if total <= 0.0 { continue; }
1574-
let mut uids = Vec::new();
1575-
let mut vals = Vec::new();
1574+
// Merge duplicate UIDs
1575+
let mut uid_map: std::collections::BTreeMap<u16, f64> = std::collections::BTreeMap::new();
15761576
let mut assigned = 0.0f64;
15771577
for a in &assignments {
15781578
if let Some(uid) = subtensor_client.as_ref().and_then(|c| c.get_uid_for_hotkey(&a.hotkey)) {
15791579
let scaled = (a.weight / total) * ew;
1580-
let v = (scaled * 65535.0).round() as u16;
1581-
if v > 0 { uids.push(uid); vals.push(v); assigned += scaled; }
1580+
*uid_map.entry(uid).or_insert(0.0) += scaled;
1581+
assigned += scaled;
15821582
}
15831583
}
1584+
let mut uids = Vec::new();
1585+
let mut vals = Vec::new();
1586+
for (uid, w) in &uid_map {
1587+
let v = (w * 65535.0).round() as u16;
1588+
if v > 0 { uids.push(*uid); vals.push(v); }
1589+
}
15841590
let burn = 1.0 - assigned;
15851591
if burn > 0.001 {
15861592
let bv = (burn * 65535.0).round() as u16;
@@ -3703,8 +3709,9 @@ async fn handle_block_event(
37033709
Ok(assignments) if !assignments.is_empty() => {
37043710
let total_weight: f64 = assignments.iter().map(|a| a.weight).sum();
37053711

3706-
let mut uids: Vec<u16> = Vec::new();
3707-
let mut vals: Vec<u16> = Vec::new();
3712+
// Use a map to merge duplicate UIDs (same hotkey appearing multiple times)
3713+
let mut uid_weight_map: std::collections::BTreeMap<u16, f64> =
3714+
std::collections::BTreeMap::new();
37083715
let mut assigned_weight: f64 = 0.0;
37093716

37103717
if total_weight > 0.0 {
@@ -3716,12 +3723,8 @@ async fn handle_block_event(
37163723
if let Some(uid) = uid {
37173724
let normalized = assignment.weight / total_weight;
37183725
let scaled = normalized * emission_weight;
3719-
let weight_u16 = (scaled * 65535.0).round() as u16;
3720-
if weight_u16 > 0 {
3721-
uids.push(uid);
3722-
vals.push(weight_u16);
3723-
assigned_weight += scaled;
3724-
}
3726+
*uid_weight_map.entry(uid).or_insert(0.0) += scaled;
3727+
assigned_weight += scaled;
37253728
} else {
37263729
warn!(
37273730
"Hotkey {} not found in metagraph, weight goes to burn",
@@ -3731,6 +3734,16 @@ async fn handle_block_event(
37313734
}
37323735
}
37333736

3737+
let mut uids: Vec<u16> = Vec::new();
3738+
let mut vals: Vec<u16> = Vec::new();
3739+
for (uid, w) in &uid_weight_map {
3740+
let weight_u16 = (w * 65535.0).round() as u16;
3741+
if weight_u16 > 0 {
3742+
uids.push(*uid);
3743+
vals.push(weight_u16);
3744+
}
3745+
}
3746+
37343747
// Remaining weight goes to burn (UID 0)
37353748
let burn_weight = 1.0 - assigned_weight;
37363749
if burn_weight > 0.001 {

0 commit comments

Comments
 (0)