Hardhat/split (#134)

* split

* consts

* cleanup
This commit is contained in:
Hardhat Chad
2025-10-03 13:17:56 -05:00
committed by GitHub
parent 7a52ff73aa
commit 3a9703d6e1
8 changed files with 37 additions and 90 deletions

View File

@@ -84,6 +84,9 @@ pub const MINT_ADDRESS: Pubkey = pubkey!("oreoU2P8bN6jkk3jbaiVxYnG1dCXcYxwhwyK9j
/// The address of the sol mint account.
pub const SOL_MINT: Pubkey = pubkey!("So11111111111111111111111111111111111111112");
/// The address to indicate ORE rewards are split between all miners.
pub const SPLIT_ADDRESS: Pubkey = pubkey!("SpLiT11111111111111111111111111111111111112");
/// The address of the treasury account.
pub const TREASURY_ADDRESS: Pubkey =
Pubkey::new_from_array(ed25519::derive_program_address(&[TREASURY], &PROGRAM_ID).0);

View File

@@ -1,6 +1,6 @@
use steel::*;
use crate::state::{board_pda, OreAccountOLD};
use crate::state::board_pda;
use super::OreAccount;
@@ -17,40 +17,6 @@ pub struct Board {
pub end_slot: u64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
pub struct BoardOLD {
/// The round number.
pub id: u64,
/// The deployed SOL for the round.
pub deployed: [u64; 25],
/// The timestamp at which the block starts mining.
pub start_at: i64,
/// The slot at which the block starts trading.
pub start_slot: u64,
/// The slot at which the block ends trading.
pub end_slot: u64,
/// The hash of the end slot, provided by solana, used for random number generation.
pub slot_hash: [u8; 32],
/// The top miner of the round.
pub top_miner: Pubkey,
/// 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 Board {
pub fn pda(&self) -> (Pubkey, u8) {
board_pda()
@@ -58,4 +24,3 @@ impl Board {
}
account!(OreAccount, Board);
account!(OreAccountOLD, BoardOLD);

View File

@@ -1,6 +1,6 @@
use steel::*;
use crate::state::{miner_pda, OreAccountOLD};
use crate::state::miner_pda;
use super::OreAccount;
@@ -38,38 +38,6 @@ pub struct Miner {
pub lifetime_rewards_ore: u64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
pub struct MinerOLD {
/// The authority of this miner account.
pub authority: Pubkey,
/// The miner's prospects in the current round.
pub deployed: [u64; 25],
/// Unused buffer.
#[deprecated(note = "No longer used")]
pub buffer: [u8; 32],
/// The amount of SOL this miner has had refunded and may claim.
pub refund_sol: u64,
/// The amount of SOL this miner can claim.
pub rewards_sol: u64,
/// The amount of ORE this miner can claim.
pub rewards_ore: u64,
/// The ID of the round this miner last played in.
pub round_id: u64,
/// The total amount of SOL this miner has mined across all blocks.
pub lifetime_rewards_sol: u64,
/// The total amount of ORE this miner has mined across all blocks.
pub lifetime_rewards_ore: u64,
}
impl Miner {
pub fn pda(&self) -> (Pubkey, u8) {
miner_pda(self.authority)
@@ -77,4 +45,3 @@ impl Miner {
}
account!(OreAccount, Miner);
account!(OreAccountOLD, MinerOLD);

View File

@@ -35,13 +35,6 @@ pub enum OreAccount {
Round = 109,
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)]
pub enum OreAccountOLD {
MinerOLD = 103,
BoardOLD = 105,
}
pub fn automation_pda(authority: Pubkey) -> (Pubkey, u8) {
Pubkey::find_program_address(&[AUTOMATION, &authority.to_bytes()], &crate::ID)
}

View File

@@ -82,6 +82,17 @@ impl Round {
total_winnings
}
pub fn is_split_reward(&self, rng: u64) -> bool {
// One out of four rounds get split rewards.
let rng = rng.reverse_bits().to_le_bytes();
let r1 = u64::from_le_bytes(rng[0..2].try_into().unwrap());
let r2 = u64::from_le_bytes(rng[2..4].try_into().unwrap());
let r3 = u64::from_le_bytes(rng[4..6].try_into().unwrap());
let r4 = u64::from_le_bytes(rng[6..8].try_into().unwrap());
let r = r1 ^ r2 ^ r3 ^ r4;
r % 4 == 0
}
pub fn did_hit_motherlode(&self, rng: u64) -> bool {
rng.reverse_bits() % 625 == 0
}

View File

@@ -636,11 +636,6 @@ async fn get_miners(rpc: &RpcClient) -> Result<Vec<(Pubkey, Miner)>, anyhow::Err
Ok(miners)
}
async fn get_miners_old(rpc: &RpcClient) -> Result<Vec<(Pubkey, MinerOLD)>, anyhow::Error> {
let miners = get_program_accounts::<MinerOLD>(rpc, ore_api::ID, vec![]).await?;
Ok(miners)
}
async fn get_miners_participating(
rpc: &RpcClient,
round_id: u64,

View File

@@ -78,12 +78,20 @@ pub fn process_checkpoint(accounts: &[AccountInfo<'_>], _data: &[u8]) -> Program
/ round.deployed[winning_square] as u128) as u64;
// Calculate ORE rewards.
let top_miner_sample = round.top_miner_sample(r, winning_square);
if top_miner_sample >= miner.cumulative[winning_square]
&& top_miner_sample < miner.cumulative[winning_square] + miner.deployed[winning_square]
{
rewards_ore = round.top_miner_reward;
round.top_miner = miner.authority;
if round.top_miner == SPLIT_ADDRESS {
// If round is split, split the reward evenly among all miners.
rewards_ore = ((round.top_miner_reward * miner.deployed[winning_square])
/ round.deployed[winning_square]) as u64;
} else {
// If round is not split, payout to the top miner.
let top_miner_sample = round.top_miner_sample(r, winning_square);
if top_miner_sample >= miner.cumulative[winning_square]
&& top_miner_sample
< miner.cumulative[winning_square] + miner.deployed[winning_square]
{
rewards_ore = round.top_miner_reward;
round.top_miner = miner.authority;
}
}
// Calculate motherlode rewards.

View File

@@ -1,5 +1,5 @@
use ore_api::prelude::*;
use solana_program::slot_hashes::SlotHashes;
use solana_program::{pubkey, slot_hashes::SlotHashes};
use steel::*;
/// Pays out the winners and block reward.
@@ -151,6 +151,11 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul
&[TREASURY],
)?;
// Set top miner to split reward address if the round is split.
if round.is_split_reward(r) {
round.top_miner = SPLIT_ADDRESS;
}
// Reset the motherlode if it was activated.
if round.did_hit_motherlode(r) {
round.motherlode = treasury.motherlode;
@@ -193,7 +198,7 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul
start_slot: board.start_slot,
end_slot: board.end_slot,
winning_square: winning_square as u64,
top_miner: Pubkey::default(), // top_miner.authority,
top_miner: round.top_miner,
motherlode: round.motherlode,
num_winners: round.count[winning_square],
total_deployed: round.total_deployed,