This commit is contained in:
Hardhat Chad
2025-10-01 12:19:54 -07:00
parent 94a5d67dcf
commit 48a21e4ecd
11 changed files with 204 additions and 152 deletions

View File

@@ -14,8 +14,26 @@ pub const ONE_ORE: u64 = 10u64.pow(TOKEN_DECIMALS as u32);
/// The duration of one minute, in seconds.
pub const ONE_MINUTE: i64 = 60;
/// The duration of one hour, in seconds.
pub const ONE_HOUR: i64 = 60 * ONE_MINUTE;
/// The duration of one day, in seconds.
pub const ONE_DAY: i64 = 24 * 60 * 60;
pub const ONE_DAY: i64 = 24 * ONE_HOUR;
/// The number of seconds for when the winning square expires.
pub const ONE_WEEK: i64 = 7 * ONE_DAY;
/// The number of slots in one week.
pub const ONE_MINUTE_SLOTS: u64 = 150;
/// The number of slots in one hour.
pub const ONE_HOUR_SLOTS: u64 = 60 * ONE_MINUTE_SLOTS;
/// The number of slots in one day.
pub const ONE_DAY_SLOTS: u64 = 24 * ONE_HOUR_SLOTS;
/// The number of slots in one week.
pub const ONE_WEEK_SLOTS: u64 = 7 * ONE_DAY_SLOTS;
/// The number of slots for breather between rounds.
pub const INTERMISSION_SLOTS: u64 = 35;

View File

@@ -9,24 +9,25 @@ pub enum OreInstruction {
Checkpoint = 2,
ClaimSOL = 3,
ClaimORE = 4,
Deploy = 5,
Initialize = 6,
Log = 7,
Reset = 8,
Close = 5,
Deploy = 6,
Initialize = 7,
Log = 8,
Reset = 9,
// Staker
Deposit = 9,
Withdraw = 10,
ClaimYield = 11,
Deposit = 10,
Withdraw = 11,
ClaimYield = 12,
// Admin
Bury = 12,
Wrap = 13,
SetAdmin = 14,
SetFeeCollector = 15,
Bury = 13,
Wrap = 14,
SetAdmin = 15,
SetFeeCollector = 16,
// Seeker
ClaimSeeker = 16,
ClaimSeeker = 17,
}
#[repr(C)]
@@ -149,8 +150,13 @@ pub struct ClaimSeeker {}
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct Checkpoint {}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct Close {}
instruction!(OreInstruction, Automate);
instruction!(OreInstruction, Boost);
instruction!(OreInstruction, Close);
instruction!(OreInstruction, Checkpoint);
instruction!(OreInstruction, ClaimSOL);
instruction!(OreInstruction, ClaimORE);

View File

@@ -10,9 +10,6 @@ pub struct Board {
/// The current round number.
pub round_id: u64,
/// The timestamp at which the current round starts mining.
pub start_at: i64,
/// The slot at which the current round starts mining.
pub start_slot: u64,
@@ -20,82 +17,6 @@ pub struct Board {
pub end_slot: u64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
pub struct Round {
/// The round number.
pub id: u64,
/// The amount of SOL deployed in each square.
pub deployed: [u64; 25],
/// The hash of the end slot, provided by solana, used for random number generation.
pub slot_hash: [u8; 32],
/// The slot at which claims for this round account end.
pub expires_at: i64,
/// The amount of ORE in the motherlode.
pub motherlode: u64,
/// The account to which rent should be returned when this account is closed.
pub rent_payer: Pubkey,
/// The top miner of the round.
pub top_miner: Pubkey,
/// The amount of ORE to distribute to the top miner.
pub top_miner_reward: u64,
/// The total amount of SOL deployed in the round.
pub total_deployed: u64,
/// The total amount of SOL put in the ORE vault.
pub total_vaulted: u64,
/// The total amount of SOL won by miners for the round.
pub total_winnings: u64,
}
impl Round {
pub fn rng(&self) -> u64 {
if self.slot_hash == [0; 32] {
return 0;
}
let r1 = u64::from_le_bytes(self.slot_hash[0..8].try_into().unwrap());
let r2 = u64::from_le_bytes(self.slot_hash[8..16].try_into().unwrap());
let r3 = u64::from_le_bytes(self.slot_hash[16..24].try_into().unwrap());
let r4 = u64::from_le_bytes(self.slot_hash[24..32].try_into().unwrap());
let r = r1 ^ r2 ^ r3 ^ r4;
r
}
pub fn winning_square(&self, rng: u64) -> usize {
(rng % 25) as usize
}
pub fn top_miner_sample(&self, rng: u64, winning_square: usize) -> u64 {
if self.deployed[winning_square] == 0 {
return 0;
}
rng.reverse_bits() % self.deployed[winning_square]
}
pub fn calculate_total_winnings(&self, winning_square: usize) -> u64 {
let mut total_winnings = 0;
for (i, &deployed) in self.deployed.iter().enumerate() {
if i != winning_square {
total_winnings += deployed;
}
}
total_winnings
}
pub fn did_hit_motherlode(&self, rng: u64) -> bool {
rng.reverse_bits() % 625 == 0
}
}
impl Board {
pub fn pda(&self) -> (Pubkey, u8) {
board_pda()
@@ -103,20 +24,3 @@ impl Board {
}
account!(OreAccount, Board);
account!(OreAccount, Round);
#[cfg(test)]
mod tests {
use solana_program::rent::Rent;
use super::*;
#[test]
fn test_rent() {
let size_of_round = 8 + std::mem::size_of::<Round>();
let required_rent = Rent::default().minimum_balance(size_of_round);
println!("required_rent: {}", required_rent);
assert!(false);
}
}

View File

@@ -2,8 +2,8 @@ mod automation;
mod board;
mod config;
mod miner;
mod round;
mod seeker;
// mod square;
mod stake;
mod treasury;
@@ -11,8 +11,8 @@ pub use automation::*;
pub use board::*;
pub use config::*;
pub use miner::*;
pub use round::*;
pub use seeker::*;
// pub use square::*;
pub use stake::*;
pub use treasury::*;
@@ -30,7 +30,6 @@ pub enum OreAccount {
//
Board = 105,
// Square = 106,
Seeker = 107,
Stake = 108,
Round = 109,
@@ -56,10 +55,6 @@ pub fn seeker_pda(mint: Pubkey) -> (Pubkey, u8) {
Pubkey::find_program_address(&[SEEKER, &mint.to_bytes()], &crate::ID)
}
// pub fn square_pda() -> (Pubkey, u8) {
// Pubkey::find_program_address(&[SQUARE], &crate::ID)
// }
pub fn round_pda(id: u64) -> (Pubkey, u8) {
Pubkey::find_program_address(&[ROUND, &id.to_le_bytes()], &crate::ID)
}

102
api/src/state/round.rs Normal file
View File

@@ -0,0 +1,102 @@
use steel::*;
use crate::state::round_pda;
use super::OreAccount;
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
pub struct Round {
/// The round number.
pub id: u64,
/// The amount of SOL deployed in each square.
pub deployed: [u64; 25],
/// The hash of the end slot, provided by solana, used for random number generation.
pub slot_hash: [u8; 32],
/// The slot at which claims for this round account end.
pub expires_at: u64,
/// The amount of ORE in the motherlode.
pub motherlode: u64,
/// The account to which rent should be returned when this account is closed.
pub rent_payer: Pubkey,
/// The top miner of the round.
pub top_miner: Pubkey,
/// The amount of ORE to distribute to the top miner.
pub top_miner_reward: u64,
/// The total amount of SOL deployed in the round.
pub total_deployed: u64,
/// The total amount of SOL put in the ORE vault.
pub total_vaulted: u64,
/// The total amount of SOL won by miners for the round.
pub total_winnings: u64,
}
impl Round {
pub fn pda(&self) -> (Pubkey, u8) {
round_pda(self.id)
}
pub fn rng(&self) -> u64 {
if self.slot_hash == [0; 32] {
return 0;
}
let r1 = u64::from_le_bytes(self.slot_hash[0..8].try_into().unwrap());
let r2 = u64::from_le_bytes(self.slot_hash[8..16].try_into().unwrap());
let r3 = u64::from_le_bytes(self.slot_hash[16..24].try_into().unwrap());
let r4 = u64::from_le_bytes(self.slot_hash[24..32].try_into().unwrap());
let r = r1 ^ r2 ^ r3 ^ r4;
r
}
pub fn winning_square(&self, rng: u64) -> usize {
(rng % 25) as usize
}
pub fn top_miner_sample(&self, rng: u64, winning_square: usize) -> u64 {
if self.deployed[winning_square] == 0 {
return 0;
}
rng.reverse_bits() % self.deployed[winning_square]
}
pub fn calculate_total_winnings(&self, winning_square: usize) -> u64 {
let mut total_winnings = 0;
for (i, &deployed) in self.deployed.iter().enumerate() {
if i != winning_square {
total_winnings += deployed;
}
}
total_winnings
}
pub fn did_hit_motherlode(&self, rng: u64) -> bool {
rng.reverse_bits() % 625 == 0
}
}
account!(OreAccount, Round);
#[cfg(test)]
mod tests {
use solana_program::rent::Rent;
use super::*;
#[test]
fn test_rent() {
let size_of_round = 8 + std::mem::size_of::<Round>();
let required_rent = Rent::default().minimum_balance(size_of_round);
println!("required_rent: {}", required_rent);
assert!(false);
}
}

View File

@@ -1,26 +0,0 @@
use steel::*;
use crate::state::square_pda;
use super::OreAccount;
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
pub struct Square {
/// The count of miners on each square.
pub count: [u64; 25],
/// The deployments of all players on each square.
pub deployed: [[u64; 16]; 25],
/// The miners authorities on each square.
pub miners: [[Pubkey; 16]; 25],
}
impl Square {
pub fn pda() -> (Pubkey, u8) {
square_pda()
}
}
account!(OreAccount, Square);