From cfc840f1b2d271a68bc868ea26429d084635a02e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20S=C3=A1nchez=20Terraf?= Date: Wed, 11 Dec 2024 22:15:07 -0300 Subject: [PATCH] feat(network): implement `GetFilteredDelegationsAndRewardAccounts` query (#552) Signed-off-by: Santiago Carmuega Co-authored-by: Santiago Carmuega --- examples/n2c-miniprotocols/src/main.rs | 24 +- .../src/miniprotocols/localstate/client.rs | 1 + .../localstate/queries_v16/codec.rs | 28 +- .../localstate/queries_v16/mod.rs | 40 ++- pallas-network/tests/protocols.rs | 255 +++++++++++------- 5 files changed, 249 insertions(+), 99 deletions(-) diff --git a/examples/n2c-miniprotocols/src/main.rs b/examples/n2c-miniprotocols/src/main.rs index f3cbb7c3..5e5a9edd 100644 --- a/examples/n2c-miniprotocols/src/main.rs +++ b/examples/n2c-miniprotocols/src/main.rs @@ -7,9 +7,7 @@ use pallas::{ facades::NodeClient, miniprotocols::{ chainsync, - localstate::queries_v16::{ - self, Addr, Addrs, TransactionInput, - }, + localstate::queries_v16::{self, Addr, Addrs, StakeAddr, TransactionInput}, Point, PRE_PRODUCTION_MAGIC, }, }, @@ -18,6 +16,8 @@ use pallas::{ use tracing::info; use hex::FromHex; +use hex::FromHex; + async fn do_localstate_query(client: &mut NodeClient) { let client = client.statequery(); @@ -46,6 +46,24 @@ 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 addresses: + let mut addrs = BTreeSet::new(); + // 1. `stake_test1uqfp3atrunssjk8a4w7lk3ct97wnscs4wc7v3ynnmx7ll7s2ea9p2` + let addr: Addr = <[u8; 28]>::from_hex( + "1218F563E4E10958FDABBDFB470B2F9D386215763CC89273D9BDFFFA" + ).unwrap().to_vec().into(); + 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(); + 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 be30f3a5..2cf30a9a 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), @@ -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 409099bd..6653d3ab 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,30 @@ 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; + +#[derive(Debug, PartialEq, Clone)] +pub struct FilteredDelegsRewards { + pub delegs: Delegations, + pub rewards: RewardAccounts, +} + pub type Pools = BTreeSet; pub type Coin = AnyUInt; @@ -494,6 +518,20 @@ 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) +} + /// Get a subset of the UTxO, filtered by transaction input. pub async fn get_utxo_by_txin( client: &mut Client, diff --git a/pallas-network/tests/protocols.rs b/pallas-network/tests/protocols.rs index 9c807e36..e5ed0dc3 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,36 @@ pub async fn local_state_query_server_and_client_happy_path() { server.statequery().send_acquired().await.unwrap(); + // server receives query from client + let query: Vec = + match server.statequery().recv_while_acquired().await.unwrap() { + ClientQueryRequest::Query(q) => q.unwrap(), + x => panic!("(While expecting `GetFilteredDeleg...`) \ + Unexpected message from client: {x:?}"), + }; + + let addr: Addr = <[u8; 28]>::from_hex( + "1218F563E4E10958FDABBDFB470B2F9D386215763CC89273D9BDFFFA" + ).unwrap().to_vec().into(); + // 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( + "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 +853,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 +867,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 +887,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 +911,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 +927,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 +936,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 +962,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 +974,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 +1002,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 +1038,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 +1076,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 +1121,39 @@ 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: Vec = client + .statequery() + .recv_while_querying() + .await + .unwrap() + .unwrap(); + + let delegs_rewards_cbor = Vec::::from_hex( + "8182a18200581c1218f563e4e10958fdabbdfb470b2f9d386215763cc89273d9bd\ + fffa581c1e3105f23f2ac91b3fb4c35fa4fe301421028e356e114944e902005ba1\ + 8200581c1218f563e4e10958fdabbdfb470b2f9d386215763cc89273d9bdfffa1a\ + 0eeebb3b" + ).unwrap(); + + assert_eq!(result, delegs_rewards_cbor); + client.statequery().send_release().await.unwrap(); client.statequery().send_done().await.unwrap();