mirror of
https://github.com/d0zingcat/ore.git
synced 2026-05-14 07:26:51 +00:00
refactor loaders into utils
This commit is contained in:
@@ -1,25 +1,11 @@
|
||||
use solana_program::{
|
||||
account_info::AccountInfo, program_error::ProgramError, program_pack::Pack, pubkey::Pubkey,
|
||||
system_program, sysvar,
|
||||
};
|
||||
use spl_token::state::Mint;
|
||||
use solana_program::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey};
|
||||
|
||||
use crate::{
|
||||
consts::*,
|
||||
state::{Bus, Config, Proof, Treasury},
|
||||
utils::{AccountDeserialize, Discriminator},
|
||||
utils::{loaders::*, AccountDeserialize, Discriminator},
|
||||
};
|
||||
|
||||
/// Errors if:
|
||||
/// - Account is not a signer.
|
||||
pub fn load_signer<'a, 'info>(info: &'a AccountInfo<'info>) -> Result<(), ProgramError> {
|
||||
if !info.is_signer {
|
||||
return Err(ProgramError::MissingRequiredSignature);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Owner is not Ore program.
|
||||
/// - Address does not match the expected bus address.
|
||||
@@ -265,185 +251,3 @@ pub fn load_treasury_tokens<'a, 'info>(
|
||||
|
||||
load_token_account(info, Some(&TREASURY_ADDRESS), &MINT_ADDRESS, is_writable)
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Owner is not SPL token program.
|
||||
/// - Address does not match the expected mint address.
|
||||
/// - Data is empty.
|
||||
/// - Data cannot deserialize into a mint account.
|
||||
/// - Expected to be writable, but is not.
|
||||
pub fn load_mint<'a, 'info>(
|
||||
info: &'a AccountInfo<'info>,
|
||||
address: Pubkey,
|
||||
is_writable: bool,
|
||||
) -> Result<(), ProgramError> {
|
||||
if info.owner.ne(&spl_token::id()) {
|
||||
return Err(ProgramError::InvalidAccountOwner);
|
||||
}
|
||||
|
||||
if info.key.ne(&address) {
|
||||
return Err(ProgramError::InvalidSeeds);
|
||||
}
|
||||
|
||||
if info.data_is_empty() {
|
||||
return Err(ProgramError::UninitializedAccount);
|
||||
}
|
||||
|
||||
Mint::unpack(&info.data.borrow())?;
|
||||
|
||||
if is_writable && !info.is_writable {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Owner is not SPL token program.
|
||||
/// - Data is empty.
|
||||
/// - Data cannot deserialize into a token account.
|
||||
/// - Token account owner does not match the expected owner address.
|
||||
/// - Token account mint does not match the expected mint address.
|
||||
/// - Expected to be writable, but is not.
|
||||
pub fn load_token_account<'a, 'info>(
|
||||
info: &'a AccountInfo<'info>,
|
||||
owner: Option<&Pubkey>,
|
||||
mint: &Pubkey,
|
||||
is_writable: bool,
|
||||
) -> Result<(), ProgramError> {
|
||||
if info.owner.ne(&spl_token::id()) {
|
||||
return Err(ProgramError::InvalidAccountOwner);
|
||||
}
|
||||
|
||||
if info.data_is_empty() {
|
||||
return Err(ProgramError::UninitializedAccount);
|
||||
}
|
||||
|
||||
let account_data = info.data.borrow();
|
||||
let account = spl_token::state::Account::unpack(&account_data)?;
|
||||
|
||||
if account.mint.ne(&mint) {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
|
||||
if let Some(owner) = owner {
|
||||
if account.owner.ne(owner) {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
}
|
||||
|
||||
if is_writable && !info.is_writable {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Address does not match PDA derived from provided seeds.
|
||||
/// - Cannot load as an uninitialized account.
|
||||
pub fn load_uninitialized_pda<'a, 'info>(
|
||||
info: &'a AccountInfo<'info>,
|
||||
seeds: &[&[u8]],
|
||||
bump: u8,
|
||||
program_id: &Pubkey,
|
||||
) -> Result<(), ProgramError> {
|
||||
let pda = Pubkey::find_program_address(seeds, program_id);
|
||||
|
||||
if info.key.ne(&pda.0) {
|
||||
return Err(ProgramError::InvalidSeeds);
|
||||
}
|
||||
|
||||
if bump.ne(&pda.1) {
|
||||
return Err(ProgramError::InvalidSeeds);
|
||||
}
|
||||
|
||||
load_system_account(info, true)
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Owner is not the system program.
|
||||
/// - Data is not empty.
|
||||
/// - Account is not writable.
|
||||
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);
|
||||
}
|
||||
|
||||
if !info.data_is_empty() {
|
||||
return Err(ProgramError::AccountAlreadyInitialized);
|
||||
}
|
||||
|
||||
if is_writable && !info.is_writable {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Owner is not the sysvar address.
|
||||
/// - Account cannot load with the expected address.
|
||||
pub fn load_sysvar<'a, 'info>(
|
||||
info: &'a AccountInfo<'info>,
|
||||
key: Pubkey,
|
||||
) -> Result<(), ProgramError> {
|
||||
if info.owner.ne(&sysvar::id()) {
|
||||
return Err(ProgramError::InvalidAccountOwner);
|
||||
}
|
||||
|
||||
load_account(info, key, false)
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Address does not match the expected value.
|
||||
/// - Expected to be writable, but is not.
|
||||
pub fn load_account<'a, 'info>(
|
||||
info: &'a AccountInfo<'info>,
|
||||
key: Pubkey,
|
||||
is_writable: bool,
|
||||
) -> Result<(), ProgramError> {
|
||||
if info.key.ne(&key) {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
|
||||
if is_writable && !info.is_writable {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Address does not match the expected value.
|
||||
/// - Account is not executable.
|
||||
pub fn load_program<'a, 'info>(
|
||||
info: &'a AccountInfo<'info>,
|
||||
key: Pubkey,
|
||||
) -> Result<(), ProgramError> {
|
||||
if info.key.ne(&key) {
|
||||
return Err(ProgramError::IncorrectProgramId);
|
||||
}
|
||||
|
||||
if !info.executable {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Account is not writable.
|
||||
pub fn load_any<'a, 'info>(
|
||||
info: &'a AccountInfo<'info>,
|
||||
is_writable: bool,
|
||||
) -> Result<(), ProgramError> {
|
||||
if is_writable && !info.is_writable {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use solana_program::{
|
||||
account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError,
|
||||
};
|
||||
|
||||
use crate::utils::AccountDeserialize;
|
||||
use ore_utils::{loaders::*, AccountDeserialize};
|
||||
|
||||
/// Claim distributes claimable ORE from the treasury to a miner.
|
||||
pub fn process_claim<'a, 'info>(accounts: &'a [AccountInfo<'info>], data: &[u8]) -> ProgramResult {
|
||||
|
||||
@@ -4,7 +4,7 @@ use solana_program::{
|
||||
system_program,
|
||||
};
|
||||
|
||||
use crate::utils::AccountDeserialize;
|
||||
use ore_utils::{loaders::*, AccountDeserialize};
|
||||
|
||||
/// Close closes a proof account and returns the rent to the owner.
|
||||
pub fn process_close<'a, 'info>(accounts: &'a [AccountInfo<'info>], _data: &[u8]) -> ProgramResult {
|
||||
|
||||
@@ -3,10 +3,9 @@ use std::mem::size_of;
|
||||
use ore_api::{
|
||||
consts::*,
|
||||
instruction::*,
|
||||
loaders::*,
|
||||
state::{Bus, Config, Treasury},
|
||||
};
|
||||
use ore_utils::spl::create_ata;
|
||||
use ore_utils::{create_pda, loaders::*, spl::create_ata, AccountDeserialize, Discriminator};
|
||||
use solana_program::{
|
||||
account_info::AccountInfo,
|
||||
entrypoint::ProgramResult,
|
||||
@@ -16,8 +15,6 @@ use solana_program::{
|
||||
};
|
||||
use spl_token::state::Mint;
|
||||
|
||||
use crate::utils::{create_pda, AccountDeserialize, Discriminator};
|
||||
|
||||
/// Initialize sets up the ORE program to begin mining.
|
||||
pub fn process_initialize<'a, 'info>(
|
||||
accounts: &'a [AccountInfo<'info>],
|
||||
|
||||
@@ -24,8 +24,6 @@ use solana_program::{
|
||||
pubkey::Pubkey,
|
||||
};
|
||||
|
||||
pub(crate) use ore_utils as utils;
|
||||
|
||||
#[cfg(not(feature = "no-entrypoint"))]
|
||||
solana_program::entrypoint!(process_instruction);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ use solana_program::{
|
||||
sysvar::{self, Sysvar},
|
||||
};
|
||||
|
||||
use crate::utils::AccountDeserialize;
|
||||
use ore_utils::{loaders::*, AccountDeserialize};
|
||||
|
||||
/// Mine validates hashes and increments a miner's collectable balance.
|
||||
pub fn process_mine<'a, 'info>(accounts: &'a [AccountInfo<'info>], data: &[u8]) -> ProgramResult {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::mem::size_of;
|
||||
|
||||
use ore_api::{consts::*, instruction::OpenArgs, loaders::*, state::Proof};
|
||||
use ore_api::{consts::*, instruction::OpenArgs, state::Proof};
|
||||
use solana_program::{
|
||||
account_info::AccountInfo,
|
||||
clock::Clock,
|
||||
@@ -12,7 +12,7 @@ use solana_program::{
|
||||
sysvar::{self, Sysvar},
|
||||
};
|
||||
|
||||
use crate::utils::{create_pda, AccountDeserialize, Discriminator};
|
||||
use ore_utils::{create_pda, loaders::*, AccountDeserialize, Discriminator};
|
||||
|
||||
/// Open creates a new proof account to track a miner's state.
|
||||
pub fn process_open<'a, 'info>(accounts: &'a [AccountInfo<'info>], data: &[u8]) -> ProgramResult {
|
||||
|
||||
@@ -10,7 +10,7 @@ use solana_program::{
|
||||
};
|
||||
use spl_token::state::Mint;
|
||||
|
||||
use crate::utils::AccountDeserialize;
|
||||
use ore_utils::{loaders::*, AccountDeserialize};
|
||||
|
||||
/// Reset tops up the bus balances, updates the base reward rate, and sets up the ORE program for the next epoch.
|
||||
pub fn process_reset<'a, 'info>(accounts: &'a [AccountInfo<'info>], _data: &[u8]) -> ProgramResult {
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use ore_api::{consts::*, instruction::StakeArgs, loaders::*, state::Proof};
|
||||
use ore_utils::spl::transfer;
|
||||
use ore_utils::{loaders::*, spl::transfer, AccountDeserialize};
|
||||
use solana_program::{
|
||||
account_info::AccountInfo, clock::Clock, entrypoint::ProgramResult,
|
||||
program_error::ProgramError, sysvar::Sysvar,
|
||||
};
|
||||
|
||||
use crate::utils::AccountDeserialize;
|
||||
|
||||
/// Stake deposits ORE into a proof account to earn multiplier.
|
||||
pub fn process_stake<'a, 'info>(accounts: &'a [AccountInfo<'info>], data: &[u8]) -> ProgramResult {
|
||||
// Parse args.
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
use ore_api::{loaders::*, state::Proof};
|
||||
use ore_utils::{loaders::*, AccountDeserialize};
|
||||
use solana_program::{
|
||||
account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError,
|
||||
};
|
||||
|
||||
use crate::utils::AccountDeserialize;
|
||||
|
||||
/// Update changes the miner authority on a proof account.
|
||||
pub fn process_update<'a, 'info>(
|
||||
accounts: &'a [AccountInfo<'info>],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use ore_api::{consts::*, error::OreError, instruction::StakeArgs, loaders::*};
|
||||
use ore_utils::spl::mint_to_signed;
|
||||
use ore_api::{consts::*, error::OreError, instruction::StakeArgs};
|
||||
use ore_utils::{loaders::*, spl::mint_to_signed};
|
||||
use solana_program::{
|
||||
account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError,
|
||||
program_pack::Pack,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod loaders;
|
||||
#[cfg(feature = "spl")]
|
||||
pub mod spl;
|
||||
|
||||
|
||||
200
utils/src/loaders.rs
Normal file
200
utils/src/loaders.rs
Normal file
@@ -0,0 +1,200 @@
|
||||
use solana_program::{
|
||||
account_info::AccountInfo, program_error::ProgramError, program_pack::Pack, pubkey::Pubkey,
|
||||
system_program, sysvar,
|
||||
};
|
||||
#[cfg(feature = "spl")]
|
||||
use spl_token::state::Mint;
|
||||
|
||||
/// Errors if:
|
||||
/// - Account is not a signer.
|
||||
pub fn load_signer<'a, 'info>(info: &'a AccountInfo<'info>) -> Result<(), ProgramError> {
|
||||
if !info.is_signer {
|
||||
return Err(ProgramError::MissingRequiredSignature);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Owner is not SPL token program.
|
||||
/// - Address does not match the expected mint address.
|
||||
/// - Data is empty.
|
||||
/// - Data cannot deserialize into a mint account.
|
||||
/// - Expected to be writable, but is not.
|
||||
#[cfg(feature = "spl")]
|
||||
pub fn load_mint<'a, 'info>(
|
||||
info: &'a AccountInfo<'info>,
|
||||
address: Pubkey,
|
||||
is_writable: bool,
|
||||
) -> Result<(), ProgramError> {
|
||||
if info.owner.ne(&spl_token::id()) {
|
||||
return Err(ProgramError::InvalidAccountOwner);
|
||||
}
|
||||
|
||||
if info.key.ne(&address) {
|
||||
return Err(ProgramError::InvalidSeeds);
|
||||
}
|
||||
|
||||
if info.data_is_empty() {
|
||||
return Err(ProgramError::UninitializedAccount);
|
||||
}
|
||||
|
||||
Mint::unpack(&info.data.borrow())?;
|
||||
|
||||
if is_writable && !info.is_writable {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Owner is not SPL token program.
|
||||
/// - Data is empty.
|
||||
/// - Data cannot deserialize into a token account.
|
||||
/// - Token account owner does not match the expected owner address.
|
||||
/// - Token account mint does not match the expected mint address.
|
||||
/// - Expected to be writable, but is not.
|
||||
#[cfg(feature = "spl")]
|
||||
pub fn load_token_account<'a, 'info>(
|
||||
info: &'a AccountInfo<'info>,
|
||||
owner: Option<&Pubkey>,
|
||||
mint: &Pubkey,
|
||||
is_writable: bool,
|
||||
) -> Result<(), ProgramError> {
|
||||
if info.owner.ne(&spl_token::id()) {
|
||||
return Err(ProgramError::InvalidAccountOwner);
|
||||
}
|
||||
|
||||
if info.data_is_empty() {
|
||||
return Err(ProgramError::UninitializedAccount);
|
||||
}
|
||||
|
||||
let account_data = info.data.borrow();
|
||||
let account = spl_token::state::Account::unpack(&account_data)?;
|
||||
|
||||
if account.mint.ne(&mint) {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
|
||||
if let Some(owner) = owner {
|
||||
if account.owner.ne(owner) {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
}
|
||||
|
||||
if is_writable && !info.is_writable {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Address does not match PDA derived from provided seeds.
|
||||
/// - Cannot load as an uninitialized account.
|
||||
pub fn load_uninitialized_pda<'a, 'info>(
|
||||
info: &'a AccountInfo<'info>,
|
||||
seeds: &[&[u8]],
|
||||
bump: u8,
|
||||
program_id: &Pubkey,
|
||||
) -> Result<(), ProgramError> {
|
||||
let pda = Pubkey::find_program_address(seeds, program_id);
|
||||
|
||||
if info.key.ne(&pda.0) {
|
||||
return Err(ProgramError::InvalidSeeds);
|
||||
}
|
||||
|
||||
if bump.ne(&pda.1) {
|
||||
return Err(ProgramError::InvalidSeeds);
|
||||
}
|
||||
|
||||
load_system_account(info, true)
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Owner is not the system program.
|
||||
/// - Data is not empty.
|
||||
/// - Account is not writable.
|
||||
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);
|
||||
}
|
||||
|
||||
if !info.data_is_empty() {
|
||||
return Err(ProgramError::AccountAlreadyInitialized);
|
||||
}
|
||||
|
||||
if is_writable && !info.is_writable {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Owner is not the sysvar address.
|
||||
/// - Account cannot load with the expected address.
|
||||
pub fn load_sysvar<'a, 'info>(
|
||||
info: &'a AccountInfo<'info>,
|
||||
key: Pubkey,
|
||||
) -> Result<(), ProgramError> {
|
||||
if info.owner.ne(&sysvar::id()) {
|
||||
return Err(ProgramError::InvalidAccountOwner);
|
||||
}
|
||||
|
||||
load_account(info, key, false)
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Address does not match the expected value.
|
||||
/// - Expected to be writable, but is not.
|
||||
pub fn load_account<'a, 'info>(
|
||||
info: &'a AccountInfo<'info>,
|
||||
key: Pubkey,
|
||||
is_writable: bool,
|
||||
) -> Result<(), ProgramError> {
|
||||
if info.key.ne(&key) {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
|
||||
if is_writable && !info.is_writable {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Address does not match the expected value.
|
||||
/// - Account is not executable.
|
||||
pub fn load_program<'a, 'info>(
|
||||
info: &'a AccountInfo<'info>,
|
||||
key: Pubkey,
|
||||
) -> Result<(), ProgramError> {
|
||||
if info.key.ne(&key) {
|
||||
return Err(ProgramError::IncorrectProgramId);
|
||||
}
|
||||
|
||||
if !info.executable {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Errors if:
|
||||
/// - Account is not writable.
|
||||
pub fn load_any<'a, 'info>(
|
||||
info: &'a AccountInfo<'info>,
|
||||
is_writable: bool,
|
||||
) -> Result<(), ProgramError> {
|
||||
if is_writable && !info.is_writable {
|
||||
return Err(ProgramError::InvalidAccountData);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user