@@ -933,10 +933,14 @@ async fn main() -> Result<()> {
933933 let mut stale_job_interval = tokio:: time:: interval ( Duration :: from_secs ( 120 ) ) ;
934934 let mut weight_check_interval = tokio:: time:: interval ( Duration :: from_secs ( 30 ) ) ;
935935 let mut last_weight_submission_epoch: u64 = 0 ; // Local tracking of weight submissions
936- let mut challenge_sync_interval = tokio:: time:: interval ( Duration :: from_secs ( 60 ) ) ; // Check every minute
937- let mut last_sync_block: u64 = 0 ; // Last block where sync was triggered
938- let sync_block_interval: u64 = 60 ; // Sync every 60 blocks
939- let mut storage_stats_interval = tokio:: time:: interval ( Duration :: from_secs ( 300 ) ) ; // Log stats every 5 min
936+ let mut challenge_sync_interval = tokio:: time:: interval ( Duration :: from_secs ( 30 ) ) ; // Check every 30s
937+ let mut last_sync_block: u64 = 0 ;
938+ let sync_block_interval: u64 = 30 ; // Sync every 30 blocks (~3 min)
939+ let mut storage_stats_interval = tokio:: time:: interval ( Duration :: from_secs ( 300 ) ) ;
940+ // Track last synced block per challenge for delta sync
941+ let challenge_last_sync: Arc <
942+ RwLock < std:: collections:: HashMap < platform_core:: ChallengeId , u64 > > ,
943+ > = Arc :: new ( RwLock :: new ( std:: collections:: HashMap :: new ( ) ) ) ;
940944
941945 // Clone p2p_cmd_tx for use in the loop
942946 let p2p_broadcast_tx = p2p_cmd_tx. clone ( ) ;
@@ -955,6 +959,7 @@ async fn main() -> Result<()> {
955959 & keypair,
956960 & p2p_cmd_tx,
957961 & chain_state,
962+ & challenge_last_sync,
958963 ) . await ;
959964 }
960965
@@ -1837,6 +1842,7 @@ async fn handle_network_event(
18371842 keypair : & Keypair ,
18381843 p2p_cmd_tx : & tokio:: sync:: mpsc:: Sender < platform_p2p_consensus:: P2PCommand > ,
18391844 chain_state : & Arc < RwLock < platform_core:: ChainState > > ,
1845+ challenge_last_sync : & Arc < RwLock < std:: collections:: HashMap < platform_core:: ChallengeId , u64 > > > ,
18401846) {
18411847 match event {
18421848 NetworkEvent :: Message { source, message } => match message {
@@ -2692,7 +2698,7 @@ async fn handle_network_event(
26922698 . put (
26932699 storage_key. clone ( ) ,
26942700 proposal. value . clone ( ) ,
2695- PutOptions :: default ( ) ,
2701+ put_options_with_block ( state_manager ) ,
26962702 )
26972703 . await
26982704 . map ( |_| true )
@@ -3142,20 +3148,31 @@ async fn handle_network_event(
31423148 } ;
31433149
31443150 if our_hash != [ 0u8 ; 32 ] && our_hash == proposal. sync_result_hash {
3151+ // In sync -- update last_sync_block
3152+ challenge_last_sync
3153+ . write ( )
3154+ . insert ( proposal. challenge_id , proposal. block_number ) ;
31453155 debug ! (
31463156 challenge_id = %proposal. challenge_id,
31473157 "Sync hash matches peer, storage is in sync"
31483158 ) ;
31493159 } else if proposal. sync_result_hash != [ 0u8 ; 32 ] {
3160+ // Delta sync: only request entries since our last known good block
3161+ let since_block = challenge_last_sync
3162+ . read ( )
3163+ . get ( & proposal. challenge_id )
3164+ . copied ( )
3165+ . unwrap_or ( 0 ) ;
3166+
31503167 info ! (
31513168 challenge_id = %proposal. challenge_id,
31523169 proposer = %proposal. proposer. to_ss58( ) ,
31533170 our_hash = %hex:: encode( & our_hash[ ..8 ] ) ,
31543171 peer_hash = %hex:: encode( & proposal. sync_result_hash[ ..8 ] ) ,
3155- "Sync hash divergence detected, requesting storage sync"
3172+ since_block = since_block,
3173+ "Sync hash divergence, requesting delta sync"
31563174 ) ;
31573175
3158- // Request storage data from the proposer
31593176 let timestamp = chrono:: Utc :: now ( ) . timestamp_millis ( ) ;
31603177 let sign_data =
31613178 bincode:: serialize ( & ( & proposal. challenge_id , & our_hash, timestamp) )
@@ -3167,6 +3184,7 @@ async fn handle_network_event(
31673184 challenge_id : proposal. challenge_id ,
31683185 requester : keypair. hotkey ( ) ,
31693186 current_hash : our_hash,
3187+ since_block,
31703188 timestamp,
31713189 signature,
31723190 } ,
@@ -3192,26 +3210,45 @@ async fn handle_network_event(
31923210 warn ! ( requester = %req. requester. to_ss58( ) , "Storage sync request from non-validator" ) ;
31933211 } else {
31943212 let challenge_ns = req. challenge_id . to_string ( ) ;
3213+ let since = req. since_block ;
31953214 info ! (
31963215 challenge_id = %req. challenge_id,
31973216 requester = %req. requester. to_ss58( ) ,
3198- "Responding to storage sync request"
3217+ since_block = since,
3218+ "Responding to storage sync request (delta)"
31993219 ) ;
32003220
3201- // Read all keys in this challenge namespace
3202- match storage. list_prefix ( & challenge_ns, None , 10_000 , None ) . await {
3203- Ok ( list_result) => {
3204- let entries: Vec < platform_p2p_consensus:: StorageSyncEntry > =
3205- list_result
3206- . items
3207- . iter ( )
3208- . map ( |( key, value) | platform_p2p_consensus:: StorageSyncEntry {
3209- namespace : key. namespace . clone ( ) ,
3210- key : key. key . clone ( ) ,
3211- value : value. data . clone ( ) ,
3212- version : value. metadata . version ,
3213- } )
3214- . collect ( ) ;
3221+ // Collect items: if since_block > 0, delta only
3222+ let items_result: Result <
3223+ Vec < (
3224+ platform_distributed_storage:: StorageKey ,
3225+ platform_distributed_storage:: StoredValue ,
3226+ ) > ,
3227+ _ ,
3228+ > = if since > 0 {
3229+ storage
3230+ . list_after_block ( & challenge_ns, since, 10_000 )
3231+ . await
3232+ . map ( |qr| qr. items )
3233+ } else {
3234+ storage
3235+ . list_prefix ( & challenge_ns, None , 10_000 , None )
3236+ . await
3237+ . map ( |lr| lr. items )
3238+ } ;
3239+
3240+ match items_result {
3241+ Ok ( items) => {
3242+ let entries: Vec < platform_p2p_consensus:: StorageSyncEntry > = items
3243+ . iter ( )
3244+ . map ( |( key, value) | platform_p2p_consensus:: StorageSyncEntry {
3245+ namespace : key. namespace . clone ( ) ,
3246+ key : key. key . clone ( ) ,
3247+ value : value. data . clone ( ) ,
3248+ version : value. metadata . version ,
3249+ updated_block : value. metadata . updated_block ,
3250+ } )
3251+ . collect ( ) ;
32153252
32163253 let total = entries. len ( ) as u64 ;
32173254
@@ -3254,7 +3291,8 @@ async fn handle_network_event(
32543291 info ! (
32553292 challenge_id = %req. challenge_id,
32563293 entries = total,
3257- "Storage sync response sent"
3294+ since_block = since,
3295+ "Storage sync delta response sent"
32583296 ) ;
32593297 }
32603298 }
@@ -3286,6 +3324,7 @@ async fn handle_network_event(
32863324
32873325 let mut applied = 0u64 ;
32883326 let mut skipped = 0u64 ;
3327+ let mut max_block = 0u64 ;
32893328 let opts = put_options_with_block ( state_manager) ;
32903329
32913330 for entry in & resp. entries {
@@ -3306,16 +3345,27 @@ async fn handle_network_event(
33063345 warn ! ( error = %e, "Failed to apply synced entry" ) ;
33073346 } else {
33083347 applied += 1 ;
3348+ if entry. updated_block > max_block {
3349+ max_block = entry. updated_block ;
3350+ }
33093351 }
33103352 }
33113353 }
33123354 }
33133355
3356+ // Update last_sync_block for this challenge
3357+ if max_block > 0 {
3358+ challenge_last_sync
3359+ . write ( )
3360+ . insert ( resp. challenge_id , max_block) ;
3361+ }
3362+
33143363 info ! (
33153364 challenge_id = %resp. challenge_id,
33163365 applied = applied,
33173366 skipped = skipped,
3318- "Storage sync complete"
3367+ max_block = max_block,
3368+ "Storage delta sync complete"
33193369 ) ;
33203370 }
33213371 }
0 commit comments