@@ -1045,29 +1045,45 @@ async fn main() -> Result<()> {
10451045 None => std:: future:: pending( ) . await ,
10461046 }
10471047 } => {
1048- // Force metagraph refresh before weight submission to avoid stale hotkey->UID mappings
1049- if matches!( event, BlockSyncEvent :: CommitWindowOpen { .. } ) {
1048+ // Check if this block triggers weight submission (every WEIGHT_SET_BLOCK_INTERVAL blocks)
1049+ let is_weight_block = if let BlockSyncEvent :: NewBlock { block_number, .. } = & event {
1050+ * block_number > 0
1051+ && * block_number % platform_core:: constants:: WEIGHT_SET_BLOCK_INTERVAL == 0
1052+ } else {
1053+ false
1054+ } ;
1055+
1056+ // Force metagraph refresh before weight submission
1057+ if is_weight_block || matches!( event, BlockSyncEvent :: CommitWindowOpen { .. } ) {
10501058 if let Some ( bittensor_client) = bittensor_client_for_metagraph. as_ref( ) {
10511059 match tokio:: time:: timeout(
10521060 Duration :: from_secs( 15 ) ,
10531061 sync_metagraph( bittensor_client, netuid) ,
10541062 ) . await {
10551063 Ok ( Ok ( mg) ) => {
1056- info!( "Pre-commit metagraph refresh: {} neurons" , mg. n) ;
1064+ info!( "Pre-weight metagraph refresh: {} neurons" , mg. n) ;
10571065 update_validator_set_from_metagraph( & mg, & validator_set, & chain_state, & valid_voters, & state_root_consensus, & state_manager) ;
10581066 if let Some ( sc) = subtensor_client. as_mut( ) {
10591067 sc. set_metagraph( mg) ;
10601068 }
10611069 }
10621070 Ok ( Err ( e) ) => {
1063- warn!( "Pre-commit metagraph refresh failed: {}. Using cached." , e) ;
1071+ warn!( "Pre-weight metagraph refresh failed: {}. Using cached." , e) ;
10641072 }
10651073 Err ( _) => {
1066- warn!( "Pre-commit metagraph refresh timed out (15s). Using cached." ) ;
1074+ warn!( "Pre-weight metagraph refresh timed out (15s). Using cached." ) ;
10671075 }
10681076 }
10691077 }
10701078 }
1079+
1080+ // Extract block number before moving event
1081+ let new_block_number = if let BlockSyncEvent :: NewBlock { block_number, .. } = & event {
1082+ Some ( * block_number)
1083+ } else {
1084+ None
1085+ } ;
1086+
10711087 handle_block_event(
10721088 event,
10731089 & subtensor,
@@ -1082,6 +1098,35 @@ async fn main() -> Result<()> {
10821098 & storage,
10831099 & mut last_weight_submission_epoch,
10841100 ) . await ;
1101+
1102+ // After processing the block, trigger weight submission at the defined interval.
1103+ // All validators see the same block numbers so they all submit at the same time.
1104+ if is_weight_block {
1105+ let block_number = new_block_number. unwrap( ) ;
1106+ let tempo = 360u64 ;
1107+ let netuid_plus_one = ( netuid as u64 ) . saturating_add( 1 ) ;
1108+ let epoch = block_number. saturating_add( netuid_plus_one) / ( tempo + 1 ) ;
1109+ info!(
1110+ "=== WEIGHT SET BLOCK {} (every {} blocks) epoch {} ===" ,
1111+ block_number,
1112+ platform_core:: constants:: WEIGHT_SET_BLOCK_INTERVAL ,
1113+ epoch,
1114+ ) ;
1115+ handle_block_event(
1116+ BlockSyncEvent :: CommitWindowOpen { epoch, block: block_number } ,
1117+ & subtensor,
1118+ & subtensor_signer,
1119+ & subtensor_client,
1120+ & state_manager,
1121+ netuid,
1122+ version_key,
1123+ & wasm_executor,
1124+ & keypair,
1125+ & chain_state,
1126+ & storage,
1127+ & mut last_weight_submission_epoch,
1128+ ) . await ;
1129+ }
10851130 }
10861131
10871132 // RPC -> P2P commands (challenge updates from sudo)
@@ -1692,67 +1737,12 @@ async fn main() -> Result<()> {
16921737 }
16931738 }
16941739
1695- // Submit weights on-chain 90s after boot (after RPC pre-compute at 70s).
1740+ // Startup weight submission disabled: all validators set weights at the
1741+ // same block via WEIGHT_SET_BLOCK_INTERVAL (every N Bittensor blocks).
16961742 _ = & mut startup_weight_delay, if !startup_weights_submitted => {
16971743 startup_weights_submitted = true ;
1698- let current_block = state_manager. apply( |state| state. bittensor_block) ;
1699- if current_block == 0 {
1700- warn!( "Startup weight submission skipped: blockchain not yet synced" ) ;
1701- } else if subtensor. is_none( ) || subtensor_signer. is_none( ) {
1702- warn!( "Startup weight submission skipped: subtensor not connected" ) ;
1703- } else if wasm_executor. is_none( ) {
1704- warn!( "Startup weight submission skipped: WASM executor not ready" ) ;
1705- } else {
1706- let has_challenges = {
1707- let cs = chain_state. read( ) ;
1708- cs. wasm_challenge_configs. iter( ) . any( |( _, cfg) | cfg. is_active)
1709- } ;
1710- if !has_challenges {
1711- warn!( "Startup weight submission skipped: no active challenges loaded" ) ;
1712- } else {
1713- // Refresh metagraph before startup weight submission
1714- if let Some ( bittensor_client) = bittensor_client_for_metagraph. as_ref( ) {
1715- match tokio:: time:: timeout(
1716- Duration :: from_secs( 15 ) ,
1717- sync_metagraph( bittensor_client, netuid) ,
1718- ) . await {
1719- Ok ( Ok ( mg) ) => {
1720- info!( "Startup metagraph refresh: {} neurons" , mg. n) ;
1721- update_validator_set_from_metagraph( & mg, & validator_set, & chain_state, & valid_voters, & state_root_consensus, & state_manager) ;
1722- if let Some ( sc) = subtensor_client. as_mut( ) {
1723- sc. set_metagraph( mg) ;
1724- }
1725- }
1726- Ok ( Err ( e) ) => warn!( "Startup metagraph refresh failed: {}" , e) ,
1727- Err ( _) => warn!( "Startup metagraph refresh timed out after 15s" ) ,
1728- }
1729- }
1730- let tempo = 360u64 ;
1731- let netuid_plus_one = ( netuid as u64 ) . saturating_add( 1 ) ;
1732- let epoch = current_block. saturating_add( netuid_plus_one) / ( tempo + 1 ) ;
1733- // Only submit if we're actually in the commit window phase.
1734- // The commit window is the first block of each epoch.
1735- let epoch_start = epoch. saturating_mul( tempo + 1 ) . saturating_sub( netuid_plus_one) ;
1736- let blocks_into_epoch = current_block. saturating_sub( epoch_start) ;
1737- // Commit window is typically ~1 block at the start of each epoch.
1738- // If we're past it, wait for the next real CommitWindowOpen event.
1739- if blocks_into_epoch > 5 {
1740- info!(
1741- "Startup weight submission skipped: block {} is {} blocks into epoch {} (past commit window), will wait for next epoch" ,
1742- current_block, blocks_into_epoch, epoch
1743- ) ;
1744- } else {
1745- info!( "Startup weight submission: epoch {} block {} (90s after boot)" , epoch, current_block) ;
1746- handle_block_event(
1747- BlockSyncEvent :: CommitWindowOpen { epoch, block: current_block } ,
1748- & subtensor, & subtensor_signer, & subtensor_client,
1749- & state_manager, netuid, version_key, & wasm_executor,
1750- & keypair, & chain_state, & storage,
1751- & mut last_weight_submission_epoch,
1752- ) . await ;
1753- }
1754- }
1755- }
1744+ info!( "Startup weight submission disabled: weights are set at block intervals (every {} blocks)" ,
1745+ platform_core:: constants:: WEIGHT_SET_BLOCK_INTERVAL ) ;
17561746 }
17571747
17581748 // Periodic checkpoint
0 commit comments