Feature/add blockstamp (#756)

* Add RawDelegationData

* Fix current tests for the new stored data

* Added migration commit. Will be reverted after doing the migration

* New tests for block height

* Use current blockstamp instead of 24h old one

* Put _alot_ of migration stuff in the migrate function scope
This commit is contained in:
Bogdan-Ștefan Neacşu
2021-08-31 14:51:15 +03:00
committed by GitHub
parent 122f5d9f2e
commit 92e13a5d00
7 changed files with 514 additions and 119 deletions
+16 -1
View File
@@ -2,11 +2,26 @@
#![allow(clippy::field_reassign_with_default)] #![allow(clippy::field_reassign_with_default)]
use crate::{Addr, IdentityKey}; use crate::{Addr, IdentityKey};
use cosmwasm_std::Coin; use cosmwasm_std::{Coin, Uint128};
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt::Display; use std::fmt::Display;
#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct RawDelegationData {
pub amount: Uint128,
pub block_height: u64,
}
impl RawDelegationData {
pub fn new(amount: Uint128, block_height: u64) -> Self {
RawDelegationData {
amount,
block_height,
}
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
pub struct Delegation { pub struct Delegation {
owner: Addr, owner: Addr,
+1 -1
View File
@@ -10,7 +10,7 @@ mod types;
pub use cosmwasm_std::{Addr, Coin}; pub use cosmwasm_std::{Addr, Coin};
pub use delegation::{ pub use delegation::{
Delegation, PagedGatewayDelegationsResponse, PagedMixDelegationsResponse, Delegation, PagedGatewayDelegationsResponse, PagedMixDelegationsResponse,
PagedReverseGatewayDelegationsResponse, PagedReverseMixDelegationsResponse, PagedReverseGatewayDelegationsResponse, PagedReverseMixDelegationsResponse, RawDelegationData,
}; };
pub use gateway::{Gateway, GatewayBond, GatewayOwnershipResponse, PagedGatewayResponse}; pub use gateway::{Gateway, GatewayBond, GatewayOwnershipResponse, PagedGatewayResponse};
pub use mixnode::{Layer, MixNode, MixNodeBond, MixOwnershipResponse, PagedMixnodeResponse}; pub use mixnode::{Layer, MixNode, MixNodeBond, MixOwnershipResponse, PagedMixnodeResponse};
+128 -17
View File
@@ -2,18 +2,19 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::helpers::calculate_epoch_reward_rate; use crate::helpers::calculate_epoch_reward_rate;
use crate::queries::DELEGATION_PAGE_MAX_LIMIT;
use crate::state::State; use crate::state::State;
use crate::storage::{ use crate::storage::{config, gateway_delegations, layer_distribution, mix_delegations};
config, layer_distribution, reverse_gateway_delegations, reverse_mix_delegations,
};
use crate::{error::ContractError, queries, transactions}; use crate::{error::ContractError, queries, transactions};
use config::defaults::NETWORK_MONITOR_ADDRESS; use config::defaults::{DENOM, NETWORK_MONITOR_ADDRESS};
use cosmwasm_std::{ use cosmwasm_std::{
entry_point, to_binary, Addr, Decimal, Deps, DepsMut, Env, MessageInfo, QueryResponse, coin, entry_point, to_binary, Addr, Decimal, Deps, DepsMut, Env, MessageInfo, Order,
Response, Uint128, QueryResponse, Response, StdResult, Storage, Uint128,
}; };
use cosmwasm_storage::ReadonlyBucket;
use mixnet_contract::{ use mixnet_contract::{
Delegation, ExecuteMsg, IdentityKey, IdentityKeyRef, InstantiateMsg, MigrateMsg, QueryMsg, Delegation, ExecuteMsg, IdentityKey, IdentityKeyRef, InstantiateMsg, MigrateMsg,
PagedGatewayDelegationsResponse, PagedMixDelegationsResponse, QueryMsg, RawDelegationData,
StateParams, StateParams,
}; };
@@ -94,7 +95,7 @@ pub fn instantiate(
#[entry_point] #[entry_point]
pub fn execute( pub fn execute(
deps: DepsMut, deps: DepsMut,
_env: Env, env: Env,
info: MessageInfo, info: MessageInfo,
msg: ExecuteMsg, msg: ExecuteMsg,
) -> Result<Response, ContractError> { ) -> Result<Response, ContractError> {
@@ -113,13 +114,13 @@ pub fn execute(
transactions::try_reward_gateway(deps, info, identity, uptime) transactions::try_reward_gateway(deps, info, identity, uptime)
} }
ExecuteMsg::DelegateToMixnode { mix_identity } => { ExecuteMsg::DelegateToMixnode { mix_identity } => {
transactions::try_delegate_to_mixnode(deps, info, mix_identity) transactions::try_delegate_to_mixnode(deps, env, info, mix_identity)
} }
ExecuteMsg::UndelegateFromMixnode { mix_identity } => { ExecuteMsg::UndelegateFromMixnode { mix_identity } => {
transactions::try_remove_delegation_from_mixnode(deps, info, mix_identity) transactions::try_remove_delegation_from_mixnode(deps, info, mix_identity)
} }
ExecuteMsg::DelegateToGateway { gateway_identity } => { ExecuteMsg::DelegateToGateway { gateway_identity } => {
transactions::try_delegate_to_gateway(deps, info, gateway_identity) transactions::try_delegate_to_gateway(deps, env, info, gateway_identity)
} }
ExecuteMsg::UndelegateFromGateway { gateway_identity } => { ExecuteMsg::UndelegateFromGateway { gateway_identity } => {
transactions::try_remove_delegation_from_gateway(deps, info, gateway_identity) transactions::try_remove_delegation_from_gateway(deps, info, gateway_identity)
@@ -206,7 +207,110 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result<QueryResponse, Cont
} }
#[entry_point] #[entry_point]
pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> { pub fn migrate(deps: DepsMut, env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
const PREFIX_MIX_DELEGATION: &[u8] = b"md";
const PREFIX_GATEWAY_DELEGATION: &[u8] = b"gd";
const DELEGATION_PAGE_DEFAULT_LIMIT: u32 = 500;
fn calculate_start_value<S: AsRef<str>>(start_after: Option<S>) -> Option<Vec<u8>> {
start_after.as_ref().map(|identity| {
identity
.as_ref()
.as_bytes()
.iter()
.cloned()
.chain(std::iter::once(0))
.collect()
})
}
fn query_mixnode_old_delegations_paged(
deps: Deps,
mix_identity: IdentityKey,
start_after: Option<Addr>,
limit: Option<u32>,
) -> StdResult<PagedMixDelegationsResponse> {
let limit = limit
.unwrap_or(DELEGATION_PAGE_DEFAULT_LIMIT)
.min(DELEGATION_PAGE_MAX_LIMIT) as usize;
let start = calculate_start_value(start_after);
let delegations = mix_old_delegations_read(deps.storage, &mix_identity)
.range(start.as_deref(), None, Order::Ascending)
.take(limit)
.map(|res| {
res.map(|entry| {
Delegation::new(
Addr::unchecked(String::from_utf8(entry.0).expect(
"Non-UTF8 address used as key in bucket. The storage is corrupted!",
)),
coin(entry.1.u128(), DENOM),
)
})
})
.collect::<StdResult<Vec<Delegation>>>()?;
let start_next_after = delegations.last().map(|delegation| delegation.owner());
Ok(PagedMixDelegationsResponse::new(
mix_identity,
delegations,
start_next_after,
))
}
fn query_gateway_old_delegations_paged(
deps: Deps,
gateway_identity: IdentityKey,
start_after: Option<Addr>,
limit: Option<u32>,
) -> StdResult<PagedGatewayDelegationsResponse> {
let limit = limit
.unwrap_or(DELEGATION_PAGE_DEFAULT_LIMIT)
.min(DELEGATION_PAGE_MAX_LIMIT) as usize;
let start = calculate_start_value(start_after);
let delegations = gateway_old_delegations_read(deps.storage, &gateway_identity)
.range(start.as_deref(), None, Order::Ascending)
.take(limit)
.map(|res| {
res.map(|entry| {
Delegation::new(
Addr::unchecked(String::from_utf8(entry.0).expect(
"Non-UTF8 address used as key in bucket. The storage is corrupted!",
)),
coin(entry.1.u128(), DENOM),
)
})
})
.collect::<StdResult<Vec<Delegation>>>()?;
let start_next_after = delegations.last().map(|delegation| delegation.owner());
Ok(PagedGatewayDelegationsResponse::new(
gateway_identity,
delegations,
start_next_after,
))
}
fn mix_old_delegations_read<'a>(
storage: &'a dyn Storage,
mix_identity: IdentityKeyRef,
) -> ReadonlyBucket<'a, Uint128> {
ReadonlyBucket::multilevel(storage, &[PREFIX_MIX_DELEGATION, mix_identity.as_bytes()])
}
fn gateway_old_delegations_read<'a>(
storage: &'a dyn Storage,
gateway_identity: IdentityKeyRef,
) -> ReadonlyBucket<'a, Uint128> {
ReadonlyBucket::multilevel(
storage,
&[PREFIX_GATEWAY_DELEGATION, gateway_identity.as_bytes()],
)
}
fn get_all_mixnodes_identities(deps: &DepsMut) -> Result<Vec<IdentityKey>, ContractError> { fn get_all_mixnodes_identities(deps: &DepsMut) -> Result<Vec<IdentityKey>, ContractError> {
let mut mixnode_bonds = Vec::new(); let mut mixnode_bonds = Vec::new();
let mut start_after = None; let mut start_after = None;
@@ -258,7 +362,7 @@ pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result<Response, C
let mut delegations = Vec::new(); let mut delegations = Vec::new();
let mut start_after = None; let mut start_after = None;
loop { loop {
let mut paged_response = queries::query_mixnode_delegations_paged( let mut paged_response = query_mixnode_old_delegations_paged(
deps.as_ref(), deps.as_ref(),
mix_identity.into(), mix_identity.into(),
start_after, start_after,
@@ -283,7 +387,7 @@ pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result<Response, C
let mut delegations = Vec::new(); let mut delegations = Vec::new();
let mut start_after = None; let mut start_after = None;
loop { loop {
let mut paged_response = queries::query_gateway_delegations_paged( let mut paged_response = query_gateway_old_delegations_paged(
deps.as_ref(), deps.as_ref(),
gateway_identity.into(), gateway_identity.into(),
start_after, start_after,
@@ -305,8 +409,11 @@ pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result<Response, C
for mix_identity in mixnodes_identities { for mix_identity in mixnodes_identities {
let delegations = get_all_mixnode_delegations(&deps, &mix_identity)?; let delegations = get_all_mixnode_delegations(&deps, &mix_identity)?;
for delegation in delegations { for delegation in delegations {
reverse_mix_delegations(deps.storage, &delegation.owner()) let old_delegation_bucket = mix_old_delegations_read(deps.storage, &mix_identity);
.save(mix_identity.as_bytes(), &())?; let amount = old_delegation_bucket.load(delegation.owner().as_bytes())?;
let new_delegation_data = RawDelegationData::new(amount, env.block.height);
let mut delegation_bucket = mix_delegations(deps.storage, &mix_identity);
delegation_bucket.save(delegation.owner().as_bytes(), &new_delegation_data)?;
} }
} }
@@ -314,8 +421,12 @@ pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result<Response, C
for gateway_identity in gateways_identities { for gateway_identity in gateways_identities {
let delegations = get_all_gateway_delegations(&deps, &gateway_identity)?; let delegations = get_all_gateway_delegations(&deps, &gateway_identity)?;
for delegation in delegations { for delegation in delegations {
reverse_gateway_delegations(deps.storage, &delegation.owner()) let old_delegation_bucket =
.save(gateway_identity.as_bytes(), &())?; gateway_old_delegations_read(deps.storage, &gateway_identity);
let amount = old_delegation_bucket.load(delegation.owner().as_bytes())?;
let new_delegation_data = RawDelegationData::new(amount, env.block.height);
let mut delegation_bucket = gateway_delegations(deps.storage, &gateway_identity);
delegation_bucket.save(delegation.owner().as_bytes(), &new_delegation_data)?;
} }
} }
+24 -25
View File
@@ -128,7 +128,7 @@ pub(crate) fn query_mixnode_delegations_paged(
Addr::unchecked(String::from_utf8(entry.0).expect( Addr::unchecked(String::from_utf8(entry.0).expect(
"Non-UTF8 address used as key in bucket. The storage is corrupted!", "Non-UTF8 address used as key in bucket. The storage is corrupted!",
)), )),
coin(entry.1.u128(), DENOM), coin(entry.1.amount.u128(), DENOM),
) )
}) })
}) })
@@ -183,7 +183,7 @@ pub(crate) fn query_mixnode_delegation(
match mix_delegations_read(deps.storage, &mix_identity).may_load(address.as_bytes())? { match mix_delegations_read(deps.storage, &mix_identity).may_load(address.as_bytes())? {
Some(delegation_value) => Ok(Delegation::new( Some(delegation_value) => Ok(Delegation::new(
address, address,
coin(delegation_value.u128(), DENOM), coin(delegation_value.amount.u128(), DENOM),
)), )),
None => Err(ContractError::NoMixnodeDelegationFound { None => Err(ContractError::NoMixnodeDelegationFound {
identity: mix_identity, identity: mix_identity,
@@ -212,7 +212,7 @@ pub(crate) fn query_gateway_delegations_paged(
Addr::unchecked(String::from_utf8(entry.0).expect( Addr::unchecked(String::from_utf8(entry.0).expect(
"Non-UTF8 address used as key in bucket. The storage is corrupted!", "Non-UTF8 address used as key in bucket. The storage is corrupted!",
)), )),
coin(entry.1.u128(), DENOM), coin(entry.1.amount.u128(), DENOM),
) )
}) })
}) })
@@ -267,7 +267,7 @@ pub(crate) fn query_gateway_delegation(
match gateway_delegations_read(deps.storage, &gateway_identity).may_load(address.as_bytes())? { match gateway_delegations_read(deps.storage, &gateway_identity).may_load(address.as_bytes())? {
Some(delegation_value) => Ok(Delegation::new( Some(delegation_value) => Ok(Delegation::new(
address, address,
coin(delegation_value.u128(), DENOM), coin(delegation_value.amount.u128(), DENOM),
)), )),
None => Err(ContractError::NoGatewayDelegationFound { None => Err(ContractError::NoGatewayDelegationFound {
identity: gateway_identity, identity: gateway_identity,
@@ -282,10 +282,12 @@ mod tests {
use crate::state::State; use crate::state::State;
use crate::storage::{config, gateway_delegations, gateways, mix_delegations, mixnodes}; use crate::storage::{config, gateway_delegations, gateways, mix_delegations, mixnodes};
use crate::support::tests::helpers; use crate::support::tests::helpers;
use crate::support::tests::helpers::{good_gateway_bond, good_mixnode_bond}; use crate::support::tests::helpers::{
good_gateway_bond, good_mixnode_bond, raw_delegation_fixture,
};
use crate::transactions; use crate::transactions;
use cosmwasm_std::testing::mock_info; use cosmwasm_std::testing::mock_info;
use cosmwasm_std::{Addr, Storage, Uint128}; use cosmwasm_std::{Addr, Storage};
use mixnet_contract::{Gateway, MixNode}; use mixnet_contract::{Gateway, MixNode};
#[test] #[test]
@@ -632,14 +634,12 @@ mod tests {
#[cfg(test)] #[cfg(test)]
mod querying_for_mixnode_delegations_paged { mod querying_for_mixnode_delegations_paged {
use super::*; use super::*;
use crate::storage::mix_delegations;
use cosmwasm_std::Uint128;
fn store_n_delegations(n: u32, storage: &mut dyn Storage, node_identity: &IdentityKey) { fn store_n_delegations(n: u32, storage: &mut dyn Storage, node_identity: &IdentityKey) {
for i in 0..n { for i in 0..n {
let address = format!("address{}", i); let address = format!("address{}", i);
mix_delegations(storage, node_identity) mix_delegations(storage, node_identity)
.save(address.as_bytes(), &Uint128(42)) .save(address.as_bytes(), &raw_delegation_fixture(42))
.unwrap(); .unwrap();
} }
} }
@@ -711,7 +711,7 @@ mod tests {
let node_identity: IdentityKey = "foo".into(); let node_identity: IdentityKey = "foo".into();
mix_delegations(&mut deps.storage, &node_identity) mix_delegations(&mut deps.storage, &node_identity)
.save("1".as_bytes(), &Uint128(42)) .save("1".as_bytes(), &raw_delegation_fixture(42))
.unwrap(); .unwrap();
let per_page = 2; let per_page = 2;
@@ -728,7 +728,7 @@ mod tests {
// save another // save another
mix_delegations(&mut deps.storage, &node_identity) mix_delegations(&mut deps.storage, &node_identity)
.save("2".as_bytes(), &Uint128(42)) .save("2".as_bytes(), &raw_delegation_fixture(42))
.unwrap(); .unwrap();
// page1 should have 2 results on it // page1 should have 2 results on it
@@ -742,7 +742,7 @@ mod tests {
assert_eq!(2, page1.delegations.len()); assert_eq!(2, page1.delegations.len());
mix_delegations(&mut deps.storage, &node_identity) mix_delegations(&mut deps.storage, &node_identity)
.save("3".as_bytes(), &Uint128(42)) .save("3".as_bytes(), &raw_delegation_fixture(42))
.unwrap(); .unwrap();
// page1 still has 2 results // page1 still has 2 results
@@ -769,7 +769,7 @@ mod tests {
// save another one // save another one
mix_delegations(&mut deps.storage, &node_identity) mix_delegations(&mut deps.storage, &node_identity)
.save("4".as_bytes(), &Uint128(42)) .save("4".as_bytes(), &raw_delegation_fixture(42))
.unwrap(); .unwrap();
let start_after = Addr::unchecked("2"); let start_after = Addr::unchecked("2");
@@ -793,7 +793,7 @@ mod tests {
let delegation_owner = Addr::unchecked("bar"); let delegation_owner = Addr::unchecked("bar");
mix_delegations(&mut deps.storage, &node_identity) mix_delegations(&mut deps.storage, &node_identity)
.save(delegation_owner.as_bytes(), &Uint128(42)) .save(delegation_owner.as_bytes(), &raw_delegation_fixture(42))
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@@ -825,7 +825,7 @@ mod tests {
// add delegation from a different address // add delegation from a different address
mix_delegations(&mut deps.storage, &node_identity1) mix_delegations(&mut deps.storage, &node_identity1)
.save(delegation_owner2.as_bytes(), &Uint128(42)) .save(delegation_owner2.as_bytes(), &raw_delegation_fixture(42))
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@@ -842,7 +842,7 @@ mod tests {
// add delegation for a different node // add delegation for a different node
mix_delegations(&mut deps.storage, &node_identity2) mix_delegations(&mut deps.storage, &node_identity2)
.save(delegation_owner1.as_bytes(), &Uint128(42)) .save(delegation_owner1.as_bytes(), &raw_delegation_fixture(42))
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@@ -1019,13 +1019,12 @@ mod tests {
mod querying_for_gateway_delegations_paged { mod querying_for_gateway_delegations_paged {
use super::*; use super::*;
use crate::storage::gateway_delegations; use crate::storage::gateway_delegations;
use cosmwasm_std::Uint128;
fn store_n_delegations(n: u32, storage: &mut dyn Storage, node_identity: &IdentityKey) { fn store_n_delegations(n: u32, storage: &mut dyn Storage, node_identity: &IdentityKey) {
for i in 0..n { for i in 0..n {
let address = format!("address{}", i); let address = format!("address{}", i);
gateway_delegations(storage, node_identity) gateway_delegations(storage, node_identity)
.save(address.as_bytes(), &Uint128(42)) .save(address.as_bytes(), &raw_delegation_fixture(42))
.unwrap(); .unwrap();
} }
} }
@@ -1097,7 +1096,7 @@ mod tests {
let node_identity: IdentityKey = "foo".into(); let node_identity: IdentityKey = "foo".into();
gateway_delegations(&mut deps.storage, &node_identity) gateway_delegations(&mut deps.storage, &node_identity)
.save("1".as_bytes(), &Uint128(42)) .save("1".as_bytes(), &raw_delegation_fixture(42))
.unwrap(); .unwrap();
let per_page = 2; let per_page = 2;
@@ -1114,7 +1113,7 @@ mod tests {
// save another // save another
gateway_delegations(&mut deps.storage, &node_identity) gateway_delegations(&mut deps.storage, &node_identity)
.save("2".as_bytes(), &Uint128(42)) .save("2".as_bytes(), &raw_delegation_fixture(42))
.unwrap(); .unwrap();
// page1 should have 2 results on it // page1 should have 2 results on it
@@ -1128,7 +1127,7 @@ mod tests {
assert_eq!(2, page1.delegations.len()); assert_eq!(2, page1.delegations.len());
gateway_delegations(&mut deps.storage, &node_identity) gateway_delegations(&mut deps.storage, &node_identity)
.save("3".as_bytes(), &Uint128(42)) .save("3".as_bytes(), &raw_delegation_fixture(42))
.unwrap(); .unwrap();
// page1 still has 2 results // page1 still has 2 results
@@ -1155,7 +1154,7 @@ mod tests {
// save another one // save another one
gateway_delegations(&mut deps.storage, &node_identity) gateway_delegations(&mut deps.storage, &node_identity)
.save("4".as_bytes(), &Uint128(42)) .save("4".as_bytes(), &raw_delegation_fixture(42))
.unwrap(); .unwrap();
let start_after = Addr::unchecked("2"); let start_after = Addr::unchecked("2");
@@ -1179,7 +1178,7 @@ mod tests {
let delegation_owner = Addr::unchecked("bar"); let delegation_owner = Addr::unchecked("bar");
gateway_delegations(&mut deps.storage, &node_identity) gateway_delegations(&mut deps.storage, &node_identity)
.save(delegation_owner.as_bytes(), &Uint128(42)) .save(delegation_owner.as_bytes(), &raw_delegation_fixture(42))
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@@ -1211,7 +1210,7 @@ mod tests {
// add delegation from a different address // add delegation from a different address
gateway_delegations(&mut deps.storage, &node_identity1) gateway_delegations(&mut deps.storage, &node_identity1)
.save(delegation_owner2.as_bytes(), &Uint128(42)) .save(delegation_owner2.as_bytes(), &raw_delegation_fixture(42))
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@@ -1228,7 +1227,7 @@ mod tests {
// add delegation for a different node // add delegation for a different node
gateway_delegations(&mut deps.storage, &node_identity2) gateway_delegations(&mut deps.storage, &node_identity2)
.save(delegation_owner1.as_bytes(), &Uint128(42)) .save(delegation_owner1.as_bytes(), &raw_delegation_fixture(42))
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
+34 -25
View File
@@ -10,7 +10,7 @@ use cosmwasm_storage::{
}; };
use mixnet_contract::{ use mixnet_contract::{
Addr, GatewayBond, IdentityKey, IdentityKeyRef, Layer, LayerDistribution, MixNodeBond, Addr, GatewayBond, IdentityKey, IdentityKeyRef, Layer, LayerDistribution, MixNodeBond,
StateParams, RawDelegationData, StateParams,
}; };
// storage prefixes // storage prefixes
@@ -193,11 +193,11 @@ pub(crate) fn increase_mix_delegated_stakes(
); );
// and for each of them increase the stake proportionally to the reward // and for each of them increase the stake proportionally to the reward
for (delegator_address, amount) in delegations_chunk.into_iter() { for (delegator_address, mut delegation) in delegations_chunk.into_iter() {
let reward = amount * scaled_reward_rate; let reward = delegation.amount * scaled_reward_rate;
let new_amount = amount + reward; delegation.amount += reward;
total_rewarded += reward; total_rewarded += reward;
mix_delegations(storage, mix_identity).save(&delegator_address, &new_amount)?; mix_delegations(storage, mix_identity).save(&delegator_address, &delegation)?;
} }
} }
@@ -237,11 +237,11 @@ pub(crate) fn increase_gateway_delegated_stakes(
); );
// and for each of them increase the stake proportionally to the reward // and for each of them increase the stake proportionally to the reward
for (delegator_address, amount) in delegations_chunk.into_iter() { for (delegator_address, mut delegation) in delegations_chunk.into_iter() {
let reward = amount * scaled_reward_rate; let reward = delegation.amount * scaled_reward_rate;
let new_amount = amount + reward; delegation.amount += reward;
total_rewarded += reward; total_rewarded += reward;
gateway_delegations(storage, gateway_identity).save(&delegator_address, &new_amount)?; gateway_delegations(storage, gateway_identity).save(&delegator_address, &delegation)?;
} }
} }
@@ -293,14 +293,14 @@ pub fn gateways_owners_read(storage: &dyn Storage) -> ReadonlyBucket<IdentityKey
pub fn mix_delegations<'a>( pub fn mix_delegations<'a>(
storage: &'a mut dyn Storage, storage: &'a mut dyn Storage,
mix_identity: IdentityKeyRef, mix_identity: IdentityKeyRef,
) -> Bucket<'a, Uint128> { ) -> Bucket<'a, RawDelegationData> {
Bucket::multilevel(storage, &[PREFIX_MIX_DELEGATION, mix_identity.as_bytes()]) Bucket::multilevel(storage, &[PREFIX_MIX_DELEGATION, mix_identity.as_bytes()])
} }
pub fn mix_delegations_read<'a>( pub fn mix_delegations_read<'a>(
storage: &'a dyn Storage, storage: &'a dyn Storage,
mix_identity: IdentityKeyRef, mix_identity: IdentityKeyRef,
) -> ReadonlyBucket<'a, Uint128> { ) -> ReadonlyBucket<'a, RawDelegationData> {
ReadonlyBucket::multilevel(storage, &[PREFIX_MIX_DELEGATION, mix_identity.as_bytes()]) ReadonlyBucket::multilevel(storage, &[PREFIX_MIX_DELEGATION, mix_identity.as_bytes()])
} }
@@ -318,7 +318,7 @@ pub fn reverse_mix_delegations_read<'a>(
pub fn gateway_delegations<'a>( pub fn gateway_delegations<'a>(
storage: &'a mut dyn Storage, storage: &'a mut dyn Storage,
gateway_identity: IdentityKeyRef, gateway_identity: IdentityKeyRef,
) -> Bucket<'a, Uint128> { ) -> Bucket<'a, RawDelegationData> {
Bucket::multilevel( Bucket::multilevel(
storage, storage,
&[PREFIX_GATEWAY_DELEGATION, gateway_identity.as_bytes()], &[PREFIX_GATEWAY_DELEGATION, gateway_identity.as_bytes()],
@@ -328,7 +328,7 @@ pub fn gateway_delegations<'a>(
pub fn gateway_delegations_read<'a>( pub fn gateway_delegations_read<'a>(
storage: &'a dyn Storage, storage: &'a dyn Storage,
gateway_identity: IdentityKeyRef, gateway_identity: IdentityKeyRef,
) -> ReadonlyBucket<'a, Uint128> { ) -> ReadonlyBucket<'a, RawDelegationData> {
ReadonlyBucket::multilevel( ReadonlyBucket::multilevel(
storage, storage,
&[PREFIX_GATEWAY_DELEGATION, gateway_identity.as_bytes()], &[PREFIX_GATEWAY_DELEGATION, gateway_identity.as_bytes()],
@@ -382,6 +382,7 @@ mod tests {
use super::*; use super::*;
use crate::support::tests::helpers::{ use crate::support::tests::helpers::{
gateway_bond_fixture, gateway_fixture, mix_node_fixture, mixnode_bond_fixture, gateway_bond_fixture, gateway_fixture, mix_node_fixture, mixnode_bond_fixture,
raw_delegation_fixture,
}; };
use config::defaults::DENOM; use config::defaults::DENOM;
use cosmwasm_std::testing::MockStorage; use cosmwasm_std::testing::MockStorage;
@@ -523,7 +524,10 @@ mod tests {
let delegator_address = Addr::unchecked("bob"); let delegator_address = Addr::unchecked("bob");
mix_delegations(&mut deps.storage, &node_identity) mix_delegations(&mut deps.storage, &node_identity)
.save(delegator_address.as_bytes(), &Uint128(1000)) .save(
delegator_address.as_bytes(),
&RawDelegationData::new(1000u128.into(), 42),
)
.unwrap(); .unwrap();
let total_increase = let total_increase =
@@ -532,8 +536,9 @@ mod tests {
assert_eq!(Uint128(1), total_increase); assert_eq!(Uint128(1), total_increase);
// amount is incremented, block height remains the same
assert_eq!( assert_eq!(
Uint128(1001), RawDelegationData::new(1001u128.into(), 42),
mix_delegations_read(&mut deps.storage, &node_identity) mix_delegations_read(&mut deps.storage, &node_identity)
.load(delegator_address.as_bytes()) .load(delegator_address.as_bytes())
.unwrap() .unwrap()
@@ -551,7 +556,7 @@ mod tests {
for i in 0..100 { for i in 0..100 {
let delegator_address = Addr::unchecked(format!("address{}", i)); let delegator_address = Addr::unchecked(format!("address{}", i));
mix_delegations(&mut deps.storage, &node_identity) mix_delegations(&mut deps.storage, &node_identity)
.save(delegator_address.as_bytes(), &Uint128(1000)) .save(delegator_address.as_bytes(), &raw_delegation_fixture(1000))
.unwrap(); .unwrap();
} }
@@ -564,7 +569,7 @@ mod tests {
for i in 0..100 { for i in 0..100 {
let delegator_address = Addr::unchecked(format!("address{}", i)); let delegator_address = Addr::unchecked(format!("address{}", i));
assert_eq!( assert_eq!(
Uint128(1001), raw_delegation_fixture(1001),
mix_delegations_read(&mut deps.storage, &node_identity) mix_delegations_read(&mut deps.storage, &node_identity)
.load(delegator_address.as_bytes()) .load(delegator_address.as_bytes())
.unwrap() .unwrap()
@@ -583,7 +588,7 @@ mod tests {
for i in 0..queries::DELEGATION_PAGE_MAX_LIMIT * 10 { for i in 0..queries::DELEGATION_PAGE_MAX_LIMIT * 10 {
let delegator_address = Addr::unchecked(format!("address{}", i)); let delegator_address = Addr::unchecked(format!("address{}", i));
mix_delegations(&mut deps.storage, &node_identity) mix_delegations(&mut deps.storage, &node_identity)
.save(delegator_address.as_bytes(), &Uint128(1000)) .save(delegator_address.as_bytes(), &raw_delegation_fixture(1000))
.unwrap(); .unwrap();
} }
@@ -599,7 +604,7 @@ mod tests {
for i in 0..queries::DELEGATION_PAGE_MAX_LIMIT * 10 { for i in 0..queries::DELEGATION_PAGE_MAX_LIMIT * 10 {
let delegator_address = Addr::unchecked(format!("address{}", i)); let delegator_address = Addr::unchecked(format!("address{}", i));
assert_eq!( assert_eq!(
Uint128(1001), raw_delegation_fixture(1001),
mix_delegations_read(&mut deps.storage, &node_identity) mix_delegations_read(&mut deps.storage, &node_identity)
.load(delegator_address.as_bytes()) .load(delegator_address.as_bytes())
.unwrap() .unwrap()
@@ -716,7 +721,10 @@ mod tests {
let delegator_address = Addr::unchecked("bob"); let delegator_address = Addr::unchecked("bob");
gateway_delegations(&mut deps.storage, &node_identity) gateway_delegations(&mut deps.storage, &node_identity)
.save(delegator_address.as_bytes(), &Uint128(1000)) .save(
delegator_address.as_bytes(),
&RawDelegationData::new(1000u128.into(), 42),
)
.unwrap(); .unwrap();
let total_increase = increase_gateway_delegated_stakes( let total_increase = increase_gateway_delegated_stakes(
@@ -728,8 +736,9 @@ mod tests {
assert_eq!(Uint128(1), total_increase); assert_eq!(Uint128(1), total_increase);
// amount is incremented, block height remains the same
assert_eq!( assert_eq!(
Uint128(1001), RawDelegationData::new(1001u128.into(), 42),
gateway_delegations_read(&mut deps.storage, &node_identity) gateway_delegations_read(&mut deps.storage, &node_identity)
.load(delegator_address.as_bytes()) .load(delegator_address.as_bytes())
.unwrap() .unwrap()
@@ -747,7 +756,7 @@ mod tests {
for i in 0..100 { for i in 0..100 {
let delegator_address = Addr::unchecked(format!("address{}", i)); let delegator_address = Addr::unchecked(format!("address{}", i));
gateway_delegations(&mut deps.storage, &node_identity) gateway_delegations(&mut deps.storage, &node_identity)
.save(delegator_address.as_bytes(), &Uint128(1000)) .save(delegator_address.as_bytes(), &raw_delegation_fixture(1000))
.unwrap(); .unwrap();
} }
@@ -763,7 +772,7 @@ mod tests {
for i in 0..100 { for i in 0..100 {
let delegator_address = Addr::unchecked(format!("address{}", i)); let delegator_address = Addr::unchecked(format!("address{}", i));
assert_eq!( assert_eq!(
Uint128(1001), raw_delegation_fixture(1001),
gateway_delegations_read(&mut deps.storage, &node_identity) gateway_delegations_read(&mut deps.storage, &node_identity)
.load(delegator_address.as_bytes()) .load(delegator_address.as_bytes())
.unwrap() .unwrap()
@@ -782,7 +791,7 @@ mod tests {
for i in 0..queries::DELEGATION_PAGE_MAX_LIMIT * 10 { for i in 0..queries::DELEGATION_PAGE_MAX_LIMIT * 10 {
let delegator_address = Addr::unchecked(format!("address{}", i)); let delegator_address = Addr::unchecked(format!("address{}", i));
gateway_delegations(&mut deps.storage, &node_identity) gateway_delegations(&mut deps.storage, &node_identity)
.save(delegator_address.as_bytes(), &Uint128(1000)) .save(delegator_address.as_bytes(), &raw_delegation_fixture(1000))
.unwrap(); .unwrap();
} }
@@ -801,7 +810,7 @@ mod tests {
for i in 0..queries::DELEGATION_PAGE_MAX_LIMIT * 10 { for i in 0..queries::DELEGATION_PAGE_MAX_LIMIT * 10 {
let delegator_address = Addr::unchecked(format!("address{}", i)); let delegator_address = Addr::unchecked(format!("address{}", i));
assert_eq!( assert_eq!(
Uint128(1001), raw_delegation_fixture(1001),
gateway_delegations_read(&mut deps.storage, &node_identity) gateway_delegations_read(&mut deps.storage, &node_identity)
.load(delegator_address.as_bytes()) .load(delegator_address.as_bytes())
.unwrap() .unwrap()
+6 -2
View File
@@ -5,7 +5,6 @@ pub mod helpers {
use crate::contract::{instantiate, INITIAL_MIXNODE_BOND}; use crate::contract::{instantiate, INITIAL_MIXNODE_BOND};
use crate::transactions::{try_add_gateway, try_add_mixnode}; use crate::transactions::{try_add_gateway, try_add_mixnode};
use config::defaults::DENOM; use config::defaults::DENOM;
use cosmwasm_std::coin;
use cosmwasm_std::from_binary; use cosmwasm_std::from_binary;
use cosmwasm_std::testing::mock_dependencies; use cosmwasm_std::testing::mock_dependencies;
use cosmwasm_std::testing::mock_env; use cosmwasm_std::testing::mock_env;
@@ -16,10 +15,11 @@ pub mod helpers {
use cosmwasm_std::Addr; use cosmwasm_std::Addr;
use cosmwasm_std::Coin; use cosmwasm_std::Coin;
use cosmwasm_std::OwnedDeps; use cosmwasm_std::OwnedDeps;
use cosmwasm_std::{coin, Uint128};
use cosmwasm_std::{Empty, MemoryStorage}; use cosmwasm_std::{Empty, MemoryStorage};
use mixnet_contract::{ use mixnet_contract::{
Gateway, GatewayBond, InstantiateMsg, Layer, MixNode, MixNodeBond, PagedGatewayResponse, Gateway, GatewayBond, InstantiateMsg, Layer, MixNode, MixNodeBond, PagedGatewayResponse,
PagedMixnodeResponse, QueryMsg, PagedMixnodeResponse, QueryMsg, RawDelegationData,
}; };
pub fn add_mixnode( pub fn add_mixnode(
@@ -159,6 +159,10 @@ pub mod helpers {
GatewayBond::new(coin(50, DENOM), Addr::unchecked("foo"), gateway) GatewayBond::new(coin(50, DENOM), Addr::unchecked("foo"), gateway)
} }
pub fn raw_delegation_fixture(amount: u128) -> RawDelegationData {
RawDelegationData::new(Uint128(amount), 42)
}
pub fn query_contract_balance( pub fn query_contract_balance(
address: Addr, address: Addr,
deps: OwnedDeps<MockStorage, MockApi, MockQuerier>, deps: OwnedDeps<MockStorage, MockApi, MockQuerier>,
+305 -48
View File
@@ -7,11 +7,12 @@ use crate::queries;
use crate::storage::*; use crate::storage::*;
use config::defaults::DENOM; use config::defaults::DENOM;
use cosmwasm_std::{ use cosmwasm_std::{
attr, coins, BankMsg, Coin, Decimal, DepsMut, MessageInfo, Order, Response, StdResult, Uint128, attr, coins, BankMsg, Coin, Decimal, DepsMut, Env, MessageInfo, Order, Response, StdResult,
Uint128,
}; };
use cosmwasm_storage::ReadonlyBucket; use cosmwasm_storage::ReadonlyBucket;
use mixnet_contract::{ use mixnet_contract::{
Gateway, GatewayBond, IdentityKey, Layer, MixNode, MixNodeBond, StateParams, Gateway, GatewayBond, IdentityKey, Layer, MixNode, MixNodeBond, RawDelegationData, StateParams,
}; };
const OLD_DELEGATIONS_CHUNK_SIZE: usize = 500; const OLD_DELEGATIONS_CHUNK_SIZE: usize = 500;
@@ -23,7 +24,7 @@ const OLD_DELEGATIONS_CHUNK_SIZE: usize = 500;
// 3. The node unbonds // 3. The node unbonds
// 4. Some of the addresses that delegated in the past have not removed the delegation yet // 4. Some of the addresses that delegated in the past have not removed the delegation yet
// 5. The node rebonds with the same identity // 5. The node rebonds with the same identity
fn find_old_delegations(delegations_bucket: ReadonlyBucket<Uint128>) -> StdResult<Coin> { fn find_old_delegations(delegations_bucket: ReadonlyBucket<RawDelegationData>) -> StdResult<Coin> {
// I think it's incredibly unlikely to ever read more than that // I think it's incredibly unlikely to ever read more than that
// but in case we do, we should guard ourselves against possible // but in case we do, we should guard ourselves against possible
// out of memory errors (wasm contracts can only allocate at most 2MB // out of memory errors (wasm contracts can only allocate at most 2MB
@@ -45,7 +46,7 @@ fn find_old_delegations(delegations_bucket: ReadonlyBucket<Uint128>) -> StdResul
continue; continue;
} }
let value = delegation?.1; let value = delegation?.1.amount;
total_delegation.amount += value; total_delegation.amount += value;
} }
@@ -540,6 +541,7 @@ fn validate_delegation_stake(delegation: &[Coin]) -> Result<(), ContractError> {
pub(crate) fn try_delegate_to_mixnode( pub(crate) fn try_delegate_to_mixnode(
deps: DepsMut, deps: DepsMut,
env: Env,
info: MessageInfo, info: MessageInfo,
mix_identity: IdentityKey, mix_identity: IdentityKey,
) -> Result<Response, ContractError> { ) -> Result<Response, ContractError> {
@@ -565,12 +567,13 @@ pub(crate) fn try_delegate_to_mixnode(
let sender_bytes = info.sender.as_bytes(); let sender_bytes = info.sender.as_bytes();
// write the delegation // write the delegation
match delegation_bucket.may_load(sender_bytes)? { let new_amount = match delegation_bucket.may_load(sender_bytes)? {
Some(existing_delegation) => { Some(existing_delegation) => existing_delegation.amount + info.funds[0].amount,
delegation_bucket.save(sender_bytes, &(existing_delegation + info.funds[0].amount))? None => info.funds[0].amount,
} };
None => delegation_bucket.save(sender_bytes, &info.funds[0].amount)?, // the block height is reset, if it existed
} let new_delegation = RawDelegationData::new(new_amount, env.block.height);
delegation_bucket.save(sender_bytes, &new_delegation)?;
reverse_mix_delegations(deps.storage, &info.sender).save(mix_identity.as_bytes(), &())?; reverse_mix_delegations(deps.storage, &info.sender).save(mix_identity.as_bytes(), &())?;
@@ -593,7 +596,7 @@ pub(crate) fn try_remove_delegation_from_mixnode(
// send delegated funds back to the delegation owner // send delegated funds back to the delegation owner
let messages = vec![BankMsg::Send { let messages = vec![BankMsg::Send {
to_address: info.sender.to_string(), to_address: info.sender.to_string(),
amount: coins(delegation.u128(), DENOM), amount: coins(delegation.amount.u128(), DENOM),
} }
.into()]; .into()];
@@ -606,7 +609,7 @@ pub(crate) fn try_remove_delegation_from_mixnode(
existing_bond.total_delegation.amount = existing_bond existing_bond.total_delegation.amount = existing_bond
.total_delegation .total_delegation
.amount .amount
.checked_sub(delegation) .checked_sub(delegation.amount)
.unwrap(); .unwrap();
mixnodes_bucket.save(mix_identity.as_bytes(), &existing_bond)?; mixnodes_bucket.save(mix_identity.as_bytes(), &existing_bond)?;
} }
@@ -627,6 +630,7 @@ pub(crate) fn try_remove_delegation_from_mixnode(
pub(crate) fn try_delegate_to_gateway( pub(crate) fn try_delegate_to_gateway(
deps: DepsMut, deps: DepsMut,
env: Env,
info: MessageInfo, info: MessageInfo,
gateway_identity: IdentityKey, gateway_identity: IdentityKey,
) -> Result<Response, ContractError> { ) -> Result<Response, ContractError> {
@@ -652,12 +656,13 @@ pub(crate) fn try_delegate_to_gateway(
let sender_bytes = info.sender.as_bytes(); let sender_bytes = info.sender.as_bytes();
// write the delegation // write the delegation
match delegation_bucket.may_load(sender_bytes)? { let new_amount = match delegation_bucket.may_load(sender_bytes)? {
Some(existing_delegation) => { Some(existing_delegation) => existing_delegation.amount + info.funds[0].amount,
delegation_bucket.save(sender_bytes, &(existing_delegation + info.funds[0].amount))? None => info.funds[0].amount,
} };
None => delegation_bucket.save(sender_bytes, &info.funds[0].amount)?, // the block height is reset, if it existed
} let new_delegation = RawDelegationData::new(new_amount, env.block.height);
delegation_bucket.save(sender_bytes, &new_delegation)?;
reverse_gateway_delegations(deps.storage, &info.sender) reverse_gateway_delegations(deps.storage, &info.sender)
.save(gateway_identity.as_bytes(), &())?; .save(gateway_identity.as_bytes(), &())?;
@@ -682,7 +687,7 @@ pub(crate) fn try_remove_delegation_from_gateway(
// send delegated funds back to the delegation owner // send delegated funds back to the delegation owner
let messages = vec![BankMsg::Send { let messages = vec![BankMsg::Send {
to_address: info.sender.to_string(), to_address: info.sender.to_string(),
amount: coins(delegation.u128(), DENOM), amount: coins(delegation.amount.u128(), DENOM),
} }
.into()]; .into()];
@@ -697,7 +702,7 @@ pub(crate) fn try_remove_delegation_from_gateway(
existing_bond.total_delegation.amount = existing_bond existing_bond.total_delegation.amount = existing_bond
.total_delegation .total_delegation
.amount .amount
.checked_sub(delegation) .checked_sub(delegation.amount)
.unwrap(); .unwrap();
gateways_bucket.save(gateway_identity.as_bytes(), &existing_bond)?; gateways_bucket.save(gateway_identity.as_bytes(), &existing_bond)?;
} }
@@ -734,7 +739,7 @@ pub mod tests {
use crate::support::tests::helpers; use crate::support::tests::helpers;
use crate::support::tests::helpers::{ use crate::support::tests::helpers::{
add_gateway, add_mixnode, gateway_fixture, good_gateway_bond, good_mixnode_bond, add_gateway, add_mixnode, gateway_fixture, good_gateway_bond, good_mixnode_bond,
mix_node_fixture, mix_node_fixture, raw_delegation_fixture,
}; };
use cosmwasm_std::testing::{mock_env, mock_info}; use cosmwasm_std::testing::{mock_env, mock_info};
use cosmwasm_std::{coin, coins, from_binary, Addr, Uint128}; use cosmwasm_std::{coin, coins, from_binary, Addr, Uint128};
@@ -1802,7 +1807,7 @@ pub mod tests {
.unwrap(); .unwrap();
mix_delegations(&mut deps.storage, &node_identity) mix_delegations(&mut deps.storage, &node_identity)
.save(b"delegator", &Uint128(initial_delegation)) .save(b"delegator", &raw_delegation_fixture(initial_delegation))
.unwrap(); .unwrap();
let bond_reward_rate = read_mixnode_epoch_bond_reward_rate(deps.as_ref().storage); let bond_reward_rate = read_mixnode_epoch_bond_reward_rate(deps.as_ref().storage);
@@ -1901,7 +1906,7 @@ pub mod tests {
.unwrap(); .unwrap();
gateway_delegations(&mut deps.storage, &node_identity) gateway_delegations(&mut deps.storage, &node_identity)
.save(b"delegator", &Uint128(initial_delegation)) .save(b"delegator", &raw_delegation_fixture(initial_delegation))
.unwrap(); .unwrap();
let bond_reward_rate = read_gateway_epoch_bond_reward_rate(deps.as_ref().storage); let bond_reward_rate = read_gateway_epoch_bond_reward_rate(deps.as_ref().storage);
@@ -2027,6 +2032,7 @@ pub mod tests {
}), }),
try_delegate_to_mixnode( try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info("sender", &coins(123, DENOM)), mock_info("sender", &coins(123, DENOM)),
"non-existent-mix-identity".into() "non-existent-mix-identity".into()
) )
@@ -2043,13 +2049,14 @@ pub mod tests {
let delegation = coin(123, DENOM); let delegation = coin(123, DENOM);
assert!(try_delegate_to_mixnode( assert!(try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &vec![delegation.clone()]), mock_info(delegation_owner.as_str(), &vec![delegation.clone()]),
identity.clone() identity.clone()
) )
.is_ok()); .is_ok());
assert_eq!( assert_eq!(
delegation.amount, RawDelegationData::new(delegation.amount, mock_env().block.height),
mix_delegations_read(&deps.storage, &identity) mix_delegations_read(&deps.storage, &identity)
.load(delegation_owner.as_bytes()) .load(delegation_owner.as_bytes())
.unwrap() .unwrap()
@@ -2086,6 +2093,7 @@ pub mod tests {
}), }),
try_delegate_to_mixnode( try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(123, DENOM)), mock_info(delegation_owner.as_str(), &coins(123, DENOM)),
identity identity
) )
@@ -2105,13 +2113,14 @@ pub mod tests {
assert!(try_delegate_to_mixnode( assert!(try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &vec![delegation.clone()]), mock_info(delegation_owner.as_str(), &vec![delegation.clone()]),
identity.clone() identity.clone()
) )
.is_ok()); .is_ok());
assert_eq!( assert_eq!(
delegation.amount, RawDelegationData::new(delegation.amount, mock_env().block.height),
mix_delegations_read(&deps.storage, &identity) mix_delegations_read(&deps.storage, &identity)
.load(delegation_owner.as_bytes()) .load(delegation_owner.as_bytes())
.unwrap() .unwrap()
@@ -2144,6 +2153,7 @@ pub mod tests {
try_delegate_to_mixnode( try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &vec![delegation1.clone()]), mock_info(delegation_owner.as_str(), &vec![delegation1.clone()]),
identity.clone(), identity.clone(),
) )
@@ -2151,13 +2161,17 @@ pub mod tests {
try_delegate_to_mixnode( try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &vec![delegation2.clone()]), mock_info(delegation_owner.as_str(), &vec![delegation2.clone()]),
identity.clone(), identity.clone(),
) )
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
delegation1.amount + delegation2.amount, RawDelegationData::new(
delegation1.amount + delegation2.amount,
mock_env().block.height
),
mix_delegations_read(&deps.storage, &identity) mix_delegations_read(&deps.storage, &identity)
.load(delegation_owner.as_bytes()) .load(delegation_owner.as_bytes())
.unwrap() .unwrap()
@@ -2179,6 +2193,106 @@ pub mod tests {
) )
} }
#[test]
fn block_height_is_updated_on_new_delegation() {
let mut deps = helpers::init_contract();
let mixnode_owner = "bob";
let identity = add_mixnode(mixnode_owner, good_mixnode_bond(), &mut deps);
let delegation_owner = Addr::unchecked("sender");
let delegation = coin(100, DENOM);
let env1 = mock_env();
let mut env2 = mock_env();
let initial_height = env1.block.height;
let updated_height = initial_height + 42;
// second env has grown in block height
env2.block.height = updated_height;
try_delegate_to_mixnode(
deps.as_mut(),
env1,
mock_info(delegation_owner.as_str(), &vec![delegation.clone()]),
identity.clone(),
)
.unwrap();
assert_eq!(
RawDelegationData::new(delegation.amount, initial_height),
mix_delegations_read(&deps.storage, &identity)
.load(delegation_owner.as_bytes())
.unwrap()
);
try_delegate_to_mixnode(
deps.as_mut(),
env2,
mock_info(delegation_owner.as_str(), &vec![delegation.clone()]),
identity.clone(),
)
.unwrap();
assert_eq!(
RawDelegationData::new(delegation.amount + delegation.amount, updated_height),
mix_delegations_read(&deps.storage, &identity)
.load(delegation_owner.as_bytes())
.unwrap()
);
}
#[test]
fn block_height_is_not_updated_on_different_delegator() {
let mut deps = helpers::init_contract();
let mixnode_owner = "bob";
let identity = add_mixnode(mixnode_owner, good_mixnode_bond(), &mut deps);
let delegation_owner1 = Addr::unchecked("sender1");
let delegation_owner2 = Addr::unchecked("sender2");
let delegation1 = coin(100, DENOM);
let delegation2 = coin(120, DENOM);
let env1 = mock_env();
let mut env2 = mock_env();
let initial_height = env1.block.height;
let second_height = initial_height + 42;
// second env has grown in block height
env2.block.height = second_height;
try_delegate_to_mixnode(
deps.as_mut(),
env1,
mock_info(delegation_owner1.as_str(), &vec![delegation1.clone()]),
identity.clone(),
)
.unwrap();
assert_eq!(
RawDelegationData::new(delegation1.amount, initial_height),
mix_delegations_read(&deps.storage, &identity)
.load(delegation_owner1.as_bytes())
.unwrap()
);
try_delegate_to_mixnode(
deps.as_mut(),
env2,
mock_info(delegation_owner2.as_str(), &vec![delegation2.clone()]),
identity.clone(),
)
.unwrap();
assert_eq!(
RawDelegationData::new(delegation1.amount, initial_height),
mix_delegations_read(&deps.storage, &identity)
.load(delegation_owner1.as_bytes())
.unwrap()
);
assert_eq!(
RawDelegationData::new(delegation2.amount, second_height),
mix_delegations_read(&deps.storage, &identity)
.load(delegation_owner2.as_bytes())
.unwrap()
);
}
#[test] #[test]
fn is_disallowed_for_already_delegated_node_if_it_unbonded() { fn is_disallowed_for_already_delegated_node_if_it_unbonded() {
let mut deps = helpers::init_contract(); let mut deps = helpers::init_contract();
@@ -2189,6 +2303,7 @@ pub mod tests {
try_delegate_to_mixnode( try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(100, DENOM)), mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
identity.clone(), identity.clone(),
) )
@@ -2202,6 +2317,7 @@ pub mod tests {
}), }),
try_delegate_to_mixnode( try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(50, DENOM)), mock_info(delegation_owner.as_str(), &coins(50, DENOM)),
identity identity
) )
@@ -2219,6 +2335,7 @@ pub mod tests {
assert!(try_delegate_to_mixnode( assert!(try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(123, DENOM)), mock_info(delegation_owner.as_str(), &coins(123, DENOM)),
identity1.clone() identity1.clone()
) )
@@ -2226,17 +2343,17 @@ pub mod tests {
assert!(try_delegate_to_mixnode( assert!(try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(42, DENOM)), mock_info(delegation_owner.as_str(), &coins(42, DENOM)),
identity2.clone() identity2.clone()
) )
.is_ok()); .is_ok());
assert_eq!( assert_eq!(
123, RawDelegationData::new(123u128.into(), mock_env().block.height),
mix_delegations_read(&deps.storage, &identity1) mix_delegations_read(&deps.storage, &identity1)
.load(delegation_owner.as_bytes()) .load(delegation_owner.as_bytes())
.unwrap() .unwrap()
.u128()
); );
assert!( assert!(
reverse_mix_delegations_read(&deps.storage, &delegation_owner) reverse_mix_delegations_read(&deps.storage, &delegation_owner)
@@ -2245,11 +2362,10 @@ pub mod tests {
); );
assert_eq!( assert_eq!(
42, RawDelegationData::new(42u128.into(), mock_env().block.height),
mix_delegations_read(&deps.storage, &identity2) mix_delegations_read(&deps.storage, &identity2)
.load(delegation_owner.as_bytes()) .load(delegation_owner.as_bytes())
.unwrap() .unwrap()
.u128()
); );
assert!( assert!(
reverse_mix_delegations_read(&deps.storage, &delegation_owner) reverse_mix_delegations_read(&deps.storage, &delegation_owner)
@@ -2269,6 +2385,7 @@ pub mod tests {
assert!(try_delegate_to_mixnode( assert!(try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info("sender1", &vec![delegation1.clone()]), mock_info("sender1", &vec![delegation1.clone()]),
identity.clone() identity.clone()
) )
@@ -2276,6 +2393,7 @@ pub mod tests {
assert!(try_delegate_to_mixnode( assert!(try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info("sender2", &vec![delegation2.clone()]), mock_info("sender2", &vec![delegation2.clone()]),
identity.clone() identity.clone()
) )
@@ -2302,6 +2420,7 @@ pub mod tests {
try_delegate_to_mixnode( try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(100, DENOM)), mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
identity.clone(), identity.clone(),
) )
@@ -2310,11 +2429,10 @@ pub mod tests {
try_remove_mixnode(deps.as_mut(), mock_info(mixnode_owner, &[])).unwrap(); try_remove_mixnode(deps.as_mut(), mock_info(mixnode_owner, &[])).unwrap();
assert_eq!( assert_eq!(
100, RawDelegationData::new(100u128.into(), mock_env().block.height),
mix_delegations_read(&deps.storage, &identity) mix_delegations_read(&deps.storage, &identity)
.load(delegation_owner.as_bytes()) .load(delegation_owner.as_bytes())
.unwrap() .unwrap()
.u128()
); );
assert!( assert!(
reverse_mix_delegations_read(&deps.storage, &delegation_owner) reverse_mix_delegations_read(&deps.storage, &delegation_owner)
@@ -2361,6 +2479,7 @@ pub mod tests {
try_delegate_to_mixnode( try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(100, DENOM)), mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
identity.clone(), identity.clone(),
) )
@@ -2416,6 +2535,7 @@ pub mod tests {
try_delegate_to_mixnode( try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(100, DENOM)), mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
identity.clone(), identity.clone(),
) )
@@ -2466,6 +2586,7 @@ pub mod tests {
assert!(try_delegate_to_mixnode( assert!(try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner1.as_str(), &vec![delegation1.clone()]), mock_info(delegation_owner1.as_str(), &vec![delegation1.clone()]),
identity.clone() identity.clone()
) )
@@ -2473,6 +2594,7 @@ pub mod tests {
assert!(try_delegate_to_mixnode( assert!(try_delegate_to_mixnode(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner2.as_str(), &vec![delegation2.clone()]), mock_info(delegation_owner2.as_str(), &vec![delegation2.clone()]),
identity.clone() identity.clone()
) )
@@ -2513,13 +2635,13 @@ pub mod tests {
let identity = add_mixnode(node_owner, good_mixnode_bond(), &mut deps); let identity = add_mixnode(node_owner, good_mixnode_bond(), &mut deps);
mix_delegations(&mut deps.storage, &identity) mix_delegations(&mut deps.storage, &identity)
.save(b"delegator1", &Uint128(initial_delegation1)) .save(b"delegator1", &raw_delegation_fixture(initial_delegation1))
.unwrap(); .unwrap();
mix_delegations(&mut deps.storage, &identity) mix_delegations(&mut deps.storage, &identity)
.save(b"delegator2", &Uint128(initial_delegation2)) .save(b"delegator2", &raw_delegation_fixture(initial_delegation2))
.unwrap(); .unwrap();
mix_delegations(&mut deps.storage, &identity) mix_delegations(&mut deps.storage, &identity)
.save(b"delegator3", &Uint128(initial_delegation3)) .save(b"delegator3", &raw_delegation_fixture(initial_delegation3))
.unwrap(); .unwrap();
let bond_reward = read_mixnode_epoch_bond_reward_rate(deps.as_ref().storage); let bond_reward = read_mixnode_epoch_bond_reward_rate(deps.as_ref().storage);
@@ -2550,6 +2672,7 @@ pub mod tests {
mix_delegations_read(deps.as_ref().storage, &identity) mix_delegations_read(deps.as_ref().storage, &identity)
.load("delegator1".as_bytes()) .load("delegator1".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -2557,6 +2680,7 @@ pub mod tests {
mix_delegations_read(deps.as_ref().storage, &identity) mix_delegations_read(deps.as_ref().storage, &identity)
.load("delegator2".as_bytes()) .load("delegator2".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -2564,6 +2688,7 @@ pub mod tests {
mix_delegations_read(deps.as_ref().storage, &identity) mix_delegations_read(deps.as_ref().storage, &identity)
.load("delegator3".as_bytes()) .load("delegator3".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -2606,6 +2731,7 @@ pub mod tests {
mix_delegations_read(deps.as_ref().storage, &identity) mix_delegations_read(deps.as_ref().storage, &identity)
.load("delegator1".as_bytes()) .load("delegator1".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -2613,6 +2739,7 @@ pub mod tests {
mix_delegations_read(deps.as_ref().storage, &identity) mix_delegations_read(deps.as_ref().storage, &identity)
.load("delegator2".as_bytes()) .load("delegator2".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -2620,6 +2747,7 @@ pub mod tests {
mix_delegations_read(deps.as_ref().storage, &identity) mix_delegations_read(deps.as_ref().storage, &identity)
.load("delegator3".as_bytes()) .load("delegator3".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -2649,6 +2777,7 @@ pub mod tests {
mix_delegations_read(deps.as_ref().storage, &identity) mix_delegations_read(deps.as_ref().storage, &identity)
.load("delegator1".as_bytes()) .load("delegator1".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -2656,6 +2785,7 @@ pub mod tests {
mix_delegations_read(deps.as_ref().storage, &identity) mix_delegations_read(deps.as_ref().storage, &identity)
.load("delegator2".as_bytes()) .load("delegator2".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -2663,6 +2793,7 @@ pub mod tests {
mix_delegations_read(deps.as_ref().storage, &identity) mix_delegations_read(deps.as_ref().storage, &identity)
.load("delegator3".as_bytes()) .load("delegator3".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -2689,6 +2820,7 @@ pub mod tests {
}), }),
try_delegate_to_gateway( try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info("sender", &coins(123, DENOM)), mock_info("sender", &coins(123, DENOM)),
"non-existent-gateway-identity".into() "non-existent-gateway-identity".into()
) )
@@ -2705,13 +2837,14 @@ pub mod tests {
let delegation = coin(123, DENOM); let delegation = coin(123, DENOM);
assert!(try_delegate_to_gateway( assert!(try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &vec![delegation.clone()]), mock_info(delegation_owner.as_str(), &vec![delegation.clone()]),
identity.clone() identity.clone()
) )
.is_ok()); .is_ok());
assert_eq!( assert_eq!(
delegation.amount, RawDelegationData::new(delegation.amount, mock_env().block.height),
gateway_delegations_read(&deps.storage, &identity) gateway_delegations_read(&deps.storage, &identity)
.load(delegation_owner.as_bytes()) .load(delegation_owner.as_bytes())
.unwrap() .unwrap()
@@ -2748,6 +2881,7 @@ pub mod tests {
}), }),
try_delegate_to_gateway( try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(123, DENOM)), mock_info(delegation_owner.as_str(), &coins(123, DENOM)),
identity identity
) )
@@ -2767,13 +2901,14 @@ pub mod tests {
assert!(try_delegate_to_gateway( assert!(try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &vec![delegation.clone()]), mock_info(delegation_owner.as_str(), &vec![delegation.clone()]),
identity.clone() identity.clone()
) )
.is_ok()); .is_ok());
assert_eq!( assert_eq!(
delegation.amount, RawDelegationData::new(delegation.amount, mock_env().block.height),
gateway_delegations_read(&deps.storage, &identity) gateway_delegations_read(&deps.storage, &identity)
.load(delegation_owner.as_bytes()) .load(delegation_owner.as_bytes())
.unwrap() .unwrap()
@@ -2806,6 +2941,7 @@ pub mod tests {
try_delegate_to_gateway( try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &vec![delegation1.clone()]), mock_info(delegation_owner.as_str(), &vec![delegation1.clone()]),
identity.clone(), identity.clone(),
) )
@@ -2813,13 +2949,17 @@ pub mod tests {
try_delegate_to_gateway( try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &vec![delegation2.clone()]), mock_info(delegation_owner.as_str(), &vec![delegation2.clone()]),
identity.clone(), identity.clone(),
) )
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
delegation1.amount + delegation2.amount, RawDelegationData::new(
delegation1.amount + delegation2.amount,
mock_env().block.height
),
gateway_delegations_read(&deps.storage, &identity) gateway_delegations_read(&deps.storage, &identity)
.load(delegation_owner.as_bytes()) .load(delegation_owner.as_bytes())
.unwrap() .unwrap()
@@ -2841,6 +2981,106 @@ pub mod tests {
) )
} }
#[test]
fn block_height_is_updated_on_new_delegation() {
let mut deps = helpers::init_contract();
let gateway_owner = "bob";
let identity = add_gateway(gateway_owner, good_gateway_bond(), &mut deps);
let delegation_owner = Addr::unchecked("sender");
let delegation = coin(100, DENOM);
let env1 = mock_env();
let mut env2 = mock_env();
let initial_height = env1.block.height;
let updated_height = initial_height + 42;
// second env has grown in block height
env2.block.height = updated_height;
try_delegate_to_gateway(
deps.as_mut(),
env1,
mock_info(delegation_owner.as_str(), &vec![delegation.clone()]),
identity.clone(),
)
.unwrap();
assert_eq!(
RawDelegationData::new(delegation.amount, initial_height),
gateway_delegations_read(&deps.storage, &identity)
.load(delegation_owner.as_bytes())
.unwrap()
);
try_delegate_to_gateway(
deps.as_mut(),
env2,
mock_info(delegation_owner.as_str(), &vec![delegation.clone()]),
identity.clone(),
)
.unwrap();
assert_eq!(
RawDelegationData::new(delegation.amount + delegation.amount, updated_height),
gateway_delegations_read(&deps.storage, &identity)
.load(delegation_owner.as_bytes())
.unwrap()
);
}
#[test]
fn block_height_is_not_updated_on_different_delegator() {
let mut deps = helpers::init_contract();
let gateway_owner = "bob";
let identity = add_gateway(gateway_owner, good_gateway_bond(), &mut deps);
let delegation_owner1 = Addr::unchecked("sender1");
let delegation_owner2 = Addr::unchecked("sender2");
let delegation1 = coin(100, DENOM);
let delegation2 = coin(120, DENOM);
let env1 = mock_env();
let mut env2 = mock_env();
let initial_height = env1.block.height;
let second_height = initial_height + 42;
// second env has grown in block height
env2.block.height = second_height;
try_delegate_to_gateway(
deps.as_mut(),
env1,
mock_info(delegation_owner1.as_str(), &vec![delegation1.clone()]),
identity.clone(),
)
.unwrap();
assert_eq!(
RawDelegationData::new(delegation1.amount, initial_height),
gateway_delegations_read(&deps.storage, &identity)
.load(delegation_owner1.as_bytes())
.unwrap()
);
try_delegate_to_gateway(
deps.as_mut(),
env2,
mock_info(delegation_owner2.as_str(), &vec![delegation2.clone()]),
identity.clone(),
)
.unwrap();
assert_eq!(
RawDelegationData::new(delegation1.amount, initial_height),
gateway_delegations_read(&deps.storage, &identity)
.load(delegation_owner1.as_bytes())
.unwrap()
);
assert_eq!(
RawDelegationData::new(delegation2.amount, second_height),
gateway_delegations_read(&deps.storage, &identity)
.load(delegation_owner2.as_bytes())
.unwrap()
);
}
#[test] #[test]
fn is_disallowed_for_already_delegated_node_if_it_unbonded() { fn is_disallowed_for_already_delegated_node_if_it_unbonded() {
let mut deps = helpers::init_contract(); let mut deps = helpers::init_contract();
@@ -2851,6 +3091,7 @@ pub mod tests {
try_delegate_to_gateway( try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(100, DENOM)), mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
identity.clone(), identity.clone(),
) )
@@ -2864,6 +3105,7 @@ pub mod tests {
}), }),
try_delegate_to_gateway( try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(50, DENOM)), mock_info(delegation_owner.as_str(), &coins(50, DENOM)),
identity.clone() identity.clone()
) )
@@ -2881,6 +3123,7 @@ pub mod tests {
assert!(try_delegate_to_gateway( assert!(try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(123, DENOM)), mock_info(delegation_owner.as_str(), &coins(123, DENOM)),
identity1.clone() identity1.clone()
) )
@@ -2888,17 +3131,17 @@ pub mod tests {
assert!(try_delegate_to_gateway( assert!(try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(42, DENOM)), mock_info(delegation_owner.as_str(), &coins(42, DENOM)),
identity2.clone() identity2.clone()
) )
.is_ok()); .is_ok());
assert_eq!( assert_eq!(
123, RawDelegationData::new(123u128.into(), mock_env().block.height),
gateway_delegations_read(&deps.storage, &identity1) gateway_delegations_read(&deps.storage, &identity1)
.load(delegation_owner.as_bytes()) .load(delegation_owner.as_bytes())
.unwrap() .unwrap()
.u128()
); );
assert!( assert!(
reverse_gateway_delegations_read(&deps.storage, &delegation_owner) reverse_gateway_delegations_read(&deps.storage, &delegation_owner)
@@ -2907,11 +3150,10 @@ pub mod tests {
); );
assert_eq!( assert_eq!(
42, RawDelegationData::new(42u128.into(), mock_env().block.height),
gateway_delegations_read(&deps.storage, &identity2) gateway_delegations_read(&deps.storage, &identity2)
.load(delegation_owner.as_bytes()) .load(delegation_owner.as_bytes())
.unwrap() .unwrap()
.u128()
); );
assert!( assert!(
reverse_gateway_delegations_read(&deps.storage, &delegation_owner) reverse_gateway_delegations_read(&deps.storage, &delegation_owner)
@@ -2931,6 +3173,7 @@ pub mod tests {
assert!(try_delegate_to_gateway( assert!(try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info("sender1", &vec![delegation1.clone()]), mock_info("sender1", &vec![delegation1.clone()]),
identity.clone() identity.clone()
) )
@@ -2938,6 +3181,7 @@ pub mod tests {
assert!(try_delegate_to_gateway( assert!(try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info("sender2", &vec![delegation2.clone()]), mock_info("sender2", &vec![delegation2.clone()]),
identity.clone() identity.clone()
) )
@@ -2964,6 +3208,7 @@ pub mod tests {
try_delegate_to_gateway( try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(100, DENOM)), mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
identity.clone(), identity.clone(),
) )
@@ -2972,11 +3217,10 @@ pub mod tests {
try_remove_gateway(deps.as_mut(), mock_info(gateway_owner, &[])).unwrap(); try_remove_gateway(deps.as_mut(), mock_info(gateway_owner, &[])).unwrap();
assert_eq!( assert_eq!(
100, RawDelegationData::new(100u128.into(), mock_env().block.height),
gateway_delegations_read(&deps.storage, &identity) gateway_delegations_read(&deps.storage, &identity)
.load(delegation_owner.as_bytes()) .load(delegation_owner.as_bytes())
.unwrap() .unwrap()
.u128()
); );
assert!( assert!(
reverse_gateway_delegations_read(&deps.storage, &delegation_owner) reverse_gateway_delegations_read(&deps.storage, &delegation_owner)
@@ -3023,6 +3267,7 @@ pub mod tests {
try_delegate_to_gateway( try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(100, DENOM)), mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
identity.clone(), identity.clone(),
) )
@@ -3078,6 +3323,7 @@ pub mod tests {
try_delegate_to_gateway( try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner.as_str(), &coins(100, DENOM)), mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
identity.clone(), identity.clone(),
) )
@@ -3128,6 +3374,7 @@ pub mod tests {
assert!(try_delegate_to_gateway( assert!(try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner1.as_str(), &vec![delegation1.clone()]), mock_info(delegation_owner1.as_str(), &vec![delegation1.clone()]),
identity.clone() identity.clone()
) )
@@ -3135,6 +3382,7 @@ pub mod tests {
assert!(try_delegate_to_gateway( assert!(try_delegate_to_gateway(
deps.as_mut(), deps.as_mut(),
mock_env(),
mock_info(delegation_owner2.as_str(), &vec![delegation2.clone()]), mock_info(delegation_owner2.as_str(), &vec![delegation2.clone()]),
identity.clone() identity.clone()
) )
@@ -3175,13 +3423,13 @@ pub mod tests {
let identity = add_gateway(node_owner, good_gateway_bond(), &mut deps); let identity = add_gateway(node_owner, good_gateway_bond(), &mut deps);
gateway_delegations(&mut deps.storage, &identity) gateway_delegations(&mut deps.storage, &identity)
.save(b"delegator1", &Uint128(initial_delegation1)) .save(b"delegator1", &raw_delegation_fixture(initial_delegation1))
.unwrap(); .unwrap();
gateway_delegations(&mut deps.storage, &identity) gateway_delegations(&mut deps.storage, &identity)
.save(b"delegator2", &Uint128(initial_delegation2)) .save(b"delegator2", &raw_delegation_fixture(initial_delegation2))
.unwrap(); .unwrap();
gateway_delegations(&mut deps.storage, &identity) gateway_delegations(&mut deps.storage, &identity)
.save(b"delegator3", &Uint128(initial_delegation3)) .save(b"delegator3", &raw_delegation_fixture(initial_delegation3))
.unwrap(); .unwrap();
let bond_reward = read_gateway_epoch_bond_reward_rate(deps.as_ref().storage); let bond_reward = read_gateway_epoch_bond_reward_rate(deps.as_ref().storage);
@@ -3212,6 +3460,7 @@ pub mod tests {
gateway_delegations_read(deps.as_ref().storage, &identity) gateway_delegations_read(deps.as_ref().storage, &identity)
.load("delegator1".as_bytes()) .load("delegator1".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -3219,6 +3468,7 @@ pub mod tests {
gateway_delegations_read(deps.as_ref().storage, &identity) gateway_delegations_read(deps.as_ref().storage, &identity)
.load("delegator2".as_bytes()) .load("delegator2".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -3226,6 +3476,7 @@ pub mod tests {
gateway_delegations_read(deps.as_ref().storage, &identity) gateway_delegations_read(deps.as_ref().storage, &identity)
.load("delegator3".as_bytes()) .load("delegator3".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -3268,6 +3519,7 @@ pub mod tests {
gateway_delegations_read(deps.as_ref().storage, &identity) gateway_delegations_read(deps.as_ref().storage, &identity)
.load("delegator1".as_bytes()) .load("delegator1".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -3275,6 +3527,7 @@ pub mod tests {
gateway_delegations_read(deps.as_ref().storage, &identity) gateway_delegations_read(deps.as_ref().storage, &identity)
.load("delegator2".as_bytes()) .load("delegator2".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -3282,6 +3535,7 @@ pub mod tests {
gateway_delegations_read(deps.as_ref().storage, &identity) gateway_delegations_read(deps.as_ref().storage, &identity)
.load("delegator3".as_bytes()) .load("delegator3".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -3311,6 +3565,7 @@ pub mod tests {
gateway_delegations_read(deps.as_ref().storage, &identity) gateway_delegations_read(deps.as_ref().storage, &identity)
.load("delegator1".as_bytes()) .load("delegator1".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -3318,6 +3573,7 @@ pub mod tests {
gateway_delegations_read(deps.as_ref().storage, &identity) gateway_delegations_read(deps.as_ref().storage, &identity)
.load("delegator2".as_bytes()) .load("delegator2".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -3325,6 +3581,7 @@ pub mod tests {
gateway_delegations_read(deps.as_ref().storage, &identity) gateway_delegations_read(deps.as_ref().storage, &identity)
.load("delegator3".as_bytes()) .load("delegator3".as_bytes())
.unwrap() .unwrap()
.amount
); );
assert_eq!( assert_eq!(
@@ -3373,7 +3630,7 @@ pub mod tests {
let mut write_bucket = mix_delegations(&mut deps.storage, &node_identity); let mut write_bucket = mix_delegations(&mut deps.storage, &node_identity);
for i in 1..=total_delegations { for i in 1..=total_delegations {
let delegator = Addr::unchecked(format!("delegator{}", i)); let delegator = Addr::unchecked(format!("delegator{}", i));
let delegation = Uint128(i as u128); let delegation = raw_delegation_fixture(i as u128);
write_bucket write_bucket
.save(delegator.as_bytes(), &delegation) .save(delegator.as_bytes(), &delegation)
.unwrap(); .unwrap();