Skip to content

Commit

Permalink
ntt-accountant: add queries for new state
Browse files Browse the repository at this point in the history
  • Loading branch information
evan-gray committed Feb 26, 2024
1 parent 4ac1a15 commit 10b2171
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 47 deletions.
116 changes: 88 additions & 28 deletions cosmwasm/contracts/ntt-global-accountant/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,16 @@ use crate::{
bail,
error::{AnyError, ContractError},
msg::{
AllAccountsResponse, AllModificationsResponse, AllPendingTransfersResponse,
AllTransfersResponse, BatchTransferStatusResponse, ChainRegistrationResponse, ExecuteMsg,
MigrateMsg, MissingObservation, MissingObservationsResponse, Observation, ObservationError,
ObservationStatus, QueryMsg, SubmitObservationResponse, TransferDetails, TransferStatus,
SUBMITTED_OBSERVATIONS_PREFIX,
AllAccountsResponse, AllEndpointHubsResponse, AllEndpointPeersResponse,
AllModificationsResponse, AllPendingTransfersResponse, AllTransfersResponse,
BatchTransferStatusResponse, ExecuteMsg, MigrateMsg, MissingObservation,
MissingObservationsResponse, Observation, ObservationError, ObservationStatus, QueryMsg,
RelayerChainRegistrationResponse, SubmitObservationResponse, TransferDetails,
TransferStatus, SUBMITTED_OBSERVATIONS_PREFIX,
},
state::{
Data, PendingTransfer, DIGESTS, ENDPOINT_PEER, ENDPOINT_TO_HUB, PENDING_TRANSFERS,
RELAYER_CHAIN_REGISTRATIONS,
Data, EndpointHub, EndpointPeer, PendingTransfer, DIGESTS, ENDPOINT_PEER, ENDPOINT_TO_HUB,
PENDING_TRANSFERS, RELAYER_CHAIN_REGISTRATIONS,
},
structs::{DeliveryInstruction, EndpointInit, EndpointRegister, EndpointTransfer, ManagerMode},
};
Expand Down Expand Up @@ -174,15 +175,15 @@ fn handle_observation(
// if the emitter is a known standard relayer, parse the sender and payload from the delivery instruction
let delivery_instruction = DeliveryInstruction::deserialize(&o.payload.0)?;
(
delivery_instruction.sender_address,
delivery_instruction.sender_address.into(),
delivery_instruction.payload,
)
} else {
// otherwise, the sender and payload is the same as the VAA
(o.emitter_address, o.payload.0)
(o.emitter_address.into(), o.payload.0)
};

let hub_key = ENDPOINT_TO_HUB.key((o.emitter_chain, sender.to_vec()));
let hub_key = ENDPOINT_TO_HUB.key((o.emitter_chain, sender));

let hub = hub_key
.may_load(deps.storage)
Expand All @@ -194,7 +195,7 @@ fn handle_observation(
.context("failed to parse observation payload")?;

let destination_chain = message.manager_payload.payload.to_chain.id;
let source_peer_key = ENDPOINT_PEER.key((o.emitter_chain, sender.to_vec(), destination_chain));
let source_peer_key = ENDPOINT_PEER.key((o.emitter_chain, sender, destination_chain));
let source_peer = source_peer_key
.may_load(deps.storage)
.context("failed to load source peer")?
Expand Down Expand Up @@ -263,7 +264,7 @@ fn handle_observation(
// and another that uses 8... this is maxed at 8, but should be actually normalized to 8 for accounting purposes.
let tx_data = transfer::Data {
amount: Uint256::from(message.manager_payload.payload.amount.denormalize(8)),
token_address: TokenAddress::from_vec(hub.1)?,
token_address: hub.1,
token_chain: hub.0,
recipient_chain: message.manager_payload.payload.to_chain.id,
};
Expand Down Expand Up @@ -478,12 +479,15 @@ fn handle_ntt_vaa(
let delivery_instruction =
DeliveryInstruction::deserialize(&Vec::from_slice(body.payload)?)?;
(
delivery_instruction.sender_address,
delivery_instruction.sender_address.into(),
delivery_instruction.payload,
)
} else {
// otherwise, the sender and payload is the same as the VAA
(body.emitter_address.0, Vec::from_slice(body.payload)?)
(
body.emitter_address.0.into(),
Vec::from_slice(body.payload)?,
)
};

if payload.len() < 4 {
Expand All @@ -493,7 +497,7 @@ fn handle_ntt_vaa(

if prefix == EndpointTransfer::PREFIX {
let source_chain = body.emitter_chain.into();
let hub_key = ENDPOINT_TO_HUB.key((source_chain, sender.to_vec()));
let hub_key = ENDPOINT_TO_HUB.key((source_chain, sender));

let hub = hub_key
.may_load(deps.storage)
Expand All @@ -505,7 +509,7 @@ fn handle_ntt_vaa(
.context("failed to parse NTT transfer payload")?;

let destination_chain = message.manager_payload.payload.to_chain.id;
let source_peer_key = ENDPOINT_PEER.key((source_chain, sender.to_vec(), destination_chain));
let source_peer_key = ENDPOINT_PEER.key((source_chain, sender, destination_chain));
let source_peer = source_peer_key
.may_load(deps.storage)
.context("failed to load source peer")?
Expand Down Expand Up @@ -558,7 +562,7 @@ fn handle_ntt_vaa(
let message = EndpointInit::deserialize(&payload)?;
if message.manager_mode == (ManagerMode::LOCKING as u8) {
let chain = body.emitter_chain.into();
let hub_key = ENDPOINT_TO_HUB.key((chain, sender.to_vec()));
let hub_key = ENDPOINT_TO_HUB.key((chain, sender));

if hub_key
.may_load(deps.storage)
Expand All @@ -568,7 +572,7 @@ fn handle_ntt_vaa(
bail!("hub entry already exists")
}
hub_key
.save(deps.storage, &(chain, sender.to_vec()))
.save(deps.storage, &(chain, sender))
.context("failed to save hub")?;
Ok(Event::new("RegisterHub")
.add_attribute("chain", chain.to_string())
Expand All @@ -582,15 +586,15 @@ fn handle_ntt_vaa(
let message = EndpointRegister::deserialize(&payload)?;

let peer_hub_key =
ENDPOINT_TO_HUB.key((message.endpoint_chain_id, message.endpoint_address.to_vec()));
ENDPOINT_TO_HUB.key((message.endpoint_chain_id, message.endpoint_address.into()));

let peer_hub = peer_hub_key
.may_load(deps.storage)
.context("failed to load peer hub")?
.ok_or(ContractError::MissingHubRegistration)?;

let chain = body.emitter_chain.into();
let peer_key = ENDPOINT_PEER.key((chain, sender.to_vec(), message.endpoint_chain_id));
let peer_key = ENDPOINT_PEER.key((chain, sender, message.endpoint_chain_id));

if peer_key
.may_load(deps.storage)
Expand All @@ -600,7 +604,7 @@ fn handle_ntt_vaa(
bail!("peer entry for this chain already exists")
}

let hub_key = ENDPOINT_TO_HUB.key((chain, sender.to_vec()));
let hub_key = ENDPOINT_TO_HUB.key((chain, sender));

if let Some(endpoint_hub) = hub_key
.may_load(deps.storage)
Expand All @@ -612,7 +616,9 @@ fn handle_ntt_vaa(
}
} else {
// this endpoint does not have a known hub, check if this peer is a hub themselves
if peer_hub.0 == message.endpoint_chain_id && peer_hub.1 == message.endpoint_address {
if peer_hub.0 == message.endpoint_chain_id
&& peer_hub.1 == message.endpoint_address.into()
{
// this peer is a hub, so set it as this endpoint's hub
hub_key
.save(deps.storage, &peer_hub.clone())
Expand All @@ -624,7 +630,7 @@ fn handle_ntt_vaa(
}

peer_key
.save(deps.storage, &(message.endpoint_address.to_vec()))
.save(deps.storage, &(message.endpoint_address.into()))
.context("failed to save hub")?;
Ok(Event::new("RegisterPeer")
.add_attribute("chain", chain.to_string())
Expand Down Expand Up @@ -662,8 +668,14 @@ pub fn query(deps: Deps<WormholeQuery>, _env: Env, msg: QueryMsg) -> StdResult<B
})
})
.and_then(|()| to_binary(&Empty {})),
QueryMsg::ChainRegistration { chain } => {
query_chain_registration(deps, chain).and_then(|resp| to_binary(&resp))
QueryMsg::RelayerChainRegistration { chain } => {
query_relayer_chain_registration(deps, chain).and_then(|resp| to_binary(&resp))
}
QueryMsg::AllEndpointHubs { start_after, limit } => {
query_all_endpoint_hubs(deps, start_after, limit).and_then(|resp| to_binary(&resp))
}
QueryMsg::AllEndpointPeers { start_after, limit } => {
query_all_endpoint_peers(deps, start_after, limit).and_then(|resp| to_binary(&resp))
}
QueryMsg::MissingObservations {
guardian_set,
Expand Down Expand Up @@ -805,13 +817,61 @@ fn query_all_modifications(
}
}

fn query_chain_registration(
fn query_relayer_chain_registration(
deps: Deps<WormholeQuery>,
chain: u16,
) -> StdResult<ChainRegistrationResponse> {
) -> StdResult<RelayerChainRegistrationResponse> {
RELAYER_CHAIN_REGISTRATIONS
.load(deps.storage, chain)
.map(|address| ChainRegistrationResponse { address })
.map(|address| RelayerChainRegistrationResponse { address })
}

fn query_all_endpoint_hubs(
deps: Deps<WormholeQuery>,
start_after: Option<(u16, TokenAddress)>,
limit: Option<u32>,
) -> StdResult<AllEndpointHubsResponse> {
let start = start_after.map(|key| Bound::Exclusive((key, PhantomData)));

let iter = ENDPOINT_TO_HUB
.range(deps.storage, start, None, Order::Ascending)
.map(|item| item.map(|(key, data)| EndpointHub { key, data }));

if let Some(lim) = limit {
let l = lim
.try_into()
.map_err(|_| ConversionOverflowError::new("u32", "usize", lim.to_string()))?;
iter.take(l)
.collect::<StdResult<Vec<_>>>()
.map(|hubs| AllEndpointHubsResponse { hubs })
} else {
iter.collect::<StdResult<Vec<_>>>()
.map(|hubs| AllEndpointHubsResponse { hubs })
}
}

fn query_all_endpoint_peers(
deps: Deps<WormholeQuery>,
start_after: Option<(u16, TokenAddress, u16)>,
limit: Option<u32>,
) -> StdResult<AllEndpointPeersResponse> {
let start = start_after.map(|key| Bound::Exclusive((key, PhantomData)));

let iter = ENDPOINT_PEER
.range(deps.storage, start, None, Order::Ascending)
.map(|item| item.map(|(key, data)| EndpointPeer { key, data }));

if let Some(lim) = limit {
let l = lim
.try_into()
.map_err(|_| ConversionOverflowError::new("u32", "usize", lim.to_string()))?;
iter.take(l)
.collect::<StdResult<Vec<_>>>()
.map(|peers| AllEndpointPeersResponse { peers })
} else {
iter.collect::<StdResult<Vec<_>>>()
.map(|peers| AllEndpointPeersResponse { peers })
}
}

fn query_missing_observations(
Expand Down
30 changes: 25 additions & 5 deletions cosmwasm/contracts/ntt-global-accountant/src/msg.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use accountant::state::{account, transfer, Account, Modification, Transfer};
use accountant::state::{account, transfer, Account, Modification, TokenAddress, Transfer};
use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::Binary;
use serde_wormhole::RawMessage;
Expand All @@ -7,7 +7,7 @@ use wormhole_sdk::{
Address,
};

use crate::state::{self, PendingTransfer};
use crate::state::{self, EndpointHub, EndpointPeer, PendingTransfer};

pub const SUBMITTED_OBSERVATIONS_PREFIX: &[u8; 35] = b"ntt_acct_sub_obsfig_00000000000000|";

Expand Down Expand Up @@ -142,8 +142,18 @@ pub enum QueryMsg {
},
#[returns(cosmwasm_std::Empty)]
ValidateTransfer { transfer: Transfer },
#[returns(ChainRegistrationResponse)]
ChainRegistration { chain: u16 },
#[returns(RelayerChainRegistrationResponse)]
RelayerChainRegistration { chain: u16 },
#[returns(AllEndpointHubsResponse)]
AllEndpointHubs {
start_after: Option<(u16, TokenAddress)>,
limit: Option<u32>,
},
#[returns(AllEndpointPeersResponse)]
AllEndpointPeers {
start_after: Option<(u16, TokenAddress, u16)>,
limit: Option<u32>,
},
#[returns(MissingObservationsResponse)]
MissingObservations { guardian_set: u32, index: u8 },
#[returns(TransferStatus)]
Expand Down Expand Up @@ -174,10 +184,20 @@ pub struct AllModificationsResponse {
}

#[cw_serde]
pub struct ChainRegistrationResponse {
pub struct RelayerChainRegistrationResponse {
pub address: Binary,
}

#[cw_serde]
pub struct AllEndpointHubsResponse {
pub hubs: Vec<EndpointHub>,
}

#[cw_serde]
pub struct AllEndpointPeersResponse {
pub peers: Vec<EndpointPeer>,
}

#[cw_serde]
pub struct MissingObservationsResponse {
pub missing: Vec<MissingObservation>,
Expand Down
19 changes: 16 additions & 3 deletions cosmwasm/contracts/ntt-global-accountant/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
use accountant::state::transfer;
use accountant::state::{transfer, TokenAddress};
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Binary;
use cw_storage_plus::Map;
use tinyvec::TinyVec;

pub const PENDING_TRANSFERS: Map<transfer::Key, TinyVec<[Data; 2]>> = Map::new("pending_transfers");
pub const RELAYER_CHAIN_REGISTRATIONS: Map<u16, Binary> = Map::new("relayer_chain_registrations");
pub const ENDPOINT_TO_HUB: Map<(u16, Vec<u8>), (u16, Vec<u8>)> = Map::new("endpoint_to_hub");
pub const ENDPOINT_PEER: Map<(u16, Vec<u8>, u16), Vec<u8>> = Map::new("endpoint_peers");
pub const ENDPOINT_TO_HUB: Map<(u16, TokenAddress), (u16, TokenAddress)> =
Map::new("endpoint_to_hub");
pub const ENDPOINT_PEER: Map<(u16, TokenAddress, u16), TokenAddress> = Map::new("endpoint_peers");
pub const DIGESTS: Map<(u16, Vec<u8>, u64), Binary> = Map::new("digests");

#[cw_serde]
pub struct EndpointHub {
pub key: (u16, TokenAddress),
pub data: (u16, TokenAddress),
}

#[cw_serde]
pub struct EndpointPeer {
pub key: (u16, TokenAddress, u16),
pub data: TokenAddress,
}

#[cw_serde]
pub struct PendingTransfer {
pub key: transfer::Key,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ mod helpers;

use cosmwasm_std::{to_binary, Event};
use helpers::*;
use ntt_global_accountant::msg::ChainRegistrationResponse;
use ntt_global_accountant::msg::RelayerChainRegistrationResponse;
use wormhole_sdk::{
relayer::{Action, GovernancePacket},
vaa::Body,
Expand Down Expand Up @@ -56,8 +56,9 @@ fn any_target() {
.add_attribute("emitter_address", emitter_address.to_string()),
);

let ChainRegistrationResponse { address } =
contract.query_chain_registration(chain.into()).unwrap();
let RelayerChainRegistrationResponse { address } = contract
.query_relayer_chain_registration(chain.into())
.unwrap();
assert_eq!(&*address, &emitter_address.0);
}

Expand Down Expand Up @@ -87,8 +88,9 @@ fn wormchain_target() {
.add_attribute("emitter_address", emitter_address.to_string()),
);

let ChainRegistrationResponse { address } =
contract.query_chain_registration(chain.into()).unwrap();
let RelayerChainRegistrationResponse { address } = contract
.query_relayer_chain_registration(chain.into())
.unwrap();
assert_eq!(&*address, &emitter_address.0);
}

Expand Down
11 changes: 7 additions & 4 deletions cosmwasm/contracts/ntt-global-accountant/tests/helpers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use cw_multi_test::{
use ntt_global_accountant::{
msg::{
AllAccountsResponse, AllModificationsResponse, AllPendingTransfersResponse,
AllTransfersResponse, BatchTransferStatusResponse, ChainRegistrationResponse, ExecuteMsg,
MissingObservationsResponse, QueryMsg, TransferStatus, SUBMITTED_OBSERVATIONS_PREFIX,
AllTransfersResponse, BatchTransferStatusResponse, ExecuteMsg, MissingObservationsResponse,
QueryMsg, RelayerChainRegistrationResponse, TransferStatus, SUBMITTED_OBSERVATIONS_PREFIX,
},
state,
};
Expand Down Expand Up @@ -234,10 +234,13 @@ impl Contract {
)
}

pub fn query_chain_registration(&self, chain: u16) -> StdResult<ChainRegistrationResponse> {
pub fn query_relayer_chain_registration(
&self,
chain: u16,
) -> StdResult<RelayerChainRegistrationResponse> {
self.app
.wrap()
.query_wasm_smart(self.addr(), &QueryMsg::ChainRegistration { chain })
.query_wasm_smart(self.addr(), &QueryMsg::RelayerChainRegistration { chain })
}

pub fn query_missing_observations(
Expand Down
Loading

0 comments on commit 10b2171

Please sign in to comment.