diff --git a/execution_engine/src/core/engine_state/mod.rs b/execution_engine/src/core/engine_state/mod.rs index cdaf5d8d8f..11f5bcfd02 100644 --- a/execution_engine/src/core/engine_state/mod.rs +++ b/execution_engine/src/core/engine_state/mod.rs @@ -23,7 +23,7 @@ pub mod upgrade; use std::{ cell::RefCell, - collections::{btree_map::Entry, BTreeMap, BTreeSet}, + collections::{BTreeMap, BTreeSet}, convert::TryFrom, rc::Rc, }; @@ -40,17 +40,17 @@ use casper_types::{ contracts::NamedKeys, system::{ auction::{ - EraValidators, UnbondingPurse, WithdrawPurse, ARG_ERA_END_TIMESTAMP_MILLIS, - ARG_EVICTED_VALIDATORS, ARG_REWARD_FACTORS, ARG_VALIDATOR_PUBLIC_KEYS, - AUCTION_DELAY_KEY, ERA_ID_KEY, LOCKED_FUNDS_PERIOD_KEY, - SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY, UNBONDING_DELAY_KEY, VALIDATOR_SLOTS_KEY, + EraValidators, ARG_ERA_END_TIMESTAMP_MILLIS, ARG_EVICTED_VALIDATORS, + ARG_REWARD_FACTORS, ARG_VALIDATOR_PUBLIC_KEYS, AUCTION_DELAY_KEY, + LOCKED_FUNDS_PERIOD_KEY, SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY, UNBONDING_DELAY_KEY, + VALIDATOR_SLOTS_KEY, }, handle_payment, mint::{self, ROUND_SEIGNIORAGE_RATE_KEY}, AUCTION, HANDLE_PAYMENT, MINT, STANDARD_PAYMENT, }, - AccessRights, ApiError, BlockTime, CLValue, ContractHash, DeployHash, DeployInfo, EraId, Gas, - Key, KeyTag, Motes, Phase, ProtocolVersion, PublicKey, RuntimeArgs, StoredValue, URef, U512, + AccessRights, ApiError, BlockTime, CLValue, ContractHash, DeployHash, DeployInfo, Gas, Key, + KeyTag, Motes, Phase, ProtocolVersion, PublicKey, RuntimeArgs, StoredValue, URef, U512, }; pub use self::{ @@ -421,89 +421,6 @@ where for (key, value) in upgrade_config.global_state_update() { tracking_copy.borrow_mut().write(*key, value.clone()); } - - // This is a one time data transformation which will be removed - // in a following upgrade. - // TODO: CRef={https://github.com/casper-network/casper-node/issues/2479} - { - let withdraw_keys = tracking_copy - .borrow_mut() - .get_keys(correlation_id, &KeyTag::Withdraw) - .map_err(|_| Error::FailedToGetWithdrawKeys)?; - - let (unbonding_delay, current_era_id) = { - let auction_contract = tracking_copy - .borrow_mut() - .get_contract(correlation_id, *auction_hash)?; - - let unbonding_delay_key = auction_contract.named_keys()[UNBONDING_DELAY_KEY]; - let delay = tracking_copy - .borrow_mut() - .read(correlation_id, &unbonding_delay_key) - .map_err(|error| error.into())? - .ok_or(Error::FailedToRetrieveUnbondingDelay)? - .as_cl_value() - .ok_or_else(|| Error::Bytesrepr("unbonding_delay".to_string()))? - .clone() - .into_t::() - .map_err(execution::Error::from)?; - - let era_id_key = auction_contract.named_keys()[ERA_ID_KEY]; - - let era_id = tracking_copy - .borrow_mut() - .read(correlation_id, &era_id_key) - .map_err(|error| error.into())? - .ok_or(Error::FailedToRetrieveEraId)? - .as_cl_value() - .ok_or_else(|| Error::Bytesrepr("era_id".to_string()))? - .clone() - .into_t::() - .map_err(execution::Error::from)?; - - (delay, era_id) - }; - - for key in withdraw_keys { - // Transform only those withdraw purses that are still to be - // processed in the unbonding queue. - let withdraw_purses = tracking_copy - .borrow_mut() - .read(correlation_id, &key) - .map_err(|_| Error::FailedToGetWithdrawKeys)? - .ok_or(Error::FailedToGetStoredWithdraws)? - .as_withdraw() - .ok_or(Error::FailedToGetWithdrawPurses)? - .to_owned(); - - // Ensure that sufficient balance exists for all unbond purses that are to be - // migrated. - Self::fail_upgrade_if_withdraw_purses_lack_sufficient_balance( - &withdraw_purses, - &tracking_copy, - correlation_id, - )?; - - let unbonding_purses: Vec = withdraw_purses - .into_iter() - .filter_map(|purse| { - if purse.era_of_creation() + unbonding_delay >= current_era_id { - return Some(UnbondingPurse::from(purse)); - } - None - }) - .collect(); - - let unbonding_key = key - .withdraw_to_unbond() - .ok_or_else(|| Error::Bytesrepr("unbond".to_string()))?; - - tracking_copy - .borrow_mut() - .write(unbonding_key, StoredValue::Unbonding(unbonding_purses)); - } - } - // We insert the new unbonding delay once the purses to be paid out have been transformed // based on the previous unbonding delay. if let Some(new_unbonding_delay) = upgrade_config.new_unbonding_delay() { @@ -2269,52 +2186,6 @@ where .map_err(Into::into)?; maybe_proof.ok_or(Error::MissingChecksumRegistry) } - - /// As the name suggests, used to ensure commit_upgrade fails if we lack sufficient balances. - fn fail_upgrade_if_withdraw_purses_lack_sufficient_balance( - withdraw_purses: &[WithdrawPurse], - tracking_copy: &Rc::Reader>>>, - correlation_id: CorrelationId, - ) -> Result<(), Error> { - let mut balances = BTreeMap::new(); - for purse in withdraw_purses.iter() { - match balances.entry(*purse.bonding_purse()) { - Entry::Vacant(entry) => { - entry.insert(*purse.amount()); - } - Entry::Occupied(mut entry) => { - let value = entry.get_mut(); - let new_val = value.checked_add(*purse.amount()).ok_or_else(|| { - Error::Mint("overflowed a u512 during unbond migration".into()) - })?; - *value = new_val; - } - } - } - for (unbond_purse_uref, unbond_amount) in balances { - let key = match tracking_copy - .borrow_mut() - .get_purse_balance_key(correlation_id, unbond_purse_uref.into()) - { - Ok(key) => key, - Err(_) => return Err(Error::Mint("purse balance not found".into())), - }; - let current_balance = tracking_copy - .borrow_mut() - .get_purse_balance(CorrelationId::new(), key)? - .value(); - - if unbond_amount > current_balance { - // If we don't have enough balance to migrate, the only thing we can do - // is to fail the upgrade. - error!(%current_balance, %unbond_purse_uref, %unbond_amount, "commit_upgrade failed during migration - insufficient in purse to unbond"); - return Err(Error::Mint( - "insufficient balance detected while migrating unbond purses".into(), - )); - } - } - Ok(()) - } } fn log_execution_result(preamble: &'static str, result: &ExecutionResult) { diff --git a/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs b/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs index 816cae8853..34b23c5e25 100644 --- a/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs +++ b/execution_engine_testing/tests/src/test/system_contracts/auction/bids.rs @@ -3306,48 +3306,6 @@ fn should_delegate_and_redelegate() { ); } -#[ignore] -#[test] -fn should_upgrade_unbonding_purses_from_rel_1_4_2() { - // The `lmdb_fixture::RELEASE_1_4_2` has a single withdraw key - // present in the unbonding queue at the upgrade point - let (mut builder, lmdb_fixture_state, _temp_dir) = - lmdb_fixture::builder_from_global_state_fixture(lmdb_fixture::RELEASE_1_4_2); - - let previous_protocol_version = lmdb_fixture_state.genesis_protocol_version(); - - let new_protocol_version = ProtocolVersion::from_parts( - previous_protocol_version.value().major, - previous_protocol_version.value().minor + 1, - 0, - ); - - let mut upgrade_request = { - UpgradeRequestBuilder::new() - .with_current_protocol_version(previous_protocol_version) - .with_new_protocol_version(new_protocol_version) - .with_activation_point(EraId::new(1u64)) - .build() - }; - - builder - .upgrade_with_upgrade_request(*builder.get_engine_state().config(), &mut upgrade_request) - .expect_upgrade_success(); - - let unbonding_purses: UnbondingPurses = builder.get_unbonds(); - assert_eq!(unbonding_purses.len(), 1); - - let unbond_list = unbonding_purses - .get(&NON_FOUNDER_VALIDATOR_1_ADDR) - .expect("should have unbonding purse for non founding validator"); - assert_eq!(unbond_list.len(), 1); - assert_eq!( - unbond_list[0].validator_public_key(), - &*NON_FOUNDER_VALIDATOR_1_PK - ); - assert!(unbond_list[0].new_validator().is_none()) -} - #[ignore] #[test] fn should_handle_redelegation_to_inactive_validator() { @@ -3540,450 +3498,6 @@ fn should_handle_redelegation_to_inactive_validator() { ); } -#[ignore] -#[test] -fn should_continue_auction_state_from_release_1_4_x() { - // The `lmdb_fixture::RELEASE_1_4_3` has three withdraw keys - // in the unbonding queue which will each be processed - // in the three eras after the upgrade. - let (mut builder, lmdb_fixture_state, _temp_dir) = - lmdb_fixture::builder_from_global_state_fixture(lmdb_fixture::RELEASE_1_4_3); - - let withdraw_purses: WithdrawPurses = builder.get_withdraw_purses(); - - assert_eq!(withdraw_purses.len(), 1); - - let previous_protocol_version = lmdb_fixture_state.genesis_protocol_version(); - - let new_protocol_version = ProtocolVersion::from_parts( - previous_protocol_version.value().major, - previous_protocol_version.value().minor + 1, - 0, - ); - - let mut upgrade_request = { - UpgradeRequestBuilder::new() - .with_current_protocol_version(previous_protocol_version) - .with_new_protocol_version(new_protocol_version) - .with_activation_point(EraId::new(20u64)) - .with_new_unbonding_delay(DEFAULT_UNBONDING_DELAY) - .build() - }; - - builder - .upgrade_with_upgrade_request(*builder.get_engine_state().config(), &mut upgrade_request) - .expect_upgrade_success(); - - let unbonding_purses: UnbondingPurses = builder.get_unbonds(); - assert_eq!(unbonding_purses.len(), 1); - - let unbond_list = unbonding_purses - .get(&NON_FOUNDER_VALIDATOR_1_ADDR) - .expect("should have unbonding purse for non founding validator"); - assert_eq!(unbond_list.len(), 3); - assert_eq!( - unbond_list[0].validator_public_key(), - &*NON_FOUNDER_VALIDATOR_1_PK - ); - assert!(unbond_list[0].new_validator().is_none()); - assert!(unbond_list[1].new_validator().is_none()); - assert!(unbond_list[2].new_validator().is_none()); - - let delegator_1_undelegate_purse = builder - .get_account(*BID_ACCOUNT_1_ADDR) - .expect("should have account") - .main_purse(); - - let delegator_2_undelegate_purse = builder - .get_account(*BID_ACCOUNT_2_ADDR) - .expect("should have account") - .main_purse(); - - let delegator_3_undelegate_purse = builder - .get_account(*DELEGATOR_1_ADDR) - .expect("should have account") - .main_purse(); - - let delegator_1_purse_balance_pre_step = - builder.get_purse_balance(delegator_1_undelegate_purse); - - let delegator_2_purse_balance_pre_step = - builder.get_purse_balance(delegator_2_undelegate_purse); - - let delegator_3_purse_balance_pre_step = - builder.get_purse_balance(delegator_3_undelegate_purse); - - builder.advance_era( - vec![ - RewardItem::new(NON_FOUNDER_VALIDATOR_1_PK.clone(), 1), - RewardItem::new(GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY.clone(), 0), - RewardItem::new(GENESIS_VALIDATOR_ACCOUNT_2_PUBLIC_KEY.clone(), 0), - ], - vec![], - ); - - let delegator_1_purse_balance_post_step = - builder.get_purse_balance(delegator_1_undelegate_purse); - - assert_eq!( - delegator_1_purse_balance_post_step, - delegator_1_purse_balance_pre_step + U512::from(UNDELEGATE_AMOUNT_1) - ); - - let delegator_2_purse_balance_post_step = - builder.get_purse_balance(delegator_2_undelegate_purse); - - assert_eq!( - delegator_2_purse_balance_post_step, - delegator_2_purse_balance_pre_step + U512::from(UNDELEGATE_AMOUNT_1) - ); - - let delegator_3_purse_balance_post_step = - builder.get_purse_balance(delegator_3_undelegate_purse); - - assert_eq!( - delegator_3_purse_balance_post_step, - delegator_3_purse_balance_pre_step + U512::from(UNDELEGATE_AMOUNT_1) - ); - - let delegator_4_fund_request = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_TRANSFER_TO_ACCOUNT, - runtime_args! { - ARG_TARGET => *DELEGATOR_2_ADDR, - ARG_AMOUNT => U512::from(TRANSFER_AMOUNT) - }, - ) - .build(); - - builder - .exec(delegator_4_fund_request) - .expect_success() - .commit(); - - let delegator_4_validator_1_delegate_request = ExecuteRequestBuilder::standard( - *DELEGATOR_2_ADDR, - CONTRACT_DELEGATE, - runtime_args! { - ARG_AMOUNT => U512::from(DELEGATE_AMOUNT_1), - ARG_VALIDATOR => NON_FOUNDER_VALIDATOR_1_PK.clone(), - ARG_DELEGATOR => DELEGATOR_2.clone(), - }, - ) - .build(); - - builder - .exec(delegator_4_validator_1_delegate_request) - .expect_success() - .commit(); - - let delegator_4_redelegate_request = ExecuteRequestBuilder::standard( - *DELEGATOR_2_ADDR, - CONTRACT_REDELEGATE, - runtime_args! { - ARG_AMOUNT => U512::from(UNDELEGATE_AMOUNT_1 + DEFAULT_MINIMUM_DELEGATION_AMOUNT), - ARG_VALIDATOR => NON_FOUNDER_VALIDATOR_1_PK.clone(), - ARG_DELEGATOR => DELEGATOR_2.clone(), - ARG_NEW_VALIDATOR => GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY.clone() - }, - ) - .build(); - - builder - .exec(delegator_4_redelegate_request) - .expect_success() - .commit(); - - let delegator_4_purse = builder - .get_account(*DELEGATOR_2_ADDR) - .expect("must have account") - .main_purse(); - - let delegator_4_purse_balance_before = builder.get_purse_balance(delegator_4_purse); - - let actual_unbonding_delay = builder.get_unbonding_delay(); - - assert_eq!(actual_unbonding_delay, DEFAULT_UNBONDING_DELAY); - - for _ in 0..=actual_unbonding_delay { - let delegator_4_redelegate_purse_balance = builder.get_purse_balance(delegator_4_purse); - assert_eq!( - delegator_4_redelegate_purse_balance, - delegator_4_purse_balance_before - ); - - builder.advance_era( - vec![ - RewardItem::new(NON_FOUNDER_VALIDATOR_1_PK.clone(), 1), - RewardItem::new(GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY.clone(), 0), - RewardItem::new(GENESIS_VALIDATOR_ACCOUNT_2_PUBLIC_KEY.clone(), 0), - ], - vec![], - ); - } - - let delegator_4_purse_balance_after = builder.get_purse_balance(delegator_4_purse); - - // redelegation will not transfer funds back to the user - // therefore the balance must remain the same - assert_eq!( - delegator_4_purse_balance_before, - delegator_4_purse_balance_after - ); - - let bids: Bids = builder.get_bids(); - assert_eq!(bids.len(), 3); - - let delegators = bids[&NON_FOUNDER_VALIDATOR_1_PK].delegators(); - assert_eq!(delegators.len(), 4); - let delegated_amount_1 = *delegators[&DELEGATOR_2].staked_amount(); - assert_eq!( - delegated_amount_1, - U512::from(DELEGATE_AMOUNT_1 - UNDELEGATE_AMOUNT_1 - DEFAULT_MINIMUM_DELEGATION_AMOUNT) - ); - - let delegators = bids[&GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY].delegators(); - assert_eq!(delegators.len(), 1); - let redelegated_amount_1 = *delegators[&DELEGATOR_2].staked_amount(); - assert_eq!( - redelegated_amount_1, - U512::from(UNDELEGATE_AMOUNT_1 + DEFAULT_MINIMUM_DELEGATION_AMOUNT) - ); -} - -#[ignore] -#[test] -fn should_transfer_to_main_purse_when_validator_is_no_longer_active() { - let (mut builder, lmdb_fixture_state, _temp_dir) = - lmdb_fixture::builder_from_global_state_fixture(lmdb_fixture::RELEASE_1_4_3); - - let withdraw_purses: WithdrawPurses = builder.get_withdraw_purses(); - - assert_eq!(withdraw_purses.len(), 1); - - let previous_protocol_version = lmdb_fixture_state.genesis_protocol_version(); - - let new_protocol_version = ProtocolVersion::from_parts( - previous_protocol_version.value().major, - previous_protocol_version.value().minor + 1, - 0, - ); - - let mut upgrade_request = { - UpgradeRequestBuilder::new() - .with_current_protocol_version(previous_protocol_version) - .with_new_protocol_version(new_protocol_version) - .with_activation_point(EraId::new(20u64)) - .build() - }; - - builder - .upgrade_with_upgrade_request(*builder.get_engine_state().config(), &mut upgrade_request) - .expect_upgrade_success(); - - let unbonding_purses: UnbondingPurses = builder.get_unbonds(); - assert_eq!(unbonding_purses.len(), 1); - - let unbond_list = unbonding_purses - .get(&NON_FOUNDER_VALIDATOR_1_ADDR) - .expect("should have unbonding purses for non founding validator"); - assert_eq!(unbond_list.len(), 3); - assert_eq!( - unbond_list[0].validator_public_key(), - &*NON_FOUNDER_VALIDATOR_1_PK - ); - assert!(unbond_list[0].new_validator().is_none()); - assert!(unbond_list[1].new_validator().is_none()); - assert!(unbond_list[2].new_validator().is_none()); - - let delegator_1_undelegate_purse = builder - .get_account(*BID_ACCOUNT_1_ADDR) - .expect("should have account") - .main_purse(); - - let delegator_1_purse_balance_pre_step = - builder.get_purse_balance(delegator_1_undelegate_purse); - - builder.advance_era( - vec![ - RewardItem::new(NON_FOUNDER_VALIDATOR_1_PK.clone(), 1), - RewardItem::new(GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY.clone(), 0), - RewardItem::new(GENESIS_VALIDATOR_ACCOUNT_2_PUBLIC_KEY.clone(), 0), - ], - vec![], - ); - - let delegator_1_purse_balance_post_step = - builder.get_purse_balance(delegator_1_undelegate_purse); - - assert_eq!( - delegator_1_purse_balance_post_step, - delegator_1_purse_balance_pre_step + U512::from(UNDELEGATE_AMOUNT_1) - ); - - let delegator_2_undelegate_purse = builder - .get_account(*BID_ACCOUNT_2_ADDR) - .expect("should have account") - .main_purse(); - - let delegator_2_purse_balance_pre_step = - builder.get_purse_balance(delegator_2_undelegate_purse); - - builder.advance_era( - vec![ - RewardItem::new(NON_FOUNDER_VALIDATOR_1_PK.clone(), 1), - RewardItem::new(GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY.clone(), 0), - RewardItem::new(GENESIS_VALIDATOR_ACCOUNT_2_PUBLIC_KEY.clone(), 0), - ], - vec![], - ); - - let delegator_2_purse_balance_post_step = - builder.get_purse_balance(delegator_2_undelegate_purse); - - assert_eq!( - delegator_2_purse_balance_post_step, - delegator_2_purse_balance_pre_step + U512::from(UNDELEGATE_AMOUNT_1) - ); - - let delegator_3_undelegate_purse = builder - .get_account(*DELEGATOR_1_ADDR) - .expect("should have account") - .main_purse(); - - let delegator_3_purse_balance_pre_step = - builder.get_purse_balance(delegator_3_undelegate_purse); - - builder.advance_era( - vec![ - RewardItem::new(NON_FOUNDER_VALIDATOR_1_PK.clone(), 1), - RewardItem::new(GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY.clone(), 0), - RewardItem::new(GENESIS_VALIDATOR_ACCOUNT_2_PUBLIC_KEY.clone(), 0), - ], - vec![], - ); - - let delegator_3_purse_balance_post_step = - builder.get_purse_balance(delegator_3_undelegate_purse); - - assert_eq!( - delegator_3_purse_balance_post_step, - delegator_3_purse_balance_pre_step + U512::from(UNDELEGATE_AMOUNT_1) - ); - - let delegator_4_fund_request = ExecuteRequestBuilder::standard( - *DEFAULT_ACCOUNT_ADDR, - CONTRACT_TRANSFER_TO_ACCOUNT, - runtime_args! { - ARG_TARGET => *DELEGATOR_2_ADDR, - ARG_AMOUNT => U512::from(TRANSFER_AMOUNT) - }, - ) - .build(); - - builder - .exec(delegator_4_fund_request) - .expect_success() - .commit(); - - let delegator_4_validator_1_delegate_request = ExecuteRequestBuilder::standard( - *DELEGATOR_2_ADDR, - CONTRACT_DELEGATE, - runtime_args! { - ARG_AMOUNT => U512::from(DELEGATE_AMOUNT_1), - ARG_VALIDATOR => GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY.clone(), - ARG_DELEGATOR => DELEGATOR_2.clone(), - }, - ) - .build(); - - builder - .exec(delegator_4_validator_1_delegate_request) - .expect_success() - .commit(); - - let delegator_4_redelegate_request = ExecuteRequestBuilder::standard( - *DELEGATOR_2_ADDR, - CONTRACT_REDELEGATE, - runtime_args! { - ARG_AMOUNT => U512::from(UNDELEGATE_AMOUNT_1 + DEFAULT_MINIMUM_DELEGATION_AMOUNT), - ARG_VALIDATOR => GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY.clone(), - ARG_DELEGATOR => DELEGATOR_2.clone(), - ARG_NEW_VALIDATOR => NON_FOUNDER_VALIDATOR_1_PK.clone() - }, - ) - .build(); - - builder - .exec(delegator_4_redelegate_request) - .expect_success() - .commit(); - - let withdraw_request = ExecuteRequestBuilder::standard( - *NON_FOUNDER_VALIDATOR_1_ADDR, - CONTRACT_WITHDRAW_BID, - runtime_args! { - ARG_PUBLIC_KEY => NON_FOUNDER_VALIDATOR_1_PK.clone(), - ARG_AMOUNT => U512::from(ADD_BID_AMOUNT_1), - }, - ) - .build(); - - builder.exec(withdraw_request).expect_success().commit(); - - builder.advance_eras_by_default_auction_delay( - vec![ - RewardItem::new(NON_FOUNDER_VALIDATOR_1_PK.clone(), 1), - RewardItem::new(GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY.clone(), 0), - RewardItem::new(GENESIS_VALIDATOR_ACCOUNT_2_PUBLIC_KEY.clone(), 0), - ], - vec![], - ); - - let delegator_4_purse = builder - .get_account(*DELEGATOR_2_ADDR) - .expect("must have account") - .main_purse(); - - let delegator_4_purse_balance_before = builder.get_purse_balance(delegator_4_purse); - - let rewards = vec![ - RewardItem::new(GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY.clone(), 0), - RewardItem::new(GENESIS_VALIDATOR_ACCOUNT_2_PUBLIC_KEY.clone(), 0), - ]; - - for _ in 0..(builder.get_unbonding_delay() - builder.get_auction_delay()) { - let delegator_4_redelegate_purse_balance = builder.get_purse_balance(delegator_4_purse); - assert_eq!( - delegator_4_redelegate_purse_balance, - delegator_4_purse_balance_before - ); - - builder.advance_era(rewards.clone(), vec![]); - } - - let delegator_4_purse_balance_after = builder.get_purse_balance(delegator_4_purse); - - let bids: Bids = builder.get_bids(); - - assert!(bids[&NON_FOUNDER_VALIDATOR_1_PK].inactive()); - - // Since we have re-delegated to an inactive validator, - // the funds should cycle back to the delegator. - assert_eq!( - delegator_4_purse_balance_before + UNDELEGATE_AMOUNT_1 + DEFAULT_MINIMUM_DELEGATION_AMOUNT, - delegator_4_purse_balance_after - ); - - let delegators = bids[&GENESIS_VALIDATOR_ACCOUNT_1_PUBLIC_KEY].delegators(); - assert_eq!(delegators.len(), 1); - let delegated_amount_1 = *delegators[&DELEGATOR_2].staked_amount(); - assert_eq!( - delegated_amount_1, - U512::from(DELEGATE_AMOUNT_1 - UNDELEGATE_AMOUNT_1 - DEFAULT_MINIMUM_DELEGATION_AMOUNT) - ); -} - #[ignore] #[test] fn should_enforce_minimum_delegation_amount() {