From ebb9ce724431966aba1d58bfeac65c187eae5e49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20S=C3=A1nchez=20Terraf?= Date: Fri, 29 Nov 2024 20:33:24 -0300 Subject: [PATCH 1/5] WIP: GetFilteredDelegationsAndRewardAccounts --- examples/n2c-miniprotocols/src/main.rs | 18 +++++++- .../src/miniprotocols/localstate/client.rs | 1 + .../localstate/queries_v16/codec.rs | 2 +- .../localstate/queries_v16/mod.rs | 41 ++++++++++++++++++- 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/examples/n2c-miniprotocols/src/main.rs b/examples/n2c-miniprotocols/src/main.rs index de784c37..f0556b4b 100644 --- a/examples/n2c-miniprotocols/src/main.rs +++ b/examples/n2c-miniprotocols/src/main.rs @@ -7,13 +7,15 @@ use pallas::{ facades::NodeClient, miniprotocols::{ chainsync, - localstate::queries_v16::{self, Addr, Addrs}, + localstate::queries_v16::{self, Addr, Addrs, StakeAddr}, Point, PRE_PRODUCTION_MAGIC, }, }, }; use tracing::info; +use hex::FromHex; + async fn do_localstate_query(client: &mut NodeClient) { let client = client.statequery(); @@ -31,6 +33,20 @@ async fn do_localstate_query(client: &mut NodeClient) { let era = queries_v16::get_current_era(client).await.unwrap(); info!("result: {:?}", era); + // Getting rewards and delegation for a stake address + // let addr = "stake_test1uqfp3atrunssjk8a4w7lk3ct97wnscs4wc7v3ynnmx7ll7s2ea9p2".to_string(); + // let addr: Address = Address::from_bech32(&addr).unwrap(); + // let addr: Addr = addr.to_vec().into(); + let addr: Addr = <[u8; 28]>::from_hex( + "1218F563E4E10958FDABBDFB470B2F9D386215763CC89273D9BDFFFA" + ).unwrap().to_vec().into(); + let mut addrs = BTreeSet::new(); + addrs.insert(StakeAddr::from((0x00, addr))); + let result = queries_v16::get_filtered_delegations_rewards(client, era, addrs) + .await + .unwrap(); + info!("result: {:?}", result); + let result = queries_v16::get_block_epoch_number(client, era) .await .unwrap(); diff --git a/pallas-network/src/miniprotocols/localstate/client.rs b/pallas-network/src/miniprotocols/localstate/client.rs index 34438d86..3d287522 100644 --- a/pallas-network/src/miniprotocols/localstate/client.rs +++ b/pallas-network/src/miniprotocols/localstate/client.rs @@ -202,6 +202,7 @@ impl GenericClient { { let request = AnyCbor::from_encode(request); let response = self.query_any(request).await?; + response.into_decode().map_err(ClientError::InvalidCbor) } } diff --git a/pallas-network/src/miniprotocols/localstate/queries_v16/codec.rs b/pallas-network/src/miniprotocols/localstate/queries_v16/codec.rs index d06763f1..0d81e1ae 100644 --- a/pallas-network/src/miniprotocols/localstate/queries_v16/codec.rs +++ b/pallas-network/src/miniprotocols/localstate/queries_v16/codec.rs @@ -139,7 +139,7 @@ impl<'b> Decode<'b, ()> for BlockQuery { // 7 => Ok(Self::GetUTxOWhole), // 8 => Ok(Self::DebugEpochState), 9 => Ok(Self::GetCBOR(d.decode()?)), - // 10 => Ok(Self::GetFilteredDelegationsAndRewardAccounts(())), + 10 => Ok(Self::GetFilteredDelegationsAndRewardAccounts(d.decode()?)), 11 => Ok(Self::GetGenesisConfig), // 12 => Ok(Self::DebugNewEpochState), 13 => Ok(Self::DebugChainDepState), diff --git a/pallas-network/src/miniprotocols/localstate/queries_v16/mod.rs b/pallas-network/src/miniprotocols/localstate/queries_v16/mod.rs index 5e4e8646..e02658ab 100644 --- a/pallas-network/src/miniprotocols/localstate/queries_v16/mod.rs +++ b/pallas-network/src/miniprotocols/localstate/queries_v16/mod.rs @@ -32,7 +32,7 @@ pub enum BlockQuery { GetUTxOWhole, DebugEpochState, GetCBOR(Box), - GetFilteredDelegationsAndRewardAccounts(AnyCbor), + GetFilteredDelegationsAndRewardAccounts(StakeAddrs), GetGenesisConfig, DebugNewEpochState, DebugChainDepState, @@ -220,6 +220,31 @@ pub type Addr = Bytes; pub type Addrs = Vec; +#[derive(Debug, Encode, Decode, PartialEq, Eq, Clone, PartialOrd, Ord)] +pub struct StakeAddr { + #[n(0)] + addr_type: u8, + #[n(1)] + payload: Addr, +} + +impl From<(u8, Bytes)> for StakeAddr { + fn from((addr_type, payload): (u8, Bytes)) -> Self { + Self { addr_type, payload } + } +} + +pub type StakeAddrs = BTreeSet; +pub type Delegations = KeyValuePairs; +pub type RewardAccounts = KeyValuePairs; + +// TODO: Destruct the tuple, define proper encoding. +#[derive(Debug, Encode, Decode, PartialEq, Clone)] +pub struct FilteredDelegsRewards { + #[n(0)] + pub delegs_rewards: (Delegations, RewardAccounts), +} + pub type Pools = BTreeSet; pub type Coin = AnyUInt; @@ -477,3 +502,17 @@ pub async fn get_genesis_config( Ok(result) } + +/// Get the delegations and rewards for the given stake addresses. +pub async fn get_filtered_delegations_rewards( + client: &mut Client, + era: u16, + addrs: StakeAddrs, +) -> Result { + let query = BlockQuery::GetFilteredDelegationsAndRewardAccounts(addrs); + let query = LedgerQuery::BlockQuery(era, query); + let query = Request::LedgerQuery(query); + let result = client.query(query).await?; + + Ok(result) +} From 060dc73d1784d25a0a83e4a79460b1731a6335a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20S=C3=A1nchez=20Terraf?= Date: Mon, 2 Dec 2024 16:00:56 -0300 Subject: [PATCH 2/5] GetFilteredDelegationsAnd... ready and example --- examples/n2c-miniprotocols/src/main.rs | 6 ++--- .../localstate/queries_v16/codec.rs | 26 +++++++++++++++++++ .../localstate/queries_v16/mod.rs | 7 +++-- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/examples/n2c-miniprotocols/src/main.rs b/examples/n2c-miniprotocols/src/main.rs index f0556b4b..1db9ec89 100644 --- a/examples/n2c-miniprotocols/src/main.rs +++ b/examples/n2c-miniprotocols/src/main.rs @@ -33,10 +33,8 @@ async fn do_localstate_query(client: &mut NodeClient) { let era = queries_v16::get_current_era(client).await.unwrap(); info!("result: {:?}", era); - // Getting rewards and delegation for a stake address - // let addr = "stake_test1uqfp3atrunssjk8a4w7lk3ct97wnscs4wc7v3ynnmx7ll7s2ea9p2".to_string(); - // let addr: Address = Address::from_bech32(&addr).unwrap(); - // let addr: Addr = addr.to_vec().into(); + // Getting delegation and rewards for preprod stake address + // `stake_test1uqfp3atrunssjk8a4w7lk3ct97wnscs4wc7v3ynnmx7ll7s2ea9p2` let addr: Addr = <[u8; 28]>::from_hex( "1218F563E4E10958FDABBDFB470B2F9D386215763CC89273D9BDFFFA" ).unwrap().to_vec().into(); diff --git a/pallas-network/src/miniprotocols/localstate/queries_v16/codec.rs b/pallas-network/src/miniprotocols/localstate/queries_v16/codec.rs index 0d81e1ae..7aa68d5a 100644 --- a/pallas-network/src/miniprotocols/localstate/queries_v16/codec.rs +++ b/pallas-network/src/miniprotocols/localstate/queries_v16/codec.rs @@ -369,3 +369,29 @@ impl minicbor::encode::Encode for TransactionOutput { Ok(()) } } + +impl<'b, C> minicbor::decode::Decode<'b, C> for FilteredDelegsRewards { + fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result { + d.array()?; + d.array()?; + Ok(FilteredDelegsRewards { + delegs: d.decode_with(ctx)?, + rewards: d.decode_with(ctx)?, + }) + } +} + +impl minicbor::encode::Encode for FilteredDelegsRewards { + fn encode( + &self, + e: &mut minicbor::Encoder, + ctx: &mut C, + ) -> Result<(), minicbor::encode::Error> { + e.array(1)?; + e.array(2)?; + e.encode_with(self.delegs.clone(), ctx)?; + e.encode_with(self.rewards.clone(), ctx)?; + + Ok(()) + } +} diff --git a/pallas-network/src/miniprotocols/localstate/queries_v16/mod.rs b/pallas-network/src/miniprotocols/localstate/queries_v16/mod.rs index e02658ab..b2a29502 100644 --- a/pallas-network/src/miniprotocols/localstate/queries_v16/mod.rs +++ b/pallas-network/src/miniprotocols/localstate/queries_v16/mod.rs @@ -238,11 +238,10 @@ pub type StakeAddrs = BTreeSet; pub type Delegations = KeyValuePairs; pub type RewardAccounts = KeyValuePairs; -// TODO: Destruct the tuple, define proper encoding. -#[derive(Debug, Encode, Decode, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone)] pub struct FilteredDelegsRewards { - #[n(0)] - pub delegs_rewards: (Delegations, RewardAccounts), + pub delegs: Delegations, + pub rewards: RewardAccounts, } pub type Pools = BTreeSet; From b31756598233b22a2a939fa79965c4cad0ed2e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20S=C3=A1nchez=20Terraf?= Date: Mon, 2 Dec 2024 18:08:48 -0300 Subject: [PATCH 3/5] Tests: FilteredDeleg... + better panics and imports --- pallas-network/tests/protocols.rs | 263 +++++++++++++++++++----------- 1 file changed, 169 insertions(+), 94 deletions(-) diff --git a/pallas-network/tests/protocols.rs b/pallas-network/tests/protocols.rs index fe8b2650..1e02aa48 100644 --- a/pallas-network/tests/protocols.rs +++ b/pallas-network/tests/protocols.rs @@ -1,28 +1,28 @@ -use std::collections::BTreeSet; -use std::fs; -use std::net::{Ipv4Addr, SocketAddrV4}; -use std::time::Duration; - +use std::{ + fs, collections::BTreeSet, net::{Ipv4Addr, SocketAddrV4}, + time::Duration, path::Path +}; use pallas_codec::utils::{AnyCbor, AnyUInt, Bytes, KeyValuePairs, TagWrap}; use pallas_crypto::hash::Hash; -use pallas_network::facades::{NodeClient, PeerClient, PeerServer}; -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, ChainBlockNumber, Fraction, Genesis, Snapshots, Stakes, SystemStart, UnitInterval, - Value, +use pallas_network::{ + facades::{NodeClient, PeerClient, PeerServer}, + multiplexer::{Bearer, Plexer}, + miniprotocols::{ + blockfetch::BlockRequest, + chainsync::{ClientRequest, HeaderContent, Tip}, + handshake::n2n::VersionData, + chainsync::{self, NextResponse}, + txsubmission::{EraTxBody, TxIdAndSize}, + localstate::ClientQueryRequest, + handshake, localstate, txsubmission, MAINNET_MAGIC, blockfetch, + Point, + }, }; -use pallas_network::miniprotocols::localstate::ClientQueryRequest; -use pallas_network::miniprotocols::txsubmission::{EraTxBody, TxIdAndSize}; -use pallas_network::miniprotocols::{ - blockfetch, - chainsync::{self, NextResponse}, - Point, +use pallas_network::miniprotocols::localstate::queries_v16::{ + self, Addr, Addrs, ChainBlockNumber, Fraction, Genesis, Snapshots, Stakes, + SystemStart, UnitInterval, Value, StakeAddr, }; -use pallas_network::miniprotocols::{handshake, localstate, txsubmission, MAINNET_MAGIC}; -use pallas_network::multiplexer::{Bearer, Plexer}; -use std::path::Path; +use hex::FromHex; use tokio::net::TcpListener; @@ -491,13 +491,14 @@ pub async fn local_state_query_server_and_client_happy_path() { // server receives query from client - let query: localstate::queries_v16::Request = + let query: 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:?}"), + x => panic!("(While expecting `GetSystemStart`) \ + Unexpected message from client: {x:?}"), }; - assert_eq!(query, localstate::queries_v16::Request::GetSystemStart); + assert_eq!(query, queries_v16::Request::GetSystemStart); assert_eq!(*server.statequery().state(), localstate::State::Querying); let result = AnyCbor::from_encode(SystemStart { @@ -511,13 +512,14 @@ pub async fn local_state_query_server_and_client_happy_path() { assert_eq!(*server.statequery().state(), localstate::State::Acquired); // server receives query from client - let query: localstate::queries_v16::Request = + let query: 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:?}"), + x => panic!("(While expecting `GetChainBlockNo`) \ + Unexpected message from client: {x:?}"), }; - assert_eq!(query, localstate::queries_v16::Request::GetChainBlockNo); + assert_eq!(query, queries_v16::Request::GetChainBlockNo); assert_eq!(*server.statequery().state(), localstate::State::Querying); let result = AnyCbor::from_encode(ChainBlockNumber { @@ -531,25 +533,26 @@ pub async fn local_state_query_server_and_client_happy_path() { // server receives query from client - let query: localstate::queries_v16::Request = + let query: 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:?}"), + x => panic!("(While expecting `GetStakeDistribution`) \ + Unexpected message from client: {x:?}"), }; assert_eq!( query, - localstate::queries_v16::Request::LedgerQuery( - localstate::queries_v16::LedgerQuery::BlockQuery( + queries_v16::Request::LedgerQuery( + queries_v16::LedgerQuery::BlockQuery( 5, - localstate::queries_v16::BlockQuery::GetStakeDistribution, + queries_v16::BlockQuery::GetStakeDistribution, ), ) ); assert_eq!(*server.statequery().state(), localstate::State::Querying); let fraction = Fraction { num: 10, dem: 20 }; - let pool = localstate::queries_v16::Pool { + let pool = queries_v16::Pool { stakes: fraction.clone(), hashes: b"pool1qv4qgv62s3ha74p0643nexee9zvcdydcyahqqnavhj90zheuykz" .to_vec() @@ -565,15 +568,16 @@ pub async fn local_state_query_server_and_client_happy_path() { let pools = KeyValuePairs::from(pools); - let result = AnyCbor::from_encode(localstate::queries_v16::StakeDistribution { pools }); + let result = AnyCbor::from_encode(queries_v16::StakeDistribution { pools }); server.statequery().send_result(result).await.unwrap(); // server receives query from client - let query: localstate::queries_v16::Request = + let query: 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:?}"), + x => panic!("(While expecting `GetUTxOByAddress`) \ + Unexpected message from client: {x:?}"), }; let addr_hex = @@ -585,10 +589,10 @@ pub async fn local_state_query_server_and_client_happy_path() { assert_eq!( query, - localstate::queries_v16::Request::LedgerQuery( - localstate::queries_v16::LedgerQuery::BlockQuery( + queries_v16::Request::LedgerQuery( + queries_v16::LedgerQuery::BlockQuery( 5, - localstate::queries_v16::BlockQuery::GetUTxOByAddress(addrs), + queries_v16::BlockQuery::GetUTxOByAddress(addrs), ), ) ); @@ -604,8 +608,8 @@ pub async fn local_state_query_server_and_client_happy_path() { let datum = hex::decode(hex_datum).unwrap().into(); let tag = TagWrap::<_, 24>::new(datum); let inline_datum = Some((1_u16, tag)); - let values = localstate::queries_v16::TransactionOutput::Current( - localstate::queries_v16::PostAlonsoTransactionOutput { + let values = queries_v16::TransactionOutput::Current( + queries_v16::PostAlonsoTransactionOutput { address: b"addr_test1vr80076l3x5uw6n94nwhgmv7ssgy6muzf47ugn6z0l92rhg2mgtu0" .to_vec() .into(), @@ -616,36 +620,36 @@ pub async fn local_state_query_server_and_client_happy_path() { ); let utxo = KeyValuePairs::from(vec![( - localstate::queries_v16::UTxO { + queries_v16::UTxO { transaction_id, index, }, values, )]); - let result = AnyCbor::from_encode(localstate::queries_v16::UTxOByAddress { utxo }); + let result = AnyCbor::from_encode(queries_v16::UTxOByAddress { utxo }); server.statequery().send_result(result).await.unwrap(); // server receives query from client - let query: localstate::queries_v16::Request = + let query: 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:?}"), + x => panic!("(While expecting `GetCurrentPParams`) \ + Unexpected message from client: {x:?}"), }; - assert_eq!( query, - localstate::queries_v16::Request::LedgerQuery( - localstate::queries_v16::LedgerQuery::BlockQuery( + queries_v16::Request::LedgerQuery( + queries_v16::LedgerQuery::BlockQuery( 5, - localstate::queries_v16::BlockQuery::GetCurrentPParams, + queries_v16::BlockQuery::GetCurrentPParams, ), ) ); assert_eq!(*server.statequery().state(), localstate::State::Querying); - let result = AnyCbor::from_encode(vec![localstate::queries_v16::ProtocolParam { + let result = AnyCbor::from_encode(vec![queries_v16::ProtocolParam { minfee_a: Some(44), minfee_b: Some(155381), max_block_body_size: Some(65536), @@ -684,18 +688,19 @@ pub async fn local_state_query_server_and_client_happy_path() { // server receives query from client - let query: localstate::queries_v16::Request = + let query: 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:?}"), + x => panic!("(While expecting `GetStakeSnapshots`) \ + Unexpected message from client: {x:?}"), }; assert_eq!( query, - localstate::queries_v16::Request::LedgerQuery( - localstate::queries_v16::LedgerQuery::BlockQuery( + queries_v16::Request::LedgerQuery( + queries_v16::LedgerQuery::BlockQuery( 5, - localstate::queries_v16::BlockQuery::GetStakeSnapshots(BTreeSet::new()), + queries_v16::BlockQuery::GetStakeSnapshots(BTreeSet::new()), ), ) ); @@ -723,22 +728,23 @@ pub async fn local_state_query_server_and_client_happy_path() { snapshot_stake_go_total: 0, }; - let result = AnyCbor::from_encode(localstate::queries_v16::StakeSnapshot { snapshots }); + let result = AnyCbor::from_encode(queries_v16::StakeSnapshot { snapshots }); server.statequery().send_result(result).await.unwrap(); // server receives query from client - let query: localstate::queries_v16::Request = + let query: 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:?}"), + x => panic!("(While expecting `GetGenesisConfig`) \ + Unexpected message from client: {x:?}"), }; assert_eq!( query, - localstate::queries_v16::Request::LedgerQuery( - localstate::queries_v16::LedgerQuery::BlockQuery( + queries_v16::Request::LedgerQuery( + queries_v16::LedgerQuery::BlockQuery( 5, - localstate::queries_v16::BlockQuery::GetGenesisConfig, + queries_v16::BlockQuery::GetGenesisConfig, ), ) ); @@ -772,7 +778,8 @@ pub async fn local_state_query_server_and_client_happy_path() { let maybe_point = match server.statequery().recv_while_acquired().await.unwrap() { ClientQueryRequest::ReAcquire(p) => p, - x => panic!("unexpected message from client: {x:?}"), + x => panic!("(While expecting `ReAcquire`) \ + Unexpected message from client: {x:?}"), }; assert_eq!(maybe_point, Some(Point::Specific(1337, vec![1, 2, 3]))); @@ -780,6 +787,42 @@ pub async fn local_state_query_server_and_client_happy_path() { server.statequery().send_acquired().await.unwrap(); + // server receives query from client + let query: queries_v16::Request = + match server.statequery().recv_while_acquired().await.unwrap() { + ClientQueryRequest::Query(q) => q.into_decode().unwrap(), + x => panic!("(While expecting `GetFilteredDeleg...`) \ + Unexpected message from client: {x:?}"), + }; + + let addr: Addr = <[u8; 28]>::from_hex( + "1218F563E4E10958FDABBDFB470B2F9D386215763CC89273D9BDFFFA" + ).unwrap().to_vec().into(); + let mut addrs = BTreeSet::new(); + addrs.insert(StakeAddr::from((0x00, addr.clone()))); + + assert_eq!( + query, + queries_v16::Request::LedgerQuery( + queries_v16::LedgerQuery::BlockQuery( + 6, + queries_v16::BlockQuery::GetFilteredDelegationsAndRewardAccounts(addrs), + ), + ) + ); + assert_eq!(*server.statequery().state(), localstate::State::Querying); + + let pool_addr: Addr = <[u8; 28]>::from_hex( + "1E3105F23F2AC91B3FB4C35FA4FE301421028E356E114944E902005B" + ).unwrap().to_vec().into(); + + let delegs = KeyValuePairs::from(vec![(StakeAddr::from((0, addr.clone())), pool_addr)]); + let rewards = KeyValuePairs::from(vec![(StakeAddr::from((0, addr)), 250526523)]); + let delegs_rewards = queries_v16::FilteredDelegsRewards { delegs, rewards }; + + let result = AnyCbor::from_encode(delegs_rewards); + server.statequery().send_result(result).await.unwrap(); + // server receives release from the client match server.statequery().recv_while_acquired().await.unwrap() { @@ -816,7 +859,7 @@ pub async fn local_state_query_server_and_client_happy_path() { // client sends a BlockQuery - let request = AnyCbor::from_encode(localstate::queries_v16::Request::GetSystemStart); + let request = AnyCbor::from_encode(queries_v16::Request::GetSystemStart); client.statequery().send_query(request).await.unwrap(); @@ -830,14 +873,14 @@ pub async fn local_state_query_server_and_client_happy_path() { assert_eq!( result, - localstate::queries_v16::SystemStart { + queries_v16::SystemStart { year: 2020, day_of_year: 1, picoseconds_of_day: 999999999, } ); - let request = AnyCbor::from_encode(localstate::queries_v16::Request::GetChainBlockNo); + let request = AnyCbor::from_encode(queries_v16::Request::GetChainBlockNo); client.statequery().send_query(request).await.unwrap(); let result: ChainBlockNumber = client @@ -850,22 +893,22 @@ pub async fn local_state_query_server_and_client_happy_path() { assert_eq!( result, - localstate::queries_v16::ChainBlockNumber { + queries_v16::ChainBlockNumber { slot_timeline: 1, // current block_number: 2143789, } ); - let request = AnyCbor::from_encode(localstate::queries_v16::Request::LedgerQuery( - localstate::queries_v16::LedgerQuery::BlockQuery( + let request = AnyCbor::from_encode(queries_v16::Request::LedgerQuery( + queries_v16::LedgerQuery::BlockQuery( 5, - localstate::queries_v16::BlockQuery::GetStakeDistribution, + queries_v16::BlockQuery::GetStakeDistribution, ), )); client.statequery().send_query(request).await.unwrap(); - let result: localstate::queries_v16::StakeDistribution = client + let result: queries_v16::StakeDistribution = client .statequery() .recv_while_querying() .await @@ -874,7 +917,7 @@ pub async fn local_state_query_server_and_client_happy_path() { .unwrap(); let fraction = Fraction { num: 10, dem: 20 }; - let pool = localstate::queries_v16::Pool { + let pool = queries_v16::Pool { stakes: fraction.clone(), hashes: b"pool1qv4qgv62s3ha74p0643nexee9zvcdydcyahqqnavhj90zheuykz" .to_vec() @@ -890,7 +933,7 @@ pub async fn local_state_query_server_and_client_happy_path() { let pools = KeyValuePairs::from(pools); - assert_eq!(result, localstate::queries_v16::StakeDistribution { pools }); + assert_eq!(result, queries_v16::StakeDistribution { pools }); let addr_hex = "981D186018CE18F718FB185F188918A918C7186A186518AC18DD1874186D189E188410184D186F1882184D187D18C4184F1842187F18CA18A118DD" @@ -899,16 +942,16 @@ pub async fn local_state_query_server_and_client_happy_path() { let addr: Addr = addr.to_vec().into(); let addrs: Addrs = Vec::from([addr]); - let request = AnyCbor::from_encode(localstate::queries_v16::Request::LedgerQuery( - localstate::queries_v16::LedgerQuery::BlockQuery( + let request = AnyCbor::from_encode(queries_v16::Request::LedgerQuery( + queries_v16::LedgerQuery::BlockQuery( 5, - localstate::queries_v16::BlockQuery::GetUTxOByAddress(addrs), + queries_v16::BlockQuery::GetUTxOByAddress(addrs), ), )); client.statequery().send_query(request).await.unwrap(); - let result: localstate::queries_v16::UTxOByAddress = client + let result: queries_v16::UTxOByAddress = client .statequery() .recv_while_querying() .await @@ -925,8 +968,8 @@ pub async fn local_state_query_server_and_client_happy_path() { let datum = hex::decode(hex_datum).unwrap().into(); let tag = TagWrap::<_, 24>::new(datum); let inline_datum = Some((1_u16, tag)); - let values = localstate::queries_v16::TransactionOutput::Current( - localstate::queries_v16::PostAlonsoTransactionOutput { + let values = queries_v16::TransactionOutput::Current( + queries_v16::PostAlonsoTransactionOutput { address: b"addr_test1vr80076l3x5uw6n94nwhgmv7ssgy6muzf47ugn6z0l92rhg2mgtu0" .to_vec() .into(), @@ -937,25 +980,25 @@ pub async fn local_state_query_server_and_client_happy_path() { ); let utxo = KeyValuePairs::from(vec![( - localstate::queries_v16::UTxO { + queries_v16::UTxO { transaction_id, index, }, values, )]); - assert_eq!(result, localstate::queries_v16::UTxOByAddress { utxo }); + assert_eq!(result, queries_v16::UTxOByAddress { utxo }); - let request = AnyCbor::from_encode(localstate::queries_v16::Request::LedgerQuery( - localstate::queries_v16::LedgerQuery::BlockQuery( + let request = AnyCbor::from_encode(queries_v16::Request::LedgerQuery( + queries_v16::LedgerQuery::BlockQuery( 5, - localstate::queries_v16::BlockQuery::GetCurrentPParams, + queries_v16::BlockQuery::GetCurrentPParams, ), )); client.statequery().send_query(request).await.unwrap(); - let result: Vec = client + let result: Vec = client .statequery() .recv_while_querying() .await @@ -965,7 +1008,7 @@ pub async fn local_state_query_server_and_client_happy_path() { assert_eq!( result, - vec![localstate::queries_v16::ProtocolParam { + vec![queries_v16::ProtocolParam { minfee_a: Some(44), minfee_b: Some(155381), max_block_body_size: Some(65536), @@ -1001,16 +1044,16 @@ pub async fn local_state_query_server_and_client_happy_path() { }] ); - let request = AnyCbor::from_encode(localstate::queries_v16::Request::LedgerQuery( - localstate::queries_v16::LedgerQuery::BlockQuery( + let request = AnyCbor::from_encode(queries_v16::Request::LedgerQuery( + queries_v16::LedgerQuery::BlockQuery( 5, - localstate::queries_v16::BlockQuery::GetStakeSnapshots(BTreeSet::new()), + queries_v16::BlockQuery::GetStakeSnapshots(BTreeSet::new()), ), )); client.statequery().send_query(request).await.unwrap(); - let result: localstate::queries_v16::StakeSnapshot = client + let result: queries_v16::StakeSnapshot = client .statequery() .recv_while_querying() .await @@ -1039,12 +1082,12 @@ pub async fn local_state_query_server_and_client_happy_path() { snapshot_stake_go_total: 0, }; - assert_eq!(result, localstate::queries_v16::StakeSnapshot { snapshots }); + assert_eq!(result, queries_v16::StakeSnapshot { snapshots }); - let request = AnyCbor::from_encode(localstate::queries_v16::Request::LedgerQuery( - localstate::queries_v16::LedgerQuery::BlockQuery( + let request = AnyCbor::from_encode(queries_v16::Request::LedgerQuery( + queries_v16::LedgerQuery::BlockQuery( 5, - localstate::queries_v16::BlockQuery::GetGenesisConfig, + queries_v16::BlockQuery::GetGenesisConfig, ), )); @@ -1084,9 +1127,41 @@ pub async fn local_state_query_server_and_client_happy_path() { .send_reacquire(Some(Point::Specific(1337, vec![1, 2, 3]))) .await .unwrap(); - + client.statequery().recv_while_acquiring().await.unwrap(); + let addr: Addr = <[u8; 28]>::from_hex( + "1218F563E4E10958FDABBDFB470B2F9D386215763CC89273D9BDFFFA" + ).unwrap().to_vec().into(); + let mut addrs = BTreeSet::new(); + addrs.insert(StakeAddr::from((0x00, addr.clone()))); + + let request = AnyCbor::from_encode(queries_v16::Request::LedgerQuery( + queries_v16::LedgerQuery::BlockQuery( + 6, + queries_v16::BlockQuery::GetFilteredDelegationsAndRewardAccounts(addrs), + ), + )); + client.statequery().send_query(request).await.unwrap(); + + let result: queries_v16::FilteredDelegsRewards = client + .statequery() + .recv_while_querying() + .await + .unwrap() + .into_decode() + .unwrap(); + + let pool_addr: Addr = <[u8; 28]>::from_hex( + "1E3105F23F2AC91B3FB4C35FA4FE301421028E356E114944E902005B" + ).unwrap().to_vec().into(); + + let delegs = KeyValuePairs::from(vec![(StakeAddr::from((0, addr.clone())), pool_addr)]); + let rewards = KeyValuePairs::from(vec![(StakeAddr::from((0, addr)), 250526523)]); + let delegs_rewards = queries_v16::FilteredDelegsRewards { delegs, rewards }; + + assert_eq!(result, delegs_rewards); + client.statequery().send_release().await.unwrap(); client.statequery().send_done().await.unwrap(); From 8cf6c6711499d87e7fb8b14a4ab69b73e7d79118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20S=C3=A1nchez=20Terraf?= Date: Tue, 3 Dec 2024 15:42:04 -0300 Subject: [PATCH 4/5] Example with two stake addresses --- examples/n2c-miniprotocols/src/main.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/examples/n2c-miniprotocols/src/main.rs b/examples/n2c-miniprotocols/src/main.rs index 1db9ec89..6373e651 100644 --- a/examples/n2c-miniprotocols/src/main.rs +++ b/examples/n2c-miniprotocols/src/main.rs @@ -33,13 +33,19 @@ async fn do_localstate_query(client: &mut NodeClient) { let era = queries_v16::get_current_era(client).await.unwrap(); info!("result: {:?}", era); - // Getting delegation and rewards for preprod stake address - // `stake_test1uqfp3atrunssjk8a4w7lk3ct97wnscs4wc7v3ynnmx7ll7s2ea9p2` + // Getting delegation and rewards for preprod stake addresses: + let mut addrs = BTreeSet::new(); + // 1. `stake_test1uqfp3atrunssjk8a4w7lk3ct97wnscs4wc7v3ynnmx7ll7s2ea9p2` let addr: Addr = <[u8; 28]>::from_hex( "1218F563E4E10958FDABBDFB470B2F9D386215763CC89273D9BDFFFA" ).unwrap().to_vec().into(); - let mut addrs = BTreeSet::new(); addrs.insert(StakeAddr::from((0x00, addr))); + // 2. `stake_test1uq2pnumhfrnnse0t3uwj4n0lhz58ehfhkdhr64ylptjhq9cyney6d` + let addr: Addr = <[u8; 28]>::from_hex( + "1419F37748E73865EB8F1D2ACDFFB8A87CDD37B36E3D549F0AE57017" + ).unwrap().to_vec().into(); + addrs.insert(StakeAddr::from((0x00, addr))); + let result = queries_v16::get_filtered_delegations_rewards(client, era, addrs) .await .unwrap(); From dddcebb3a04ac1c37b6749237e0996846ee59770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20S=C3=A1nchez=20Terraf?= Date: Tue, 3 Dec 2024 15:45:21 -0300 Subject: [PATCH 5/5] CBOR of query/responses from real use case, less repetition --- pallas-network/tests/protocols.rs | 42 +++++++++++++------------------ 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/pallas-network/tests/protocols.rs b/pallas-network/tests/protocols.rs index 1e02aa48..152f9370 100644 --- a/pallas-network/tests/protocols.rs +++ b/pallas-network/tests/protocols.rs @@ -788,9 +788,9 @@ pub async fn local_state_query_server_and_client_happy_path() { server.statequery().send_acquired().await.unwrap(); // server receives query from client - let query: queries_v16::Request = + let query: Vec = match server.statequery().recv_while_acquired().await.unwrap() { - ClientQueryRequest::Query(q) => q.into_decode().unwrap(), + ClientQueryRequest::Query(q) => q.unwrap(), x => panic!("(While expecting `GetFilteredDeleg...`) \ Unexpected message from client: {x:?}"), }; @@ -798,18 +798,12 @@ pub async fn local_state_query_server_and_client_happy_path() { let addr: Addr = <[u8; 28]>::from_hex( "1218F563E4E10958FDABBDFB470B2F9D386215763CC89273D9BDFFFA" ).unwrap().to_vec().into(); - let mut addrs = BTreeSet::new(); - addrs.insert(StakeAddr::from((0x00, addr.clone()))); - - assert_eq!( - query, - queries_v16::Request::LedgerQuery( - queries_v16::LedgerQuery::BlockQuery( - 6, - queries_v16::BlockQuery::GetFilteredDelegationsAndRewardAccounts(addrs), - ), - ) - ); + // CBOR got from preprod node. Mind the stripped `8203`. + let cbor_query = Vec::::from_hex( + "820082008206820a818200581c1218f563e4e10958fdabbdfb470b2f9d386215763cc89273d9bdfffa" + ).unwrap(); + + assert_eq!(query, cbor_query); assert_eq!(*server.statequery().state(), localstate::State::Querying); let pool_addr: Addr = <[u8; 28]>::from_hex( @@ -1144,23 +1138,21 @@ pub async fn local_state_query_server_and_client_happy_path() { )); client.statequery().send_query(request).await.unwrap(); - let result: queries_v16::FilteredDelegsRewards = client + let result: Vec = client .statequery() .recv_while_querying() .await .unwrap() - .into_decode() .unwrap(); - - let pool_addr: Addr = <[u8; 28]>::from_hex( - "1E3105F23F2AC91B3FB4C35FA4FE301421028E356E114944E902005B" - ).unwrap().to_vec().into(); - - let delegs = KeyValuePairs::from(vec![(StakeAddr::from((0, addr.clone())), pool_addr)]); - let rewards = KeyValuePairs::from(vec![(StakeAddr::from((0, addr)), 250526523)]); - let delegs_rewards = queries_v16::FilteredDelegsRewards { delegs, rewards }; - assert_eq!(result, delegs_rewards); + let delegs_rewards_cbor = Vec::::from_hex( + "8182a18200581c1218f563e4e10958fdabbdfb470b2f9d386215763cc89273d9bd\ + fffa581c1e3105f23f2ac91b3fb4c35fa4fe301421028e356e114944e902005ba1\ + 8200581c1218f563e4e10958fdabbdfb470b2f9d386215763cc89273d9bdfffa1a\ + 0eeebb3b" + ).unwrap(); + + assert_eq!(result, delegs_rewards_cbor); client.statequery().send_release().await.unwrap();