diff --git a/examples/n2c-miniprotocols/src/main.rs b/examples/n2c-miniprotocols/src/main.rs index 16c2483..3a656c8 100644 --- a/examples/n2c-miniprotocols/src/main.rs +++ b/examples/n2c-miniprotocols/src/main.rs @@ -65,6 +65,9 @@ async fn do_localstate_query(client: &mut NodeClient) { .unwrap(); println!("result: {:?}", result); + let result = queries_v16::get_genesis_config(client, era).await.unwrap(); + println!("result: {:?}", result); + client.send_release().await.unwrap(); } diff --git a/pallas-network/src/miniprotocols/localstate/queries_v16/mod.rs b/pallas-network/src/miniprotocols/localstate/queries_v16/mod.rs index 0d01e81..f4ccdd0 100644 --- a/pallas-network/src/miniprotocols/localstate/queries_v16/mod.rs +++ b/pallas-network/src/miniprotocols/localstate/queries_v16/mod.rs @@ -306,6 +306,42 @@ pub struct Stakes { pub snapshot_go_pool: u64, } +#[derive(Debug, Encode, Decode, PartialEq)] +pub struct Genesis { + #[n(0)] + pub system_start: SystemStart, + + #[n(1)] + pub network_magic: u32, + + #[n(2)] + pub network_id: u32, + + #[n(3)] + pub active_slots_coefficient: Fraction, + + #[n(4)] + pub security_param: u32, + + #[n(5)] + pub epoch_length: u32, + + #[n(6)] + pub slots_per_kes_period: u32, + + #[n(7)] + pub max_kes_evolutions: u32, + + #[n(8)] + pub slot_length: u32, + + #[n(9)] + pub update_quorum: u32, + + #[n(10)] + pub max_lovelace_supply: Coin, +} + /// Get the current tip of the ledger. pub async fn get_chain_point(client: &mut Client) -> Result { let query = Request::GetChainPoint; @@ -398,3 +434,16 @@ pub async fn get_stake_snapshots( Ok(result) } + +/// Get the genesis configuration for the given era. +pub async fn get_genesis_config( + client: &mut Client, + era: u16, +) -> Result, ClientError> { + let query = BlockQuery::GetGenesisConfig; + let query = LedgerQuery::BlockQuery(era, query); + let query = Request::LedgerQuery(query); + let result = client.query(query).await?; + + Ok(result) +} diff --git a/pallas-network/tests/protocols.rs b/pallas-network/tests/protocols.rs index 0f6a67d..8136921 100644 --- a/pallas-network/tests/protocols.rs +++ b/pallas-network/tests/protocols.rs @@ -10,7 +10,7 @@ use pallas_network::miniprotocols::blockfetch::BlockRequest; use pallas_network::miniprotocols::chainsync::{ClientRequest, HeaderContent, Tip}; use pallas_network::miniprotocols::handshake::n2n::VersionData; use pallas_network::miniprotocols::localstate::queries_v16::{ - Addr, Addrs, Snapshots, Stakes, UnitInterval, Value, + Addr, Addrs, Fraction, Genesis, Snapshots, Stakes, SystemStart, UnitInterval, Value, }; use pallas_network::miniprotocols::localstate::ClientQueryRequest; use pallas_network::miniprotocols::txsubmission::{EraTxBody, TxIdAndSize}; @@ -498,7 +498,7 @@ pub async fn local_state_query_server_and_client_happy_path() { assert_eq!(query, localstate::queries_v16::Request::GetSystemStart); assert_eq!(*server.statequery().state(), localstate::State::Querying); - let result = AnyCbor::from_encode(localstate::queries_v16::SystemStart { + let result = AnyCbor::from_encode(SystemStart { year: 2020, day_of_year: 1, picoseconds_of_day: 999999999, @@ -527,7 +527,7 @@ pub async fn local_state_query_server_and_client_happy_path() { ); assert_eq!(*server.statequery().state(), localstate::State::Querying); - let fraction = localstate::queries_v16::Fraction { num: 10, dem: 20 }; + let fraction = Fraction { num: 10, dem: 20 }; let pool = localstate::queries_v16::Pool { stakes: fraction.clone(), hashes: b"pool1qv4qgv62s3ha74p0643nexee9zvcdydcyahqqnavhj90zheuykz" @@ -705,6 +705,46 @@ pub async fn local_state_query_server_and_client_happy_path() { let result = AnyCbor::from_encode(localstate::queries_v16::StakeSnapshot { snapshots }); server.statequery().send_result(result).await.unwrap(); + // server receives query from client + let query: localstate::queries_v16::Request = + match server.statequery().recv_while_acquired().await.unwrap() { + ClientQueryRequest::Query(q) => q.into_decode().unwrap(), + x => panic!("unexpected message from client: {x:?}"), + }; + + assert_eq!( + query, + localstate::queries_v16::Request::LedgerQuery( + localstate::queries_v16::LedgerQuery::BlockQuery( + 5, + localstate::queries_v16::BlockQuery::GetGenesisConfig, + ), + ) + ); + + assert_eq!(*server.statequery().state(), localstate::State::Querying); + + let genesis = vec![Genesis { + system_start: SystemStart { + year: 2021, + day_of_year: 150, + picoseconds_of_day: 0, + }, + network_magic: 42, + network_id: 42, + active_slots_coefficient: Fraction { num: 6, dem: 10 }, + security_param: 2160, + epoch_length: 432000, + slots_per_kes_period: 129600, + max_kes_evolutions: 62, + slot_length: 1, + update_quorum: 5, + max_lovelace_supply: AnyUInt::MajorByte(2), + }]; + + let result = AnyCbor::from_encode(genesis); + server.statequery().send_result(result).await.unwrap(); + assert_eq!(*server.statequery().state(), localstate::State::Acquired); // server receives re-acquire from the client @@ -759,7 +799,7 @@ pub async fn local_state_query_server_and_client_happy_path() { client.statequery().send_query(request).await.unwrap(); - let result: localstate::queries_v16::SystemStart = client + let result: SystemStart = client .statequery() .recv_while_querying() .await @@ -793,7 +833,7 @@ pub async fn local_state_query_server_and_client_happy_path() { .into_decode() .unwrap(); - let fraction = localstate::queries_v16::Fraction { num: 10, dem: 20 }; + let fraction = Fraction { num: 10, dem: 20 }; let pool = localstate::queries_v16::Pool { stakes: fraction.clone(), hashes: b"pool1qv4qgv62s3ha74p0643nexee9zvcdydcyahqqnavhj90zheuykz" @@ -961,6 +1001,43 @@ pub async fn local_state_query_server_and_client_happy_path() { assert_eq!(result, localstate::queries_v16::StakeSnapshot { snapshots }); + let request = AnyCbor::from_encode(localstate::queries_v16::Request::LedgerQuery( + localstate::queries_v16::LedgerQuery::BlockQuery( + 5, + localstate::queries_v16::BlockQuery::GetGenesisConfig, + ), + )); + + client.statequery().send_query(request).await.unwrap(); + + let result: Vec = client + .statequery() + .recv_while_querying() + .await + .unwrap() + .into_decode() + .unwrap(); + + let genesis = vec![Genesis { + system_start: SystemStart { + year: 2021, + day_of_year: 150, + picoseconds_of_day: 0, + }, + network_magic: 42, + network_id: 42, + active_slots_coefficient: Fraction { num: 6, dem: 10 }, + security_param: 2160, + epoch_length: 432000, + slots_per_kes_period: 129600, + max_kes_evolutions: 62, + slot_length: 1, + update_quorum: 5, + max_lovelace_supply: AnyUInt::MajorByte(2), + }]; + + assert_eq!(result, genesis); + // client sends a ReAquire client .statequery()