@@ -4,7 +4,10 @@ use crate::{
44 EpochActivityRest , ProtocolParamsRest , SPDDByEpochAndPoolItemRest , SPDDByEpochItemRest ,
55 } ,
66} ;
7- use acropolis_common:: queries:: errors:: QueryError ;
7+ use acropolis_common:: queries:: {
8+ blocks:: { BlocksStateQuery , BlocksStateQueryResponse } ,
9+ errors:: QueryError ,
10+ } ;
811use acropolis_common:: rest_error:: RESTError ;
912use acropolis_common:: serialization:: Bech32Conversion ;
1013use acropolis_common:: {
@@ -501,11 +504,102 @@ pub async fn handle_epoch_pool_stakes_blockfrost(
501504}
502505
503506pub async fn handle_epoch_total_blocks_blockfrost (
504- _context : Arc < Context < Message > > ,
505- _params : Vec < String > ,
506- _handlers_config : Arc < HandlersConfig > ,
507+ context : Arc < Context < Message > > ,
508+ params : Vec < String > ,
509+ handlers_config : Arc < HandlersConfig > ,
507510) -> Result < RESTResponse , RESTError > {
508- Err ( RESTError :: not_implemented ( "Epoch total blocks endpoint" ) )
511+ if params. len ( ) != 1 {
512+ return Err ( RESTError :: BadRequest (
513+ "Expected one parameter: an epoch number" . to_string ( ) ,
514+ ) ) ;
515+ }
516+ let param = & params[ 0 ] ;
517+
518+ let epoch_number = param
519+ . parse :: < u64 > ( )
520+ . map_err ( |_| RESTError :: invalid_param ( "epoch" , "invalid epoch number" ) ) ?;
521+
522+ let latest_epoch_msg = Arc :: new ( Message :: StateQuery ( StateQuery :: Epochs (
523+ EpochsStateQuery :: GetLatestEpoch ,
524+ ) ) ) ;
525+ let latest_epoch = query_state (
526+ & context,
527+ & handlers_config. epochs_query_topic ,
528+ latest_epoch_msg,
529+ |message| match message {
530+ Message :: StateQueryResponse ( StateQueryResponse :: Epochs (
531+ EpochsStateQueryResponse :: LatestEpoch ( res) ,
532+ ) ) => Ok ( res. epoch ) ,
533+ Message :: StateQueryResponse ( StateQueryResponse :: Epochs (
534+ EpochsStateQueryResponse :: Error ( e) ,
535+ ) ) => Err ( e) ,
536+ _ => Err ( QueryError :: internal_error (
537+ "Unexpected message type while retrieving latest epoch" ,
538+ ) ) ,
539+ } ,
540+ )
541+ . await ?;
542+
543+ if epoch_number > latest_epoch. epoch {
544+ return Err ( RESTError :: not_found ( "Epoch not found" ) ) ;
545+ }
546+
547+ let ( first_block_height, last_block_height) = if epoch_number == latest_epoch. epoch {
548+ (
549+ latest_epoch. first_block_height ,
550+ latest_epoch. last_block_height ,
551+ )
552+ } else {
553+ // Query from historical epochs state
554+ let epoch_info_msg = Arc :: new ( Message :: StateQuery ( StateQuery :: Epochs (
555+ EpochsStateQuery :: GetEpochInfo { epoch_number } ,
556+ ) ) ) ;
557+ let epoch_info = query_state (
558+ & context,
559+ & handlers_config. epochs_query_topic ,
560+ epoch_info_msg,
561+ |message| match message {
562+ Message :: StateQueryResponse ( StateQueryResponse :: Epochs (
563+ EpochsStateQueryResponse :: EpochInfo ( res) ,
564+ ) ) => Ok ( res. epoch ) ,
565+ Message :: StateQueryResponse ( StateQueryResponse :: Epochs (
566+ EpochsStateQueryResponse :: Error ( e) ,
567+ ) ) => Err ( e) ,
568+ _ => Err ( QueryError :: internal_error (
569+ "Unexpected message type while retrieving epoch info" ,
570+ ) ) ,
571+ } ,
572+ )
573+ . await ?;
574+ ( epoch_info. first_block_height , epoch_info. last_block_height )
575+ } ;
576+
577+ // Query all blocks hashes from chain_store
578+ // using first_block_height and last_block_height
579+ let block_hashes_msg = Arc :: new ( Message :: StateQuery ( StateQuery :: Blocks (
580+ BlocksStateQuery :: GetBlockHashesByNumberRange {
581+ min_number : first_block_height,
582+ max_number : last_block_height,
583+ } ,
584+ ) ) ) ;
585+ let block_hashes = query_state (
586+ & context,
587+ & handlers_config. blocks_query_topic ,
588+ block_hashes_msg,
589+ |message| match message {
590+ Message :: StateQueryResponse ( StateQueryResponse :: Blocks (
591+ BlocksStateQueryResponse :: BlockHashesByNumberRange ( block_hashes) ,
592+ ) ) => Ok ( block_hashes) ,
593+ Message :: StateQueryResponse ( StateQueryResponse :: Blocks (
594+ BlocksStateQueryResponse :: Error ( e) ,
595+ ) ) => Err ( e) ,
596+ _ => Err ( QueryError :: internal_error ( "Unexpected message type" ) ) ,
597+ } ,
598+ )
599+ . await ?;
600+
601+ let json = serde_json:: to_string_pretty ( & block_hashes) ?;
602+ Ok ( RESTResponse :: with_json ( 200 , & json) )
509603}
510604
511605pub async fn handle_epoch_pool_blocks_blockfrost (
0 commit comments