solana_program/
epoch_rewards.rs1use {crate::hash::Hash, solana_sdk_macro::CloneZeroed};
10
11#[repr(C, align(16))]
12#[cfg_attr(feature = "frozen-abi", derive(AbiExample))]
13#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Default, CloneZeroed)]
14pub struct EpochRewards {
15 pub distribution_starting_block_height: u64,
18
19 pub num_partitions: u64,
22
23 pub parent_blockhash: Hash,
26
27 pub total_points: u128,
31
32 pub total_rewards: u64,
36
37 pub distributed_rewards: u64,
39
40 pub active: bool,
43}
44
45impl EpochRewards {
46 pub fn distribute(&mut self, amount: u64) {
47 let new_distributed_rewards = self.distributed_rewards.saturating_add(amount);
48 assert!(new_distributed_rewards <= self.total_rewards);
49 self.distributed_rewards = new_distributed_rewards;
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 impl EpochRewards {
58 pub fn new(
59 total_rewards: u64,
60 distributed_rewards: u64,
61 distribution_starting_block_height: u64,
62 ) -> Self {
63 Self {
64 total_rewards,
65 distributed_rewards,
66 distribution_starting_block_height,
67 ..Self::default()
68 }
69 }
70 }
71
72 #[test]
73 fn test_epoch_rewards_new() {
74 let epoch_rewards = EpochRewards::new(100, 0, 64);
75
76 assert_eq!(epoch_rewards.total_rewards, 100);
77 assert_eq!(epoch_rewards.distributed_rewards, 0);
78 assert_eq!(epoch_rewards.distribution_starting_block_height, 64);
79 }
80
81 #[test]
82 fn test_epoch_rewards_distribute() {
83 let mut epoch_rewards = EpochRewards::new(100, 0, 64);
84 epoch_rewards.distribute(100);
85
86 assert_eq!(epoch_rewards.total_rewards, 100);
87 assert_eq!(epoch_rewards.distributed_rewards, 100);
88 }
89
90 #[test]
91 #[should_panic(expected = "new_distributed_rewards <= self.total_rewards")]
92 fn test_epoch_rewards_distribute_panic() {
93 let mut epoch_rewards = EpochRewards::new(100, 0, 64);
94 epoch_rewards.distribute(200);
95 }
96}