Skip to content

Commit c061eee

Browse files
committed
refactor(cardano-node-chain): update 'CardanoCliChainObserver' implementation of 'ChainObserver'
1 parent 6326899 commit c061eee

File tree

2 files changed

+57
-54
lines changed

2 files changed

+57
-54
lines changed

internal/cardano-node/mithril-cardano-node-chain/src/chain_observer/cli_observer.rs

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::fs;
99
use std::path::PathBuf;
1010
use tokio::process::Command;
1111

12-
use mithril_common::crypto_helper::{KesPeriod, OpCert, SerDeShelleyFileFormat, encode_bech32};
12+
use mithril_common::crypto_helper::{KesPeriod, encode_bech32};
1313
use mithril_common::entities::{BlockNumber, ChainPoint, Epoch, SlotNumber, StakeDistribution};
1414
use mithril_common::{CardanoNetwork, StdResult};
1515

@@ -38,7 +38,7 @@ pub trait CliRunner {
3838
/// Launches the chain point.
3939
async fn launch_chain_point(&self) -> StdResult<String>;
4040
/// 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)>;
4242
}
4343

4444
/// A runner able to request data from a Cardano node using the
@@ -141,14 +141,9 @@ impl CardanoCliRunner {
141141
command
142142
}
143143

144-
fn command_for_kes_period(&self, opcert_file: &str) -> Command {
144+
fn command_for_kes_period(&self) -> Command {
145145
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");
152147
self.post_config_command(&mut command);
153148

154149
command
@@ -172,6 +167,20 @@ impl CardanoCliRunner {
172167
}
173168
}
174169
}
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+
}
175184
}
176185

177186
#[async_trait]
@@ -289,17 +298,20 @@ impl CliRunner for CardanoCliRunner {
289298
}
290299
}
291300

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?;
294303

295304
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+
))
297309
} else {
298310
let message = String::from_utf8_lossy(&output.stderr);
299311

300312
Err(anyhow!(
301313
"Error launching command {:?}, error = '{}'",
302-
self.command_for_kes_period(opcert_file),
314+
self.command_for_kes_period(),
303315
message
304316
))
305317
}
@@ -526,29 +538,26 @@ impl ChainObserver for CardanoCliChainObserver {
526538
}
527539
}
528540

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> {
533542
let dir = std::env::temp_dir().join("mithril_kes_period");
534543
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
540545
.cli_runner
541-
.launch_kes_period(opcert_file.to_str().unwrap())
546+
.launch_kes_period()
542547
.await
543548
.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+
}
544553
let first_left_curly_bracket_index = output.find('{').unwrap_or_default();
545554
let output_cleaned = output.split_at(first_left_curly_bracket_index).1;
546555
let v: Value = serde_json::from_str(output_cleaned)
547556
.with_context(|| format!("output was = '{output}'"))
548557
.map_err(ChainObserverError::InvalidContent)?;
549558

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))
552561
} else {
553562
Ok(None)
554563
}
@@ -557,12 +566,9 @@ impl ChainObserver for CardanoCliChainObserver {
557566

558567
#[cfg(test)]
559568
mod tests {
560-
use kes_summed_ed25519::{kes::Sum6Kes, traits::KesSk};
561569
use std::collections::BTreeMap;
562570
use std::ffi::OsStr;
563571

564-
use mithril_common::crypto_helper::ColdKeyGenerator;
565-
566572
use crate::test::test_cli_runner::{TestCliRunner, test_expected};
567573

568574
use super::*;
@@ -807,17 +813,12 @@ mod tests {
807813

808814
#[tokio::test]
809815
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);
815816
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+
);
822823
}
823824
}

internal/cardano-node/mithril-cardano-node-chain/src/test/test_cli_runner.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub(crate) mod test_expected {
2929
pub(crate) const BYTES: &str = "5b0a20207b0a20202020226e616d65223a20227468616c6573222c0a202020202265706f6368223a203132330a20207d2c0a20207b0a20202020226e616d65223a20227079746861676f726173222c0a202020202265706f6368223a206e756c6c0a20207d0a5d0a";
3030
}
3131
pub(crate) mod launch_kes_period {
32-
pub(crate) const KES_PERIOD: u32 = 404;
32+
pub(crate) const SLOTS_PER_KES_PERIOD: u64 = 10000;
3333
}
3434
pub(crate) mod launch_stake_snapshot {
3535
pub(crate) const DEFAULT_POOL_STAKE_MARK: u64 = 3_000_000;
@@ -256,25 +256,27 @@ pool1qz2vzszautc2c8mljnqre2857dpmheq7kgt6vav0s38tvvhxm6w 1.051e-6
256256
}
257257

258258
/// launches the kes period.
259-
async fn launch_kes_period(&self, _opcert_file: &str) -> StdResult<String> {
259+
async fn launch_kes_period(&self) -> StdResult<(String, u64)> {
260260
let output = format!(
261261
r#"
262-
✓ The operational certificate counter agrees with the node protocol state counter
263-
✓ Operational certificate's kes period is within the correct KES period interval
264262
{{
265-
"qKesNodeStateOperationalCertificateNumber": 6,
266-
"qKesCurrentKesPeriod": {},
267-
"qKesOnDiskOperationalCertificateNumber": 6,
268-
"qKesRemainingSlotsInKesPeriod": 3760228,
269-
"qKesMaxKESEvolutions": 62,
270-
"qKesKesKeyExpiry": "2022-03-20T21:44:51Z",
271-
"qKesEndKesInterval": 434,
272-
"qKesStartKesInterval": 372,
273-
"qKesSlotsPerKesPeriod": 129600
263+
"block": {},
264+
"epoch": 299,
265+
"era": "Conway",
266+
"hash": "{}",
267+
"slot": {},
268+
"slotInEpoch": 53017,
269+
"slotsToEpochEnd": 33383,
270+
"syncProgress": "100.00"
274271
}}"#,
275-
test_expected::launch_kes_period::KES_PERIOD
272+
test_expected::launch_chain_point::BLOCK_NUMBER,
273+
test_expected::launch_chain_point::BLOCK_HASH,
274+
test_expected::launch_chain_point::SLOT_NUMBER,
276275
);
277276

278-
Ok(output)
277+
Ok((
278+
output,
279+
test_expected::launch_kes_period::SLOTS_PER_KES_PERIOD,
280+
))
279281
}
280282
}

0 commit comments

Comments
 (0)