From 499ddbd362766745b249fe82d4ff6cc96ca4b91f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 25 Aug 2022 15:42:56 +0100 Subject: [PATCH] Updating vesting contract storage --- contracts/vesting/src/contract.rs | 175 +++++++++++-------- contracts/vesting/src/errors.rs | 3 + contracts/vesting/src/storage.rs | 21 ++- contracts/vesting/src/vesting/account/mod.rs | 98 ++++++----- 4 files changed, 176 insertions(+), 121 deletions(-) diff --git a/contracts/vesting/src/contract.rs b/contracts/vesting/src/contract.rs index 4f9722fcd4..39725fdbd4 100644 --- a/contracts/vesting/src/contract.rs +++ b/contracts/vesting/src/contract.rs @@ -1,8 +1,8 @@ use crate::errors::ContractError; use crate::queued_migrations::migrate_config_from_env; use crate::storage::{ - account_from_address, locked_pledge_cap, update_locked_pledge_cap, BlockTimestampSecs, ADMIN, - DELEGATIONS, MIXNET_CONTRACT_ADDRESS, MIX_DENOM, + account_from_address, locked_pledge_cap, update_locked_pledge_cap, BlockTimestampSecs, NodeId, + ADMIN, DELEGATIONS, MIXNET_CONTRACT_ADDRESS, MIX_DENOM, OLD_DELEGATIONS, }; use crate::traits::{ DelegatingAccount, GatewayBondingAccount, MixnodeBondingAccount, VestingAccount, @@ -50,85 +50,122 @@ pub fn migrate(_deps: DepsMut<'_>, _env: Env, _msg: MigrateMsg) -> Result, + info: MessageInfo, + owner: String, + node_identity: String, + mix_id: NodeId, +) -> Result { + if info.sender != MIXNET_CONTRACT_ADDRESS.load(deps.storage)? { + return Err(ContractError::NotMixnetContract(info.sender)); + } + + // this MUST succeed since we know this delegation was created via vesting contract... + let account = account_from_address(&owner, deps.storage, deps.api)?; + let storage_prefix = (account.storage_key(), node_identity); + let old_data = OLD_DELEGATIONS + .prefix(storage_prefix.clone()) + .range(deps.storage, None, None, Order::Ascending) + .collect::>>()?; + + for (timestamp, amount) in old_data { + OLD_DELEGATIONS.remove( + deps.storage, + (storage_prefix.0, storage_prefix.1.clone(), timestamp), + ); + DELEGATIONS.save(deps.storage, (storage_prefix.0, mix_id, timestamp), &amount)?; + } + + Ok(Response::new()) +} + #[entry_point] pub fn execute( deps: DepsMut<'_>, - env: Env, + _env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { match msg { - ExecuteMsg::UpdateLockedPledgeCap { amount } => { - try_update_locked_pledge_cap(amount, info, deps) - } - ExecuteMsg::TrackReward { amount, address } => { - try_track_reward(deps, info, amount, &address) - } - ExecuteMsg::ClaimOperatorReward {} => try_claim_operator_reward(deps, info), - ExecuteMsg::ClaimDelegatorReward { mix_identity } => { - try_claim_delegator_reward(deps, info, mix_identity) - } - ExecuteMsg::CompoundDelegatorReward { mix_identity } => { - try_compound_delegator_reward(mix_identity, info, deps) - } - ExecuteMsg::CompoundOperatorReward {} => try_compound_operator_reward(info, deps), - ExecuteMsg::UpdateMixnodeConfig { - profit_margin_percent, - } => try_update_mixnode_config(profit_margin_percent, info, deps), - ExecuteMsg::UpdateMixnetAddress { address } => { - try_update_mixnet_address(address, info, deps) - } - ExecuteMsg::DelegateToMixnode { - mix_identity, - amount, - } => try_delegate_to_mixnode(mix_identity, amount, info, env, deps), - ExecuteMsg::UndelegateFromMixnode { mix_identity } => { - try_undelegate_from_mixnode(mix_identity, info, deps) - } - ExecuteMsg::CreateAccount { - owner_address, - staking_address, - vesting_spec, - } => try_create_periodic_vesting_account( - &owner_address, - staking_address, - vesting_spec, - info, - env, - deps, - ), - ExecuteMsg::WithdrawVestedCoins { amount } => { - try_withdraw_vested_coins(amount, env, info, deps) - } + ExecuteMsg::AuthorisedUpdateToV2 { + owner, + node_identity, + mix_id, + } => update_delegation_to_v2(deps, info, owner, node_identity, mix_id), ExecuteMsg::TrackUndelegation { owner, mix_identity, amount, } => try_track_undelegation(&owner, mix_identity, amount, info, deps), - ExecuteMsg::BondMixnode { - mix_node, - owner_signature, - amount, - } => try_bond_mixnode(mix_node, owner_signature, amount, info, env, deps), - ExecuteMsg::UnbondMixnode {} => try_unbond_mixnode(info, deps), - ExecuteMsg::TrackUnbondMixnode { owner, amount } => { - try_track_unbond_mixnode(&owner, amount, info, deps) - } - ExecuteMsg::BondGateway { - gateway, - owner_signature, - amount, - } => try_bond_gateway(gateway, owner_signature, amount, info, env, deps), - ExecuteMsg::UnbondGateway {} => try_unbond_gateway(info, deps), - ExecuteMsg::TrackUnbondGateway { owner, amount } => { - try_track_unbond_gateway(&owner, amount, info, deps) - } - ExecuteMsg::TransferOwnership { to_address } => { - try_transfer_ownership(to_address, info, deps) - } - ExecuteMsg::UpdateStakingAddress { to_address } => { - try_update_staking_address(to_address, info, deps) - } + _ => Err(ContractError::MaintenanceMode), + // ExecuteMsg::UpdateLockedPledgeCap { amount } => { + // try_update_locked_pledge_cap(amount, info, deps) + // } + // ExecuteMsg::TrackReward { amount, address } => { + // try_track_reward(deps, info, amount, &address) + // } + // ExecuteMsg::ClaimOperatorReward {} => try_claim_operator_reward(deps, info), + // ExecuteMsg::ClaimDelegatorReward { mix_identity } => { + // try_claim_delegator_reward(deps, info, mix_identity) + // } + // ExecuteMsg::CompoundDelegatorReward { mix_identity } => { + // try_compound_delegator_reward(mix_identity, info, deps) + // } + // ExecuteMsg::CompoundOperatorReward {} => try_compound_operator_reward(info, deps), + // ExecuteMsg::UpdateMixnodeConfig { + // profit_margin_percent, + // } => try_update_mixnode_config(profit_margin_percent, info, deps), + // ExecuteMsg::UpdateMixnetAddress { address } => { + // try_update_mixnet_address(address, info, deps) + // } + // ExecuteMsg::DelegateToMixnode { + // mix_identity, + // amount, + // } => try_delegate_to_mixnode(mix_identity, amount, info, env, deps), + // ExecuteMsg::UndelegateFromMixnode { mix_identity } => { + // try_undelegate_from_mixnode(mix_identity, info, deps) + // } + // ExecuteMsg::CreateAccount { + // owner_address, + // staking_address, + // vesting_spec, + // } => try_create_periodic_vesting_account( + // &owner_address, + // staking_address, + // vesting_spec, + // info, + // env, + // deps, + // ), + // ExecuteMsg::WithdrawVestedCoins { amount } => { + // try_withdraw_vested_coins(amount, env, info, deps) + // } + // + // ExecuteMsg::BondMixnode { + // mix_node, + // owner_signature, + // amount, + // } => try_bond_mixnode(mix_node, owner_signature, amount, info, env, deps), + // ExecuteMsg::UnbondMixnode {} => try_unbond_mixnode(info, deps), + // ExecuteMsg::TrackUnbondMixnode { owner, amount } => { + // try_track_unbond_mixnode(&owner, amount, info, deps) + // } + // ExecuteMsg::BondGateway { + // gateway, + // owner_signature, + // amount, + // } => try_bond_gateway(gateway, owner_signature, amount, info, env, deps), + // ExecuteMsg::UnbondGateway {} => try_unbond_gateway(info, deps), + // ExecuteMsg::TrackUnbondGateway { owner, amount } => { + // try_track_unbond_gateway(&owner, amount, info, deps) + // } + // ExecuteMsg::TransferOwnership { to_address } => { + // try_transfer_ownership(to_address, info, deps) + // } + // ExecuteMsg::UpdateStakingAddress { to_address } => { + // try_update_staking_address(to_address, info, deps) + // } } } diff --git a/contracts/vesting/src/errors.rs b/contracts/vesting/src/errors.rs index 867620ff8f..39bfaf4108 100644 --- a/contracts/vesting/src/errors.rs +++ b/contracts/vesting/src/errors.rs @@ -48,4 +48,7 @@ pub enum ContractError { MinVestingFunds { sent: u128, need: u128 }, #[error("VESTING ({}): Maximum amount of locked coins has already been pledged: {current}, cap is {cap}", line!())] LockedPledgeCapReached { current: Uint128, cap: Uint128 }, + + #[error("Contract is currently set to the maintenance mode - all transactions are temporarily disabled")] + MaintenanceMode, } diff --git a/contracts/vesting/src/storage.rs b/contracts/vesting/src/storage.rs index c753e57c37..96c263b0b8 100644 --- a/contracts/vesting/src/storage.rs +++ b/contracts/vesting/src/storage.rs @@ -6,6 +6,7 @@ use mixnet_contract_common::IdentityKey; use vesting_contract_common::PledgeData; pub(crate) type BlockTimestampSecs = u64; +pub(crate) type NodeId = u64; pub const KEY: Item<'_, u32> = Item::new("key"); const ACCOUNTS: Map<'_, String, Account> = Map::new("acc"); @@ -14,7 +15,9 @@ const BALANCES: Map<'_, u32, Uint128> = Map::new("blc"); const WITHDRAWNS: Map<'_, u32, Uint128> = Map::new("wthd"); const BOND_PLEDGES: Map<'_, u32, PledgeData> = Map::new("bnd"); const GATEWAY_PLEDGES: Map<'_, u32, PledgeData> = Map::new("gtw"); -pub const DELEGATIONS: Map<'_, (u32, IdentityKey, BlockTimestampSecs), Uint128> = Map::new("dlg"); +pub const OLD_DELEGATIONS: Map<'_, (u32, IdentityKey, BlockTimestampSecs), Uint128> = + Map::new("dlg"); +pub const DELEGATIONS: Map<'_, (u32, NodeId, BlockTimestampSecs), Uint128> = Map::new("dlg_v2"); pub const ADMIN: Item<'_, String> = Item::new("adm"); pub const MIXNET_CONTRACT_ADDRESS: Item<'_, String> = Item::new("mix"); pub const MIX_DENOM: Item<'_, String> = Item::new("den"); @@ -30,8 +33,9 @@ pub fn update_locked_pledge_cap( amount: Uint128, storage: &mut dyn Storage, ) -> Result<(), ContractError> { - LOCKED_PLEDGE_CAP.save(storage, &amount)?; - Ok(()) + Err(ContractError::MaintenanceMode) + // LOCKED_PLEDGE_CAP.save(storage, &amount)?; + // Ok(()) } pub fn save_delegation( @@ -39,16 +43,19 @@ pub fn save_delegation( amount: Uint128, storage: &mut dyn Storage, ) -> Result<(), ContractError> { - DELEGATIONS.save(storage, key, &amount)?; - Ok(()) + Err(ContractError::MaintenanceMode) + // DELEGATIONS.save(storage, key, &amount)?; + // Ok(()) } pub fn remove_delegation( key: (u32, IdentityKey, BlockTimestampSecs), storage: &mut dyn Storage, ) -> Result<(), ContractError> { - DELEGATIONS.remove(storage, key); - Ok(()) + Err(ContractError::MaintenanceMode) + // + // DELEGATIONS.remove(storage, key); + // Ok(()) } pub fn delete_account(address: &Addr, storage: &mut dyn Storage) -> Result<(), ContractError> { diff --git a/contracts/vesting/src/vesting/account/mod.rs b/contracts/vesting/src/vesting/account/mod.rs index f698037f8e..5ea3e2f5c0 100644 --- a/contracts/vesting/src/vesting/account/mod.rs +++ b/contracts/vesting/src/vesting/account/mod.rs @@ -198,11 +198,13 @@ impl Account { } pub fn any_delegation_for_mix(&self, mix: &str, storage: &dyn Storage) -> bool { - DELEGATIONS - .prefix((self.storage_key(), mix.to_string())) - .range(storage, None, None, Order::Ascending) - .next() - .is_some() + false + // + // DELEGATIONS + // .prefix((self.storage_key(), mix.to_string())) + // .range(storage, None, None, Order::Ascending) + // .next() + // .is_some() } pub fn remove_delegations_for_mix( @@ -210,36 +212,38 @@ impl Account { mix: &str, storage: &mut dyn Storage, ) -> Result<(), ContractError> { - let limit = 50; - let mut start_after = None; - let mut block_heights = Vec::new(); - let mut prev_len = 0; - // TODO: Test this - loop { - block_heights.extend( - DELEGATIONS - .prefix((self.storage_key(), mix.to_string())) - .keys(storage, start_after, None, Order::Ascending) - .take(limit) - .filter_map(|key| key.ok()), - ); - - if prev_len == block_heights.len() { - break; - } - - prev_len = block_heights.len(); - - start_after = block_heights.last().map(|last| Bound::exclusive(*last)); - if start_after.is_none() { - break; - } - } - - for block_height in block_heights { - remove_delegation((self.storage_key(), mix.to_string(), block_height), storage)?; - } - Ok(()) + Err(ContractError::MaintenanceMode) + // + // let limit = 50; + // let mut start_after = None; + // let mut block_heights = Vec::new(); + // let mut prev_len = 0; + // // TODO: Test this + // loop { + // block_heights.extend( + // DELEGATIONS + // .prefix((self.storage_key(), mix.to_string())) + // .keys(storage, start_after, None, Order::Ascending) + // .take(limit) + // .filter_map(|key| key.ok()), + // ); + // + // if prev_len == block_heights.len() { + // break; + // } + // + // prev_len = block_heights.len(); + // + // start_after = block_heights.last().map(|last| Bound::exclusive(*last)); + // if start_after.is_none() { + // break; + // } + // } + // + // for block_height in block_heights { + // remove_delegation((self.storage_key(), mix.to_string(), block_height), storage)?; + // } + // Ok(()) } pub fn total_delegations_for_mix( @@ -247,19 +251,23 @@ impl Account { mix: IdentityKey, storage: &dyn Storage, ) -> Result { - Ok(DELEGATIONS - .prefix((self.storage_key(), mix)) - .range(storage, None, None, Order::Ascending) - .filter_map(|x| x.ok()) - .fold(Uint128::zero(), |acc, (_key, val)| acc + val)) + Err(ContractError::MaintenanceMode) + + // Ok(DELEGATIONS + // .prefix((self.storage_key(), mix)) + // .range(storage, None, None, Order::Ascending) + // .filter_map(|x| x.ok()) + // .fold(Uint128::zero(), |acc, (_key, val)| acc + val)) } pub fn total_delegations(&self, storage: &dyn Storage) -> Result { - Ok(DELEGATIONS - .sub_prefix(self.storage_key()) - .range(storage, None, None, Order::Ascending) - .filter_map(|x| x.ok()) - .fold(Uint128::zero(), |acc, (_key, val)| acc + val)) + Err(ContractError::MaintenanceMode) + + // Ok(DELEGATIONS + // .sub_prefix(self.storage_key()) + // .range(storage, None, None, Order::Ascending) + // .filter_map(|x| x.ok()) + // .fold(Uint128::zero(), |acc, (_key, val)| acc + val)) } pub fn total_delegations_at_timestamp(