From cddcd493a831bd3f6f84a5131bd0a78b32834561 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 28 Jun 2024 12:42:54 +0000 Subject: [PATCH 1/4] introduce update ix --- src/instruction.rs | 108 +++++++++++++++++++++++----------------- src/lib.rs | 7 +-- src/processor/mod.rs | 2 + src/processor/update.rs | 30 +++++++++++ 4 files changed, 99 insertions(+), 48 deletions(-) create mode 100644 src/processor/update.rs diff --git a/src/instruction.rs b/src/instruction.rs index dade54e..0e9e5a7 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -17,6 +17,36 @@ use crate::{ #[derive(Clone, Copy, Debug, Eq, PartialEq, ShankInstruction, TryFromPrimitive)] #[rustfmt::skip] pub enum OreInstruction { + #[account(0, name = "ore_program", desc = "Ore program")] + #[account(1, name = "signer", desc = "Signer", signer)] + #[account(2, name = "beneficiary", desc = "Beneficiary token account", writable)] + #[account(3, name = "proof", desc = "Ore proof account", writable)] + #[account(4, name = "treasury", desc = "Ore treasury account", writable)] + #[account(5, name = "treasury_tokens", desc = "Ore treasury token account", writable)] + #[account(6, name = "token_program", desc = "SPL token program")] + Claim = 0, + + #[account(0, name = "ore_program", desc = "Ore program")] + #[account(1, name = "signer", desc = "Signer", signer)] + #[account(2, name = "proof", desc = "Ore proof account", writable)] + #[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 = "bus", desc = "Ore bus account", writable)] + #[account(3, name = "config", desc = "Ore config account")] + #[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 = 2, + + #[account(0, name = "ore_program", desc = "Ore program")] + #[account(1, name = "signer", desc = "Signer", signer)] + #[account(2, name = "proof", desc = "Ore proof account", writable)] + #[account(3, name = "system_program", desc = "Solana system program")] + Open = 3, + #[account(0, name = "ore_program", desc = "Ore program")] #[account(1, name = "signer", desc = "Signer", signer)] #[account(2, name = "bus_0", desc = "Ore bus account 0", writable)] @@ -32,37 +62,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 = 0, - - #[account(0, name = "ore_program", desc = "Ore program")] - #[account(1, name = "signer", desc = "Signer", signer)] - #[account(2, name = "proof", desc = "Ore proof account", writable)] - #[account(3, name = "system_program", desc = "Solana system program")] - Open = 1, - - #[account(0, name = "ore_program", desc = "Ore program")] - #[account(1, name = "signer", desc = "Signer", signer)] - #[account(2, name = "proof", desc = "Ore proof account", writable)] - #[account(3, name = "system_program", desc = "Solana system program")] - Close = 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)] - #[account(3, name = "config", desc = "Ore config account")] - #[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, - - #[account(0, name = "ore_program", desc = "Ore program")] - #[account(1, name = "signer", desc = "Signer", signer)] - #[account(2, name = "beneficiary", desc = "Beneficiary token account", writable)] - #[account(3, name = "proof", desc = "Ore proof account", writable)] - #[account(4, name = "treasury", desc = "Ore treasury account", writable)] - #[account(5, name = "treasury_tokens", desc = "Ore treasury token account", writable)] - #[account(6, name = "token_program", desc = "SPL token program")] - Claim = 4, + Reset = 4, #[account(0, name = "ore_program", desc = "Ore program")] #[account(1, name = "signer", desc = "Signer", signer)] @@ -71,6 +71,11 @@ pub enum OreInstruction { #[account(4, name = "treasury_tokens", desc = "Ore treasury token account", writable)] #[account(5, name = "token_program", desc = "SPL token program")] 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 = 6, #[account(0, name = "ore_program", desc = "Ore program")] #[account(1, name = "signer", desc = "Signer", signer)] @@ -80,7 +85,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 = 6, + Upgrade = 7, #[account(0, name = "ore_program", desc = "Ore program")] #[account(1, name = "signer", desc = "Admin signer", signer)] @@ -153,29 +158,24 @@ pub struct StakeArgs { pub amount: [u8; 8], } +#[repr(C)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct UpdateArgs { + pub new_miner: Pubkey, +} + #[repr(C)] #[derive(Clone, Copy, Debug, Pod, Zeroable)] pub struct UpgradeArgs { pub amount: [u8; 8], } -#[repr(C)] -#[derive(Clone, Copy, Debug, Pod, Zeroable)] -pub struct UpdateAdminArgs { - pub new_admin: Pubkey, -} - -#[repr(C)] -#[derive(Clone, Copy, Debug, Pod, Zeroable)] -pub struct PauseArgs { - pub paused: u8, -} - impl_to_bytes!(InitializeArgs); impl_to_bytes!(OpenArgs); impl_to_bytes!(MineArgs); impl_to_bytes!(ClaimArgs); impl_to_bytes!(StakeArgs); +impl_to_bytes!(UpdateArgs); impl_to_bytes!(UpgradeArgs); impl_instruction_from_bytes!(InitializeArgs); @@ -183,6 +183,7 @@ impl_instruction_from_bytes!(OpenArgs); impl_instruction_from_bytes!(MineArgs); impl_instruction_from_bytes!(ClaimArgs); impl_instruction_from_bytes!(StakeArgs); +impl_instruction_from_bytes!(UpdateArgs); impl_instruction_from_bytes!(UpgradeArgs); /// Builds a reset instruction. @@ -331,7 +332,24 @@ pub fn stake(signer: Pubkey, sender: Pubkey, amount: u64) -> Instruction { } } -// build an upgrade instruction. +// Build an update instruction. +pub fn update(signer: Pubkey, new_miner: Pubkey) -> Instruction { + let proof = Pubkey::find_program_address(&[PROOF, signer.as_ref()], &crate::id()).0; + Instruction { + program_id: crate::id(), + accounts: vec![ + AccountMeta::new(signer, true), + AccountMeta::new(proof, false), + ], + data: [ + OreInstruction::Update.to_vec(), + UpdateArgs { new_miner }.to_bytes().to_vec(), + ] + .concat(), + } +} + +// Build an upgrade instruction. pub fn upgrade(signer: Pubkey, beneficiary: Pubkey, sender: Pubkey, amount: u64) -> Instruction { Instruction { program_id: crate::id(), diff --git a/src/lib.rs b/src/lib.rs index a5d064d..a6cf811 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,12 +33,13 @@ pub fn process_instruction( .ok_or(ProgramError::InvalidInstructionData)?; match OreInstruction::try_from(*tag).or(Err(ProgramError::InvalidInstructionData))? { - OreInstruction::Open => process_open(program_id, accounts, data)?, + OreInstruction::Claim => process_claim(program_id, accounts, data)?, OreInstruction::Close => process_close(program_id, accounts, data)?, OreInstruction::Mine => process_mine(program_id, accounts, data)?, - OreInstruction::Claim => process_claim(program_id, accounts, data)?, - OreInstruction::Stake => process_stake(program_id, accounts, data)?, + OreInstruction::Open => process_open(program_id, accounts, data)?, OreInstruction::Reset => process_reset(program_id, accounts, data)?, + OreInstruction::Stake => process_stake(program_id, accounts, data)?, + OreInstruction::Update => process_update(program_id, accounts, data)?, OreInstruction::Upgrade => process_upgrade(program_id, accounts, data)?, OreInstruction::Initialize => process_initialize(program_id, accounts, data)?, } diff --git a/src/processor/mod.rs b/src/processor/mod.rs index 91b8fb4..5ded886 100644 --- a/src/processor/mod.rs +++ b/src/processor/mod.rs @@ -5,6 +5,7 @@ mod mine; mod open; mod reset; mod stake; +mod update; mod upgrade; pub use claim::*; @@ -14,4 +15,5 @@ pub use mine::*; pub use open::*; pub use reset::*; pub use stake::*; +pub use update::*; pub use upgrade::*; diff --git a/src/processor/update.rs b/src/processor/update.rs new file mode 100644 index 0000000..c1fa203 --- /dev/null +++ b/src/processor/update.rs @@ -0,0 +1,30 @@ +use solana_program::{ + account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, + pubkey::Pubkey, +}; + +use crate::{instruction::UpdateArgs, loaders::*, state::Proof, utils::AccountDeserialize}; + +/// Update updates a proof account. +pub fn process_update<'a, 'info>( + _program_id: &Pubkey, + accounts: &'a [AccountInfo<'info>], + data: &[u8], +) -> ProgramResult { + // Parse args + let args = UpdateArgs::try_from_bytes(data)?; + + // Load accounts + let [signer, proof_info] = accounts else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + load_signer(signer)?; + load_proof(proof_info, signer.key, true)?; + + // Update the proof + let mut proof_data = proof_info.data.borrow_mut(); + let proof = Proof::try_from_bytes_mut(&mut proof_data)?; + proof.miner = args.new_miner; + + Ok(()) +} From 45f5d133dfd7f8aee437636d5f49a5f6e9c99c9a Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 28 Jun 2024 12:44:01 +0000 Subject: [PATCH 2/4] comment --- src/processor/update.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/processor/update.rs b/src/processor/update.rs index c1fa203..fcb7b17 100644 --- a/src/processor/update.rs +++ b/src/processor/update.rs @@ -5,7 +5,7 @@ use solana_program::{ use crate::{instruction::UpdateArgs, loaders::*, state::Proof, utils::AccountDeserialize}; -/// Update updates a proof account. +/// Update changes the miner authority on a proof account. pub fn process_update<'a, 'info>( _program_id: &Pubkey, accounts: &'a [AccountInfo<'info>], From fb33d594341ce1284989eaa6f1e8866639b4bd31 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 28 Jun 2024 13:14:00 +0000 Subject: [PATCH 3/4] cleanup --- src/instruction.rs | 19 ++++--------------- src/processor/open.rs | 2 +- src/processor/update.rs | 12 +++++------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/src/instruction.rs b/src/instruction.rs index 0e9e5a7..304ce4c 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -158,12 +158,6 @@ pub struct StakeArgs { pub amount: [u8; 8], } -#[repr(C)] -#[derive(Clone, Copy, Debug, Pod, Zeroable)] -pub struct UpdateArgs { - pub new_miner: Pubkey, -} - #[repr(C)] #[derive(Clone, Copy, Debug, Pod, Zeroable)] pub struct UpgradeArgs { @@ -175,7 +169,6 @@ impl_to_bytes!(OpenArgs); impl_to_bytes!(MineArgs); impl_to_bytes!(ClaimArgs); impl_to_bytes!(StakeArgs); -impl_to_bytes!(UpdateArgs); impl_to_bytes!(UpgradeArgs); impl_instruction_from_bytes!(InitializeArgs); @@ -183,7 +176,6 @@ impl_instruction_from_bytes!(OpenArgs); impl_instruction_from_bytes!(MineArgs); impl_instruction_from_bytes!(ClaimArgs); impl_instruction_from_bytes!(StakeArgs); -impl_instruction_from_bytes!(UpdateArgs); impl_instruction_from_bytes!(UpgradeArgs); /// Builds a reset instruction. @@ -221,7 +213,7 @@ pub fn open(signer: Pubkey, miner: Pubkey) -> Instruction { program_id: crate::id(), accounts: vec![ AccountMeta::new(signer, true), - AccountMeta::new(miner, true), + AccountMeta::new(miner, false), AccountMeta::new(proof_pda.0, false), AccountMeta::new_readonly(solana_program::system_program::id(), false), AccountMeta::new_readonly(sysvar::slot_hashes::id(), false), @@ -333,19 +325,16 @@ pub fn stake(signer: Pubkey, sender: Pubkey, amount: u64) -> Instruction { } // Build an update instruction. -pub fn update(signer: Pubkey, new_miner: Pubkey) -> Instruction { +pub fn update(signer: Pubkey, miner: Pubkey) -> Instruction { let proof = Pubkey::find_program_address(&[PROOF, signer.as_ref()], &crate::id()).0; Instruction { program_id: crate::id(), accounts: vec![ AccountMeta::new(signer, true), + AccountMeta::new(miner, false), AccountMeta::new(proof, false), ], - data: [ - OreInstruction::Update.to_vec(), - UpdateArgs { new_miner }.to_bytes().to_vec(), - ] - .concat(), + data: OreInstruction::Update.to_vec(), } } diff --git a/src/processor/open.rs b/src/processor/open.rs index f9ea4a7..0ac2bd4 100644 --- a/src/processor/open.rs +++ b/src/processor/open.rs @@ -43,7 +43,7 @@ pub fn process_open<'a, 'info>( return Err(ProgramError::NotEnoughAccountKeys); }; load_signer(signer)?; - load_signer(miner_info)?; + load_uninitialized_account(miner_info)?; load_uninitialized_pda( proof_info, &[PROOF, signer.key.as_ref()], diff --git a/src/processor/update.rs b/src/processor/update.rs index fcb7b17..d8c95ad 100644 --- a/src/processor/update.rs +++ b/src/processor/update.rs @@ -3,28 +3,26 @@ use solana_program::{ pubkey::Pubkey, }; -use crate::{instruction::UpdateArgs, loaders::*, state::Proof, utils::AccountDeserialize}; +use crate::{loaders::*, state::Proof, utils::AccountDeserialize}; /// Update changes the miner authority on a proof account. pub fn process_update<'a, 'info>( _program_id: &Pubkey, accounts: &'a [AccountInfo<'info>], - data: &[u8], + _data: &[u8], ) -> ProgramResult { - // Parse args - let args = UpdateArgs::try_from_bytes(data)?; - // Load accounts - let [signer, proof_info] = accounts else { + let [signer, miner_info, proof_info] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; load_signer(signer)?; + load_uninitialized_account(miner_info)?; load_proof(proof_info, signer.key, true)?; // Update the proof let mut proof_data = proof_info.data.borrow_mut(); let proof = Proof::try_from_bytes_mut(&mut proof_data)?; - proof.miner = args.new_miner; + proof.miner = *miner_info.key; Ok(()) } From 9d0f948f054c4f23f9ebc894966bf98924b7517b Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 28 Jun 2024 13:21:09 +0000 Subject: [PATCH 4/4] account meta --- src/instruction.rs | 4 ++-- src/loaders.rs | 7 ++++--- src/processor/initialize.rs | 2 +- src/processor/open.rs | 2 +- src/processor/update.rs | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/instruction.rs b/src/instruction.rs index 304ce4c..a265ab0 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -213,7 +213,7 @@ pub fn open(signer: Pubkey, miner: Pubkey) -> Instruction { program_id: crate::id(), accounts: vec![ AccountMeta::new(signer, true), - AccountMeta::new(miner, false), + AccountMeta::new_readonly(miner, false), AccountMeta::new(proof_pda.0, false), AccountMeta::new_readonly(solana_program::system_program::id(), false), AccountMeta::new_readonly(sysvar::slot_hashes::id(), false), @@ -331,7 +331,7 @@ pub fn update(signer: Pubkey, miner: Pubkey) -> Instruction { program_id: crate::id(), accounts: vec![ AccountMeta::new(signer, true), - AccountMeta::new(miner, false), + AccountMeta::new_readonly(miner, false), AccountMeta::new(proof, false), ], data: OreInstruction::Update.to_vec(), diff --git a/src/loaders.rs b/src/loaders.rs index 8cc7e07..44a3ffe 100644 --- a/src/loaders.rs +++ b/src/loaders.rs @@ -319,15 +319,16 @@ pub fn load_uninitialized_pda<'a, 'info>( return Err(ProgramError::InvalidSeeds); } - load_uninitialized_account(info) + load_system_account(info, true) } /// Errors if: /// - Owner is not the system program. /// - Data is not empty. /// - Account is not writable. -pub fn load_uninitialized_account<'a, 'info>( +pub fn load_system_account<'a, 'info>( info: &'a AccountInfo<'info>, + is_writable: bool, ) -> Result<(), ProgramError> { if info.owner.ne(&system_program::id()) { return Err(ProgramError::InvalidAccountOwner); @@ -337,7 +338,7 @@ pub fn load_uninitialized_account<'a, 'info>( return Err(ProgramError::AccountAlreadyInitialized); } - if !info.is_writable { + if is_writable && !info.is_writable { return Err(ProgramError::InvalidAccountData); } diff --git a/src/processor/initialize.rs b/src/processor/initialize.rs index 7717a5f..7c0b0af 100644 --- a/src/processor/initialize.rs +++ b/src/processor/initialize.rs @@ -80,7 +80,7 @@ pub fn process_initialize<'a, 'info>( &crate::id(), )?; load_uninitialized_pda(treasury_info, &[TREASURY], args.treasury_bump, &crate::id())?; - load_uninitialized_account(treasury_tokens_info)?; + load_system_account(treasury_tokens_info, true)?; load_program(system_program, system_program::id())?; load_program(token_program, spl_token::id())?; load_program(associated_token_program, spl_associated_token_account::id())?; diff --git a/src/processor/open.rs b/src/processor/open.rs index 0ac2bd4..3f03f61 100644 --- a/src/processor/open.rs +++ b/src/processor/open.rs @@ -43,7 +43,7 @@ pub fn process_open<'a, 'info>( return Err(ProgramError::NotEnoughAccountKeys); }; load_signer(signer)?; - load_uninitialized_account(miner_info)?; + load_system_account(miner_info, false)?; load_uninitialized_pda( proof_info, &[PROOF, signer.key.as_ref()], diff --git a/src/processor/update.rs b/src/processor/update.rs index d8c95ad..246c6d8 100644 --- a/src/processor/update.rs +++ b/src/processor/update.rs @@ -16,7 +16,7 @@ pub fn process_update<'a, 'info>( return Err(ProgramError::NotEnoughAccountKeys); }; load_signer(signer)?; - load_uninitialized_account(miner_info)?; + load_system_account(miner_info, false)?; load_proof(proof_info, signer.key, true)?; // Update the proof