Skip to content

Commit 2c83bf9

Browse files
committed
feat: implement 'get_current_chain_point' for CardanoCliChainObserver
1 parent 1a077a0 commit 2c83bf9

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

mithril-common/src/chain_observer/cli_observer.rs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use tokio::process::Command;
1212
use crate::chain_observer::interface::{ChainObserver, ChainObserverError};
1313
use crate::chain_observer::{ChainAddress, TxDatum};
1414
use crate::crypto_helper::{encode_bech32, KESPeriod, OpCert, SerDeShelleyFileFormat};
15-
use crate::entities::{Epoch, StakeDistribution};
15+
use crate::entities::{ChainPoint, Epoch, StakeDistribution};
1616
use crate::{CardanoNetwork, StdResult};
1717

1818
/// `CliRunner` trait defines the asynchronous methods
@@ -29,6 +29,8 @@ pub trait CliRunner {
2929
async fn launch_stake_snapshot_all_pools(&self) -> StdResult<String>;
3030
/// Launches the epoch info.
3131
async fn launch_epoch(&self) -> StdResult<String>;
32+
/// Launches the chain point.
33+
async fn launch_chain_point(&self) -> StdResult<String>;
3234
/// Launches the kes period.
3335
async fn launch_kes_period(&self, opcert_file: &str) -> StdResult<String>;
3436
}
@@ -114,6 +116,14 @@ impl CardanoCliRunner {
114116
command
115117
}
116118

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+
117127
fn command_for_kes_period(&self, opcert_file: &str) -> Command {
118128
let mut command = self.get_command();
119129
command
@@ -240,6 +250,22 @@ impl CliRunner for CardanoCliRunner {
240250
}
241251
}
242252

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+
243269
async fn launch_kes_period(&self, opcert_file: &str) -> StdResult<String> {
244270
let output = self.command_for_kes_period(opcert_file).output().await?;
245271

@@ -407,6 +433,27 @@ impl ChainObserver for CardanoCliChainObserver {
407433
}
408434
}
409435

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+
410457
async fn get_current_datums(
411458
&self,
412459
address: &ChainAddress,
@@ -485,6 +532,22 @@ mod tests {
485532
assert_eq!(Epoch(120), epoch);
486533
}
487534

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+
488551
#[tokio::test]
489552
async fn test_cli_testnet_runner() {
490553
let runner = CardanoCliRunner::new(

mithril-common/src/chain_observer/test_cli_runner.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,23 @@ pool1qz2vzszautc2c8mljnqre2857dpmheq7kgt6vav0s38tvvhxm6w 1.051e-6
169169
Ok(output.to_string())
170170
}
171171

172+
/// launches the chain point info.
173+
async fn launch_chain_point(&self) -> StdResult<String> {
174+
let output = r#"
175+
{
176+
"block": 1270276,
177+
"epoch": 299,
178+
"era": "Conway",
179+
"hash": "7383b17d7b05b0953cf0649abff60173995eb9febe556889333e20e1e5b7ca84",
180+
"slot": 25886617,
181+
"slotInEpoch": 53017,
182+
"slotsToEpochEnd": 33383,
183+
"syncProgress": "100.00"
184+
}"#;
185+
186+
Ok(output.to_string())
187+
}
188+
172189
/// launches the kes period.
173190
async fn launch_kes_period(&self, _opcert_file: &str) -> StdResult<String> {
174191
let output = r#"

0 commit comments

Comments
 (0)