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 f7e6a9ca3e..f430ea79b3 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 @@ -4653,4 +4653,16 @@ fn should_change_validator_bid_public_key() { .build(); builder.exec(distribute_request).commit().expect_success(); + + let bids = builder.get_bids(); + assert_eq!(bids.len(), 4); + + let delegator = bids + .delegator_by_public_keys(&NON_FOUNDER_VALIDATOR_2_PK, &BID_ACCOUNT_1_PK) + .expect("should have account1 delegation"); + assert!(delegator.staked_amount() > U512::from(DELEGATE_AMOUNT_1)); + let delegator = bids + .delegator_by_public_keys(&NON_FOUNDER_VALIDATOR_2_PK, &BID_ACCOUNT_2_PK) + .expect("should have account2 delegation"); + assert!(delegator.staked_amount() > U512::from(DELEGATE_AMOUNT_2)); } diff --git a/storage/src/system/auction/detail.rs b/storage/src/system/auction/detail.rs index 079f245610..d793bcf982 100644 --- a/storage/src/system/auction/detail.rs +++ b/storage/src/system/auction/detail.rs @@ -282,6 +282,7 @@ pub fn create_unbonding_purse( /// Attempts to apply the delegator reward to the existing stake. If the reward recipient has /// completely unstaked, applies it to their unbond instead. In either case, returns /// the purse the amount should be applied to. +/// If the `ValidatorBid` public key was changed, attemps to fetch the current `validator_public_key`. pub fn distribute_delegator_rewards

( provider: &mut P, seigniorage_allocations: &mut Vec, @@ -291,6 +292,11 @@ pub fn distribute_delegator_rewards

( where P: RuntimeProvider + StorageProvider, { + // fetch current `ValidatorBid` if public key was changed + let validator_bid_addr = BidAddr::from(validator_public_key); + let validator_bid = read_current_validator_bid(provider, &validator_bid_addr.into())?; + let validator_public_key = validator_bid.validator_public_key().clone(); + let mut delegator_payouts = Vec::new(); for (delegator_public_key, delegator_reward) in rewards { let bid_key = @@ -551,6 +557,29 @@ where } } +/// Returns current `ValidatorBid` in case the public key was changed. +pub fn read_current_validator_bid

( + provider: &mut P, + bid_key: &Key, +) -> Result, Error> +where + P: StorageProvider + ?Sized, +{ + if !bid_key.is_bid_addr_key() { + return Err(Error::InvalidKeyVariant); + } + if let Some(BidKind::Validator(mut validator_bid)) = provider.read_bid(bid_key)? { + while let Some(new_bid_bridge) = validator_bid.new_validator_bid_bridge() { + let validator_bid_addr = + BidAddr::from(new_bid_bridge.new_validator_public_key().clone()); + validator_bid = read_validator_bid(provider, &validator_bid_addr.into())?; + } + Ok(validator_bid) + } else { + Err(Error::ValidatorNotFound) + } +} + pub fn read_delegator_bids

( provider: &mut P, validator_public_key: &PublicKey,