@@ -9,7 +9,7 @@ use std::fs;
9
9
use std:: path:: PathBuf ;
10
10
use tokio:: process:: Command ;
11
11
12
- use mithril_common:: crypto_helper:: { KesPeriod , OpCert , SerDeShelleyFileFormat , encode_bech32} ;
12
+ use mithril_common:: crypto_helper:: { KesPeriod , encode_bech32} ;
13
13
use mithril_common:: entities:: { BlockNumber , ChainPoint , Epoch , SlotNumber , StakeDistribution } ;
14
14
use mithril_common:: { CardanoNetwork , StdResult } ;
15
15
@@ -38,7 +38,7 @@ pub trait CliRunner {
38
38
/// Launches the chain point.
39
39
async fn launch_chain_point ( & self ) -> StdResult < String > ;
40
40
/// Launches the kes period.
41
- async fn launch_kes_period ( & self , opcert_file : & str ) -> StdResult < String > ;
41
+ async fn launch_kes_period ( & self ) -> StdResult < ( String , u64 ) > ;
42
42
}
43
43
44
44
/// A runner able to request data from a Cardano node using the
@@ -141,14 +141,9 @@ impl CardanoCliRunner {
141
141
command
142
142
}
143
143
144
- fn command_for_kes_period ( & self , opcert_file : & str ) -> Command {
144
+ fn command_for_kes_period ( & self ) -> Command {
145
145
let mut command = self . get_command ( ) ;
146
- command
147
- . arg ( CARDANO_ERA )
148
- . arg ( "query" )
149
- . arg ( "kes-period-info" )
150
- . arg ( "--op-cert-file" )
151
- . arg ( opcert_file) ;
146
+ command. arg ( CARDANO_ERA ) . arg ( "query" ) . arg ( "tip" ) ;
152
147
self . post_config_command ( & mut command) ;
153
148
154
149
command
@@ -172,6 +167,20 @@ impl CardanoCliRunner {
172
167
}
173
168
}
174
169
}
170
+
171
+ /// Get slots per kes period
172
+ ///
173
+ /// This implementation is aligned with current value for the KES period on the testnet and mainnet networks of Cardano.
174
+ /// If this value changes in the future, the implementation should be updated accordingly.
175
+ /// The value can be retrieved in the 'slotsPerKESPeriod' field of the 'shelly-genesis.json' configuration file.
176
+ fn get_slots_per_kes_period ( & self ) -> u64 {
177
+ match self . network {
178
+ CardanoNetwork :: MainNet => 129600 ,
179
+ CardanoNetwork :: TestNet ( 1 ) => 129600 ,
180
+ CardanoNetwork :: TestNet ( 2 ) => 129600 ,
181
+ CardanoNetwork :: TestNet ( _) => 129600 ,
182
+ }
183
+ }
175
184
}
176
185
177
186
#[ async_trait]
@@ -289,17 +298,20 @@ impl CliRunner for CardanoCliRunner {
289
298
}
290
299
}
291
300
292
- async fn launch_kes_period ( & self , opcert_file : & str ) -> StdResult < String > {
293
- let output = self . command_for_kes_period ( opcert_file ) . output ( ) . await ?;
301
+ async fn launch_kes_period ( & self ) -> StdResult < ( String , u64 ) > {
302
+ let output = self . command_for_kes_period ( ) . output ( ) . await ?;
294
303
295
304
if output. status . success ( ) {
296
- Ok ( std:: str:: from_utf8 ( & output. stdout ) ?. trim ( ) . to_string ( ) )
305
+ Ok ( (
306
+ std:: str:: from_utf8 ( & output. stdout ) ?. trim ( ) . to_string ( ) ,
307
+ self . get_slots_per_kes_period ( ) ,
308
+ ) )
297
309
} else {
298
310
let message = String :: from_utf8_lossy ( & output. stderr ) ;
299
311
300
312
Err ( anyhow ! (
301
313
"Error launching command {:?}, error = '{}'" ,
302
- self . command_for_kes_period( opcert_file ) ,
314
+ self . command_for_kes_period( ) ,
303
315
message
304
316
) )
305
317
}
@@ -526,29 +538,26 @@ impl ChainObserver for CardanoCliChainObserver {
526
538
}
527
539
}
528
540
529
- async fn get_current_kes_period (
530
- & self ,
531
- opcert : & OpCert ,
532
- ) -> Result < Option < KesPeriod > , ChainObserverError > {
541
+ async fn get_current_kes_period ( & self ) -> Result < Option < KesPeriod > , ChainObserverError > {
533
542
let dir = std:: env:: temp_dir ( ) . join ( "mithril_kes_period" ) ;
534
543
fs:: create_dir_all ( & dir) . map_err ( |e| ChainObserverError :: General ( e. into ( ) ) ) ?;
535
- let opcert_file = dir. join ( format ! ( "opcert_kes_period-{}" , opcert. compute_hash( ) ) ) ;
536
- opcert
537
- . to_file ( & opcert_file)
538
- . map_err ( |e| ChainObserverError :: General ( e. into ( ) ) ) ?;
539
- let output = self
544
+ let ( output, slots_per_kes_period) = self
540
545
. cli_runner
541
- . launch_kes_period ( opcert_file . to_str ( ) . unwrap ( ) )
546
+ . launch_kes_period ( )
542
547
. await
543
548
. map_err ( ChainObserverError :: General ) ?;
549
+ if slots_per_kes_period == 0 {
550
+ return Err ( anyhow ! ( "slots_per_kes_period must be greater than 0" ) )
551
+ . with_context ( || "CardanoCliChainObserver failed to calculate kes period" ) ?;
552
+ }
544
553
let first_left_curly_bracket_index = output. find ( '{' ) . unwrap_or_default ( ) ;
545
554
let output_cleaned = output. split_at ( first_left_curly_bracket_index) . 1 ;
546
555
let v: Value = serde_json:: from_str ( output_cleaned)
547
556
. with_context ( || format ! ( "output was = '{output}'" ) )
548
557
. map_err ( ChainObserverError :: InvalidContent ) ?;
549
558
550
- if let Value :: Number ( kes_period ) = & v[ "qKesCurrentKesPeriod " ] {
551
- Ok ( kes_period . as_u64 ( ) . map ( |p| p as KesPeriod ) )
559
+ if let Value :: Number ( slot ) = & v[ "slot " ] {
560
+ Ok ( slot . as_u64 ( ) . map ( |slot| ( slot / slots_per_kes_period ) as KesPeriod ) )
552
561
} else {
553
562
Ok ( None )
554
563
}
@@ -557,12 +566,9 @@ impl ChainObserver for CardanoCliChainObserver {
557
566
558
567
#[ cfg( test) ]
559
568
mod tests {
560
- use kes_summed_ed25519:: { kes:: Sum6Kes , traits:: KesSk } ;
561
569
use std:: collections:: BTreeMap ;
562
570
use std:: ffi:: OsStr ;
563
571
564
- use mithril_common:: crypto_helper:: ColdKeyGenerator ;
565
-
566
572
use crate :: test:: test_cli_runner:: { TestCliRunner , test_expected} ;
567
573
568
574
use super :: * ;
@@ -807,17 +813,12 @@ mod tests {
807
813
808
814
#[ tokio:: test]
809
815
async fn test_get_current_kes_period ( ) {
810
- let keypair = ColdKeyGenerator :: create_deterministic_keypair ( [ 0u8 ; 32 ] ) ;
811
- let mut dummy_key_buffer = [ 0u8 ; Sum6Kes :: SIZE + 4 ] ;
812
- let mut dummy_seed = [ 0u8 ; 32 ] ;
813
- let ( _, kes_verification_key) = Sum6Kes :: keygen ( & mut dummy_key_buffer, & mut dummy_seed) ;
814
- let operational_certificate = OpCert :: new ( kes_verification_key, 0 , 0 , keypair) ;
815
816
let observer = CardanoCliChainObserver :: new ( Box :: < TestCliRunner > :: default ( ) ) ;
816
- let kes_period = observer
817
- . get_current_kes_period ( & operational_certificate )
818
- . await
819
- . unwrap ( )
820
- . unwrap ( ) ;
821
- assert_eq ! ( test_expected :: launch_kes_period :: KES_PERIOD , kes_period ) ;
817
+ let kes_period = observer. get_current_kes_period ( ) . await . unwrap ( ) . unwrap ( ) ;
818
+ assert_eq ! (
819
+ ( test_expected :: launch_chain_point :: SLOT_NUMBER . 0
820
+ / test_expected :: launch_kes_period :: SLOTS_PER_KES_PERIOD ) as u32 ,
821
+ kes_period
822
+ ) ;
822
823
}
823
824
}
0 commit comments