@@ -12,7 +12,7 @@ use tokio::process::Command;
12
12
use crate :: chain_observer:: interface:: { ChainObserver , ChainObserverError } ;
13
13
use crate :: chain_observer:: { ChainAddress , TxDatum } ;
14
14
use crate :: crypto_helper:: { encode_bech32, KESPeriod , OpCert , SerDeShelleyFileFormat } ;
15
- use crate :: entities:: { Epoch , StakeDistribution } ;
15
+ use crate :: entities:: { ChainPoint , Epoch , StakeDistribution } ;
16
16
use crate :: { CardanoNetwork , StdResult } ;
17
17
18
18
/// `CliRunner` trait defines the asynchronous methods
@@ -29,6 +29,8 @@ pub trait CliRunner {
29
29
async fn launch_stake_snapshot_all_pools ( & self ) -> StdResult < String > ;
30
30
/// Launches the epoch info.
31
31
async fn launch_epoch ( & self ) -> StdResult < String > ;
32
+ /// Launches the chain point.
33
+ async fn launch_chain_point ( & self ) -> StdResult < String > ;
32
34
/// Launches the kes period.
33
35
async fn launch_kes_period ( & self , opcert_file : & str ) -> StdResult < String > ;
34
36
}
@@ -114,6 +116,14 @@ impl CardanoCliRunner {
114
116
command
115
117
}
116
118
119
+ fn command_for_chain_point ( & self ) -> Command {
120
+ let mut command = self . get_command ( ) ;
121
+ command. arg ( "query" ) . arg ( "tip" ) ;
122
+ self . post_config_command ( & mut command) ;
123
+
124
+ command
125
+ }
126
+
117
127
fn command_for_kes_period ( & self , opcert_file : & str ) -> Command {
118
128
let mut command = self . get_command ( ) ;
119
129
command
@@ -240,6 +250,22 @@ impl CliRunner for CardanoCliRunner {
240
250
}
241
251
}
242
252
253
+ async fn launch_chain_point ( & self ) -> StdResult < String > {
254
+ let output = self . command_for_chain_point ( ) . output ( ) . await ?;
255
+
256
+ if output. status . success ( ) {
257
+ Ok ( std:: str:: from_utf8 ( & output. stdout ) ?. trim ( ) . to_string ( ) )
258
+ } else {
259
+ let message = String :: from_utf8_lossy ( & output. stderr ) ;
260
+
261
+ Err ( anyhow ! (
262
+ "Error launching command {:?}, error = '{}'" ,
263
+ self . command_for_chain_point( ) ,
264
+ message
265
+ ) )
266
+ }
267
+ }
268
+
243
269
async fn launch_kes_period ( & self , opcert_file : & str ) -> StdResult < String > {
244
270
let output = self . command_for_kes_period ( opcert_file) . output ( ) . await ?;
245
271
@@ -407,6 +433,27 @@ impl ChainObserver for CardanoCliChainObserver {
407
433
}
408
434
}
409
435
436
+ async fn get_current_chain_point ( & self ) -> Result < Option < ChainPoint > , ChainObserverError > {
437
+ let output = self
438
+ . cli_runner
439
+ . launch_chain_point ( )
440
+ . await
441
+ . map_err ( ChainObserverError :: General ) ?;
442
+ let v: Value = serde_json:: from_str ( & output)
443
+ . with_context ( || format ! ( "output was = '{output}'" ) )
444
+ . map_err ( ChainObserverError :: InvalidContent ) ?;
445
+
446
+ if let Value :: String ( hash) = & v[ "hash" ] {
447
+ Ok ( Some ( ChainPoint {
448
+ slot_number : v[ "slot" ] . as_u64 ( ) . unwrap_or_default ( ) ,
449
+ block_number : v[ "block" ] . as_u64 ( ) . unwrap_or_default ( ) ,
450
+ block_hash : hash. to_string ( ) ,
451
+ } ) )
452
+ } else {
453
+ Ok ( None )
454
+ }
455
+ }
456
+
410
457
async fn get_current_datums (
411
458
& self ,
412
459
address : & ChainAddress ,
@@ -485,6 +532,22 @@ mod tests {
485
532
assert_eq ! ( Epoch ( 120 ) , epoch) ;
486
533
}
487
534
535
+ #[ tokio:: test]
536
+ async fn test_get_current_chain_point ( ) {
537
+ let observer = CardanoCliChainObserver :: new ( Box :: < TestCliRunner > :: default ( ) ) ;
538
+ let chain_point = observer. get_current_chain_point ( ) . await . unwrap ( ) . unwrap ( ) ;
539
+
540
+ assert_eq ! (
541
+ ChainPoint {
542
+ slot_number: 25886617 ,
543
+ block_number: 1270276 ,
544
+ block_hash: "7383b17d7b05b0953cf0649abff60173995eb9febe556889333e20e1e5b7ca84"
545
+ . to_string( ) ,
546
+ } ,
547
+ chain_point
548
+ ) ;
549
+ }
550
+
488
551
#[ tokio:: test]
489
552
async fn test_cli_testnet_runner ( ) {
490
553
let runner = CardanoCliRunner :: new (
0 commit comments