Skip to content

Commit ca08a44

Browse files
committed
fix: prevent 1010 duplicate commit errors after validator restart
- Init last_weight_submission_epoch to current epoch at boot (not 0) so we don't re-submit for an epoch we may have already committed to - Remove first_block_seen CommitWindowOpen (caused immediate duplicate) - Disable startup weight timer (redundant with PhaseChange handler) - Weights now submit cleanly at the next epoch boundary via CommitWindowOpen
1 parent 3bf3976 commit ca08a44

File tree

2 files changed

+11
-48
lines changed

2 files changed

+11
-48
lines changed

bins/validator-node/src/main.rs

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,37 +1637,12 @@ async fn main() -> Result<()> {
16371637
}
16381638
}
16391639

1640-
// Submit weights on-chain 90s after boot (after RPC pre-compute at 70s).
1640+
// Startup weight timer disabled: we init last_weight_submission_epoch to current
1641+
// epoch to avoid 1010 duplicate commit errors after restart. Weights will be
1642+
// submitted on the next epoch boundary via CommitWindowOpen from block_sync.
16411643
_ = &mut startup_weight_delay, if !startup_weights_submitted => {
16421644
startup_weights_submitted = true;
1643-
let current_block = state_manager.apply(|state| state.bittensor_block);
1644-
if current_block == 0 {
1645-
warn!("Startup weight submission skipped: blockchain not yet synced");
1646-
} else if subtensor.is_none() || subtensor_signer.is_none() {
1647-
warn!("Startup weight submission skipped: subtensor not connected");
1648-
} else if wasm_executor.is_none() {
1649-
warn!("Startup weight submission skipped: WASM executor not ready");
1650-
} else {
1651-
let has_challenges = {
1652-
let cs = chain_state.read();
1653-
cs.wasm_challenge_configs.iter().any(|(_, cfg)| cfg.is_active)
1654-
};
1655-
if !has_challenges {
1656-
warn!("Startup weight submission skipped: no active challenges loaded");
1657-
} else {
1658-
let tempo = 360u64;
1659-
let netuid_plus_one = (netuid as u64).saturating_add(1);
1660-
let epoch = current_block.saturating_add(netuid_plus_one) / (tempo + 1);
1661-
info!("Startup weight submission: epoch {} block {} (90s after boot)", epoch, current_block);
1662-
handle_block_event(
1663-
BlockSyncEvent::CommitWindowOpen { epoch, block: current_block },
1664-
&subtensor, &subtensor_signer, &subtensor_client,
1665-
&state_manager, netuid, version_key, &wasm_executor,
1666-
&keypair, &chain_state, &storage,
1667-
&mut last_weight_submission_epoch,
1668-
).await;
1669-
}
1670-
}
1645+
info!("Startup weight timer fired (no-op): weights will submit at next epoch boundary");
16711646
}
16721647

16731648
// Periodic checkpoint

crates/bittensor-integration/src/block_sync.rs

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -231,22 +231,12 @@ impl BlockSync {
231231
*current_epoch.write().await = epoch_info.epoch_number;
232232
*current_phase.write().await = epoch_info.phase;
233233

234-
// On first block after startup, trigger immediate weight submission
235-
// so the validator doesn't have to wait for the next epoch boundary.
236234
if !*first_block_seen {
237235
*first_block_seen = true;
238-
if epoch_info.commit_reveal_enabled {
239-
info!(
240-
"First block after startup: triggering immediate weight submission (epoch={}, block={})",
241-
epoch_info.epoch_number, block_number
242-
);
243-
let _ = event_tx
244-
.send(BlockSyncEvent::CommitWindowOpen {
245-
epoch: epoch_info.epoch_number,
246-
block: block_number,
247-
})
248-
.await;
249-
}
236+
info!(
237+
"First block seen after startup: epoch={}, block={}. Weights will submit at next epoch boundary.",
238+
epoch_info.epoch_number, block_number
239+
);
250240
}
251241

252242
if let Err(e) = event_tx
@@ -463,13 +453,11 @@ mod tests {
463453
EpochPhase::CommitWindow
464454
));
465455

466-
// First event: CommitWindowOpen (triggered on first block after startup)
456+
// First event: NewBlock (first_block_seen no longer emits CommitWindowOpen)
467457
let first = rx.recv().await.unwrap();
468-
assert!(matches!(first, BlockSyncEvent::CommitWindowOpen { .. }));
458+
assert!(matches!(first, BlockSyncEvent::NewBlock { .. }));
469459
let second = rx.recv().await.unwrap();
470-
assert!(matches!(second, BlockSyncEvent::NewBlock { .. }));
471-
let third = rx.recv().await.unwrap();
472-
assert!(matches!(third, BlockSyncEvent::Reconnected));
460+
assert!(matches!(second, BlockSyncEvent::Reconnected));
473461
assert!(!was_disconnected);
474462
}
475463

0 commit comments

Comments
 (0)