Skip to content

feat: add get_current_chain_point function to fetch chain point information #1674

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions mithril-common/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-common"
version = "0.4.4"
version = "0.4.5"
description = "Common types, interfaces, and utilities for Mithril nodes."
authors = { workspace = true }
edition = { workspace = true }
Expand Down Expand Up @@ -48,12 +48,12 @@ kes-summed-ed25519 = { version = "0.2.1", features = [
"sk_clone_enabled",
] }
nom = "7.1.3"
pallas-addresses = { version = "0.25.0", optional = true }
pallas-codec = { version = "0.25.0", optional = true }
pallas-hardano = { version = "0.25.0", optional = true }
pallas-network = { version = "0.25.0", optional = true }
pallas-primitives = { version = "0.25.0", optional = true }
pallas-traverse = { version = "0.25.0", optional = true }
pallas-addresses = { version = "0.26.0", optional = true }
pallas-codec = { version = "0.26.0", optional = true }
pallas-hardano = { version = "0.26.0", optional = true }
pallas-network = { version = "0.26.0", optional = true }
pallas-primitives = { version = "0.26.0", optional = true }
pallas-traverse = { version = "0.26.0", optional = true }
rand_chacha = "0.3.1"
rand_core = "0.6.4"
rayon = "1.8.1"
Expand Down Expand Up @@ -93,7 +93,7 @@ wasm-bindgen = "0.2.90"
[dev-dependencies]
criterion = { version = "0.5.1", features = ["html_reports", "async_tokio"] }
mockall = "0.12.1"
pallas-crypto = "0.25.0"
pallas-crypto = "0.26.0"
rand_core = { version = "0.6.4", features = ["getrandom"] }
reqwest = { version = "0.12.0", features = ["json"] }
slog-async = "2.8.0"
Expand Down
79 changes: 73 additions & 6 deletions mithril-common/src/chain_observer/pallas_observer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use pallas_network::{
miniprotocols::{
localstate::{
queries_v16::{
self, Addr, Addrs, Genesis, PostAlonsoTransactionOutput, StakeSnapshot, Stakes,
TransactionOutput, UTxOByAddress,
self, Addr, Addrs, ChainBlockNumber, Genesis, PostAlonsoTransactionOutput,
StakeSnapshot, Stakes, TransactionOutput, UTxOByAddress,
},
Client,
},
Expand Down Expand Up @@ -279,6 +279,16 @@ impl PallasChainObserver {
Ok(chain_point)
}

/// Fetches the current chain point using the provided `NodeClient`.
async fn do_get_chain_block_no(&self, statequery: &mut Client) -> StdResult<ChainBlockNumber> {
let chain_block_number = queries_v16::get_chain_block_no(statequery)
.await
.map_err(|err| anyhow!(err))
.with_context(|| "PallasChainObserver failed to get chain block number")?;

Ok(chain_block_number)
}

/// Fetches the current era using the provided `statequery` client.
async fn do_get_current_era_state_query(&self, statequery: &mut Client) -> StdResult<u16> {
let era = queries_v16::get_current_era(statequery)
Expand All @@ -303,6 +313,30 @@ impl PallasChainObserver {
Ok(genesis_config)
}

/// Fetches the current chain point using the provided `NodeClient`.
async fn get_chain_point(&self, statequery: &mut Client) -> StdResult<ChainPoint> {
statequery
.acquire(None)
.await
.map_err(|err| anyhow!(err))
.with_context(|| "PallasChainObserver failed to acquire statequery")?;

let chain_point = self.do_get_chain_point_state_query(statequery).await?;

let header_hash = match chain_point {
Point::Origin => None,
Point::Specific(_at_slot, ref hash) => Some(hex::encode(hash)),
};

let chain_block_number = self.do_get_chain_block_no(statequery).await?;

Ok(ChainPoint {
slot_number: chain_point.slot_or_default(),
block_hash: header_hash.unwrap_or_default(),
block_number: chain_block_number.block_number as u64,
})
}

/// Fetches chain point and genesis config through the local statequery.
/// The KES period is calculated afterwards.
async fn get_kes_period(
Expand Down Expand Up @@ -385,8 +419,15 @@ impl ChainObserver for PallasChainObserver {
}

async fn get_current_chain_point(&self) -> Result<Option<ChainPoint>, ChainObserverError> {
// TODO: Implement get_current_chain_point with pallas
todo!("Implement get_current_chain_point")
let mut client = self.get_client().await?;

let chain_point = self.get_chain_point(client.statequery()).await?;

self.post_process_statequery(&mut client).await?;

client.abort().await;

Ok(Some(chain_point))
}

async fn get_current_datums(
Expand Down Expand Up @@ -444,8 +485,8 @@ mod tests {
use pallas_network::miniprotocols::{
localstate::{
queries_v16::{
BlockQuery, Fraction, Genesis, HardForkQuery, LedgerQuery, Request, Snapshots,
StakeSnapshot, SystemStart, Value,
BlockQuery, ChainBlockNumber, Fraction, Genesis, HardForkQuery, LedgerQuery,
Request, Snapshots, StakeSnapshot, SystemStart, Value,
},
ClientQueryRequest,
},
Expand Down Expand Up @@ -581,6 +622,10 @@ mod tests {
Request::GetChainPoint => {
AnyCbor::from_encode(Point::Specific(52851885, vec![1, 2, 3]))
}
Request::GetChainBlockNo => AnyCbor::from_encode(ChainBlockNumber {
slot_timeline: 1,
block_number: 52851885,
}),
Request::LedgerQuery(LedgerQuery::HardForkQuery(HardForkQuery::GetCurrentEra)) => {
AnyCbor::from_encode(4)
}
Expand Down Expand Up @@ -816,4 +861,26 @@ mod tests {
let era = client_res.expect("Client failed");
assert_eq!(era, 4);
}

#[tokio::test]
async fn get_current_chain_point() {
let socket_path = create_temp_dir("get_current_chain_point").join("node.socket");
let server = setup_server(socket_path.clone(), 2).await;
let client = tokio::spawn(async move {
let observer =
PallasChainObserver::new(socket_path.as_path(), CardanoNetwork::TestNet(10));
observer.get_current_chain_point().await.unwrap()
});

let (_, client_res) = tokio::join!(server, client);
let chain_point = client_res.expect("Client failed");
assert_eq!(
chain_point,
Some(ChainPoint {
slot_number: 52851885,
block_hash: "010203".to_string(),
block_number: 52851885
})
);
}
}
Loading