Compare commits

...

3 Commits

Author SHA1 Message Date
Jędrzej Stuczyński bde44164e7 Usingn IndexedMap for mixnodes 2021-11-25 16:56:53 +00:00
Jędrzej Stuczyński 18add0a0f1 The same for main mixnode storage 2021-11-25 14:51:07 +00:00
Jędrzej Stuczyński 1846ed3476 Experimentally replaced storage for config and layers with cw plus Item 2021-11-25 14:26:51 +00:00
15 changed files with 347 additions and 296 deletions
+11
View File
@@ -190,6 +190,16 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "cw-storage-plus"
version = "0.6.2"
source = "git+https://github.com/jstuczyn/cw-plus?branch=feature/0.6.2-cosmwasm-fork#5d3e59c8327d1ab4a748c0be5ad3a376b710bfe5"
dependencies = [
"cosmwasm-std",
"schemars",
"serde",
]
[[package]] [[package]]
name = "der" name = "der"
version = "0.4.4" version = "0.4.4"
@@ -493,6 +503,7 @@ dependencies = [
"cosmwasm-schema", "cosmwasm-schema",
"cosmwasm-std", "cosmwasm-std",
"cosmwasm-storage", "cosmwasm-storage",
"cw-storage-plus",
"fixed", "fixed",
"mixnet-contract", "mixnet-contract",
"schemars", "schemars",
+1
View File
@@ -40,6 +40,7 @@ config = { path = "../../common/config"}
cosmwasm-std = { git = "https://github.com/jstuczyn/cosmwasm", branch="0.14.1-updatedk256", features = ["iterator"] } cosmwasm-std = { git = "https://github.com/jstuczyn/cosmwasm", branch="0.14.1-updatedk256", features = ["iterator"] }
cosmwasm-storage = { git = "https://github.com/jstuczyn/cosmwasm", branch="0.14.1-updatedk256", features = ["iterator"] } cosmwasm-storage = { git = "https://github.com/jstuczyn/cosmwasm", branch="0.14.1-updatedk256", features = ["iterator"] }
cw-storage-plus = { git = "https://github.com/jstuczyn/cw-plus", branch = "feature/0.6.2-cosmwasm-fork", features = ["iterator"] }
#cosmwasm-std = { version = "0.14.1", features = ["iterator"] } #cosmwasm-std = { version = "0.14.1", features = ["iterator"] }
#cosmwasm-storage = { version = "0.14.1", features = ["iterator"] } #cosmwasm-storage = { version = "0.14.1", features = ["iterator"] }
+5 -5
View File
@@ -70,8 +70,8 @@ pub fn instantiate(
) -> Result<Response, ContractError> { ) -> Result<Response, ContractError> {
let state = default_initial_state(info.sender, env); let state = default_initial_state(info.sender, env);
mixnet_params_storage::contract_settings(deps.storage).save(&state)?; mixnet_params_storage::CONTRACT_SETTINGS.save(deps.storage, &state)?;
mixnet_params_storage::layer_distribution(deps.storage).save(&Default::default())?; mixnet_params_storage::LAYERS.save(deps.storage, &Default::default())?;
Ok(Response::default()) Ok(Response::default())
} }
@@ -168,9 +168,9 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result<QueryResponse, Cont
to_binary(&mixnode_queries::query_owns_mixnode(deps, address)?) to_binary(&mixnode_queries::query_owns_mixnode(deps, address)?)
} }
QueryMsg::OwnsGateway { address } => to_binary(&query_owns_gateway(deps, address)?), QueryMsg::OwnsGateway { address } => to_binary(&query_owns_gateway(deps, address)?),
QueryMsg::StateParams {} => to_binary(&query_contract_settings_params(deps)), QueryMsg::StateParams {} => to_binary(&query_contract_settings_params(deps)?),
QueryMsg::CurrentRewardingInterval {} => to_binary(&query_rewarding_interval(deps)), QueryMsg::CurrentRewardingInterval {} => to_binary(&query_rewarding_interval(deps)?),
QueryMsg::LayerDistribution {} => to_binary(&query_layer_distribution(deps)), QueryMsg::LayerDistribution {} => to_binary(&query_layer_distribution(deps)?),
QueryMsg::GetMixDelegations { QueryMsg::GetMixDelegations {
mix_identity, mix_identity,
start_after, start_after,
@@ -15,8 +15,10 @@ pub(crate) fn try_add_gateway(
let sender_bytes = info.sender.as_bytes(); let sender_bytes = info.sender.as_bytes();
// if the client has an active bonded mixnode, don't allow gateway bonding // if the client has an active bonded mixnode, don't allow gateway bonding
if mixnodes_storage::mixnodes_owners_read(deps.storage) if mixnodes_storage::mixnodes()
.may_load(sender_bytes)? .idx
.owner
.item(deps.storage, info.sender.to_string())?
.is_some() .is_some()
{ {
return Err(ContractError::AlreadyOwnsMixnode); return Err(ContractError::AlreadyOwnsMixnode);
@@ -41,8 +43,10 @@ pub(crate) fn try_add_gateway(
} }
} }
let minimum_bond = let minimum_bond = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::read_contract_settings_params(deps.storage).minimum_gateway_bond; .load(deps.storage)?
.params
.minimum_gateway_bond;
validate_gateway_bond(&info.funds, minimum_bond)?; validate_gateway_bond(&info.funds, minimum_bond)?;
let bond = GatewayBond::new( let bond = GatewayBond::new(
@@ -1,20 +1,21 @@
use super::storage; use super::storage;
use cosmwasm_std::Deps; use cosmwasm_std::{Deps, StdResult};
use mixnet_contract::{ContractSettingsParams, RewardingIntervalResponse}; use mixnet_contract::{ContractSettingsParams, RewardingIntervalResponse};
pub(crate) fn query_contract_settings_params(deps: Deps) -> ContractSettingsParams { pub(crate) fn query_contract_settings_params(deps: Deps) -> StdResult<ContractSettingsParams> {
storage::read_contract_settings_params(deps.storage) storage::CONTRACT_SETTINGS
.load(deps.storage)
.map(|settings| settings.params)
} }
pub(crate) fn query_rewarding_interval(deps: Deps) -> RewardingIntervalResponse { pub(crate) fn query_rewarding_interval(deps: Deps) -> StdResult<RewardingIntervalResponse> {
let state = storage::contract_settings_read(deps.storage) let state = storage::CONTRACT_SETTINGS.load(deps.storage)?;
.load()
.unwrap(); Ok(RewardingIntervalResponse {
RewardingIntervalResponse {
current_rewarding_interval_starting_block: state.rewarding_interval_starting_block, current_rewarding_interval_starting_block: state.rewarding_interval_starting_block,
current_rewarding_interval_nonce: state.latest_rewarding_interval_nonce, current_rewarding_interval_nonce: state.latest_rewarding_interval_nonce,
rewarding_in_progress: state.rewarding_in_progress, rewarding_in_progress: state.rewarding_in_progress,
} })
} }
#[cfg(test)] #[cfg(test)]
@@ -43,13 +44,13 @@ pub(crate) mod tests {
rewarding_in_progress: false, rewarding_in_progress: false,
}; };
storage::contract_settings(deps.as_mut().storage) storage::CONTRACT_SETTINGS
.save(&dummy_state) .save(deps.as_mut().storage, &dummy_state)
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
dummy_state.params, dummy_state.params,
query_contract_settings_params(deps.as_ref()) query_contract_settings_params(deps.as_ref()).unwrap()
) )
} }
} }
@@ -4,62 +4,30 @@
use crate::mixnet_contract_settings::models::ContractSettings; use crate::mixnet_contract_settings::models::ContractSettings;
use cosmwasm_std::StdResult; use cosmwasm_std::StdResult;
use cosmwasm_std::Storage; use cosmwasm_std::Storage;
use cosmwasm_storage::singleton; use cw_storage_plus::Item;
use cosmwasm_storage::singleton_read;
use cosmwasm_storage::ReadonlySingleton;
use cosmwasm_storage::Singleton;
use mixnet_contract::ContractSettingsParams;
use mixnet_contract::Layer; use mixnet_contract::Layer;
use mixnet_contract::LayerDistribution; use mixnet_contract::LayerDistribution;
// storage prefixes pub(crate) const CONTRACT_SETTINGS: Item<ContractSettings> = Item::new("config");
const CONFIG_KEY: &[u8] = b"config"; pub(crate) const LAYERS: Item<LayerDistribution> = Item::new("layers");
const LAYER_DISTRIBUTION_KEY: &[u8] = b"layers";
pub fn contract_settings(storage: &mut dyn Storage) -> Singleton<ContractSettings> {
singleton(storage, CONFIG_KEY)
}
pub fn contract_settings_read(storage: &dyn Storage) -> ReadonlySingleton<ContractSettings> {
singleton_read(storage, CONFIG_KEY)
}
pub(crate) fn read_contract_settings_params(storage: &dyn Storage) -> ContractSettingsParams {
// note: In any other case, I wouldn't have attempted to unwrap this result, but in here
// if we fail to load the stored state we would already be in the undefined behaviour land,
// so we better just blow up immediately.
contract_settings_read(storage).load().unwrap().params
}
pub fn layer_distribution(storage: &mut dyn Storage) -> Singleton<LayerDistribution> {
singleton(storage, LAYER_DISTRIBUTION_KEY)
}
pub(crate) fn read_layer_distribution(storage: &dyn Storage) -> LayerDistribution {
// note: In any other case, I wouldn't have attempted to unwrap this result, but in here
// if we fail to load the stored state we would already be in the undefined behaviour land,
// so we better just blow up immediately.
layer_distribution_read(storage).load().unwrap()
}
pub fn layer_distribution_read(storage: &dyn Storage) -> ReadonlySingleton<LayerDistribution> {
singleton_read(storage, LAYER_DISTRIBUTION_KEY)
}
pub fn increment_layer_count(storage: &mut dyn Storage, layer: Layer) -> StdResult<()> { pub fn increment_layer_count(storage: &mut dyn Storage, layer: Layer) -> StdResult<()> {
let mut distribution = layer_distribution(storage).load()?; LAYERS
.update(storage, |mut distribution| {
match layer { match layer {
Layer::Gateway => distribution.gateways += 1, Layer::Gateway => distribution.gateways += 1,
Layer::One => distribution.layer1 += 1, Layer::One => distribution.layer1 += 1,
Layer::Two => distribution.layer2 += 1, Layer::Two => distribution.layer2 += 1,
Layer::Three => distribution.layer3 += 1, Layer::Three => distribution.layer3 += 1,
} }
layer_distribution(storage).save(&distribution) Ok(distribution)
})
.map(|_| ())
} }
pub fn decrement_layer_count(storage: &mut dyn Storage, layer: Layer) -> StdResult<()> { pub fn decrement_layer_count(storage: &mut dyn Storage, layer: Layer) -> StdResult<()> {
let mut distribution = layer_distribution(storage).load()?; LAYERS
// It can't possibly go below zero, if it does, it means there's a serious error in the contract logic .update(storage, |mut distribution| {
match layer { match layer {
Layer::Gateway => { Layer::Gateway => {
distribution.gateways = distribution distribution.gateways = distribution
@@ -85,6 +53,8 @@ pub fn decrement_layer_count(storage: &mut dyn Storage, layer: Layer) -> StdResu
.checked_sub(1) .checked_sub(1)
.expect("tried to subtract from unsigned zero!") .expect("tried to subtract from unsigned zero!")
} }
}; }
layer_distribution(storage).save(&distribution) Ok(distribution)
})
.map(|_| ())
} }
@@ -13,7 +13,7 @@ pub(crate) fn try_update_contract_settings(
info: MessageInfo, info: MessageInfo,
params: ContractSettingsParams, params: ContractSettingsParams,
) -> Result<Response, ContractError> { ) -> Result<Response, ContractError> {
let mut state = storage::contract_settings_read(deps.storage).load()?; let mut state = storage::CONTRACT_SETTINGS.load(deps.storage)?;
// check if this is executed by the owner, if not reject the transaction // check if this is executed by the owner, if not reject the transaction
if info.sender != state.owner { if info.sender != state.owner {
@@ -35,8 +35,33 @@ pub(crate) fn try_update_contract_settings(
} }
state.params = params; state.params = params;
storage::CONTRACT_SETTINGS.save(deps.storage, &state)?;
storage::contract_settings(deps.storage).save(&state)?; // alternative:
// storage::CONTRACT_SETTINGS.update(deps.storage, |mut state| {
// // check if this is executed by the owner, if not reject the transaction
// if info.sender != state.owner {
// return Err(ContractError::Unauthorized);
// }
//
// if params.mixnode_rewarded_set_size == 0 {
// return Err(ContractError::ZeroRewardedSet);
// }
//
// if params.mixnode_active_set_size == 0 {
// return Err(ContractError::ZeroActiveSet);
// }
//
// // note: rewarded_set = active_set + idle_set
// // hence rewarded set must always be bigger than (or equal to) the active set
// if params.mixnode_rewarded_set_size < params.mixnode_active_set_size {
// return Err(ContractError::InvalidActiveSetSize);
// }
//
// state.params = params;
// Ok(state)
// });
Ok(Response::default()) Ok(Response::default())
} }
@@ -66,8 +91,8 @@ pub mod tests {
// sanity check to ensure new_params are different than the default ones // sanity check to ensure new_params are different than the default ones
assert_ne!( assert_ne!(
new_params, new_params,
storage::contract_settings_read(deps.as_ref().storage) storage::CONTRACT_SETTINGS
.load() .load(deps.as_ref().storage)
.unwrap() .unwrap()
.params .params
); );
@@ -83,8 +108,8 @@ pub mod tests {
assert_eq!(res, Ok(Response::default())); assert_eq!(res, Ok(Response::default()));
// and the state is actually updated // and the state is actually updated
let current_state = storage::contract_settings_read(deps.as_ref().storage) let current_state = storage::CONTRACT_SETTINGS
.load() .load(deps.as_ref().storage)
.unwrap(); .unwrap();
assert_eq!(current_state.params, new_params); assert_eq!(current_state.params, new_params);
@@ -5,6 +5,7 @@ use super::storage;
use crate::query_support::calculate_start_value; use crate::query_support::calculate_start_value;
use config::defaults::DENOM; use config::defaults::DENOM;
use cosmwasm_std::{coin, Addr, Deps, Order, StdResult}; use cosmwasm_std::{coin, Addr, Deps, Order, StdResult};
use cw_storage_plus::Bound;
use mixnet_contract::{ use mixnet_contract::{
Delegation, IdentityKey, MixNodeBond, MixOwnershipResponse, PagedMixDelegationsResponse, Delegation, IdentityKey, MixNodeBond, MixOwnershipResponse, PagedMixDelegationsResponse,
PagedMixnodeResponse, PagedMixnodeResponse,
@@ -18,10 +19,11 @@ pub fn query_mixnodes_paged(
let limit = limit let limit = limit
.unwrap_or(storage::BOND_PAGE_DEFAULT_LIMIT) .unwrap_or(storage::BOND_PAGE_DEFAULT_LIMIT)
.min(storage::BOND_PAGE_MAX_LIMIT) as usize; .min(storage::BOND_PAGE_MAX_LIMIT) as usize;
let start = calculate_start_value(start_after);
let nodes = storage::mixnodes_read(deps.storage) let start = start_after.map(Bound::exclusive);
.range(start.as_deref(), None, Order::Ascending)
let nodes = storage::mixnodes()
.range(deps.storage, start, None, Order::Ascending)
.take(limit) .take(limit)
.map(|res| res.map(|item| item.1)) .map(|res| res.map(|item| item.1))
.map(|stored_bond| { .map(|stored_bond| {
@@ -41,8 +43,10 @@ pub fn query_mixnodes_paged(
} }
pub fn query_owns_mixnode(deps: Deps, address: Addr) -> StdResult<MixOwnershipResponse> { pub fn query_owns_mixnode(deps: Deps, address: Addr) -> StdResult<MixOwnershipResponse> {
let has_node = storage::mixnodes_owners_read(deps.storage) let has_node = storage::mixnodes()
.may_load(address.as_bytes())? .idx
.owner
.item(deps.storage, address.to_string())?
.is_some(); .is_some();
Ok(MixOwnershipResponse { address, has_node }) Ok(MixOwnershipResponse { address, has_node })
} }
@@ -28,8 +28,10 @@ pub(crate) fn try_add_mixnode(
} }
// if the client has an active bonded mixnode, regardless of its identity, don't allow bonding // if the client has an active bonded mixnode, regardless of its identity, don't allow bonding
if storage::mixnodes_owners_read(deps.storage) if storage::mixnodes()
.may_load(sender_bytes)? .idx
.owner
.item(deps.storage, info.sender.to_string())?
.is_some() .is_some()
{ {
return Err(ContractError::AlreadyOwnsMixnode); return Err(ContractError::AlreadyOwnsMixnode);
@@ -37,7 +39,7 @@ pub(crate) fn try_add_mixnode(
// check if somebody else has already bonded a mixnode with this identity // check if somebody else has already bonded a mixnode with this identity
if let Some(existing_bond) = if let Some(existing_bond) =
storage::mixnodes_read(deps.storage).may_load(mix_node.identity_key.as_bytes())? storage::mixnodes().may_load(deps.storage, mix_node.identity_key.as_bytes())?
{ {
if existing_bond.owner != info.sender { if existing_bond.owner != info.sender {
return Err(ContractError::DuplicateMixnode { return Err(ContractError::DuplicateMixnode {
@@ -46,11 +48,13 @@ pub(crate) fn try_add_mixnode(
} }
} }
let minimum_bond = let minimum_bond = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::read_contract_settings_params(deps.storage).minimum_mixnode_bond; .load(deps.storage)?
.params
.minimum_mixnode_bond;
validate_mixnode_bond(&info.funds, minimum_bond)?; validate_mixnode_bond(&info.funds, minimum_bond)?;
let layer_distribution = query_layer_distribution(deps.as_ref()); let layer_distribution = query_layer_distribution(deps.as_ref())?;
let layer = layer_distribution.choose_with_fewest(); let layer = layer_distribution.choose_with_fewest();
let stored_bond = StoredMixnodeBond::new( let stored_bond = StoredMixnodeBond::new(
@@ -62,13 +66,11 @@ pub(crate) fn try_add_mixnode(
None, None,
); );
let identity = stored_bond.identity();
// technically we don't have to set the total_delegation bucket, but it makes things easier // technically we don't have to set the total_delegation bucket, but it makes things easier
// in different places that we can guarantee that if node exists, so does the data behind the total delegation // in different places that we can guarantee that if node exists, so does the data behind the total delegation
storage::mixnodes(deps.storage).save(identity.as_bytes(), &stored_bond)?; let identity = stored_bond.identity().as_bytes();
storage::mixnodes_owners(deps.storage).save(sender_bytes, identity)?; storage::mixnodes().save(deps.storage, identity, &stored_bond)?;
storage::total_delegation(deps.storage).save(identity.as_bytes(), &Uint128::zero())?; storage::total_delegation(deps.storage).save(identity, &Uint128::zero())?;
mixnet_params_storage::increment_layer_count(deps.storage, stored_bond.layer)?; mixnet_params_storage::increment_layer_count(deps.storage, stored_bond.layer)?;
Ok(Response::new()) Ok(Response::new())
@@ -78,17 +80,16 @@ pub(crate) fn try_remove_mixnode(
deps: DepsMut, deps: DepsMut,
info: MessageInfo, info: MessageInfo,
) -> Result<Response, ContractError> { ) -> Result<Response, ContractError> {
let sender_bytes = info.sender.as_bytes(); // try to find the node of the sender
let (entry_key, mixnode_bond) = match storage::mixnodes()
// try to find the identity of the sender's node .idx
let mix_identity = match storage::mixnodes_owners_read(deps.storage).may_load(sender_bytes)? { .owner
Some(identity) => identity, .item(deps.storage, info.sender.to_string())?
{
Some(node) => (node.0, node.1),
None => return Err(ContractError::NoAssociatedMixNodeBond { owner: info.sender }), None => return Err(ContractError::NoAssociatedMixNodeBond { owner: info.sender }),
}; };
// get the bond, since we found associated identity, the node MUST exist
let mixnode_bond = storage::mixnodes_read(deps.storage).load(mix_identity.as_bytes())?;
// send bonded funds back to the bond owner // send bonded funds back to the bond owner
let messages = vec![BankMsg::Send { let messages = vec![BankMsg::Send {
to_address: info.sender.as_str().to_owned(), to_address: info.sender.as_str().to_owned(),
@@ -96,10 +97,9 @@ pub(crate) fn try_remove_mixnode(
} }
.into()]; .into()];
// remove the bond from the list of bonded mixnodes // remove the bond
storage::mixnodes(deps.storage).remove(mix_identity.as_bytes()); storage::mixnodes().remove(deps.storage, &entry_key)?;
// remove the node ownership
storage::mixnodes_owners(deps.storage).remove(sender_bytes);
// decrement layer count // decrement layer count
mixnet_params_storage::decrement_layer_count(deps.storage, mixnode_bond.layer)?; mixnet_params_storage::decrement_layer_count(deps.storage, mixnode_bond.layer)?;
@@ -303,8 +303,10 @@ pub mod tests {
}; };
// before the execution the node had no associated owner // before the execution the node had no associated owner
assert!(storage::mixnodes_owners_read(deps.as_ref().storage) assert!(storage::mixnodes()
.may_load("myAwesomeMixnode".as_bytes()) .idx
.owner
.item(deps.as_ref().storage, "mix-owner".to_string())
.unwrap() .unwrap()
.is_none()); .is_none());
@@ -314,9 +316,14 @@ pub mod tests {
assert_eq!( assert_eq!(
"myAwesomeMixnode", "myAwesomeMixnode",
storage::mixnodes_owners_read(deps.as_ref().storage) storage::mixnodes()
.load("mix-owner".as_bytes()) .idx
.owner
.item(deps.as_ref().storage, "mix-owner".to_string())
.unwrap() .unwrap()
.unwrap()
.1
.identity()
); );
} }
@@ -386,9 +393,7 @@ pub mod tests {
assert_eq!( assert_eq!(
LayerDistribution::default(), LayerDistribution::default(),
mixnet_params_storage::layer_distribution_read(&deps.storage) mixnet_params_storage::LAYERS.load(&deps.storage).unwrap(),
.load()
.unwrap(),
); );
let info = mock_info("mix-owner", &test_helpers::good_mixnode_bond()); let info = mock_info("mix-owner", &test_helpers::good_mixnode_bond());
@@ -405,9 +410,7 @@ pub mod tests {
layer1: 1, layer1: 1,
..Default::default() ..Default::default()
}, },
mixnet_params_storage::layer_distribution_read(&deps.storage) mixnet_params_storage::LAYERS.load(&deps.storage).unwrap()
.load()
.unwrap()
); );
} }
@@ -517,9 +520,14 @@ pub mod tests {
execute(deps.as_mut(), mock_env(), info, msg).unwrap(); execute(deps.as_mut(), mock_env(), info, msg).unwrap();
assert_eq!( assert_eq!(
"myAwesomeMixnode", "myAwesomeMixnode",
storage::mixnodes_owners_read(deps.as_ref().storage) storage::mixnodes()
.load("mix-owner".as_bytes()) .idx
.owner
.item(deps.as_ref().storage, "mix-owner".to_string())
.unwrap() .unwrap()
.unwrap()
.1
.identity()
); );
let info = mock_info("mix-owner", &[]); let info = mock_info("mix-owner", &[]);
@@ -527,8 +535,10 @@ pub mod tests {
assert!(execute(deps.as_mut(), mock_env(), info, msg).is_ok()); assert!(execute(deps.as_mut(), mock_env(), info, msg).is_ok());
assert!(storage::mixnodes_owners_read(deps.as_ref().storage) assert!(storage::mixnodes()
.may_load("mix-owner".as_bytes()) .idx
.owner
.item(deps.as_ref().storage, "mix-owner".to_string())
.unwrap() .unwrap()
.is_none()); .is_none());
@@ -544,9 +554,14 @@ pub mod tests {
assert!(execute(deps.as_mut(), mock_env(), info, msg).is_ok()); assert!(execute(deps.as_mut(), mock_env(), info, msg).is_ok());
assert_eq!( assert_eq!(
"myAwesomeMixnode", "myAwesomeMixnode",
storage::mixnodes_owners_read(deps.as_ref().storage) storage::mixnodes()
.load("mix-owner".as_bytes()) .idx
.owner
.item(deps.as_ref().storage, "mix-owner".to_string())
.unwrap() .unwrap()
.unwrap()
.1
.identity()
); );
} }
@@ -41,8 +41,8 @@ pub(crate) fn try_delegate_to_mixnode(
validate_delegation_stake(&info.funds)?; validate_delegation_stake(&info.funds)?;
// check if the target node actually exists // check if the target node actually exists
if storage::mixnodes_read(deps.storage) if storage::mixnodes()
.load(mix_identity.as_bytes()) .load(deps.storage, mix_identity.as_bytes())
.is_err() .is_err()
{ {
return Err(ContractError::MixNodeBondNotFound { return Err(ContractError::MixNodeBondNotFound {
@@ -2,9 +2,9 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::mixnet_contract_settings::storage as mixnet_params_storage; use crate::mixnet_contract_settings::storage as mixnet_params_storage;
use cosmwasm_std::Deps; use cosmwasm_std::{Deps, StdResult};
use mixnet_contract::LayerDistribution; use mixnet_contract::LayerDistribution;
pub(crate) fn query_layer_distribution(deps: Deps) -> LayerDistribution { pub(crate) fn query_layer_distribution(deps: Deps) -> StdResult<LayerDistribution> {
mixnet_params_storage::read_layer_distribution(deps.storage) mixnet_params_storage::LAYERS.load(deps.storage)
} }
+36 -27
View File
@@ -4,6 +4,7 @@
use config::defaults::DENOM; use config::defaults::DENOM;
use cosmwasm_std::{StdResult, Storage, Uint128}; use cosmwasm_std::{StdResult, Storage, Uint128};
use cosmwasm_storage::{bucket, bucket_read, Bucket, ReadonlyBucket}; use cosmwasm_storage::{bucket, bucket_read, Bucket, ReadonlyBucket};
use cw_storage_plus::{Index, IndexList, IndexedMap, UniqueIndex};
use mixnet_contract::{ use mixnet_contract::{
Addr, Coin, IdentityKey, IdentityKeyRef, Layer, MixNode, MixNodeBond, RawDelegationData, Addr, Coin, IdentityKey, IdentityKeyRef, Layer, MixNode, MixNodeBond, RawDelegationData,
RewardingStatus, RewardingStatus,
@@ -13,8 +14,8 @@ use serde::{Deserialize, Serialize};
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
// storage prefixes // storage prefixes
const PREFIX_MIXNODES: &[u8] = b"mn"; // const PREFIX_MIXNODES: &[u8] = b"mn";
const PREFIX_MIXNODES_OWNERS: &[u8] = b"mo"; // const PREFIX_MIXNODES_OWNERS: &[u8] = b"mo";
const PREFIX_MIX_DELEGATION: &[u8] = b"md"; const PREFIX_MIX_DELEGATION: &[u8] = b"md";
const PREFIX_REVERSE_MIX_DELEGATION: &[u8] = b"dm"; const PREFIX_REVERSE_MIX_DELEGATION: &[u8] = b"dm";
pub const PREFIX_REWARDED_MIXNODES: &[u8] = b"rm"; pub const PREFIX_REWARDED_MIXNODES: &[u8] = b"rm";
@@ -28,7 +29,32 @@ pub(crate) const BOND_PAGE_DEFAULT_LIMIT: u32 = 50;
const PREFIX_TOTAL_DELEGATION: &[u8] = b"td"; const PREFIX_TOTAL_DELEGATION: &[u8] = b"td";
#[derive(Serialize, Deserialize, Debug, PartialEq)] pub(crate) struct MixnodeBondIndex<'a> {
pub(crate) identity: UniqueIndex<'a, IdentityKey, StoredMixnodeBond>,
// somehow PrimaryKey is not implemented for Addr but is for String?
// maybe it's an omission in this version and is fixed in the cosmwasm 1.0 compatible release?
pub(crate) owner: UniqueIndex<'a, String, StoredMixnodeBond>,
}
// IndexList is just boilerplate code for fetching a struct's indexes
impl<'a> IndexList<StoredMixnodeBond> for MixnodeBondIndex<'a> {
fn get_indexes(&'_ self) -> Box<dyn Iterator<Item = &'_ dyn Index<StoredMixnodeBond>> + '_> {
let v: Vec<&dyn Index<StoredMixnodeBond>> = vec![&self.identity, &self.owner];
Box::new(v.into_iter())
}
}
// mixnodes() is the storage access function.
pub(crate) fn mixnodes<'a>() -> IndexedMap<'a, &'a [u8], StoredMixnodeBond, MixnodeBondIndex<'a>> {
let indexes = MixnodeBondIndex {
identity: UniqueIndex::new(|d| d.mix_node.identity_key.clone(), "mni"),
owner: UniqueIndex::new(|d| d.owner.to_string(), "mno"),
};
IndexedMap::new("mn", indexes)
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub(crate) struct StoredMixnodeBond { pub(crate) struct StoredMixnodeBond {
pub bond_amount: Coin, pub bond_amount: Coin,
pub owner: Addr, pub owner: Addr,
@@ -93,23 +119,6 @@ impl Display for StoredMixnodeBond {
// Mixnode-related stuff // Mixnode-related stuff
pub(crate) fn mixnodes(storage: &mut dyn Storage) -> Bucket<StoredMixnodeBond> {
bucket(storage, PREFIX_MIXNODES)
}
pub(crate) fn mixnodes_read(storage: &dyn Storage) -> ReadonlyBucket<StoredMixnodeBond> {
bucket_read(storage, PREFIX_MIXNODES)
}
// owner address -> node identity
pub fn mixnodes_owners(storage: &mut dyn Storage) -> Bucket<IdentityKey> {
bucket(storage, PREFIX_MIXNODES_OWNERS)
}
pub fn mixnodes_owners_read(storage: &dyn Storage) -> ReadonlyBucket<IdentityKey> {
bucket_read(storage, PREFIX_MIXNODES_OWNERS)
}
pub fn total_delegation(storage: &mut dyn Storage) -> Bucket<Uint128> { pub fn total_delegation(storage: &mut dyn Storage) -> Bucket<Uint128> {
bucket(storage, PREFIX_TOTAL_DELEGATION) bucket(storage, PREFIX_TOTAL_DELEGATION)
} }
@@ -151,7 +160,7 @@ pub(crate) fn read_mixnode_bond(
storage: &dyn Storage, storage: &dyn Storage,
mix_identity: IdentityKeyRef, mix_identity: IdentityKeyRef,
) -> StdResult<Option<MixNodeBond>> { ) -> StdResult<Option<MixNodeBond>> {
let stored_bond = mixnodes_read(storage).may_load(mix_identity.as_bytes())?; let stored_bond = mixnodes().may_load(storage, mix_identity.as_bytes())?;
match stored_bond { match stored_bond {
None => Ok(None), None => Ok(None),
Some(stored_bond) => { Some(stored_bond) => {
@@ -223,13 +232,13 @@ mod tests {
#[test] #[test]
fn mixnode_single_read_retrieval() { fn mixnode_single_read_retrieval() {
let mut storage = MockStorage::new(); let mut storage = MockStorage::new();
let bond1 = test_helpers::stored_mixnode_bond_fixture(); let bond1 = test_helpers::stored_mixnode_bond_fixture("owner1");
let bond2 = test_helpers::stored_mixnode_bond_fixture(); let bond2 = test_helpers::stored_mixnode_bond_fixture("owner2");
mixnodes(&mut storage).save(b"bond1", &bond1).unwrap(); mixnodes().save(&mut storage, b"bond1", &bond1).unwrap();
mixnodes(&mut storage).save(b"bond2", &bond2).unwrap(); mixnodes().save(&mut storage, b"bond2", &bond2).unwrap();
let res1 = storage::mixnodes_read(&storage).load(b"bond1").unwrap(); let res1 = mixnodes().load(&storage, b"bond1").unwrap();
let res2 = storage::mixnodes_read(&storage).load(b"bond2").unwrap(); let res2 = mixnodes().load(&storage, b"bond2").unwrap();
assert_eq!(bond1, res1); assert_eq!(bond1, res1);
assert_eq!(bond2, res2); assert_eq!(bond2, res2);
} }
+6 -9
View File
@@ -52,9 +52,8 @@ pub(crate) mod tests {
fn returns_empty_status_for_unrewarded_nodes() { fn returns_empty_status_for_unrewarded_nodes() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let env = mock_env(); let env = mock_env();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -93,9 +92,8 @@ pub(crate) mod tests {
// with single page // with single page
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let mut env = mock_env(); let mut env = mock_env();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -216,9 +214,8 @@ pub(crate) mod tests {
fn returns_pending_next_delegator_page_status_when_there_are_more_delegators_to_reward() { fn returns_pending_next_delegator_page_status_when_there_are_more_delegators_to_reward() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let mut env = mock_env(); let mut env = mock_env();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
+94 -82
View File
@@ -34,7 +34,7 @@ fn verify_rewarding_state(
info: MessageInfo, info: MessageInfo,
rewarding_interval_nonce: u32, rewarding_interval_nonce: u32,
) -> Result<(), ContractError> { ) -> Result<(), ContractError> {
let state = mixnet_params_storage::contract_settings_read(storage).load()?; let state = mixnet_params_storage::CONTRACT_SETTINGS.load(storage)?;
// check if this is executed by the permitted validator, if not reject the transaction // check if this is executed by the permitted validator, if not reject the transaction
if info.sender != state.rewarding_validator_address { if info.sender != state.rewarding_validator_address {
@@ -70,7 +70,7 @@ pub(crate) fn try_begin_mixnode_rewarding(
info: MessageInfo, info: MessageInfo,
rewarding_interval_nonce: u32, rewarding_interval_nonce: u32,
) -> Result<Response, ContractError> { ) -> Result<Response, ContractError> {
let mut state = mixnet_params_storage::contract_settings_read(deps.storage).load()?; let mut state = mixnet_params_storage::CONTRACT_SETTINGS.load(deps.storage)?;
// check if this is executed by the permitted validator, if not reject the transaction // check if this is executed by the permitted validator, if not reject the transaction
if info.sender != state.rewarding_validator_address { if info.sender != state.rewarding_validator_address {
@@ -102,7 +102,7 @@ pub(crate) fn try_begin_mixnode_rewarding(
state.latest_rewarding_interval_nonce = rewarding_interval_nonce; state.latest_rewarding_interval_nonce = rewarding_interval_nonce;
state.rewarding_in_progress = true; state.rewarding_in_progress = true;
mixnet_params_storage::contract_settings(deps.storage).save(&state)?; mixnet_params_storage::CONTRACT_SETTINGS.save(deps.storage, &state)?;
let mut response = Response::new(); let mut response = Response::new();
response.add_attribute( response.add_attribute(
@@ -341,7 +341,8 @@ pub(crate) fn try_reward_mixnode_v2(
Ok(current_total.unwrap() + delegation_rewarding_result.total_rewarded) Ok(current_total.unwrap() + delegation_rewarding_result.total_rewarded)
}, },
)?; )?;
mixnodes_storage::mixnodes(deps.storage).update::<_, ContractError>( mixnodes_storage::mixnodes().update::<_, ContractError>(
deps.storage,
mix_identity.as_bytes(), mix_identity.as_bytes(),
|current_bond| { |current_bond| {
// unwrap is fine because we just read the entry... // unwrap is fine because we just read the entry...
@@ -405,7 +406,7 @@ pub(crate) fn try_finish_mixnode_rewarding(
info: MessageInfo, info: MessageInfo,
rewarding_interval_nonce: u32, rewarding_interval_nonce: u32,
) -> Result<Response, ContractError> { ) -> Result<Response, ContractError> {
let mut state = mixnet_params_storage::contract_settings_read(deps.storage).load()?; let mut state = mixnet_params_storage::CONTRACT_SETTINGS.load(deps.storage)?;
// check if this is executed by the permitted validator, if not reject the transaction // check if this is executed by the permitted validator, if not reject the transaction
if info.sender != state.rewarding_validator_address { if info.sender != state.rewarding_validator_address {
@@ -425,7 +426,30 @@ pub(crate) fn try_finish_mixnode_rewarding(
} }
state.rewarding_in_progress = false; state.rewarding_in_progress = false;
mixnet_params_storage::contract_settings(deps.storage).save(&state)?; mixnet_params_storage::CONTRACT_SETTINGS.save(deps.storage, &state)?;
// // alternative:
// mixnet_params_storage::CONTRACT_SETTINGS.update(storage, |mut state| {
// // check if this is executed by the permitted validator, if not reject the transaction
// if info.sender != state.rewarding_validator_address {
// return Err(ContractError::Unauthorized);
// }
//
// if !state.rewarding_in_progress {
// return Err(ContractError::RewardingNotInProgress);
// }
//
// // make sure the validator is in sync with the contract state
// if rewarding_interval_nonce != state.latest_rewarding_interval_nonce {
// return Err(ContractError::InvalidRewardingIntervalNonce {
// received: rewarding_interval_nonce,
// expected: state.latest_rewarding_interval_nonce,
// });
// }
//
// state.rewarding_in_progress = false;
// Ok(state)
// })?;
Ok(Response::new()) Ok(Response::new())
} }
@@ -465,9 +489,8 @@ pub mod tests {
fn can_only_be_called_by_specified_validator_address() { fn can_only_be_called_by_specified_validator_address() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let env = mock_env(); let env = mock_env();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -492,9 +515,8 @@ pub mod tests {
fn cannot_be_called_if_rewarding_is_already_in_progress_with_little_day() { fn cannot_be_called_if_rewarding_is_already_in_progress_with_little_day() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let env = mock_env(); let env = mock_env();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -519,9 +541,8 @@ pub mod tests {
fn can_be_called_if_rewarding_is_in_progress_if_sufficient_number_of_blocks_elapsed() { fn can_be_called_if_rewarding_is_in_progress_if_sufficient_number_of_blocks_elapsed() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let env = mock_env(); let env = mock_env();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -550,13 +571,12 @@ pub mod tests {
fn provided_nonce_must_be_equal_the_current_plus_one() { fn provided_nonce_must_be_equal_the_current_plus_one() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let env = mock_env(); let env = mock_env();
let mut current_state = let mut current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
current_state.latest_rewarding_interval_nonce = 42; current_state.latest_rewarding_interval_nonce = 42;
mixnet_params_storage::contract_settings(deps.as_mut().storage) mixnet_params_storage::CONTRACT_SETTINGS
.save(&current_state) .save(deps.as_mut().storage, &current_state)
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -616,8 +636,8 @@ pub mod tests {
fn updates_contract_state() { fn updates_contract_state() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let env = mock_env(); let env = mock_env();
let start_state = mixnet_params_storage::contract_settings_read(deps.as_mut().storage) let start_state = mixnet_params_storage::CONTRACT_SETTINGS
.load() .load(deps.as_mut().storage)
.unwrap(); .unwrap();
let rewarding_validator_address = start_state.rewarding_validator_address; let rewarding_validator_address = start_state.rewarding_validator_address;
@@ -629,8 +649,8 @@ pub mod tests {
) )
.unwrap(); .unwrap();
let new_state = mixnet_params_storage::contract_settings_read(deps.as_mut().storage) let new_state = mixnet_params_storage::CONTRACT_SETTINGS
.load() .load(deps.as_mut().storage)
.unwrap(); .unwrap();
assert!(new_state.rewarding_in_progress); assert!(new_state.rewarding_in_progress);
assert_eq!( assert_eq!(
@@ -656,9 +676,8 @@ pub mod tests {
fn can_only_be_called_by_specified_validator_address() { fn can_only_be_called_by_specified_validator_address() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let env = mock_env(); let env = mock_env();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -688,9 +707,8 @@ pub mod tests {
#[test] #[test]
fn cannot_be_called_if_rewarding_is_not_in_progress() { fn cannot_be_called_if_rewarding_is_not_in_progress() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -706,13 +724,12 @@ pub mod tests {
fn provided_nonce_must_be_equal_the_current_one() { fn provided_nonce_must_be_equal_the_current_one() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let env = mock_env(); let env = mock_env();
let mut current_state = let mut current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
current_state.latest_rewarding_interval_nonce = 42; current_state.latest_rewarding_interval_nonce = 42;
mixnet_params_storage::contract_settings(deps.as_mut().storage) mixnet_params_storage::CONTRACT_SETTINGS
.save(&current_state) .save(deps.as_mut().storage, &current_state)
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -776,9 +793,8 @@ pub mod tests {
fn updates_contract_state() { fn updates_contract_state() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let env = mock_env(); let env = mock_env();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -797,8 +813,8 @@ pub mod tests {
) )
.unwrap(); .unwrap();
let new_state = mixnet_params_storage::contract_settings_read(deps.as_mut().storage) let new_state = mixnet_params_storage::CONTRACT_SETTINGS
.load() .load(deps.as_mut().storage)
.unwrap(); .unwrap();
assert!(!new_state.rewarding_in_progress); assert!(!new_state.rewarding_in_progress);
} }
@@ -808,8 +824,8 @@ pub mod tests {
fn rewarding_mixnodes_outside_rewarding_period() { fn rewarding_mixnodes_outside_rewarding_period() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let env = mock_env(); let env = mock_env();
let current_state = mixnet_params_storage::contract_settings_read(deps.as_mut().storage) let current_state = mixnet_params_storage::CONTRACT_SETTINGS
.load() .load(deps.as_mut().storage)
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -856,8 +872,8 @@ pub mod tests {
fn rewarding_mixnodes_with_incorrect_rewarding_nonce() { fn rewarding_mixnodes_with_incorrect_rewarding_nonce() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let env = mock_env(); let env = mock_env();
let current_state = mixnet_params_storage::contract_settings_read(deps.as_mut().storage) let current_state = mixnet_params_storage::CONTRACT_SETTINGS
.load() .load(deps.as_mut().storage)
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -925,8 +941,8 @@ pub mod tests {
fn attempting_rewarding_mixnode_multiple_times_per_interval() { fn attempting_rewarding_mixnode_multiple_times_per_interval() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let env = mock_env(); let env = mock_env();
let current_state = mixnet_params_storage::contract_settings_read(deps.as_mut().storage) let current_state = mixnet_params_storage::CONTRACT_SETTINGS
.load() .load(deps.as_mut().storage)
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -994,8 +1010,8 @@ pub mod tests {
fn rewarding_mixnode_blockstamp_based() { fn rewarding_mixnode_blockstamp_based() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let mut env = mock_env(); let mut env = mock_env();
let current_state = mixnet_params_storage::contract_settings_read(deps.as_mut().storage) let current_state = mixnet_params_storage::CONTRACT_SETTINGS
.load() .load(deps.as_mut().storage)
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -1016,8 +1032,12 @@ pub mod tests {
profit_margin_percent: Some(10), profit_margin_percent: Some(10),
}; };
mixnodes_storage::mixnodes(deps.as_mut().storage) mixnodes_storage::mixnodes()
.save(node_identity.as_bytes(), &mixnode_bond) .save(
deps.as_mut().storage,
node_identity.as_bytes(),
&mixnode_bond,
)
.unwrap(); .unwrap();
mixnodes_storage::total_delegation(deps.as_mut().storage) mixnodes_storage::total_delegation(deps.as_mut().storage)
.save(node_identity.as_bytes(), &Uint128::new(initial_delegation)) .save(node_identity.as_bytes(), &Uint128::new(initial_delegation))
@@ -1048,7 +1068,7 @@ pub mod tests {
assert_eq!( assert_eq!(
initial_bond, initial_bond,
test_helpers::read_mixnode_bond_amount(deps.as_ref().storage, node_identity.as_bytes()) test_helpers::read_mixnode_bond_amount(deps.as_ref().storage, &node_identity)
.unwrap() .unwrap()
.u128() .u128()
); );
@@ -1082,7 +1102,7 @@ pub mod tests {
try_finish_mixnode_rewarding(deps.as_mut(), info, 2).unwrap(); try_finish_mixnode_rewarding(deps.as_mut(), info, 2).unwrap();
assert!( assert!(
test_helpers::read_mixnode_bond_amount(deps.as_ref().storage, node_identity.as_bytes()) test_helpers::read_mixnode_bond_amount(deps.as_ref().storage, &node_identity)
.unwrap() .unwrap()
.u128() .u128()
> initial_bond > initial_bond
@@ -1104,7 +1124,7 @@ pub mod tests {
env.block.height += storage::MINIMUM_BLOCK_AGE_FOR_REWARDING - 1; env.block.height += storage::MINIMUM_BLOCK_AGE_FOR_REWARDING - 1;
let bond_before_rewarding = let bond_before_rewarding =
test_helpers::read_mixnode_bond_amount(deps.as_ref().storage, node_identity.as_bytes()) test_helpers::read_mixnode_bond_amount(deps.as_ref().storage, &node_identity)
.unwrap() .unwrap()
.u128(); .u128();
@@ -1122,7 +1142,7 @@ pub mod tests {
try_finish_mixnode_rewarding(deps.as_mut(), info, 3).unwrap(); try_finish_mixnode_rewarding(deps.as_mut(), info, 3).unwrap();
assert!( assert!(
test_helpers::read_mixnode_bond_amount(deps.as_ref().storage, node_identity.as_bytes()) test_helpers::read_mixnode_bond_amount(deps.as_ref().storage, &node_identity)
.unwrap() .unwrap()
.u128() .u128()
> bond_before_rewarding > bond_before_rewarding
@@ -1149,8 +1169,8 @@ pub mod tests {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let mut env = mock_env(); let mut env = mock_env();
let current_state = mixnet_params_storage::contract_settings_read(deps.as_ref().storage) let current_state = mixnet_params_storage::CONTRACT_SETTINGS
.load() .load(deps.as_ref().storage)
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
let period_reward_pool = (INITIAL_REWARD_POOL / 100) * EPOCH_REWARD_PERCENT as u128; let period_reward_pool = (INITIAL_REWARD_POOL / 100) * EPOCH_REWARD_PERCENT as u128;
@@ -1246,7 +1266,7 @@ pub mod tests {
assert_eq!(mix1_delegator1_reward, U128::from_num(22552615)); assert_eq!(mix1_delegator1_reward, U128::from_num(22552615));
assert_eq!(mix1_delegator2_reward, U128::from_num(5638153)); assert_eq!(mix1_delegator2_reward, U128::from_num(5638153));
let pre_reward_bond = test_helpers::read_mixnode_bond_amount(&deps.storage, b"alice") let pre_reward_bond = test_helpers::read_mixnode_bond_amount(&deps.storage, "alice")
.unwrap() .unwrap()
.u128(); .u128();
assert_eq!(pre_reward_bond, 10_000_000_000); assert_eq!(pre_reward_bond, 10_000_000_000);
@@ -1260,7 +1280,7 @@ pub mod tests {
try_reward_mixnode_v2(deps.as_mut(), env, info, "alice".to_string(), params, 1).unwrap(); try_reward_mixnode_v2(deps.as_mut(), env, info, "alice".to_string(), params, 1).unwrap();
assert_eq!( assert_eq!(
test_helpers::read_mixnode_bond_amount(&deps.storage, b"alice") test_helpers::read_mixnode_bond_amount(&deps.storage, "alice")
.unwrap() .unwrap()
.u128(), .u128(),
U128::from_num(pre_reward_bond) + U128::from_num(mix1_operator_profit) U128::from_num(pre_reward_bond) + U128::from_num(mix1_operator_profit)
@@ -1308,9 +1328,8 @@ pub mod tests {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let mut env = mock_env(); let mut env = mock_env();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -1390,9 +1409,8 @@ pub mod tests {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let mut env = mock_env(); let mut env = mock_env();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -1474,9 +1492,8 @@ pub mod tests {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let mut env = mock_env(); let mut env = mock_env();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -1736,9 +1753,8 @@ pub mod tests {
#[test] #[test]
fn cannot_be_called_if_rewarding_is_not_in_progress() { fn cannot_be_called_if_rewarding_is_not_in_progress() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -1756,9 +1772,8 @@ pub mod tests {
fn cannot_be_called_if_mixnodes_operator_wasnt_rewarded() { fn cannot_be_called_if_mixnodes_operator_wasnt_rewarded() {
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let env = mock_env(); let env = mock_env();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -1790,9 +1805,8 @@ pub mod tests {
// everything was done in a single reward call // everything was done in a single reward call
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let mut env = mock_env(); let mut env = mock_env();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -1942,9 +1956,8 @@ pub mod tests {
// setup: bond > page limit delegators, reward operator + first batch // setup: bond > page limit delegators, reward operator + first batch
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let mut env = mock_env(); let mut env = mock_env();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
@@ -2041,9 +2054,8 @@ pub mod tests {
// setup: bond > page limit delegators, reward operator + first batch // setup: bond > page limit delegators, reward operator + first batch
let mut deps = test_helpers::init_contract(); let mut deps = test_helpers::init_contract();
let mut env = mock_env(); let mut env = mock_env();
let current_state = let current_state = mixnet_params_storage::CONTRACT_SETTINGS
mixnet_params_storage::contract_settings_read(deps.as_mut().storage) .load(deps.as_mut().storage)
.load()
.unwrap(); .unwrap();
let rewarding_validator_address = current_state.rewarding_validator_address; let rewarding_validator_address = current_state.rewarding_validator_address;
+10 -8
View File
@@ -24,8 +24,8 @@ pub mod test_helpers {
use cosmwasm_std::{Empty, MemoryStorage}; use cosmwasm_std::{Empty, MemoryStorage};
use mixnet_contract::mixnode::NodeRewardParams; use mixnet_contract::mixnode::NodeRewardParams;
use mixnet_contract::{ use mixnet_contract::{
Gateway, GatewayBond, InstantiateMsg, Layer, MixNode, MixNodeBond, PagedGatewayResponse, Gateway, GatewayBond, IdentityKeyRef, InstantiateMsg, Layer, MixNode, MixNodeBond,
PagedMixnodeResponse, QueryMsg, RawDelegationData, PagedGatewayResponse, PagedMixnodeResponse, QueryMsg, RawDelegationData,
}; };
pub fn add_mixnode(sender: &str, stake: Vec<Coin>, deps: DepsMut) -> String { pub fn add_mixnode(sender: &str, stake: Vec<Coin>, deps: DepsMut) -> String {
@@ -139,13 +139,16 @@ pub mod test_helpers {
) )
} }
pub(crate) fn stored_mixnode_bond_fixture() -> mixnodes_storage::StoredMixnodeBond { pub(crate) fn stored_mixnode_bond_fixture(owner: &str) -> mixnodes_storage::StoredMixnodeBond {
StoredMixnodeBond::new( StoredMixnodeBond::new(
coin(50, DENOM), coin(50, DENOM),
Addr::unchecked("foo"), Addr::unchecked(owner),
Layer::One, Layer::One,
12_345, 12_345,
mix_node_fixture(), MixNode {
identity_key: format!("id-{}", owner),
..mix_node_fixture()
},
None, None,
) )
} }
@@ -227,10 +230,9 @@ pub mod test_helpers {
// currently not used outside tests // currently not used outside tests
pub(crate) fn read_mixnode_bond_amount( pub(crate) fn read_mixnode_bond_amount(
storage: &dyn Storage, storage: &dyn Storage,
identity: &[u8], identity: IdentityKeyRef,
) -> StdResult<cosmwasm_std::Uint128> { ) -> StdResult<cosmwasm_std::Uint128> {
let bucket = mixnodes_storage::mixnodes_read(storage); let node = mixnodes_storage::mixnodes().load(storage, identity.as_bytes())?;
let node = bucket.load(identity)?;
Ok(node.bond_amount.amount) Ok(node.bond_amount.amount)
} }
} }