Added contract query to check if given address owns a mixnode/gateway (#544)
* Added contract query to check if given address owns a mixnode/gateway * Fixed merge conflict
This commit is contained in:
committed by
GitHub
parent
52d4ddb714
commit
7361d7a220
@@ -109,3 +109,9 @@ impl PagedGatewayResponse {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct GatewayOwnershipResponse {
|
||||
pub address: HumanAddr,
|
||||
pub has_gateway: bool,
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@ mod gateway;
|
||||
mod mixnode;
|
||||
|
||||
pub use cosmwasm_std::{Coin, HumanAddr};
|
||||
pub use gateway::{Gateway, GatewayBond, PagedGatewayResponse};
|
||||
pub use mixnode::{MixNode, MixNodeBond, PagedResponse};
|
||||
pub use gateway::{Gateway, GatewayBond, GatewayOwnershipResponse, PagedGatewayResponse};
|
||||
pub use mixnode::{MixNode, MixNodeBond, MixOwnershipResponse, PagedResponse};
|
||||
|
||||
@@ -105,3 +105,9 @@ impl PagedResponse {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct MixOwnershipResponse {
|
||||
pub address: HumanAddr,
|
||||
pub has_node: bool,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use crate::msg::{HandleMsg, InitMsg, QueryMsg};
|
||||
use crate::queries::{query_gateways_paged, query_mixnodes_paged};
|
||||
use crate::queries::{
|
||||
query_gateways_paged, query_mixnodes_paged, query_owns_gateway, query_owns_mixnode,
|
||||
};
|
||||
use crate::state::{config, gateways, gateways_read, State};
|
||||
use crate::{error::ContractError, state::mixnodes, state::mixnodes_read};
|
||||
use cosmwasm_std::{
|
||||
@@ -200,6 +202,8 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
|
||||
QueryMsg::GetGateways { limit, start_after } => {
|
||||
to_binary(&query_gateways_paged(deps, start_after, limit)?)
|
||||
}
|
||||
QueryMsg::OwnsMixnode { address } => to_binary(&query_owns_mixnode(deps, address)?),
|
||||
QueryMsg::OwnsGateway { address } => to_binary(&query_owns_gateway(deps, address)?),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,4 +26,10 @@ pub enum QueryMsg {
|
||||
start_after: Option<HumanAddr>,
|
||||
limit: Option<u32>,
|
||||
},
|
||||
OwnsMixnode {
|
||||
address: HumanAddr,
|
||||
},
|
||||
OwnsGateway {
|
||||
address: HumanAddr,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
// settings for pagination
|
||||
use crate::state::{gateways_read, PREFIX_MIXNODES};
|
||||
use crate::state::{gateways_read, mixnodes_read, PREFIX_MIXNODES};
|
||||
use cosmwasm_std::Deps;
|
||||
use cosmwasm_std::HumanAddr;
|
||||
use cosmwasm_std::Order;
|
||||
use cosmwasm_std::StdResult;
|
||||
use cosmwasm_storage::bucket_read;
|
||||
use mixnet_contract::{GatewayBond, MixNodeBond, PagedGatewayResponse, PagedResponse};
|
||||
use mixnet_contract::{
|
||||
GatewayBond, GatewayOwnershipResponse, MixNodeBond, MixOwnershipResponse, PagedGatewayResponse,
|
||||
PagedResponse,
|
||||
};
|
||||
|
||||
const MAX_LIMIT: u32 = 30;
|
||||
const DEFAULT_LIMIT: u32 = 10;
|
||||
@@ -52,6 +55,29 @@ pub(crate) fn query_gateways_paged(
|
||||
Ok(PagedGatewayResponse::new(nodes, limit, start_next_after))
|
||||
}
|
||||
|
||||
pub(crate) fn query_owns_mixnode(
|
||||
deps: Deps,
|
||||
address: HumanAddr,
|
||||
) -> StdResult<MixOwnershipResponse> {
|
||||
let has_node = mixnodes_read(deps.storage)
|
||||
.may_load(address.as_ref())?
|
||||
.is_some();
|
||||
Ok(MixOwnershipResponse { address, has_node })
|
||||
}
|
||||
|
||||
pub(crate) fn query_owns_gateway(
|
||||
deps: Deps,
|
||||
address: HumanAddr,
|
||||
) -> StdResult<GatewayOwnershipResponse> {
|
||||
let has_gateway = gateways_read(deps.storage)
|
||||
.may_load(address.as_ref())?
|
||||
.is_some();
|
||||
Ok(GatewayOwnershipResponse {
|
||||
address,
|
||||
has_gateway,
|
||||
})
|
||||
}
|
||||
|
||||
/// Adds a 0 byte to terminate the `start_after` value given. This allows CosmWasm
|
||||
/// to get the succeeding key as the start of the next page.
|
||||
fn calculate_start_value(
|
||||
@@ -306,4 +332,68 @@ mod tests {
|
||||
// now we have 2 pages, with 2 results on the second page
|
||||
assert_eq!(2, page2.nodes.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn query_for_mixnode_owner_works() {
|
||||
let mut deps = helpers::init_contract();
|
||||
|
||||
// "fred" does not own a mixnode if there are no mixnodes
|
||||
let res = query_owns_mixnode(deps.as_ref(), "fred".into()).unwrap();
|
||||
assert!(!res.has_node);
|
||||
|
||||
// mixnode was added to "bob", "fred" still does not own one
|
||||
let node = helpers::mixnode_bond_fixture();
|
||||
mixnodes(&mut deps.storage)
|
||||
.save("bob".as_bytes(), &node)
|
||||
.unwrap();
|
||||
|
||||
let res = query_owns_mixnode(deps.as_ref(), "fred".into()).unwrap();
|
||||
assert!(!res.has_node);
|
||||
|
||||
// "fred" now owns a mixnode!
|
||||
let node2 = helpers::mixnode_bond_fixture();
|
||||
mixnodes(&mut deps.storage)
|
||||
.save("fred".as_bytes(), &node2)
|
||||
.unwrap();
|
||||
|
||||
let res = query_owns_mixnode(deps.as_ref(), "fred".into()).unwrap();
|
||||
assert!(res.has_node);
|
||||
|
||||
// but after unbonding it, he doesn't own one anymore
|
||||
mixnodes(&mut deps.storage).remove("fred".as_bytes());
|
||||
let res = query_owns_mixnode(deps.as_ref(), "fred".into()).unwrap();
|
||||
assert!(!res.has_node);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn query_for_gateway_owner_works() {
|
||||
let mut deps = helpers::init_contract();
|
||||
|
||||
// "fred" does not own a mixnode if there are no mixnodes
|
||||
let res = query_owns_gateway(deps.as_ref(), "fred".into()).unwrap();
|
||||
assert!(!res.has_gateway);
|
||||
|
||||
// mixnode was added to "bob", "fred" still does not own one
|
||||
let node = helpers::gateway_bond_fixture();
|
||||
gateways(&mut deps.storage)
|
||||
.save("bob".as_bytes(), &node)
|
||||
.unwrap();
|
||||
|
||||
let res = query_owns_gateway(deps.as_ref(), "fred".into()).unwrap();
|
||||
assert!(!res.has_gateway);
|
||||
|
||||
// "fred" now owns a mixnode!
|
||||
let node2 = helpers::gateway_bond_fixture();
|
||||
gateways(&mut deps.storage)
|
||||
.save("fred".as_bytes(), &node2)
|
||||
.unwrap();
|
||||
|
||||
let res = query_owns_gateway(deps.as_ref(), "fred".into()).unwrap();
|
||||
assert!(res.has_gateway);
|
||||
|
||||
// but after unbonding it, he doesn't own one anymore
|
||||
gateways(&mut deps.storage).remove("fred".as_bytes());
|
||||
let res = query_owns_gateway(deps.as_ref(), "fred".into()).unwrap();
|
||||
assert!(!res.has_gateway);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user