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:
committed by
GitHub
parent
122f5d9f2e
commit
92e13a5d00
@@ -2,11 +2,26 @@
|
||||
#![allow(clippy::field_reassign_with_default)]
|
||||
|
||||
use crate::{Addr, IdentityKey};
|
||||
use cosmwasm_std::Coin;
|
||||
use cosmwasm_std::{Coin, Uint128};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
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)]
|
||||
pub struct Delegation {
|
||||
owner: Addr,
|
||||
|
||||
@@ -10,7 +10,7 @@ mod types;
|
||||
pub use cosmwasm_std::{Addr, Coin};
|
||||
pub use delegation::{
|
||||
Delegation, PagedGatewayDelegationsResponse, PagedMixDelegationsResponse,
|
||||
PagedReverseGatewayDelegationsResponse, PagedReverseMixDelegationsResponse,
|
||||
PagedReverseGatewayDelegationsResponse, PagedReverseMixDelegationsResponse, RawDelegationData,
|
||||
};
|
||||
pub use gateway::{Gateway, GatewayBond, GatewayOwnershipResponse, PagedGatewayResponse};
|
||||
pub use mixnode::{Layer, MixNode, MixNodeBond, MixOwnershipResponse, PagedMixnodeResponse};
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::helpers::calculate_epoch_reward_rate;
|
||||
use crate::queries::DELEGATION_PAGE_MAX_LIMIT;
|
||||
use crate::state::State;
|
||||
use crate::storage::{
|
||||
config, layer_distribution, reverse_gateway_delegations, reverse_mix_delegations,
|
||||
};
|
||||
use crate::storage::{config, gateway_delegations, layer_distribution, mix_delegations};
|
||||
use crate::{error::ContractError, queries, transactions};
|
||||
use config::defaults::NETWORK_MONITOR_ADDRESS;
|
||||
use config::defaults::{DENOM, NETWORK_MONITOR_ADDRESS};
|
||||
use cosmwasm_std::{
|
||||
entry_point, to_binary, Addr, Decimal, Deps, DepsMut, Env, MessageInfo, QueryResponse,
|
||||
Response, Uint128,
|
||||
coin, entry_point, to_binary, Addr, Decimal, Deps, DepsMut, Env, MessageInfo, Order,
|
||||
QueryResponse, Response, StdResult, Storage, Uint128,
|
||||
};
|
||||
use cosmwasm_storage::ReadonlyBucket;
|
||||
use mixnet_contract::{
|
||||
Delegation, ExecuteMsg, IdentityKey, IdentityKeyRef, InstantiateMsg, MigrateMsg, QueryMsg,
|
||||
Delegation, ExecuteMsg, IdentityKey, IdentityKeyRef, InstantiateMsg, MigrateMsg,
|
||||
PagedGatewayDelegationsResponse, PagedMixDelegationsResponse, QueryMsg, RawDelegationData,
|
||||
StateParams,
|
||||
};
|
||||
|
||||
@@ -94,7 +95,7 @@ pub fn instantiate(
|
||||
#[entry_point]
|
||||
pub fn execute(
|
||||
deps: DepsMut,
|
||||
_env: Env,
|
||||
env: Env,
|
||||
info: MessageInfo,
|
||||
msg: ExecuteMsg,
|
||||
) -> Result<Response, ContractError> {
|
||||
@@ -113,13 +114,13 @@ pub fn execute(
|
||||
transactions::try_reward_gateway(deps, info, identity, uptime)
|
||||
}
|
||||
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 } => {
|
||||
transactions::try_remove_delegation_from_mixnode(deps, info, mix_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 } => {
|
||||
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]
|
||||
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> {
|
||||
let mut mixnode_bonds = Vec::new();
|
||||
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 start_after = None;
|
||||
loop {
|
||||
let mut paged_response = queries::query_mixnode_delegations_paged(
|
||||
let mut paged_response = query_mixnode_old_delegations_paged(
|
||||
deps.as_ref(),
|
||||
mix_identity.into(),
|
||||
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 start_after = None;
|
||||
loop {
|
||||
let mut paged_response = queries::query_gateway_delegations_paged(
|
||||
let mut paged_response = query_gateway_old_delegations_paged(
|
||||
deps.as_ref(),
|
||||
gateway_identity.into(),
|
||||
start_after,
|
||||
@@ -305,8 +409,11 @@ pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result<Response, C
|
||||
for mix_identity in mixnodes_identities {
|
||||
let delegations = get_all_mixnode_delegations(&deps, &mix_identity)?;
|
||||
for delegation in delegations {
|
||||
reverse_mix_delegations(deps.storage, &delegation.owner())
|
||||
.save(mix_identity.as_bytes(), &())?;
|
||||
let old_delegation_bucket = mix_old_delegations_read(deps.storage, &mix_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 = 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 {
|
||||
let delegations = get_all_gateway_delegations(&deps, &gateway_identity)?;
|
||||
for delegation in delegations {
|
||||
reverse_gateway_delegations(deps.storage, &delegation.owner())
|
||||
.save(gateway_identity.as_bytes(), &())?;
|
||||
let old_delegation_bucket =
|
||||
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)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ pub(crate) fn query_mixnode_delegations_paged(
|
||||
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),
|
||||
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())? {
|
||||
Some(delegation_value) => Ok(Delegation::new(
|
||||
address,
|
||||
coin(delegation_value.u128(), DENOM),
|
||||
coin(delegation_value.amount.u128(), DENOM),
|
||||
)),
|
||||
None => Err(ContractError::NoMixnodeDelegationFound {
|
||||
identity: mix_identity,
|
||||
@@ -212,7 +212,7 @@ pub(crate) fn query_gateway_delegations_paged(
|
||||
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),
|
||||
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())? {
|
||||
Some(delegation_value) => Ok(Delegation::new(
|
||||
address,
|
||||
coin(delegation_value.u128(), DENOM),
|
||||
coin(delegation_value.amount.u128(), DENOM),
|
||||
)),
|
||||
None => Err(ContractError::NoGatewayDelegationFound {
|
||||
identity: gateway_identity,
|
||||
@@ -282,10 +282,12 @@ mod tests {
|
||||
use crate::state::State;
|
||||
use crate::storage::{config, gateway_delegations, gateways, mix_delegations, mixnodes};
|
||||
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 cosmwasm_std::testing::mock_info;
|
||||
use cosmwasm_std::{Addr, Storage, Uint128};
|
||||
use cosmwasm_std::{Addr, Storage};
|
||||
use mixnet_contract::{Gateway, MixNode};
|
||||
|
||||
#[test]
|
||||
@@ -632,14 +634,12 @@ mod tests {
|
||||
#[cfg(test)]
|
||||
mod querying_for_mixnode_delegations_paged {
|
||||
use super::*;
|
||||
use crate::storage::mix_delegations;
|
||||
use cosmwasm_std::Uint128;
|
||||
|
||||
fn store_n_delegations(n: u32, storage: &mut dyn Storage, node_identity: &IdentityKey) {
|
||||
for i in 0..n {
|
||||
let address = format!("address{}", i);
|
||||
mix_delegations(storage, node_identity)
|
||||
.save(address.as_bytes(), &Uint128(42))
|
||||
.save(address.as_bytes(), &raw_delegation_fixture(42))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
@@ -711,7 +711,7 @@ mod tests {
|
||||
let node_identity: IdentityKey = "foo".into();
|
||||
|
||||
mix_delegations(&mut deps.storage, &node_identity)
|
||||
.save("1".as_bytes(), &Uint128(42))
|
||||
.save("1".as_bytes(), &raw_delegation_fixture(42))
|
||||
.unwrap();
|
||||
|
||||
let per_page = 2;
|
||||
@@ -728,7 +728,7 @@ mod tests {
|
||||
|
||||
// save another
|
||||
mix_delegations(&mut deps.storage, &node_identity)
|
||||
.save("2".as_bytes(), &Uint128(42))
|
||||
.save("2".as_bytes(), &raw_delegation_fixture(42))
|
||||
.unwrap();
|
||||
|
||||
// page1 should have 2 results on it
|
||||
@@ -742,7 +742,7 @@ mod tests {
|
||||
assert_eq!(2, page1.delegations.len());
|
||||
|
||||
mix_delegations(&mut deps.storage, &node_identity)
|
||||
.save("3".as_bytes(), &Uint128(42))
|
||||
.save("3".as_bytes(), &raw_delegation_fixture(42))
|
||||
.unwrap();
|
||||
|
||||
// page1 still has 2 results
|
||||
@@ -769,7 +769,7 @@ mod tests {
|
||||
|
||||
// save another one
|
||||
mix_delegations(&mut deps.storage, &node_identity)
|
||||
.save("4".as_bytes(), &Uint128(42))
|
||||
.save("4".as_bytes(), &raw_delegation_fixture(42))
|
||||
.unwrap();
|
||||
|
||||
let start_after = Addr::unchecked("2");
|
||||
@@ -793,7 +793,7 @@ mod tests {
|
||||
let delegation_owner = Addr::unchecked("bar");
|
||||
|
||||
mix_delegations(&mut deps.storage, &node_identity)
|
||||
.save(delegation_owner.as_bytes(), &Uint128(42))
|
||||
.save(delegation_owner.as_bytes(), &raw_delegation_fixture(42))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
@@ -825,7 +825,7 @@ mod tests {
|
||||
|
||||
// add delegation from a different address
|
||||
mix_delegations(&mut deps.storage, &node_identity1)
|
||||
.save(delegation_owner2.as_bytes(), &Uint128(42))
|
||||
.save(delegation_owner2.as_bytes(), &raw_delegation_fixture(42))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
@@ -842,7 +842,7 @@ mod tests {
|
||||
|
||||
// add delegation for a different node
|
||||
mix_delegations(&mut deps.storage, &node_identity2)
|
||||
.save(delegation_owner1.as_bytes(), &Uint128(42))
|
||||
.save(delegation_owner1.as_bytes(), &raw_delegation_fixture(42))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
@@ -1019,13 +1019,12 @@ mod tests {
|
||||
mod querying_for_gateway_delegations_paged {
|
||||
use super::*;
|
||||
use crate::storage::gateway_delegations;
|
||||
use cosmwasm_std::Uint128;
|
||||
|
||||
fn store_n_delegations(n: u32, storage: &mut dyn Storage, node_identity: &IdentityKey) {
|
||||
for i in 0..n {
|
||||
let address = format!("address{}", i);
|
||||
gateway_delegations(storage, node_identity)
|
||||
.save(address.as_bytes(), &Uint128(42))
|
||||
.save(address.as_bytes(), &raw_delegation_fixture(42))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
@@ -1097,7 +1096,7 @@ mod tests {
|
||||
let node_identity: IdentityKey = "foo".into();
|
||||
|
||||
gateway_delegations(&mut deps.storage, &node_identity)
|
||||
.save("1".as_bytes(), &Uint128(42))
|
||||
.save("1".as_bytes(), &raw_delegation_fixture(42))
|
||||
.unwrap();
|
||||
|
||||
let per_page = 2;
|
||||
@@ -1114,7 +1113,7 @@ mod tests {
|
||||
|
||||
// save another
|
||||
gateway_delegations(&mut deps.storage, &node_identity)
|
||||
.save("2".as_bytes(), &Uint128(42))
|
||||
.save("2".as_bytes(), &raw_delegation_fixture(42))
|
||||
.unwrap();
|
||||
|
||||
// page1 should have 2 results on it
|
||||
@@ -1128,7 +1127,7 @@ mod tests {
|
||||
assert_eq!(2, page1.delegations.len());
|
||||
|
||||
gateway_delegations(&mut deps.storage, &node_identity)
|
||||
.save("3".as_bytes(), &Uint128(42))
|
||||
.save("3".as_bytes(), &raw_delegation_fixture(42))
|
||||
.unwrap();
|
||||
|
||||
// page1 still has 2 results
|
||||
@@ -1155,7 +1154,7 @@ mod tests {
|
||||
|
||||
// save another one
|
||||
gateway_delegations(&mut deps.storage, &node_identity)
|
||||
.save("4".as_bytes(), &Uint128(42))
|
||||
.save("4".as_bytes(), &raw_delegation_fixture(42))
|
||||
.unwrap();
|
||||
|
||||
let start_after = Addr::unchecked("2");
|
||||
@@ -1179,7 +1178,7 @@ mod tests {
|
||||
let delegation_owner = Addr::unchecked("bar");
|
||||
|
||||
gateway_delegations(&mut deps.storage, &node_identity)
|
||||
.save(delegation_owner.as_bytes(), &Uint128(42))
|
||||
.save(delegation_owner.as_bytes(), &raw_delegation_fixture(42))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
@@ -1211,7 +1210,7 @@ mod tests {
|
||||
|
||||
// add delegation from a different address
|
||||
gateway_delegations(&mut deps.storage, &node_identity1)
|
||||
.save(delegation_owner2.as_bytes(), &Uint128(42))
|
||||
.save(delegation_owner2.as_bytes(), &raw_delegation_fixture(42))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
@@ -1228,7 +1227,7 @@ mod tests {
|
||||
|
||||
// add delegation for a different node
|
||||
gateway_delegations(&mut deps.storage, &node_identity2)
|
||||
.save(delegation_owner1.as_bytes(), &Uint128(42))
|
||||
.save(delegation_owner1.as_bytes(), &raw_delegation_fixture(42))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
|
||||
@@ -10,7 +10,7 @@ use cosmwasm_storage::{
|
||||
};
|
||||
use mixnet_contract::{
|
||||
Addr, GatewayBond, IdentityKey, IdentityKeyRef, Layer, LayerDistribution, MixNodeBond,
|
||||
StateParams,
|
||||
RawDelegationData, StateParams,
|
||||
};
|
||||
|
||||
// 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
|
||||
for (delegator_address, amount) in delegations_chunk.into_iter() {
|
||||
let reward = amount * scaled_reward_rate;
|
||||
let new_amount = amount + reward;
|
||||
for (delegator_address, mut delegation) in delegations_chunk.into_iter() {
|
||||
let reward = delegation.amount * scaled_reward_rate;
|
||||
delegation.amount += 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
|
||||
for (delegator_address, amount) in delegations_chunk.into_iter() {
|
||||
let reward = amount * scaled_reward_rate;
|
||||
let new_amount = amount + reward;
|
||||
for (delegator_address, mut delegation) in delegations_chunk.into_iter() {
|
||||
let reward = delegation.amount * scaled_reward_rate;
|
||||
delegation.amount += 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>(
|
||||
storage: &'a mut dyn Storage,
|
||||
mix_identity: IdentityKeyRef,
|
||||
) -> Bucket<'a, Uint128> {
|
||||
) -> Bucket<'a, RawDelegationData> {
|
||||
Bucket::multilevel(storage, &[PREFIX_MIX_DELEGATION, mix_identity.as_bytes()])
|
||||
}
|
||||
|
||||
pub fn mix_delegations_read<'a>(
|
||||
storage: &'a dyn Storage,
|
||||
mix_identity: IdentityKeyRef,
|
||||
) -> ReadonlyBucket<'a, Uint128> {
|
||||
) -> ReadonlyBucket<'a, RawDelegationData> {
|
||||
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>(
|
||||
storage: &'a mut dyn Storage,
|
||||
gateway_identity: IdentityKeyRef,
|
||||
) -> Bucket<'a, Uint128> {
|
||||
) -> Bucket<'a, RawDelegationData> {
|
||||
Bucket::multilevel(
|
||||
storage,
|
||||
&[PREFIX_GATEWAY_DELEGATION, gateway_identity.as_bytes()],
|
||||
@@ -328,7 +328,7 @@ pub fn gateway_delegations<'a>(
|
||||
pub fn gateway_delegations_read<'a>(
|
||||
storage: &'a dyn Storage,
|
||||
gateway_identity: IdentityKeyRef,
|
||||
) -> ReadonlyBucket<'a, Uint128> {
|
||||
) -> ReadonlyBucket<'a, RawDelegationData> {
|
||||
ReadonlyBucket::multilevel(
|
||||
storage,
|
||||
&[PREFIX_GATEWAY_DELEGATION, gateway_identity.as_bytes()],
|
||||
@@ -382,6 +382,7 @@ mod tests {
|
||||
use super::*;
|
||||
use crate::support::tests::helpers::{
|
||||
gateway_bond_fixture, gateway_fixture, mix_node_fixture, mixnode_bond_fixture,
|
||||
raw_delegation_fixture,
|
||||
};
|
||||
use config::defaults::DENOM;
|
||||
use cosmwasm_std::testing::MockStorage;
|
||||
@@ -523,7 +524,10 @@ mod tests {
|
||||
|
||||
let delegator_address = Addr::unchecked("bob");
|
||||
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();
|
||||
|
||||
let total_increase =
|
||||
@@ -532,8 +536,9 @@ mod tests {
|
||||
|
||||
assert_eq!(Uint128(1), total_increase);
|
||||
|
||||
// amount is incremented, block height remains the same
|
||||
assert_eq!(
|
||||
Uint128(1001),
|
||||
RawDelegationData::new(1001u128.into(), 42),
|
||||
mix_delegations_read(&mut deps.storage, &node_identity)
|
||||
.load(delegator_address.as_bytes())
|
||||
.unwrap()
|
||||
@@ -551,7 +556,7 @@ mod tests {
|
||||
for i in 0..100 {
|
||||
let delegator_address = Addr::unchecked(format!("address{}", i));
|
||||
mix_delegations(&mut deps.storage, &node_identity)
|
||||
.save(delegator_address.as_bytes(), &Uint128(1000))
|
||||
.save(delegator_address.as_bytes(), &raw_delegation_fixture(1000))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -564,7 +569,7 @@ mod tests {
|
||||
for i in 0..100 {
|
||||
let delegator_address = Addr::unchecked(format!("address{}", i));
|
||||
assert_eq!(
|
||||
Uint128(1001),
|
||||
raw_delegation_fixture(1001),
|
||||
mix_delegations_read(&mut deps.storage, &node_identity)
|
||||
.load(delegator_address.as_bytes())
|
||||
.unwrap()
|
||||
@@ -583,7 +588,7 @@ mod tests {
|
||||
for i in 0..queries::DELEGATION_PAGE_MAX_LIMIT * 10 {
|
||||
let delegator_address = Addr::unchecked(format!("address{}", i));
|
||||
mix_delegations(&mut deps.storage, &node_identity)
|
||||
.save(delegator_address.as_bytes(), &Uint128(1000))
|
||||
.save(delegator_address.as_bytes(), &raw_delegation_fixture(1000))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -599,7 +604,7 @@ mod tests {
|
||||
for i in 0..queries::DELEGATION_PAGE_MAX_LIMIT * 10 {
|
||||
let delegator_address = Addr::unchecked(format!("address{}", i));
|
||||
assert_eq!(
|
||||
Uint128(1001),
|
||||
raw_delegation_fixture(1001),
|
||||
mix_delegations_read(&mut deps.storage, &node_identity)
|
||||
.load(delegator_address.as_bytes())
|
||||
.unwrap()
|
||||
@@ -716,7 +721,10 @@ mod tests {
|
||||
|
||||
let delegator_address = Addr::unchecked("bob");
|
||||
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();
|
||||
|
||||
let total_increase = increase_gateway_delegated_stakes(
|
||||
@@ -728,8 +736,9 @@ mod tests {
|
||||
|
||||
assert_eq!(Uint128(1), total_increase);
|
||||
|
||||
// amount is incremented, block height remains the same
|
||||
assert_eq!(
|
||||
Uint128(1001),
|
||||
RawDelegationData::new(1001u128.into(), 42),
|
||||
gateway_delegations_read(&mut deps.storage, &node_identity)
|
||||
.load(delegator_address.as_bytes())
|
||||
.unwrap()
|
||||
@@ -747,7 +756,7 @@ mod tests {
|
||||
for i in 0..100 {
|
||||
let delegator_address = Addr::unchecked(format!("address{}", i));
|
||||
gateway_delegations(&mut deps.storage, &node_identity)
|
||||
.save(delegator_address.as_bytes(), &Uint128(1000))
|
||||
.save(delegator_address.as_bytes(), &raw_delegation_fixture(1000))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -763,7 +772,7 @@ mod tests {
|
||||
for i in 0..100 {
|
||||
let delegator_address = Addr::unchecked(format!("address{}", i));
|
||||
assert_eq!(
|
||||
Uint128(1001),
|
||||
raw_delegation_fixture(1001),
|
||||
gateway_delegations_read(&mut deps.storage, &node_identity)
|
||||
.load(delegator_address.as_bytes())
|
||||
.unwrap()
|
||||
@@ -782,7 +791,7 @@ mod tests {
|
||||
for i in 0..queries::DELEGATION_PAGE_MAX_LIMIT * 10 {
|
||||
let delegator_address = Addr::unchecked(format!("address{}", i));
|
||||
gateway_delegations(&mut deps.storage, &node_identity)
|
||||
.save(delegator_address.as_bytes(), &Uint128(1000))
|
||||
.save(delegator_address.as_bytes(), &raw_delegation_fixture(1000))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -801,7 +810,7 @@ mod tests {
|
||||
for i in 0..queries::DELEGATION_PAGE_MAX_LIMIT * 10 {
|
||||
let delegator_address = Addr::unchecked(format!("address{}", i));
|
||||
assert_eq!(
|
||||
Uint128(1001),
|
||||
raw_delegation_fixture(1001),
|
||||
gateway_delegations_read(&mut deps.storage, &node_identity)
|
||||
.load(delegator_address.as_bytes())
|
||||
.unwrap()
|
||||
|
||||
@@ -5,7 +5,6 @@ pub mod helpers {
|
||||
use crate::contract::{instantiate, INITIAL_MIXNODE_BOND};
|
||||
use crate::transactions::{try_add_gateway, try_add_mixnode};
|
||||
use config::defaults::DENOM;
|
||||
use cosmwasm_std::coin;
|
||||
use cosmwasm_std::from_binary;
|
||||
use cosmwasm_std::testing::mock_dependencies;
|
||||
use cosmwasm_std::testing::mock_env;
|
||||
@@ -16,10 +15,11 @@ pub mod helpers {
|
||||
use cosmwasm_std::Addr;
|
||||
use cosmwasm_std::Coin;
|
||||
use cosmwasm_std::OwnedDeps;
|
||||
use cosmwasm_std::{coin, Uint128};
|
||||
use cosmwasm_std::{Empty, MemoryStorage};
|
||||
use mixnet_contract::{
|
||||
Gateway, GatewayBond, InstantiateMsg, Layer, MixNode, MixNodeBond, PagedGatewayResponse,
|
||||
PagedMixnodeResponse, QueryMsg,
|
||||
PagedMixnodeResponse, QueryMsg, RawDelegationData,
|
||||
};
|
||||
|
||||
pub fn add_mixnode(
|
||||
@@ -159,6 +159,10 @@ pub mod helpers {
|
||||
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(
|
||||
address: Addr,
|
||||
deps: OwnedDeps<MockStorage, MockApi, MockQuerier>,
|
||||
|
||||
@@ -7,11 +7,12 @@ use crate::queries;
|
||||
use crate::storage::*;
|
||||
use config::defaults::DENOM;
|
||||
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 mixnet_contract::{
|
||||
Gateway, GatewayBond, IdentityKey, Layer, MixNode, MixNodeBond, StateParams,
|
||||
Gateway, GatewayBond, IdentityKey, Layer, MixNode, MixNodeBond, RawDelegationData, StateParams,
|
||||
};
|
||||
|
||||
const OLD_DELEGATIONS_CHUNK_SIZE: usize = 500;
|
||||
@@ -23,7 +24,7 @@ const OLD_DELEGATIONS_CHUNK_SIZE: usize = 500;
|
||||
// 3. The node unbonds
|
||||
// 4. Some of the addresses that delegated in the past have not removed the delegation yet
|
||||
// 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
|
||||
// but in case we do, we should guard ourselves against possible
|
||||
// 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;
|
||||
}
|
||||
|
||||
let value = delegation?.1;
|
||||
let value = delegation?.1.amount;
|
||||
total_delegation.amount += value;
|
||||
}
|
||||
|
||||
@@ -540,6 +541,7 @@ fn validate_delegation_stake(delegation: &[Coin]) -> Result<(), ContractError> {
|
||||
|
||||
pub(crate) fn try_delegate_to_mixnode(
|
||||
deps: DepsMut,
|
||||
env: Env,
|
||||
info: MessageInfo,
|
||||
mix_identity: IdentityKey,
|
||||
) -> Result<Response, ContractError> {
|
||||
@@ -565,12 +567,13 @@ pub(crate) fn try_delegate_to_mixnode(
|
||||
let sender_bytes = info.sender.as_bytes();
|
||||
|
||||
// write the delegation
|
||||
match delegation_bucket.may_load(sender_bytes)? {
|
||||
Some(existing_delegation) => {
|
||||
delegation_bucket.save(sender_bytes, &(existing_delegation + info.funds[0].amount))?
|
||||
}
|
||||
None => delegation_bucket.save(sender_bytes, &info.funds[0].amount)?,
|
||||
}
|
||||
let new_amount = match delegation_bucket.may_load(sender_bytes)? {
|
||||
Some(existing_delegation) => existing_delegation.amount + info.funds[0].amount,
|
||||
None => 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(), &())?;
|
||||
|
||||
@@ -593,7 +596,7 @@ pub(crate) fn try_remove_delegation_from_mixnode(
|
||||
// send delegated funds back to the delegation owner
|
||||
let messages = vec![BankMsg::Send {
|
||||
to_address: info.sender.to_string(),
|
||||
amount: coins(delegation.u128(), DENOM),
|
||||
amount: coins(delegation.amount.u128(), DENOM),
|
||||
}
|
||||
.into()];
|
||||
|
||||
@@ -606,7 +609,7 @@ pub(crate) fn try_remove_delegation_from_mixnode(
|
||||
existing_bond.total_delegation.amount = existing_bond
|
||||
.total_delegation
|
||||
.amount
|
||||
.checked_sub(delegation)
|
||||
.checked_sub(delegation.amount)
|
||||
.unwrap();
|
||||
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(
|
||||
deps: DepsMut,
|
||||
env: Env,
|
||||
info: MessageInfo,
|
||||
gateway_identity: IdentityKey,
|
||||
) -> Result<Response, ContractError> {
|
||||
@@ -652,12 +656,13 @@ pub(crate) fn try_delegate_to_gateway(
|
||||
let sender_bytes = info.sender.as_bytes();
|
||||
|
||||
// write the delegation
|
||||
match delegation_bucket.may_load(sender_bytes)? {
|
||||
Some(existing_delegation) => {
|
||||
delegation_bucket.save(sender_bytes, &(existing_delegation + info.funds[0].amount))?
|
||||
}
|
||||
None => delegation_bucket.save(sender_bytes, &info.funds[0].amount)?,
|
||||
}
|
||||
let new_amount = match delegation_bucket.may_load(sender_bytes)? {
|
||||
Some(existing_delegation) => existing_delegation.amount + info.funds[0].amount,
|
||||
None => 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)
|
||||
.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
|
||||
let messages = vec![BankMsg::Send {
|
||||
to_address: info.sender.to_string(),
|
||||
amount: coins(delegation.u128(), DENOM),
|
||||
amount: coins(delegation.amount.u128(), DENOM),
|
||||
}
|
||||
.into()];
|
||||
|
||||
@@ -697,7 +702,7 @@ pub(crate) fn try_remove_delegation_from_gateway(
|
||||
existing_bond.total_delegation.amount = existing_bond
|
||||
.total_delegation
|
||||
.amount
|
||||
.checked_sub(delegation)
|
||||
.checked_sub(delegation.amount)
|
||||
.unwrap();
|
||||
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::{
|
||||
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::{coin, coins, from_binary, Addr, Uint128};
|
||||
@@ -1802,7 +1807,7 @@ pub mod tests {
|
||||
.unwrap();
|
||||
|
||||
mix_delegations(&mut deps.storage, &node_identity)
|
||||
.save(b"delegator", &Uint128(initial_delegation))
|
||||
.save(b"delegator", &raw_delegation_fixture(initial_delegation))
|
||||
.unwrap();
|
||||
|
||||
let bond_reward_rate = read_mixnode_epoch_bond_reward_rate(deps.as_ref().storage);
|
||||
@@ -1901,7 +1906,7 @@ pub mod tests {
|
||||
.unwrap();
|
||||
|
||||
gateway_delegations(&mut deps.storage, &node_identity)
|
||||
.save(b"delegator", &Uint128(initial_delegation))
|
||||
.save(b"delegator", &raw_delegation_fixture(initial_delegation))
|
||||
.unwrap();
|
||||
|
||||
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(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("sender", &coins(123, DENOM)),
|
||||
"non-existent-mix-identity".into()
|
||||
)
|
||||
@@ -2043,13 +2049,14 @@ pub mod tests {
|
||||
let delegation = coin(123, DENOM);
|
||||
assert!(try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &vec![delegation.clone()]),
|
||||
identity.clone()
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
assert_eq!(
|
||||
delegation.amount,
|
||||
RawDelegationData::new(delegation.amount, mock_env().block.height),
|
||||
mix_delegations_read(&deps.storage, &identity)
|
||||
.load(delegation_owner.as_bytes())
|
||||
.unwrap()
|
||||
@@ -2086,6 +2093,7 @@ pub mod tests {
|
||||
}),
|
||||
try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &coins(123, DENOM)),
|
||||
identity
|
||||
)
|
||||
@@ -2105,13 +2113,14 @@ pub mod tests {
|
||||
|
||||
assert!(try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &vec![delegation.clone()]),
|
||||
identity.clone()
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
assert_eq!(
|
||||
delegation.amount,
|
||||
RawDelegationData::new(delegation.amount, mock_env().block.height),
|
||||
mix_delegations_read(&deps.storage, &identity)
|
||||
.load(delegation_owner.as_bytes())
|
||||
.unwrap()
|
||||
@@ -2144,6 +2153,7 @@ pub mod tests {
|
||||
|
||||
try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &vec![delegation1.clone()]),
|
||||
identity.clone(),
|
||||
)
|
||||
@@ -2151,13 +2161,17 @@ pub mod tests {
|
||||
|
||||
try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &vec![delegation2.clone()]),
|
||||
identity.clone(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
delegation1.amount + delegation2.amount,
|
||||
RawDelegationData::new(
|
||||
delegation1.amount + delegation2.amount,
|
||||
mock_env().block.height
|
||||
),
|
||||
mix_delegations_read(&deps.storage, &identity)
|
||||
.load(delegation_owner.as_bytes())
|
||||
.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]
|
||||
fn is_disallowed_for_already_delegated_node_if_it_unbonded() {
|
||||
let mut deps = helpers::init_contract();
|
||||
@@ -2189,6 +2303,7 @@ pub mod tests {
|
||||
|
||||
try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
|
||||
identity.clone(),
|
||||
)
|
||||
@@ -2202,6 +2317,7 @@ pub mod tests {
|
||||
}),
|
||||
try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &coins(50, DENOM)),
|
||||
identity
|
||||
)
|
||||
@@ -2219,6 +2335,7 @@ pub mod tests {
|
||||
|
||||
assert!(try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &coins(123, DENOM)),
|
||||
identity1.clone()
|
||||
)
|
||||
@@ -2226,17 +2343,17 @@ pub mod tests {
|
||||
|
||||
assert!(try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &coins(42, DENOM)),
|
||||
identity2.clone()
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
assert_eq!(
|
||||
123,
|
||||
RawDelegationData::new(123u128.into(), mock_env().block.height),
|
||||
mix_delegations_read(&deps.storage, &identity1)
|
||||
.load(delegation_owner.as_bytes())
|
||||
.unwrap()
|
||||
.u128()
|
||||
);
|
||||
assert!(
|
||||
reverse_mix_delegations_read(&deps.storage, &delegation_owner)
|
||||
@@ -2245,11 +2362,10 @@ pub mod tests {
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
42,
|
||||
RawDelegationData::new(42u128.into(), mock_env().block.height),
|
||||
mix_delegations_read(&deps.storage, &identity2)
|
||||
.load(delegation_owner.as_bytes())
|
||||
.unwrap()
|
||||
.u128()
|
||||
);
|
||||
assert!(
|
||||
reverse_mix_delegations_read(&deps.storage, &delegation_owner)
|
||||
@@ -2269,6 +2385,7 @@ pub mod tests {
|
||||
|
||||
assert!(try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("sender1", &vec![delegation1.clone()]),
|
||||
identity.clone()
|
||||
)
|
||||
@@ -2276,6 +2393,7 @@ pub mod tests {
|
||||
|
||||
assert!(try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("sender2", &vec![delegation2.clone()]),
|
||||
identity.clone()
|
||||
)
|
||||
@@ -2302,6 +2420,7 @@ pub mod tests {
|
||||
|
||||
try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
|
||||
identity.clone(),
|
||||
)
|
||||
@@ -2310,11 +2429,10 @@ pub mod tests {
|
||||
try_remove_mixnode(deps.as_mut(), mock_info(mixnode_owner, &[])).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
100,
|
||||
RawDelegationData::new(100u128.into(), mock_env().block.height),
|
||||
mix_delegations_read(&deps.storage, &identity)
|
||||
.load(delegation_owner.as_bytes())
|
||||
.unwrap()
|
||||
.u128()
|
||||
);
|
||||
assert!(
|
||||
reverse_mix_delegations_read(&deps.storage, &delegation_owner)
|
||||
@@ -2361,6 +2479,7 @@ pub mod tests {
|
||||
|
||||
try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
|
||||
identity.clone(),
|
||||
)
|
||||
@@ -2416,6 +2535,7 @@ pub mod tests {
|
||||
|
||||
try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
|
||||
identity.clone(),
|
||||
)
|
||||
@@ -2466,6 +2586,7 @@ pub mod tests {
|
||||
|
||||
assert!(try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner1.as_str(), &vec![delegation1.clone()]),
|
||||
identity.clone()
|
||||
)
|
||||
@@ -2473,6 +2594,7 @@ pub mod tests {
|
||||
|
||||
assert!(try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner2.as_str(), &vec![delegation2.clone()]),
|
||||
identity.clone()
|
||||
)
|
||||
@@ -2513,13 +2635,13 @@ pub mod tests {
|
||||
let identity = add_mixnode(node_owner, good_mixnode_bond(), &mut deps);
|
||||
|
||||
mix_delegations(&mut deps.storage, &identity)
|
||||
.save(b"delegator1", &Uint128(initial_delegation1))
|
||||
.save(b"delegator1", &raw_delegation_fixture(initial_delegation1))
|
||||
.unwrap();
|
||||
mix_delegations(&mut deps.storage, &identity)
|
||||
.save(b"delegator2", &Uint128(initial_delegation2))
|
||||
.save(b"delegator2", &raw_delegation_fixture(initial_delegation2))
|
||||
.unwrap();
|
||||
mix_delegations(&mut deps.storage, &identity)
|
||||
.save(b"delegator3", &Uint128(initial_delegation3))
|
||||
.save(b"delegator3", &raw_delegation_fixture(initial_delegation3))
|
||||
.unwrap();
|
||||
|
||||
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)
|
||||
.load("delegator1".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -2557,6 +2680,7 @@ pub mod tests {
|
||||
mix_delegations_read(deps.as_ref().storage, &identity)
|
||||
.load("delegator2".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -2564,6 +2688,7 @@ pub mod tests {
|
||||
mix_delegations_read(deps.as_ref().storage, &identity)
|
||||
.load("delegator3".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -2606,6 +2731,7 @@ pub mod tests {
|
||||
mix_delegations_read(deps.as_ref().storage, &identity)
|
||||
.load("delegator1".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -2613,6 +2739,7 @@ pub mod tests {
|
||||
mix_delegations_read(deps.as_ref().storage, &identity)
|
||||
.load("delegator2".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -2620,6 +2747,7 @@ pub mod tests {
|
||||
mix_delegations_read(deps.as_ref().storage, &identity)
|
||||
.load("delegator3".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -2649,6 +2777,7 @@ pub mod tests {
|
||||
mix_delegations_read(deps.as_ref().storage, &identity)
|
||||
.load("delegator1".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -2656,6 +2785,7 @@ pub mod tests {
|
||||
mix_delegations_read(deps.as_ref().storage, &identity)
|
||||
.load("delegator2".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -2663,6 +2793,7 @@ pub mod tests {
|
||||
mix_delegations_read(deps.as_ref().storage, &identity)
|
||||
.load("delegator3".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -2689,6 +2820,7 @@ pub mod tests {
|
||||
}),
|
||||
try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("sender", &coins(123, DENOM)),
|
||||
"non-existent-gateway-identity".into()
|
||||
)
|
||||
@@ -2705,13 +2837,14 @@ pub mod tests {
|
||||
let delegation = coin(123, DENOM);
|
||||
assert!(try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &vec![delegation.clone()]),
|
||||
identity.clone()
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
assert_eq!(
|
||||
delegation.amount,
|
||||
RawDelegationData::new(delegation.amount, mock_env().block.height),
|
||||
gateway_delegations_read(&deps.storage, &identity)
|
||||
.load(delegation_owner.as_bytes())
|
||||
.unwrap()
|
||||
@@ -2748,6 +2881,7 @@ pub mod tests {
|
||||
}),
|
||||
try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &coins(123, DENOM)),
|
||||
identity
|
||||
)
|
||||
@@ -2767,13 +2901,14 @@ pub mod tests {
|
||||
|
||||
assert!(try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &vec![delegation.clone()]),
|
||||
identity.clone()
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
assert_eq!(
|
||||
delegation.amount,
|
||||
RawDelegationData::new(delegation.amount, mock_env().block.height),
|
||||
gateway_delegations_read(&deps.storage, &identity)
|
||||
.load(delegation_owner.as_bytes())
|
||||
.unwrap()
|
||||
@@ -2806,6 +2941,7 @@ pub mod tests {
|
||||
|
||||
try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &vec![delegation1.clone()]),
|
||||
identity.clone(),
|
||||
)
|
||||
@@ -2813,13 +2949,17 @@ pub mod tests {
|
||||
|
||||
try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &vec![delegation2.clone()]),
|
||||
identity.clone(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
delegation1.amount + delegation2.amount,
|
||||
RawDelegationData::new(
|
||||
delegation1.amount + delegation2.amount,
|
||||
mock_env().block.height
|
||||
),
|
||||
gateway_delegations_read(&deps.storage, &identity)
|
||||
.load(delegation_owner.as_bytes())
|
||||
.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]
|
||||
fn is_disallowed_for_already_delegated_node_if_it_unbonded() {
|
||||
let mut deps = helpers::init_contract();
|
||||
@@ -2851,6 +3091,7 @@ pub mod tests {
|
||||
|
||||
try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
|
||||
identity.clone(),
|
||||
)
|
||||
@@ -2864,6 +3105,7 @@ pub mod tests {
|
||||
}),
|
||||
try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &coins(50, DENOM)),
|
||||
identity.clone()
|
||||
)
|
||||
@@ -2881,6 +3123,7 @@ pub mod tests {
|
||||
|
||||
assert!(try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &coins(123, DENOM)),
|
||||
identity1.clone()
|
||||
)
|
||||
@@ -2888,17 +3131,17 @@ pub mod tests {
|
||||
|
||||
assert!(try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &coins(42, DENOM)),
|
||||
identity2.clone()
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
assert_eq!(
|
||||
123,
|
||||
RawDelegationData::new(123u128.into(), mock_env().block.height),
|
||||
gateway_delegations_read(&deps.storage, &identity1)
|
||||
.load(delegation_owner.as_bytes())
|
||||
.unwrap()
|
||||
.u128()
|
||||
);
|
||||
assert!(
|
||||
reverse_gateway_delegations_read(&deps.storage, &delegation_owner)
|
||||
@@ -2907,11 +3150,10 @@ pub mod tests {
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
42,
|
||||
RawDelegationData::new(42u128.into(), mock_env().block.height),
|
||||
gateway_delegations_read(&deps.storage, &identity2)
|
||||
.load(delegation_owner.as_bytes())
|
||||
.unwrap()
|
||||
.u128()
|
||||
);
|
||||
assert!(
|
||||
reverse_gateway_delegations_read(&deps.storage, &delegation_owner)
|
||||
@@ -2931,6 +3173,7 @@ pub mod tests {
|
||||
|
||||
assert!(try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("sender1", &vec![delegation1.clone()]),
|
||||
identity.clone()
|
||||
)
|
||||
@@ -2938,6 +3181,7 @@ pub mod tests {
|
||||
|
||||
assert!(try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("sender2", &vec![delegation2.clone()]),
|
||||
identity.clone()
|
||||
)
|
||||
@@ -2964,6 +3208,7 @@ pub mod tests {
|
||||
|
||||
try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
|
||||
identity.clone(),
|
||||
)
|
||||
@@ -2972,11 +3217,10 @@ pub mod tests {
|
||||
try_remove_gateway(deps.as_mut(), mock_info(gateway_owner, &[])).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
100,
|
||||
RawDelegationData::new(100u128.into(), mock_env().block.height),
|
||||
gateway_delegations_read(&deps.storage, &identity)
|
||||
.load(delegation_owner.as_bytes())
|
||||
.unwrap()
|
||||
.u128()
|
||||
);
|
||||
assert!(
|
||||
reverse_gateway_delegations_read(&deps.storage, &delegation_owner)
|
||||
@@ -3023,6 +3267,7 @@ pub mod tests {
|
||||
|
||||
try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
|
||||
identity.clone(),
|
||||
)
|
||||
@@ -3078,6 +3323,7 @@ pub mod tests {
|
||||
|
||||
try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner.as_str(), &coins(100, DENOM)),
|
||||
identity.clone(),
|
||||
)
|
||||
@@ -3128,6 +3374,7 @@ pub mod tests {
|
||||
|
||||
assert!(try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner1.as_str(), &vec![delegation1.clone()]),
|
||||
identity.clone()
|
||||
)
|
||||
@@ -3135,6 +3382,7 @@ pub mod tests {
|
||||
|
||||
assert!(try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info(delegation_owner2.as_str(), &vec![delegation2.clone()]),
|
||||
identity.clone()
|
||||
)
|
||||
@@ -3175,13 +3423,13 @@ pub mod tests {
|
||||
let identity = add_gateway(node_owner, good_gateway_bond(), &mut deps);
|
||||
|
||||
gateway_delegations(&mut deps.storage, &identity)
|
||||
.save(b"delegator1", &Uint128(initial_delegation1))
|
||||
.save(b"delegator1", &raw_delegation_fixture(initial_delegation1))
|
||||
.unwrap();
|
||||
gateway_delegations(&mut deps.storage, &identity)
|
||||
.save(b"delegator2", &Uint128(initial_delegation2))
|
||||
.save(b"delegator2", &raw_delegation_fixture(initial_delegation2))
|
||||
.unwrap();
|
||||
gateway_delegations(&mut deps.storage, &identity)
|
||||
.save(b"delegator3", &Uint128(initial_delegation3))
|
||||
.save(b"delegator3", &raw_delegation_fixture(initial_delegation3))
|
||||
.unwrap();
|
||||
|
||||
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)
|
||||
.load("delegator1".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -3219,6 +3468,7 @@ pub mod tests {
|
||||
gateway_delegations_read(deps.as_ref().storage, &identity)
|
||||
.load("delegator2".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -3226,6 +3476,7 @@ pub mod tests {
|
||||
gateway_delegations_read(deps.as_ref().storage, &identity)
|
||||
.load("delegator3".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -3268,6 +3519,7 @@ pub mod tests {
|
||||
gateway_delegations_read(deps.as_ref().storage, &identity)
|
||||
.load("delegator1".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -3275,6 +3527,7 @@ pub mod tests {
|
||||
gateway_delegations_read(deps.as_ref().storage, &identity)
|
||||
.load("delegator2".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -3282,6 +3535,7 @@ pub mod tests {
|
||||
gateway_delegations_read(deps.as_ref().storage, &identity)
|
||||
.load("delegator3".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -3311,6 +3565,7 @@ pub mod tests {
|
||||
gateway_delegations_read(deps.as_ref().storage, &identity)
|
||||
.load("delegator1".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -3318,6 +3573,7 @@ pub mod tests {
|
||||
gateway_delegations_read(deps.as_ref().storage, &identity)
|
||||
.load("delegator2".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -3325,6 +3581,7 @@ pub mod tests {
|
||||
gateway_delegations_read(deps.as_ref().storage, &identity)
|
||||
.load("delegator3".as_bytes())
|
||||
.unwrap()
|
||||
.amount
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -3373,7 +3630,7 @@ pub mod tests {
|
||||
let mut write_bucket = mix_delegations(&mut deps.storage, &node_identity);
|
||||
for i in 1..=total_delegations {
|
||||
let delegator = Addr::unchecked(format!("delegator{}", i));
|
||||
let delegation = Uint128(i as u128);
|
||||
let delegation = raw_delegation_fixture(i as u128);
|
||||
write_bucket
|
||||
.save(delegator.as_bytes(), &delegation)
|
||||
.unwrap();
|
||||
|
||||
Reference in New Issue
Block a user