@@ -483,27 +483,60 @@ pub async fn toggle_windows(
483483 Ok ( ( ) )
484484}
485485
486- // TODO: multiple blocks for the same slot should be counted as one
487486// TODO: take into account the validated flag to count blocks
488- pub async fn update_scores ( pool : & SqlitePool ) -> Result < ( ) > {
487+ pub async fn update_scores ( pool : & SqlitePool , config : & Config ) -> Result < ( ) > {
488+ let window_start = to_unix_timestamp ( config. window_range_start ) ;
489+ let current_time = chrono:: Utc :: now ( ) . timestamp ( ) ;
490+
489491 sqlx:: query!(
490492 r#"
493+ WITH ValidWindows AS (
494+ SELECT id, start_time, end_time
495+ FROM time_windows
496+ WHERE disabled = FALSE
497+ AND end_time <= ?2
498+ AND start_time >= ?1
499+ ),
500+ BlockCounts AS (
501+ -- Count one block per global slot per producer
502+ SELECT
503+ public_key_id,
504+ COUNT(DISTINCT block_global_slot) as blocks
505+ FROM (
506+ -- Deduplicate blocks per global slot
507+ SELECT
508+ pb.public_key_id,
509+ pb.block_global_slot
510+ FROM produced_blocks pb
511+ JOIN ValidWindows vw ON vw.id = pb.window_id
512+ -- TODO: enable once block proof validation has been implemented
513+ -- WHERE pb.validated = TRUE
514+ GROUP BY pb.public_key_id, pb.block_global_slot
515+ ) unique_blocks
516+ GROUP BY public_key_id
517+ ),
518+ HeartbeatCounts AS (
519+ SELECT hp.public_key_id, COUNT(DISTINCT hp.window_id) as heartbeats
520+ FROM heartbeat_presence hp
521+ JOIN ValidWindows vw ON vw.id = hp.window_id
522+ GROUP BY hp.public_key_id
523+ )
491524 INSERT INTO submitter_scores (public_key_id, score, blocks_produced)
492525 SELECT
493526 pk.id,
494- COUNT(DISTINCT hp.window_id ) as score,
495- COUNT(DISTINCT pb.id ) as blocks_produced
527+ COALESCE(hc.heartbeats, 0 ) as score,
528+ COALESCE(bc.blocks, 0 ) as blocks_produced
496529 FROM public_keys pk
497- LEFT JOIN heartbeat_presence hp ON pk.id = hp.public_key_id
498- LEFT JOIN time_windows tw ON hp.window_id = tw.id
499- LEFT JOIN produced_blocks pb ON pk.id = pb.public_key_id
500- WHERE tw.disabled = FALSE
501- GROUP BY pk.id
530+ LEFT JOIN HeartbeatCounts hc ON hc.public_key_id = pk.id
531+ LEFT JOIN BlockCounts bc ON bc.public_key_id = pk.id
532+ WHERE hc.heartbeats > 0 OR bc.blocks > 0
502533 ON CONFLICT(public_key_id) DO UPDATE SET
503534 score = excluded.score,
504535 blocks_produced = excluded.blocks_produced,
505536 last_updated = strftime('%s', 'now')
506- "#
537+ "# ,
538+ window_start,
539+ current_time
507540 )
508541 . execute ( pool)
509542 . await ?;
@@ -537,9 +570,9 @@ pub async fn get_max_scores(pool: &SqlitePool) -> Result<MaxScores> {
537570 Ok ( MaxScores { total, current } )
538571}
539572
540- pub async fn view_scores ( pool : & SqlitePool ) -> Result < ( ) > {
573+ pub async fn view_scores ( pool : & SqlitePool , config : & Config ) -> Result < ( ) > {
541574 // Make sure scores are up to date
542- update_scores ( pool) . await ?;
575+ update_scores ( pool, config ) . await ?;
543576
544577 let scores = sqlx:: query!(
545578 r#"
@@ -559,11 +592,11 @@ pub async fn view_scores(pool: &SqlitePool) -> Result<()> {
559592 let max_scores = get_max_scores ( pool) . await ?;
560593
561594 println ! ( "\n Submitter Scores:" ) ;
562- println ! ( "----------------------------------------" ) ;
595+ println ! ( "-------------------------------------------------------- " ) ;
563596 println ! (
564- "Public Key | Score | Blocks | Current Max | Total Max | Last Updated"
597+ "Public Key | Score | Blocks | Current Max | Total Max | Last Updated"
565598 ) ;
566- println ! ( "----------------------------------------" ) ;
599+ println ! ( "-------------------------------------------------------- " ) ;
567600
568601 for row in scores {
569602 println ! (
0 commit comments