ore_api/state/
miner.rs

1use serde::{Deserialize, Serialize};
2use steel::*;
3
4use crate::state::{miner_pda, OreAccountOLD, Treasury};
5
6use super::OreAccount;
7
8#[repr(C)]
9#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable, Serialize, Deserialize)]
10pub struct Miner {
11    /// The authority of this miner account.
12    pub authority: Pubkey,
13
14    /// The miner's prospects in the current round.
15    pub deployed: [u64; 25],
16
17    /// The cumulative amount of SOL deployed on each square prior to this miner's move.
18    pub cumulative: [u64; 25],
19
20    /// SOL witheld in reserve to pay for checkpointing.
21    pub checkpoint_fee: u64,
22
23    /// The last round that this miner checkpointed.
24    pub checkpoint_id: u64,
25
26    /// The last time this miner claimed ORE rewards.
27    pub last_claim_ore_at: i64,
28
29    /// The last time this miner claimed SOL rewards.
30    pub last_claim_sol_at: i64,
31
32    /// The rewards factor last time rewards were updated on this miner account.
33    pub rewards_factor: Numeric,
34
35    /// The amount of SOL this miner can claim.
36    pub rewards_sol: u64,
37
38    /// The amount of ORE this miner can claim.
39    pub rewards_ore: u64,
40
41    /// The amount of ORE this miner has earned from claim fees.
42    pub refined_ore: u64,
43
44    /// The ID of the round this miner last played in.
45    pub round_id: u64,
46
47    /// The total amount of SOL this miner has mined across all blocks.
48    pub lifetime_rewards_sol: u64,
49
50    /// The total amount of ORE this miner has mined across all blocks.
51    pub lifetime_rewards_ore: u64,
52
53    /// The total amount of ORE this miner has deployed across all rounds.
54    pub lifetime_deployed: u64,
55}
56
57#[repr(C)]
58#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable, Serialize, Deserialize)]
59pub struct MinerOLD {
60    /// The authority of this miner account.
61    pub authority: Pubkey,
62
63    /// The miner's prospects in the current round.
64    pub deployed: [u64; 25],
65
66    /// The cumulative amount of SOL deployed on each square prior to this miner's move.
67    pub cumulative: [u64; 25],
68
69    /// SOL witheld in reserve to pay for checkpointing.
70    pub checkpoint_fee: u64,
71
72    /// The last round that this miner checkpointed.
73    pub checkpoint_id: u64,
74
75    /// The last time this miner claimed ORE rewards.
76    pub last_claim_ore_at: i64,
77
78    /// The last time this miner claimed SOL rewards.
79    pub last_claim_sol_at: i64,
80
81    /// The rewards factor last time rewards were updated on this miner account.
82    pub rewards_factor: Numeric,
83
84    /// The amount of SOL this miner can claim.
85    pub rewards_sol: u64,
86
87    /// The amount of ORE this miner can claim.
88    pub rewards_ore: u64,
89
90    /// The amount of ORE this miner has earned from claim fees.
91    pub refined_ore: u64,
92
93    /// The ID of the round this miner last played in.
94    pub round_id: u64,
95
96    /// The total amount of SOL this miner has mined across all blocks.
97    pub lifetime_rewards_sol: u64,
98
99    /// The total amount of ORE this miner has mined across all blocks.
100    pub lifetime_rewards_ore: u64,
101}
102
103impl Miner {
104    pub fn pda(&self) -> (Pubkey, u8) {
105        miner_pda(self.authority)
106    }
107
108    pub fn claim_ore(&mut self, clock: &Clock, treasury: &mut Treasury) -> u64 {
109        self.update_rewards(treasury);
110        let refined_ore = self.refined_ore;
111        let rewards_ore = self.rewards_ore;
112        let mut amount = refined_ore + rewards_ore;
113        self.refined_ore = 0;
114        self.rewards_ore = 0;
115        treasury.total_unclaimed -= rewards_ore;
116        treasury.total_refined -= refined_ore;
117        self.last_claim_ore_at = clock.unix_timestamp;
118
119        // Charge a 10% fee and share with miners who haven't claimed yet.
120        if treasury.total_unclaimed > 0 {
121            let fee = rewards_ore / 10;
122            amount -= fee;
123            treasury.miner_rewards_factor += Numeric::from_fraction(fee, treasury.total_unclaimed);
124            treasury.total_refined += fee;
125            self.lifetime_rewards_ore -= fee;
126        }
127
128        amount
129    }
130
131    pub fn claim_sol(&mut self, clock: &Clock) -> u64 {
132        let amount = self.rewards_sol;
133        self.rewards_sol = 0;
134        self.last_claim_sol_at = clock.unix_timestamp;
135        amount
136    }
137
138    pub fn update_rewards(&mut self, treasury: &Treasury) {
139        // Accumulate rewards, weighted by stake balance.
140        if treasury.miner_rewards_factor > self.rewards_factor {
141            let accumulated_rewards = treasury.miner_rewards_factor - self.rewards_factor;
142            if accumulated_rewards < Numeric::ZERO {
143                panic!("Accumulated rewards is negative");
144            }
145            let personal_rewards = accumulated_rewards * Numeric::from_u64(self.rewards_ore);
146            self.refined_ore += personal_rewards.to_u64();
147            self.lifetime_rewards_ore += personal_rewards.to_u64();
148        }
149
150        // Update this miner account's last seen rewards factor.
151        self.rewards_factor = treasury.miner_rewards_factor;
152    }
153}
154
155impl MinerOLD {
156    pub fn pda(&self) -> (Pubkey, u8) {
157        miner_pda(self.authority)
158    }
159
160    pub fn claim_ore(&mut self, clock: &Clock, treasury: &mut Treasury) -> u64 {
161        self.update_rewards(treasury);
162        let refined_ore = self.refined_ore;
163        let rewards_ore = self.rewards_ore;
164        let mut amount = refined_ore + rewards_ore;
165        self.refined_ore = 0;
166        self.rewards_ore = 0;
167        treasury.total_unclaimed -= rewards_ore;
168        treasury.total_refined -= refined_ore;
169        self.last_claim_ore_at = clock.unix_timestamp;
170
171        // Charge a 10% fee and share with miners who haven't claimed yet.
172        if treasury.total_unclaimed > 0 {
173            let fee = rewards_ore / 10;
174            amount -= fee;
175            treasury.miner_rewards_factor += Numeric::from_fraction(fee, treasury.total_unclaimed);
176            treasury.total_refined += fee;
177            self.lifetime_rewards_ore -= fee;
178        }
179
180        amount
181    }
182
183    pub fn claim_sol(&mut self, clock: &Clock) -> u64 {
184        let amount = self.rewards_sol;
185        self.rewards_sol = 0;
186        self.last_claim_sol_at = clock.unix_timestamp;
187        amount
188    }
189
190    pub fn update_rewards(&mut self, treasury: &Treasury) {
191        // Accumulate rewards, weighted by stake balance.
192        if treasury.miner_rewards_factor > self.rewards_factor {
193            let accumulated_rewards = treasury.miner_rewards_factor - self.rewards_factor;
194            if accumulated_rewards < Numeric::ZERO {
195                panic!("Accumulated rewards is negative");
196            }
197            let personal_rewards = accumulated_rewards * Numeric::from_u64(self.rewards_ore);
198            self.refined_ore += personal_rewards.to_u64();
199            self.lifetime_rewards_ore += personal_rewards.to_u64();
200        }
201
202        // Update this miner account's last seen rewards factor.
203        self.rewards_factor = treasury.miner_rewards_factor;
204    }
205}
206
207account!(OreAccount, Miner);
208account!(OreAccountOLD, MinerOLD);