feat(network): implement get stake pool parameters query (#554)

This commit is contained in:
Pedro Sánchez Terraf 2024-12-17 13:04:48 -03:00 committed by GitHub
parent b483b3a17a
commit 914631adcb
5 changed files with 375 additions and 8 deletions

View file

@ -1,9 +1,9 @@
use hex::FromHex;
use pallas_codec::utils::{AnyCbor, AnyUInt, Bytes, KeyValuePairs, TagWrap};
use pallas_codec::utils::{AnyCbor, AnyUInt, Bytes, KeyValuePairs, Nullable, TagWrap};
use pallas_crypto::hash::Hash;
use pallas_network::miniprotocols::localstate::queries_v16::{
self, Addr, Addrs, ChainBlockNumber, Fraction, GenesisConfig, RationalNumber, Snapshots,
StakeAddr, Stakes, SystemStart, UnitInterval, Value,
self, Addr, Addrs, ChainBlockNumber, Fraction, GenesisConfig, PoolMetadata, PoolParams,
RationalNumber, Relay, Snapshots, StakeAddr, Stakes, SystemStart, UnitInterval, Value,
};
use pallas_network::{
facades::{NodeClient, PeerClient, PeerServer},
@ -23,10 +23,11 @@ use pallas_network::{
multiplexer::{Bearer, Plexer},
};
use std::{
collections::BTreeSet,
collections::{BTreeMap, BTreeSet},
fs,
net::{Ipv4Addr, SocketAddrV4},
path::Path,
str::FromStr,
time::Duration,
};
@ -1175,6 +1176,181 @@ pub async fn local_state_query_server_and_client_happy_path() {
tokio::try_join!(client, server).unwrap();
}
#[cfg(unix)]
#[tokio::test]
pub async fn local_state_query_server_and_client_happy_path2() {
let server = tokio::spawn({
async move {
// server setup
let socket_path = Path::new("node2.socket");
if socket_path.exists() {
fs::remove_file(socket_path).unwrap();
}
let listener = UnixListener::bind(socket_path).unwrap();
let mut server = pallas_network::facades::NodeServer::accept(&listener, 0)
.await
.unwrap();
// wait for acquire request from client
let maybe_acquire = server.statequery().recv_while_idle().await.unwrap();
assert!(maybe_acquire.is_some());
assert_eq!(*server.statequery().state(), localstate::State::Acquiring);
server.statequery().send_acquired().await.unwrap();
assert_eq!(*server.statequery().state(), localstate::State::Acquired);
// server receives query from client
let query: Vec<u8> = match server.statequery().recv_while_acquired().await.unwrap() {
ClientQueryRequest::Query(q) => q.unwrap(),
x => panic!(
"While expecting `GetStakePoolParams`) \
Unexpected message from client: {x:?}"
),
};
// CBOR got from preprod node. Mind the stripped `82038200`.
let cbor_query = Vec::<u8>::from_hex(
"820082068211d9010281581cfdb5834ba06eb4baafd50550d2dc9b3742d2c52cc5ee65bf8673823b",
)
.unwrap();
assert_eq!(query, cbor_query);
assert_eq!(*server.statequery().state(), localstate::State::Querying);
let pool_id: Bytes =
Vec::<u8>::from_hex("fdb5834ba06eb4baafd50550d2dc9b3742d2c52cc5ee65bf8673823b")
.unwrap()
.into();
let operator = pool_id.clone();
let vrf_keyhash = Vec::<u8>::from_hex(
"2A6A3D82278A554E9C1777C427BF0397FAF5CD7734900752D698E57679CC523F",
)
.unwrap()
.into();
let reward_account =
Vec::<u8>::from_hex("E01AEF81CBAB75DB2DE0FE3885332EBE67C34EB1ADBF43BB2408BA3981")
.unwrap()
.into();
let pool_metadata: Nullable<PoolMetadata> = Some(PoolMetadata {
url: "https://csouza.me/jp-pp.json".to_string(),
hash: Hash::<32>::from_str(
"C9623111188D0BF90E8305E40AA91A040D8036C7813A4ECA44E06FA0A1A893A6",
)
.unwrap(),
})
.into();
let pool_params = PoolParams {
operator,
vrf_keyhash,
pledge: AnyUInt::U64(5_000_000_000),
cost: AnyUInt::U32(340_000_000),
margin: localstate::queries_v16::RationalNumber {
numerator: 3,
denominator: 40,
},
reward_account,
pool_owners: BTreeSet::from([Bytes::from(
Vec::<u8>::from_hex("1AEF81CBAB75DB2DE0FE3885332EBE67C34EB1ADBF43BB2408BA3981")
.unwrap(),
)])
.into(),
relays: vec![Relay::SingleHostName(
Some(3001).into(),
"preprod.junglestakepool.com".to_string(),
)],
pool_metadata,
};
// The map is inside a (singleton) array
let result = AnyCbor::from_encode([BTreeMap::from([(pool_id, pool_params)])]);
server.statequery().send_result(result).await.unwrap();
assert_eq!(*server.statequery().state(), localstate::State::Acquired);
match server.statequery().recv_while_acquired().await.unwrap() {
ClientQueryRequest::Release => (),
x => panic!("unexpected message from client: {x:?}"),
};
let next_request = server.statequery().recv_while_idle().await.unwrap();
assert!(next_request.is_none());
assert_eq!(*server.statequery().state(), localstate::State::Done);
}
});
let client = tokio::spawn(async move {
tokio::time::sleep(Duration::from_secs(1)).await;
// client setup
let socket_path = "node2.socket";
let mut client = NodeClient::connect(socket_path, 0).await.unwrap();
// client sends acquire
client
.statequery()
.send_acquire(Some(Point::Origin))
.await
.unwrap();
client.statequery().recv_while_acquiring().await.unwrap();
assert_eq!(*client.statequery().state(), localstate::State::Acquired);
// client sends a BlockQuery
let pool_id1 = "fdb5834ba06eb4baafd50550d2dc9b3742d2c52cc5ee65bf8673823b";
let pool_id1: Bytes = Vec::<u8>::from_hex(pool_id1).unwrap().into();
let mut pools = BTreeSet::<Bytes>::new();
pools.insert(pool_id1);
let request = AnyCbor::from_encode(localstate::queries_v16::LedgerQuery::BlockQuery(
6,
localstate::queries_v16::BlockQuery::GetStakePoolParams(pools.into()),
));
client.statequery().send_query(request).await.unwrap();
let result: Vec<u8> = client
.statequery()
.recv_while_querying()
.await
.unwrap()
.unwrap();
// CBOR got from preprod node.
let pool_params_cbor = Vec::<u8>::from_hex(
"81a1581cfdb5834ba06eb4baafd50550d2dc9b3742d2c52cc5ee65bf8673823b8958\
1cfdb5834ba06eb4baafd50550d2dc9b3742d2c52cc5ee65bf8673823b58202a6a3d\
82278a554e9c1777c427bf0397faf5cd7734900752d698e57679cc523f1b00000001\
2a05f2001a1443fd00d81e82031828581de01aef81cbab75db2de0fe3885332ebe67\
c34eb1adbf43bb2408ba3981d9010281581c1aef81cbab75db2de0fe3885332ebe67\
c34eb1adbf43bb2408ba3981818301190bb9781b70726570726f642e6a756e676c65\
7374616b65706f6f6c2e636f6d82781c68747470733a2f2f63736f757a612e6d652f\
6a702d70702e6a736f6e5820c9623111188d0bf90e8305e40aa91a040d8036c7813a\
4eca44e06fa0a1a893a6",
)
.unwrap();
assert_eq!(result, pool_params_cbor);
client.statequery().send_release().await.unwrap();
client.statequery().send_done().await.unwrap();
});
tokio::try_join!(client, server).unwrap();
}
#[tokio::test]
#[ignore]
pub async fn txsubmission_server_and_client_happy_path_n2n() {