From 7954bfa9ecffa0cbcda515d9a9e2046ca655025b Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Sat, 20 Jul 2024 19:16:36 +0000 Subject: [PATCH 1/2] remove crown instruction --- api/src/instruction.rs | 34 ++++----------------- api/src/state/bus.rs | 3 ++ api/src/state/config.rs | 8 ++--- program/src/close.rs | 16 ++-------- program/src/crown.rs | 63 --------------------------------------- program/src/initialize.rs | 3 +- program/src/lib.rs | 3 -- program/src/mine.rs | 11 ++++--- program/src/reset.rs | 7 +++++ 9 files changed, 28 insertions(+), 120 deletions(-) delete mode 100644 program/src/crown.rs diff --git a/api/src/instruction.rs b/api/src/instruction.rs index 01c9ff0..fdf0469 100644 --- a/api/src/instruction.rs +++ b/api/src/instruction.rs @@ -32,13 +32,6 @@ pub enum OreInstruction { #[account(3, name = "system_program", desc = "Solana system program")] Close = 1, - #[account(0, name = "ore_program", desc = "Ore program")] - #[account(1, name = "signer", desc = "Signer", signer)] - #[account(2, name = "config", desc = "Ore config account", writable)] - #[account(3, name = "proof", desc = "Ore proof account – current top staker")] - #[account(4, name = "proof_new", desc = "Ore proof account – new top staker")] - Crown = 2, - #[account(0, name = "ore_program", desc = "Ore program")] #[account(1, name = "signer", desc = "Signer", signer)] #[account(2, name = "bus", desc = "Ore bus account", writable)] @@ -46,7 +39,7 @@ pub enum OreInstruction { #[account(4, name = "noise", desc = "Ore noise account")] #[account(5, name = "proof", desc = "Ore proof account", writable)] #[account(6, name = "slot_hashes", desc = "Solana slot hashes sysvar")] - Mine = 3, + Mine = 2, #[account(0, name = "ore_program", desc = "Ore program")] #[account(1, name = "signer", desc = "Signer", signer)] @@ -55,7 +48,7 @@ pub enum OreInstruction { #[account(4, name = "proof", desc = "Ore proof account", writable)] #[account(5, name = "system_program", desc = "Solana system program")] #[account(6, name = "slot_hashes", desc = "Solana slot hashes sysvar")] - Open = 4, + Open = 3, #[account(0, name = "ore_program", desc = "Ore program")] #[account(1, name = "signer", desc = "Signer", signer)] @@ -72,7 +65,7 @@ pub enum OreInstruction { #[account(12, name = "treasury", desc = "Ore treasury account", writable)] #[account(13, name = "treasury_tokens", desc = "Ore treasury token account", writable)] #[account(14, name = "token_program", desc = "SPL token program")] - Reset = 5, + Reset = 4, #[account(0, name = "ore_program", desc = "Ore program")] #[account(1, name = "signer", desc = "Signer", signer)] @@ -80,12 +73,12 @@ pub enum OreInstruction { #[account(3, name = "sender", desc = "Signer token account", writable)] #[account(4, name = "treasury_tokens", desc = "Ore treasury token account", writable)] #[account(5, name = "token_program", desc = "SPL token program")] - Stake = 6, + Stake = 5, #[account(0, name = "ore_program", desc = "Ore program")] #[account(1, name = "signer", desc = "Signer", signer)] #[account(2, name = "proof", desc = "Ore proof account", writable)] - Update = 7, + Update = 6, #[account(0, name = "ore_program", desc = "Ore program")] #[account(1, name = "signer", desc = "Signer", signer)] @@ -95,7 +88,7 @@ pub enum OreInstruction { #[account(5, name = "mint", desc = "Ore token mint account", writable)] #[account(6, name = "mint_v1", desc = "Ore v1 token mint account", writable)] #[account(7, name = "token_program", desc = "SPL token program")] - Upgrade = 8, + Upgrade = 7, #[account(0, name = "ore_program", desc = "Ore program")] #[account(1, name = "signer", desc = "Admin signer", signer)] @@ -231,21 +224,6 @@ pub fn close(signer: Pubkey) -> Instruction { } } -/// Builds a crown instruction. -pub fn crown(signer: Pubkey, current_top_staker: Pubkey) -> Instruction { - let proof_pda = Pubkey::find_program_address(&[PROOF, signer.as_ref()], &crate::id()); - Instruction { - program_id: crate::id(), - accounts: vec![ - AccountMeta::new(signer, true), - AccountMeta::new(CONFIG_ADDRESS, false), - AccountMeta::new_readonly(current_top_staker, false), - AccountMeta::new_readonly(proof_pda.0, false), - ], - data: OreInstruction::Crown.to_vec(), - } -} - /// Builds a mine instruction. pub fn mine( signer: Pubkey, diff --git a/api/src/state/bus.rs b/api/src/state/bus.rs index 2eaa557..113b7dd 100644 --- a/api/src/state/bus.rs +++ b/api/src/state/bus.rs @@ -19,6 +19,9 @@ pub struct Bus { /// The rewards this bus would have paid out in the current epoch if there no limit. /// Used to calculate the updated reward rate. pub theoretical_rewards: u64, + + /// The largest known stake balance seen by the bus this epoch. + pub top_balance: u64, } impl Discriminator for Bus { diff --git a/api/src/state/config.rs b/api/src/state/config.rs index 3dacec7..d6fd073 100644 --- a/api/src/state/config.rs +++ b/api/src/state/config.rs @@ -1,6 +1,5 @@ use bytemuck::{Pod, Zeroable}; use shank::ShankAccount; -use solana_program::pubkey::Pubkey; use crate::utils::{impl_account_from_bytes, impl_to_bytes, Discriminator}; @@ -19,11 +18,8 @@ pub struct Config { /// The minimum accepted difficulty. pub min_difficulty: u64, - /// The address of the proof account with the highest stake balance. - pub top_staker: Pubkey, - - /// The largest known stake balance on the network. - pub top_staker_balance: u64, + /// The largest known stake balance on the network from the last epoch. + pub top_balance: u64, } impl Discriminator for Config { diff --git a/program/src/close.rs b/program/src/close.rs index 052f87d..d92bb20 100644 --- a/program/src/close.rs +++ b/program/src/close.rs @@ -1,8 +1,4 @@ -use ore_api::{ - error::OreError, - loaders::*, - state::{Config, Proof}, -}; +use ore_api::{loaders::*, state::Proof}; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey, system_program, @@ -24,21 +20,13 @@ pub fn process_close<'a, 'info>( _data: &[u8], ) -> ProgramResult { // Load accounts - let [signer, config_info, proof_info, system_program] = accounts else { + let [signer, proof_info, system_program] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; load_signer(signer)?; - load_config(config_info, false)?; load_proof(proof_info, signer.key, true)?; load_program(system_program, system_program::id())?; - // Validate the account is not the crowned top staker. - let config_data = config_info.data.borrow(); - let config = Config::try_from_bytes(&config_data)?; - if config.top_staker.eq(proof_info.key) { - return Err(OreError::CannotClose.into()); - } - // Validate balance is zero let proof_data = proof_info.data.borrow(); let proof = Proof::try_from_bytes(&proof_data)?; diff --git a/program/src/crown.rs b/program/src/crown.rs deleted file mode 100644 index 41c2999..0000000 --- a/program/src/crown.rs +++ /dev/null @@ -1,63 +0,0 @@ -use ore_api::{ - consts::ONE_MINUTE, - error::OreError, - loaders::*, - state::{Config, Proof}, -}; -use solana_program::{ - account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult, - program_error::ProgramError, pubkey::Pubkey, sysvar::Sysvar, -}; - -use crate::utils::AccountDeserialize; - -/// Crown flags an account as the top staker if their balance is greater than the last known top staker. -pub fn process_crown<'a, 'info>( - _program_id: &Pubkey, - accounts: &'a [AccountInfo<'info>], - _data: &[u8], -) -> ProgramResult { - // Load accounts - let [signer, config_info, proof_info, proof_new_info] = accounts else { - return Err(ProgramError::NotEnoughAccountKeys); - }; - load_signer(signer)?; - load_config(config_info, true)?; - load_any_proof(proof_new_info, false)?; - - // Load the proof accounts. - let clock = Clock::get().unwrap(); - let proof_new_data = proof_new_info.data.borrow(); - let proof_new = Proof::try_from_bytes(&proof_new_data)?; - if proof_new - .last_stake_at - .saturating_add(ONE_MINUTE) - .gt(&clock.unix_timestamp) - { - return Err(OreError::CannotCrown.into()); - } - - // If top staker is the default null address, skip this. - let mut config_data = config_info.data.borrow_mut(); - let config = Config::try_from_bytes_mut(&mut config_data)?; - if config.top_staker.ne(&Pubkey::new_from_array([0; 32])) { - // Load current top staker - load_any_proof(proof_info, false)?; - let proof_data = proof_info.data.borrow(); - let proof = Proof::try_from_bytes(&proof_data)?; - if proof_info.key.ne(&config.top_staker) { - return Ok(()); - } - - // Compare balances - if proof_new.balance.lt(&proof.balance) { - return Ok(()); - } - } - - // Crown the new top staker. - config.top_staker = *proof_new_info.key; - config.top_staker_balance = proof_new.balance; - - Ok(()) -} diff --git a/program/src/initialize.rs b/program/src/initialize.rs index ce850e3..510f467 100644 --- a/program/src/initialize.rs +++ b/program/src/initialize.rs @@ -141,8 +141,7 @@ pub fn process_initialize<'a, 'info>( config.base_reward_rate = INITIAL_BASE_REWARD_RATE; config.last_reset_at = 0; config.min_difficulty = INITIAL_MIN_DIFFICULTY as u64; - config.top_staker = Pubkey::new_from_array([0; 32]); - config.top_staker_balance = 0; + config.top_balance = 0; // Initialize treasury create_pda( diff --git a/program/src/lib.rs b/program/src/lib.rs index e36f9db..909a87a 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -1,6 +1,5 @@ mod claim; mod close; -mod crown; mod initialize; mod mine; mod open; @@ -11,7 +10,6 @@ mod upgrade; use claim::*; use close::*; -use crown::*; use initialize::*; use mine::*; use open::*; @@ -47,7 +45,6 @@ pub fn process_instruction( match OreInstruction::try_from(*tag).or(Err(ProgramError::InvalidInstructionData))? { OreInstruction::Claim => process_claim(program_id, accounts, data)?, OreInstruction::Close => process_close(program_id, accounts, data)?, - OreInstruction::Crown => process_crown(program_id, accounts, data)?, OreInstruction::Mine => process_mine(program_id, accounts, data)?, OreInstruction::Open => process_open(program_id, accounts, data)?, OreInstruction::Reset => process_reset(program_id, accounts, data)?, diff --git a/program/src/mine.rs b/program/src/mine.rs index 758b19c..3686ebb 100644 --- a/program/src/mine.rs +++ b/program/src/mine.rs @@ -115,14 +115,14 @@ pub fn process_mine<'a, 'info>( // If user has greater than or equal to the max stake on the network, they receive 2x multiplier. // Any stake less than this will receives between 1x and 2x multipler. The multipler is only active // if the miner's last stake deposit was more than one minute ago. - if config.max_stake.gt(&0) + if config.top_balance.gt(&0) && proof.balance.gt(&0) - && proof.last_stake_at.saturating_add(ONE_MINUTE).le(&t) + && proof.last_stake_at.saturating_add(ONE_MINUTE).lt(&t) { let staking_reward = (reward as u128) - .checked_mul(proof.balance.min(config.top_staker_balance) as u128) + .checked_mul(proof.balance.min(config.top_balance) as u128) .unwrap() - .checked_div(config.top_staker_balance as u128) + .checked_div(config.top_balance as u128) .unwrap() as u64; reward = reward.checked_add(staking_reward).unwrap(); } @@ -148,6 +148,9 @@ pub fn process_mine<'a, 'info>( bus.theoretical_rewards = bus.theoretical_rewards.checked_add(reward).unwrap(); bus.rewards = bus.rewards.checked_sub(reward_actual).unwrap(); proof.balance = proof.balance.checked_add(reward_actual).unwrap(); + if proof.balance.gt(&bus.top_balance) { + bus.top_balance = proof.balance; + } // Hash recent slot hash into the next challenge to prevent pre-mining attacks proof.last_hash = hash.h; diff --git a/program/src/reset.rs b/program/src/reset.rs index 63c0754..4d2fcff 100644 --- a/program/src/reset.rs +++ b/program/src/reset.rs @@ -79,9 +79,13 @@ pub fn process_reset<'a, 'info>( // Reset bus accounts and calculate actual rewards mined since last reset let mut total_remaining_rewards = 0u64; let mut total_theoretical_rewards = 0u64; + let mut top_balance = 0u64; for i in 0..BUS_COUNT { let mut bus_data = busses[i].data.borrow_mut(); let bus = Bus::try_from_bytes_mut(&mut bus_data)?; + if bus.top_balance.gt(&top_balance) { + top_balance = bus.top_balance; + } total_remaining_rewards = total_remaining_rewards.saturating_add(bus.rewards); total_theoretical_rewards = total_theoretical_rewards.saturating_add(bus.theoretical_rewards); @@ -90,6 +94,9 @@ pub fn process_reset<'a, 'info>( } let total_epoch_rewards = MAX_EPOCH_REWARDS.saturating_sub(total_remaining_rewards); + // Update the top balance + config.top_balance = top_balance; + // Update base reward rate for next epoch config.base_reward_rate = calculate_new_reward_rate(config.base_reward_rate, total_theoretical_rewards); From f9015f01c2840588174ed98a4f539f131a5325af Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Sat, 20 Jul 2024 19:17:19 +0000 Subject: [PATCH 2/2] reset bus top balance --- program/src/reset.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/program/src/reset.rs b/program/src/reset.rs index 4d2fcff..e19eb80 100644 --- a/program/src/reset.rs +++ b/program/src/reset.rs @@ -91,6 +91,7 @@ pub fn process_reset<'a, 'info>( total_theoretical_rewards.saturating_add(bus.theoretical_rewards); bus.rewards = BUS_EPOCH_REWARDS; bus.theoretical_rewards = 0; + bus.top_balance = 0; } let total_epoch_rewards = MAX_EPOCH_REWARDS.saturating_sub(total_remaining_rewards);