extended the paged query client

This commit is contained in:
Jędrzej Stuczyński
2023-07-31 17:43:46 +01:00
parent e911e9e7ee
commit a4f415cb45
3 changed files with 86 additions and 302 deletions
@@ -43,13 +43,7 @@ pub struct Config {
nyxd_url: Url,
// TODO: until refactored, this is a dead field under some features
#[allow(dead_code)]
nyxd_config: nyxd::Config,
mixnode_page_limit: Option<u32>,
gateway_page_limit: Option<u32>,
mixnode_delegations_page_limit: Option<u32>,
rewarded_set_page_limit: Option<u32>,
}
impl Config {
@@ -74,10 +68,6 @@ impl Config {
.parse()
.map_err(ValidatorClientError::MalformedUrlProvided)?,
nyxd_config: nyxd::Config::try_from_nym_network_details(details)?,
mixnode_page_limit: None,
gateway_page_limit: None,
mixnode_delegations_page_limit: None,
rewarded_set_page_limit: None,
})
}
@@ -93,38 +83,9 @@ impl Config {
self.nyxd_url = nyxd_url;
self
}
pub fn with_mixnode_page_limit(mut self, limit: Option<u32>) -> Config {
self.mixnode_page_limit = limit;
self
}
pub fn with_gateway_page_limit(mut self, limit: Option<u32>) -> Config {
self.gateway_page_limit = limit;
self
}
pub fn with_mixnode_delegations_page_limit(mut self, limit: Option<u32>) -> Config {
self.mixnode_delegations_page_limit = limit;
self
}
pub fn with_rewarded_set_page_limit(mut self, limit: Option<u32>) -> Config {
self.rewarded_set_page_limit = limit;
self
}
}
pub struct Client<C, S = NoSigner> {
#[deprecated]
mixnode_page_limit: Option<u32>,
#[deprecated]
gateway_page_limit: Option<u32>,
#[deprecated]
mixnode_delegations_page_limit: Option<u32>,
#[deprecated]
rewarded_set_page_limit: Option<u32>,
// ideally they would have been read-only, but unfortunately rust doesn't have such features
pub nym_api: nym_api::Client,
pub nyxd: NyxdClient<C, S>,
@@ -144,10 +105,6 @@ impl Client<HttpClient, DirectSecp256k1HdWallet> {
)?;
Ok(Client {
mixnode_page_limit: config.mixnode_page_limit,
gateway_page_limit: config.gateway_page_limit,
mixnode_delegations_page_limit: config.mixnode_delegations_page_limit,
rewarded_set_page_limit: config.rewarded_set_page_limit,
nym_api: nym_api_client,
nyxd: nyxd_client,
})
@@ -172,10 +129,6 @@ impl Client<HttpClient> {
NyxdClient::connect(config.nyxd_config.clone(), config.nyxd_url.as_str())?;
Ok(Client {
mixnode_page_limit: config.mixnode_page_limit,
gateway_page_limit: config.gateway_page_limit,
mixnode_delegations_page_limit: config.mixnode_delegations_page_limit,
rewarded_set_page_limit: config.rewarded_set_page_limit,
nym_api: nym_api_client,
nyxd: nyxd_client,
})
@@ -192,11 +145,13 @@ impl<C> Client<C> {
// use case: somebody initialised client without a contract in order to upload and initialise one
// and now they want to actually use it without making new client
#[deprecated]
pub fn set_mixnet_contract_address(&mut self, mixnet_contract_address: cosmrs::AccountId) {
self.nyxd
.set_mixnet_contract_address(mixnet_contract_address)
}
#[deprecated]
pub fn get_mixnet_contract_address(&self) -> cosmrs::AccountId {
// TODO: deal with the expect
self.nyxd
@@ -204,249 +159,6 @@ impl<C> Client<C> {
.expect("mixnet contract address is not available")
.clone()
}
//
// pub async fn get_all_nyxd_unbonded_mixnodes(
// &self,
// ) -> Result<Vec<(MixId, UnbondedMixnode)>, ValidatorClientError>
// where
// C: CosmWasmClient + Sync + Send,
// {
// let mut mixnodes = Vec::new();
// let mut start_after = None;
// loop {
// let mut paged_response = self
// .nyxd
// .get_unbonded_paged(self.mixnode_page_limit, start_after.take())
// .await?;
// mixnodes.append(&mut paged_response.nodes);
//
// if let Some(start_after_res) = paged_response.start_next_after {
// start_after = Some(start_after_res)
// } else {
// break;
// }
// }
//
// Ok(mixnodes)
// }
//
// pub async fn get_all_nyxd_unbonded_mixnodes_by_owner(
// &self,
// owner: &cosmrs::AccountId,
// ) -> Result<Vec<(MixId, UnbondedMixnode)>, ValidatorClientError>
// where
// C: CosmWasmClient + Sync + Send,
// {
// let mut mixnodes = Vec::new();
// let mut start_after = None;
// loop {
// let mut paged_response = self
// .nyxd
// .get_unbonded_by_owner_paged(owner, self.mixnode_page_limit, start_after.take())
// .await?;
// mixnodes.append(&mut paged_response.nodes);
//
// if let Some(start_after_res) = paged_response.start_next_after {
// start_after = Some(start_after_res)
// } else {
// break;
// }
// }
//
// Ok(mixnodes)
// }
//
// pub async fn get_all_nyxd_unbonded_mixnodes_by_identity(
// &self,
// identity_key: String,
// ) -> Result<Vec<(MixId, UnbondedMixnode)>, ValidatorClientError>
// where
// C: CosmWasmClient + Sync + Send,
// {
// let mut mixnodes = Vec::new();
// let mut start_after = None;
// loop {
// let mut paged_response = self
// .nyxd
// .get_unbonded_by_identity_paged(
// identity_key.clone(),
// self.mixnode_page_limit,
// start_after.take(),
// )
// .await?;
// mixnodes.append(&mut paged_response.nodes);
//
// if let Some(start_after_res) = paged_response.start_next_after {
// start_after = Some(start_after_res)
// } else {
// break;
// }
// }
//
// Ok(mixnodes)
// }
//
// pub async fn get_all_nyxd_gateways(&self) -> Result<Vec<GatewayBond>, ValidatorClientError>
// where
// C: CosmWasmClient + Sync + Send,
// {
// let mut gateways = Vec::new();
// let mut start_after = None;
// loop {
// let mut paged_response = self
// .nyxd
// .get_gateways_paged(start_after.take(), self.gateway_page_limit)
// .await?;
// gateways.append(&mut paged_response.nodes);
//
// if let Some(start_after_res) = paged_response.start_next_after {
// start_after = Some(start_after_res)
// } else {
// break;
// }
// }
//
// Ok(gateways)
// }
//
// pub async fn get_all_nyxd_single_mixnode_delegations(
// &self,
// mix_id: MixId,
// ) -> Result<Vec<Delegation>, ValidatorClientError>
// where
// C: CosmWasmClient + Sync + Send,
// {
// let mut delegations = Vec::new();
// let mut start_after = None;
// loop {
// let mut paged_response = self
// .nyxd
// .get_mixnode_delegations_paged(
// mix_id,
// start_after.take(),
// self.mixnode_delegations_page_limit,
// )
// .await?;
// delegations.append(&mut paged_response.delegations);
//
// if let Some(start_after_res) = paged_response.start_next_after {
// start_after = Some(start_after_res)
// } else {
// break;
// }
// }
//
// Ok(delegations)
// }
//
// pub async fn get_all_delegator_delegations(
// &self,
// delegation_owner: &cosmrs::AccountId,
// ) -> Result<Vec<Delegation>, ValidatorClientError>
// where
// C: CosmWasmClient + Sync + Send,
// {
// let mut delegations = Vec::new();
// let mut start_after = None;
// loop {
// let mut paged_response = self
// .nyxd
// .get_delegator_delegations_paged(
// delegation_owner.to_string(),
// start_after.take(),
// self.mixnode_delegations_page_limit,
// )
// .await?;
// delegations.append(&mut paged_response.delegations);
//
// if let Some(start_after_res) = paged_response.start_next_after {
// start_after = Some(start_after_res)
// } else {
// break;
// }
// }
//
// Ok(delegations)
// }
//
// pub async fn get_all_network_delegations(&self) -> Result<Vec<Delegation>, ValidatorClientError>
// where
// C: CosmWasmClient + Sync + Send,
// {
// let mut delegations = Vec::new();
// let mut start_after = None;
// loop {
// let mut paged_response = self
// .nyxd
// .get_all_network_delegations_paged(
// start_after.take(),
// self.mixnode_delegations_page_limit,
// )
// .await?;
// delegations.append(&mut paged_response.delegations);
//
// if let Some(start_after_res) = paged_response.start_next_after {
// start_after = Some(start_after_res)
// } else {
// break;
// }
// }
//
// Ok(delegations)
// }
//
// pub async fn get_all_nyxd_pending_epoch_events(
// &self,
// ) -> Result<Vec<PendingEpochEvent>, ValidatorClientError>
// where
// C: CosmWasmClient + Sync + Send,
// {
// let mut events = Vec::new();
// let mut start_after = None;
//
// loop {
// let mut paged_response = self
// .nyxd
// .get_pending_epoch_events_paged(start_after.take(), self.rewarded_set_page_limit)
// .await?;
// events.append(&mut paged_response.events);
//
// if let Some(start_after_res) = paged_response.start_next_after {
// start_after = Some(start_after_res)
// } else {
// break;
// }
// }
//
// Ok(events)
// }
//
// pub async fn get_all_nyxd_pending_interval_events(
// &self,
// ) -> Result<Vec<PendingIntervalEvent>, ValidatorClientError>
// where
// C: CosmWasmClient + Sync + Send,
// {
// let mut events = Vec::new();
// let mut start_after = None;
//
// loop {
// let mut paged_response = self
// .nyxd
// .get_pending_interval_events_paged(start_after.take(), self.rewarded_set_page_limit)
// .await?;
// events.append(&mut paged_response.events);
//
// if let Some(start_after_res) = paged_response.start_next_after {
// start_after = Some(start_after_res)
// } else {
// break;
// }
// }
//
// Ok(events)
// }
}
// validator-api wrappers
@@ -8,6 +8,7 @@ use crate::nyxd::CosmWasmClient;
use async_trait::async_trait;
use cosmrs::AccountId;
use nym_contracts_common::signing::Nonce;
use nym_contracts_common::IdentityKeyRef;
use nym_mixnet_contract_common::delegation::{MixNodeDelegationResponse, OwnerProxySubKey};
use nym_mixnet_contract_common::families::{Family, FamilyHead};
use nym_mixnet_contract_common::mixnode::{
@@ -20,16 +21,16 @@ use nym_mixnet_contract_common::rewarding::{
};
use nym_mixnet_contract_common::{
delegation, ContractBuildInformation, ContractState, ContractStateParams,
CurrentIntervalResponse, EpochEventId, EpochStatus, FamilyByHeadResponse,
FamilyByLabelResponse, FamilyMembersByHeadResponse, FamilyMembersByLabelResponse,
CurrentIntervalResponse, Delegation, EpochEventId, EpochStatus, FamilyByHeadResponse,
FamilyByLabelResponse, FamilyMembersByHeadResponse, FamilyMembersByLabelResponse, GatewayBond,
GatewayBondResponse, GatewayOwnershipResponse, IdentityKey, IntervalEventId, LayerDistribution,
MixId, MixNodeBond, MixNodeDetails, MixOwnershipResponse, MixnodeDetailsByIdentityResponse,
MixnodeDetailsResponse, NumberOfPendingEventsResponse, PagedAllDelegationsResponse,
PagedDelegatorDelegationsResponse, PagedFamiliesResponse, PagedGatewayResponse,
PagedMembersResponse, PagedMixNodeDelegationsResponse, PagedMixnodeBondsResponse,
PagedRewardedSetResponse, PendingEpochEventResponse, PendingEpochEventsResponse,
MixId, MixNodeBond, MixNodeDetails, MixOwnershipResponse, MixnodeDetailsResponse,
NumberOfPendingEventsResponse, PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse,
PagedFamiliesResponse, PagedGatewayResponse, PagedMembersResponse,
PagedMixNodeDelegationsResponse, PagedMixnodeBondsResponse, PagedRewardedSetResponse,
PendingEpochEvent, PendingEpochEventResponse, PendingEpochEventsResponse, PendingIntervalEvent,
PendingIntervalEventResponse, PendingIntervalEventsResponse, QueryMsg as MixnetQueryMsg,
RewardedSetNodeStatus,
RewardedSetNodeStatus, UnbondedMixnode,
};
use serde::Deserialize;
@@ -166,12 +167,12 @@ pub trait MixnetQueryClient {
async fn get_unbonded_by_identity_paged(
&self,
identity_key: String,
identity_key: IdentityKeyRef<'_>,
start_after: Option<MixId>,
limit: Option<u32>,
) -> Result<PagedUnbondedMixnodesResponse, NyxdError> {
self.query_mixnet_contract(MixnetQueryMsg::GetUnbondedMixNodesByIdentityKey {
identity_key,
identity_key: identity_key.to_string(),
limit,
start_after,
})
@@ -286,12 +287,12 @@ pub trait MixnetQueryClient {
/// Gets list of all the mixnodes to which a particular address delegated.
async fn get_delegator_delegations_paged(
&self,
delegator: String,
delegator: &AccountId,
start_after: Option<(MixId, OwnerProxySubKey)>,
limit: Option<u32>,
) -> Result<PagedDelegatorDelegationsResponse, NyxdError> {
self.query_mixnet_contract(MixnetQueryMsg::GetDelegatorDelegations {
delegator,
delegator: delegator.to_string(),
start_after,
limit,
})
@@ -478,6 +479,61 @@ pub trait PagedMixnetQueryClient: MixnetQueryClient {
async fn get_all_mixnodes_detailed(&self) -> Result<Vec<MixNodeDetails>, NyxdError> {
collect_paged!(self, get_mixnodes_detailed_paged, nodes)
}
async fn get_all_unbonded_mixnodes(&self) -> Result<Vec<(MixId, UnbondedMixnode)>, NyxdError> {
collect_paged!(self, get_unbonded_paged, nodes)
}
async fn get_all_unbonded_mixnodes_by_owner(
&self,
owner: &AccountId,
) -> Result<Vec<(MixId, UnbondedMixnode)>, NyxdError> {
collect_paged!(self, get_unbonded_by_owner_paged, nodes, owner)
}
async fn get_all_unbonded_mixnodes_by_identity(
&self,
identity_key: IdentityKeyRef<'_>,
) -> Result<Vec<(MixId, UnbondedMixnode)>, NyxdError> {
collect_paged!(self, get_unbonded_by_identity_paged, nodes, identity_key)
}
async fn get_all_gateways(&self) -> Result<Vec<GatewayBond>, NyxdError> {
collect_paged!(self, get_gateways_paged, nodes)
}
async fn get_all_single_mixnode_delegations(
&self,
mix_id: MixId,
) -> Result<Vec<Delegation>, NyxdError> {
collect_paged!(self, get_mixnode_delegations_paged, delegations, mix_id)
}
async fn get_all_delegator_delegations(
&self,
delegation_owner: &AccountId,
) -> Result<Vec<Delegation>, NyxdError> {
collect_paged!(
self,
get_delegator_delegations_paged,
delegations,
delegation_owner
)
}
async fn get_all_network_delegations(&self) -> Result<Vec<Delegation>, NyxdError> {
collect_paged!(self, get_all_network_delegations_paged, delegations)
}
async fn get_all_pending_epoch_events(&self) -> Result<Vec<PendingEpochEvent>, NyxdError> {
collect_paged!(self, get_pending_epoch_events_paged, events)
}
async fn get_all_pending_interval_events(
&self,
) -> Result<Vec<PendingIntervalEvent>, NyxdError> {
collect_paged!(self, get_pending_interval_events_paged, events)
}
}
#[async_trait]
@@ -129,6 +129,7 @@ impl TryFrom<NymContracts> for TypedNymContracts {
// a simple helper macro to define to repeatedly call a paged query until a full response is constructed
#[macro_export]
macro_rules! collect_paged {
// TODO: deal with the args in a nicer way
( $self:ident, $f: ident, $field: ident ) => {{
let mut res = Vec::new();
let mut start_after = None;
@@ -143,4 +144,19 @@ macro_rules! collect_paged {
}
}
}};
( $self:ident, $f: ident, $field: ident, $($args:tt),*) => {{
let mut res = Vec::new();
let mut start_after = None;
loop {
let paged_response = $self.$f($($args),*, start_after.take(), None).await?;
res.extend(paged_response.$field);
if let Some(start_next_after) = paged_response.start_next_after {
start_after = Some(start_next_after)
} else {
break Ok(res);
}
}
}};
}