|
1 | 1 | //! Acropolis AccountsState: State storage |
2 | 2 | use crate::monetary::calculate_monetary_change; |
3 | | -use crate::rewards::{calculate_rewards, RewardsResult}; |
| 3 | +use crate::rewards::{calculate_rewards, RewardType, RewardsResult}; |
4 | 4 | use crate::snapshot::Snapshot; |
5 | 5 | use crate::verifier::Verifier; |
6 | 6 | use acropolis_common::queries::accounts::OptimalPoolSizing; |
@@ -117,9 +117,6 @@ pub struct State { |
117 | 117 | /// Pool refunds to apply next epoch (list of reward accounts to refund to) |
118 | 118 | pool_refunds: Vec<StakeAddress>, |
119 | 119 |
|
120 | | - /// Stake address refunds to apply next epoch |
121 | | - stake_refunds: Vec<(StakeAddress, Lovelace)>, |
122 | | - |
123 | 120 | /// MIRs to pay next epoch |
124 | 121 | mirs: Vec<MoveInstantaneousReward>, |
125 | 122 |
|
@@ -325,7 +322,6 @@ impl State { |
325 | 322 |
|
326 | 323 | // Pay the refunds after snapshot, so they don't appear in active_stake |
327 | 324 | reward_deltas.extend(self.pay_pool_refunds()); |
328 | | - reward_deltas.extend(self.pay_stake_refunds()); |
329 | 325 |
|
330 | 326 | // Verify pots state |
331 | 327 | verifier.verify_pots(epoch, &self.pots); |
@@ -497,33 +493,6 @@ impl State { |
497 | 493 | reward_deltas |
498 | 494 | } |
499 | 495 |
|
500 | | - /// Pay stake address refunds |
501 | | - fn pay_stake_refunds(&mut self) -> Vec<StakeRewardDelta> { |
502 | | - let mut reward_deltas = Vec::<StakeRewardDelta>::new(); |
503 | | - |
504 | | - let refunds = take(&mut self.stake_refunds); |
505 | | - if !refunds.is_empty() { |
506 | | - info!( |
507 | | - "{} deregistered stake addresses, total refunds {}", |
508 | | - refunds.len(), |
509 | | - refunds.iter().map(|(_, n)| n).sum::<Lovelace>() |
510 | | - ); |
511 | | - } |
512 | | - |
513 | | - // Send them their deposits back |
514 | | - for (stake_address, deposit) in refunds { |
515 | | - let mut stake_addresses = self.stake_addresses.lock().unwrap(); |
516 | | - reward_deltas.push(StakeRewardDelta { |
517 | | - stake_address: stake_address.clone(), // Extract hash for delta |
518 | | - delta: deposit as i64, |
519 | | - }); |
520 | | - stake_addresses.add_to_reward(&stake_address, deposit); |
521 | | - self.pots.deposits -= deposit; |
522 | | - } |
523 | | - |
524 | | - reward_deltas |
525 | | - } |
526 | | - |
527 | 496 | /// Pay MIRs |
528 | 497 | fn pay_mirs(&mut self) -> Vec<StakeRewardDelta> { |
529 | 498 | let mut reward_deltas = Vec::<StakeRewardDelta>::new(); |
@@ -658,36 +627,52 @@ impl State { |
658 | 627 |
|
659 | 628 | // If rewards have been calculated, save the results |
660 | 629 | if let Some(task) = task.take() { |
661 | | - if let Ok(Ok(reward_result)) = task.await { |
662 | | - // Collect rewards to stake addresses reward deltas |
663 | | - for rewards in reward_result.rewards.values() { |
664 | | - reward_deltas.extend( |
665 | | - rewards |
666 | | - .iter() |
667 | | - .map(|reward| StakeRewardDelta { |
668 | | - stake_address: reward.account.clone(), |
669 | | - delta: reward.amount as i64, |
670 | | - }) |
671 | | - .collect::<Vec<_>>(), |
672 | | - ); |
673 | | - } |
674 | | - |
675 | | - // Verify them |
676 | | - verifier.verify_rewards(reward_result.epoch, &reward_result); |
677 | | - |
| 630 | + if let Ok(Ok(rewards_result)) = task.await { |
678 | 631 | // Pay the rewards |
679 | 632 | let mut stake_addresses = self.stake_addresses.lock().unwrap(); |
680 | | - for (_, rewards) in reward_result.rewards { |
| 633 | + let mut filtered_rewards_result = rewards_result.clone(); |
| 634 | + for (spo, rewards) in rewards_result.rewards { |
681 | 635 | for reward in rewards { |
682 | | - stake_addresses.add_to_reward(&reward.account, reward.amount); |
| 636 | + if stake_addresses.is_registered(&reward.account) { |
| 637 | + stake_addresses.add_to_reward(&reward.account, reward.amount); |
| 638 | + reward_deltas.push(StakeRewardDelta { |
| 639 | + stake_address: reward.account.clone(), |
| 640 | + delta: reward.amount as i64, |
| 641 | + }); |
| 642 | + } else { |
| 643 | + warn!( |
| 644 | + "Reward account {} deregistered - paying reward {} to treasury", |
| 645 | + reward.account, reward.amount |
| 646 | + ); |
| 647 | + self.pots.treasury += reward.amount; |
| 648 | + |
| 649 | + // Remove from filtered version for comparison and result |
| 650 | + if let Some(rewards) = filtered_rewards_result.rewards.get_mut(&spo) { |
| 651 | + rewards.retain(|r| r.account != reward.account); |
| 652 | + } |
| 653 | + |
| 654 | + if let Some((_, spor)) = filtered_rewards_result |
| 655 | + .spo_rewards |
| 656 | + .iter_mut() |
| 657 | + .find(|(fspo, _)| *fspo == spo) |
| 658 | + { |
| 659 | + spor.total_rewards -= reward.amount; |
| 660 | + if reward.rtype == RewardType::Leader { |
| 661 | + spor.operator_rewards -= reward.amount; |
| 662 | + } |
| 663 | + } |
| 664 | + } |
683 | 665 | } |
684 | 666 | } |
685 | 667 |
|
| 668 | + // Verify them |
| 669 | + verifier.verify_rewards(&filtered_rewards_result); |
| 670 | + |
686 | 671 | // save SPO rewards |
687 | | - spo_rewards = reward_result.spo_rewards.into_iter().collect(); |
| 672 | + spo_rewards = filtered_rewards_result.spo_rewards.clone(); |
688 | 673 |
|
689 | 674 | // Adjust the reserves for next time with amount actually paid |
690 | | - self.pots.reserves -= reward_result.total_paid; |
| 675 | + self.pots.reserves -= rewards_result.total_paid; |
691 | 676 | } |
692 | 677 | }; |
693 | 678 |
|
@@ -842,8 +827,7 @@ impl State { |
842 | 827 | } |
843 | 828 | }; |
844 | 829 |
|
845 | | - // Schedule refund |
846 | | - self.stake_refunds.push((stake_address.clone(), deposit)); |
| 830 | + self.pots.deposits -= deposit; |
847 | 831 |
|
848 | 832 | // Add to registration changes |
849 | 833 | self.current_epoch_registration_changes.lock().unwrap().push(RegistrationChange { |
@@ -1331,6 +1315,7 @@ mod tests { |
1331 | 1315 | withdrawals: vec![Withdrawal { |
1332 | 1316 | address: stake_address.clone(), |
1333 | 1317 | value: 39, |
| 1318 | + tx_identifier: TxIdentifier::default(), |
1334 | 1319 | }], |
1335 | 1320 | }; |
1336 | 1321 |
|
|
0 commit comments