@@ -391,9 +391,11 @@ pub async fn process_heartbeats(
391391
392392 let best_tip = entry. best_tip_block ( ) ;
393393 let public_key_id = * public_key_map. get ( & entry. submitter ) . unwrap ( ) ;
394+ let has_presence =
395+ ( entry. is_synced ( ) || entry. is_catchup ( ) ) && best_tip. is_some ( ) ;
394396
395397 // Record presence only if node is synced and has a best tip
396- if entry . is_synced ( ) && best_tip . is_some ( ) {
398+ if has_presence {
397399 presence_batch. push ( HeartbeatPresence {
398400 window_id : window. id . unwrap ( ) ,
399401 public_key_id,
@@ -448,15 +450,25 @@ pub async fn process_heartbeats(
448450 continue ;
449451 }
450452
451- seen_blocks. insert ( key. clone ( ) , entry. create_time ) ;
452- produced_blocks_batch. push ( ProducedBlock {
453- window_id : window. id . unwrap ( ) ,
454- public_key_id,
455- block_hash : block_info. hash ,
456- block_height : block_info. height ,
457- block_global_slot : block_info. global_slot ,
458- block_data : block_info. base64_encoded_header ,
459- } ) ;
453+ if has_presence {
454+ seen_blocks. insert ( key. clone ( ) , entry. create_time ) ;
455+ produced_blocks_batch. push ( ProducedBlock {
456+ window_id : window. id . unwrap ( ) ,
457+ public_key_id,
458+ block_hash : block_info. hash ,
459+ block_height : block_info. height ,
460+ block_global_slot : block_info. global_slot ,
461+ block_data : block_info. base64_encoded_header ,
462+ } ) ;
463+ } else {
464+ println ! (
465+ "WARNING: Block produced by unsynced node: {} (height: {}, producer: {})" ,
466+ block_info. hash, block_info. height, entry. submitter
467+ ) ;
468+ println ! ( "Submitter: {:?}" , entry. submitter) ;
469+ println ! ( "Sync status: {}" , entry. sync_phase( ) . unwrap_or_default( ) ) ;
470+ println ! ( "Best tip: {:?}" , entry. best_tip_block( ) . map( |b| b. hash) ) ;
471+ }
460472 }
461473 Some ( ( _block_info, Err ( e) ) ) => {
462474 println ! (
0 commit comments