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