@@ -7,8 +7,8 @@ use pallas_network::{
77 miniprotocols:: {
88 localstate:: {
99 queries_v16:: {
10- self , Addr , Addrs , Genesis , PostAlonsoTransactionOutput , StakeSnapshot , Stakes ,
11- TransactionOutput , UTxOByAddress ,
10+ self , Addr , Addrs , ChainBlockNumber , Genesis , PostAlonsoTransactionOutput ,
11+ StakeSnapshot , Stakes , TransactionOutput , UTxOByAddress ,
1212 } ,
1313 Client ,
1414 } ,
@@ -279,6 +279,16 @@ impl PallasChainObserver {
279279 Ok ( chain_point)
280280 }
281281
282+ /// Fetches the current chain point using the provided `NodeClient`.
283+ async fn do_get_chain_block_no ( & self , statequery : & mut Client ) -> StdResult < ChainBlockNumber > {
284+ let chain_block_number = queries_v16:: get_chain_block_no ( statequery)
285+ . await
286+ . map_err ( |err| anyhow ! ( err) )
287+ . with_context ( || "PallasChainObserver failed to get chain block number" ) ?;
288+
289+ Ok ( chain_block_number)
290+ }
291+
282292 /// Fetches the current era using the provided `statequery` client.
283293 async fn do_get_current_era_state_query ( & self , statequery : & mut Client ) -> StdResult < u16 > {
284294 let era = queries_v16:: get_current_era ( statequery)
@@ -303,6 +313,30 @@ impl PallasChainObserver {
303313 Ok ( genesis_config)
304314 }
305315
316+ /// Fetches the current chain point using the provided `NodeClient`.
317+ async fn get_chain_point ( & self , statequery : & mut Client ) -> StdResult < ChainPoint > {
318+ statequery
319+ . acquire ( None )
320+ . await
321+ . map_err ( |err| anyhow ! ( err) )
322+ . with_context ( || "PallasChainObserver failed to acquire statequery" ) ?;
323+
324+ let chain_point = self . do_get_chain_point_state_query ( statequery) . await ?;
325+
326+ let header_hash = match chain_point {
327+ Point :: Origin => None ,
328+ Point :: Specific ( _at_slot, ref hash) => Some ( hex:: encode ( hash) ) ,
329+ } ;
330+
331+ let chain_block_number = self . do_get_chain_block_no ( statequery) . await ?;
332+
333+ Ok ( ChainPoint {
334+ slot_number : chain_point. slot_or_default ( ) ,
335+ block_hash : header_hash. unwrap_or_default ( ) ,
336+ block_number : chain_block_number. block_number as u64 ,
337+ } )
338+ }
339+
306340 /// Fetches chain point and genesis config through the local statequery.
307341 /// The KES period is calculated afterwards.
308342 async fn get_kes_period (
@@ -385,8 +419,15 @@ impl ChainObserver for PallasChainObserver {
385419 }
386420
387421 async fn get_current_chain_point ( & self ) -> Result < Option < ChainPoint > , ChainObserverError > {
388- // TODO: Implement get_current_chain_point with pallas
389- todo ! ( "Implement get_current_chain_point" )
422+ let mut client = self . get_client ( ) . await ?;
423+
424+ let chain_point = self . get_chain_point ( client. statequery ( ) ) . await ?;
425+
426+ self . post_process_statequery ( & mut client) . await ?;
427+
428+ client. abort ( ) . await ;
429+
430+ Ok ( Some ( chain_point) )
390431 }
391432
392433 async fn get_current_datums (
@@ -444,8 +485,8 @@ mod tests {
444485 use pallas_network:: miniprotocols:: {
445486 localstate:: {
446487 queries_v16:: {
447- BlockQuery , Fraction , Genesis , HardForkQuery , LedgerQuery , Request , Snapshots ,
448- StakeSnapshot , SystemStart , Value ,
488+ BlockQuery , ChainBlockNumber , Fraction , Genesis , HardForkQuery , LedgerQuery ,
489+ Request , Snapshots , StakeSnapshot , SystemStart , Value ,
449490 } ,
450491 ClientQueryRequest ,
451492 } ,
@@ -581,6 +622,10 @@ mod tests {
581622 Request :: GetChainPoint => {
582623 AnyCbor :: from_encode ( Point :: Specific ( 52851885 , vec ! [ 1 , 2 , 3 ] ) )
583624 }
625+ Request :: GetChainBlockNo => AnyCbor :: from_encode ( ChainBlockNumber {
626+ slot_timeline : 1 ,
627+ block_number : 52851885 ,
628+ } ) ,
584629 Request :: LedgerQuery ( LedgerQuery :: HardForkQuery ( HardForkQuery :: GetCurrentEra ) ) => {
585630 AnyCbor :: from_encode ( 4 )
586631 }
@@ -816,4 +861,26 @@ mod tests {
816861 let era = client_res. expect ( "Client failed" ) ;
817862 assert_eq ! ( era, 4 ) ;
818863 }
864+
865+ #[ tokio:: test]
866+ async fn get_current_chain_point ( ) {
867+ let socket_path = create_temp_dir ( "get_current_chain_point" ) . join ( "node.socket" ) ;
868+ let server = setup_server ( socket_path. clone ( ) , 2 ) . await ;
869+ let client = tokio:: spawn ( async move {
870+ let observer =
871+ PallasChainObserver :: new ( socket_path. as_path ( ) , CardanoNetwork :: TestNet ( 10 ) ) ;
872+ observer. get_current_chain_point ( ) . await . unwrap ( )
873+ } ) ;
874+
875+ let ( _, client_res) = tokio:: join!( server, client) ;
876+ let chain_point = client_res. expect ( "Client failed" ) ;
877+ assert_eq ! (
878+ chain_point,
879+ Some ( ChainPoint {
880+ slot_number: 52851885 ,
881+ block_hash: "010203" . to_string( ) ,
882+ block_number: 52851885
883+ } )
884+ ) ;
885+ }
819886}
0 commit comments