diff --git a/src/instruction.rs b/src/instruction.rs index b6664e2..340bff6 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -74,6 +74,12 @@ pub enum OreInstruction { #[account(6, name = "mint_v1", desc = "Ore v1 token mint account", writable)] #[account(7, name = "token_program", desc = "SPL token program")] Upgrade = 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)] + #[account(3, name = "system_program", desc = "Solana system program")] + Deregister = 6, #[account(0, name = "ore_program", desc = "Ore program")] #[account(1, name = "signer", desc = "Admin signer", signer)] diff --git a/src/lib.rs b/src/lib.rs index dbf8573..fc29e90 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,6 +14,7 @@ use solana_program::{ program_error::ProgramError, pubkey::Pubkey, }; +// TODO Close proof accounts to recover sol // TODO Is downgrade necessary? declare_id!("mineRHF5r6S7HyD9SppBfVMXMavDkJsxwGesEvxZr2A"); @@ -41,6 +42,7 @@ pub fn process_instruction( OreInstruction::Claim => process_claim(program_id, accounts, data)?, OreInstruction::Stake => process_stake(program_id, accounts, data)?, OreInstruction::Upgrade => process_upgrade(program_id, accounts, data)?, + OreInstruction::Deregister => process_deregister(program_id, accounts, data)?, OreInstruction::Initialize => process_initialize(program_id, accounts, data)?, OreInstruction::UpdateAdmin => process_update_admin(program_id, accounts, data)?, OreInstruction::UpdateTolerance => process_update_tolerance(program_id, accounts, data)?, diff --git a/src/processor/deregister.rs b/src/processor/deregister.rs new file mode 100644 index 0000000..6d6c881 --- /dev/null +++ b/src/processor/deregister.rs @@ -0,0 +1,36 @@ +use solana_program::{ + account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, + pubkey::Pubkey, system_program, +}; + +use crate::{instruction::RegisterArgs, loaders::*}; + +/// Register generates a new hash chain for a prospective miner. Its responsibilities include: +/// 1. Initialize a new proof account. +/// 2. Generate an initial hash from the signer's key. +/// +/// Safety requirements: +/// - Register is a permissionless instruction and can be invoked by any singer. +/// - Can only succeed if the provided proof acount PDA is valid (associated with the signer). +/// - Can only succeed once per signer. +/// - The provided system program must be valid. +pub fn process_deregister<'a, 'info>( + _program_id: &Pubkey, + accounts: &'a [AccountInfo<'info>], + data: &[u8], +) -> ProgramResult { + // Load accounts + let [signer, proof_info, system_program] = accounts else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + load_signer(signer)?; + load_proof(proof_info, signer.key, true)?; + load_program(system_program, system_program::id())?; + + // TODO Ensure proof.balance == 0 + // TODO Send lamports to signer + // TODO Realloc data to 0 + // TODO Reassign back to system program + + Ok(()) +} diff --git a/src/processor/mod.rs b/src/processor/mod.rs index f1dd9cc..6807980 100644 --- a/src/processor/mod.rs +++ b/src/processor/mod.rs @@ -1,4 +1,5 @@ mod claim; +mod deregister; mod initialize; mod mine; mod pause; @@ -10,6 +11,7 @@ mod update_tolerance; mod upgrade; pub use claim::*; +pub use deregister::*; pub use initialize::*; pub use mine::*; pub use pause::*; diff --git a/src/processor/register.rs b/src/processor/register.rs index 4ad7c15..6b100ca 100644 --- a/src/processor/register.rs +++ b/src/processor/register.rs @@ -64,6 +64,7 @@ pub fn process_register<'a, 'info>( &slot_hashes_info.data.borrow()[0..size_of::()], ]) .0; + proof.last_deposit_slot = 0; proof.last_hash_at = 0; proof.total_hashes = 0; proof.total_rewards = 0; diff --git a/src/processor/update_tolerance.rs b/src/processor/update_tolerance.rs index c869f6f..6dfbfe9 100644 --- a/src/processor/update_tolerance.rs +++ b/src/processor/update_tolerance.rs @@ -5,7 +5,7 @@ use solana_program::{ use crate::{ error::OreError, instruction::UpdateToleranceArgs, loaders::*, state::Config, - utils::AccountDeserialize, + utils::AccountDeserialize, ONE_MINUTE, }; pub fn process_update_tolerance<'a, 'info>( @@ -30,11 +30,11 @@ pub fn process_update_tolerance<'a, 'info>( return Err(ProgramError::MissingRequiredSignature); } - // Overflow checks - if args.tolerance_liveness.gt(&(i64::MAX as u64)) { + // Sanity checks + if args.tolerance_liveness.ge(&(ONE_MINUTE as u64)) { return Err(OreError::ToleranceOverflow.into()); } - if args.tolerance_spam.gt(&(i64::MAX as u64)) { + if args.tolerance_spam.ge(&(ONE_MINUTE as u64)) { return Err(OreError::ToleranceOverflow.into()); }