mirror of
https://github.com/d0zingcat/ore.git
synced 2026-05-14 15:10:13 +00:00
338 lines
10 KiB
Rust
338 lines
10 KiB
Rust
use bytemuck::{Pod, Zeroable};
|
|
use drillx::Solution;
|
|
use num_enum::TryFromPrimitive;
|
|
use ore_utils::*;
|
|
use solana_program::{
|
|
instruction::{AccountMeta, Instruction},
|
|
pubkey::Pubkey,
|
|
system_program, sysvar,
|
|
};
|
|
|
|
use crate::{
|
|
consts::*,
|
|
state::{bus_pda, config_pda, proof_pda, treasury_pda},
|
|
};
|
|
|
|
#[repr(u8)]
|
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)]
|
|
pub enum OreInstruction {
|
|
// User
|
|
Claim = 0,
|
|
Close = 1,
|
|
Mine = 2,
|
|
Open = 3,
|
|
Reset = 4,
|
|
Stake = 5,
|
|
Update = 6,
|
|
Upgrade = 7,
|
|
|
|
// Admin
|
|
Initialize = 100,
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
|
|
pub struct Claim {
|
|
pub amount: [u8; 8],
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
|
|
pub struct Close {}
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
|
|
pub struct Mine {
|
|
pub digest: [u8; 16],
|
|
pub nonce: [u8; 8],
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
|
|
pub struct Open {
|
|
pub bump: u8,
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
|
|
pub struct Reset {}
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
|
|
pub struct Stake {
|
|
pub amount: [u8; 8],
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
|
|
pub struct Update {}
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
|
|
pub struct Upgrade {
|
|
pub amount: [u8; 8],
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
|
|
pub struct Initialize {
|
|
pub bus_0_bump: u8,
|
|
pub bus_1_bump: u8,
|
|
pub bus_2_bump: u8,
|
|
pub bus_3_bump: u8,
|
|
pub bus_4_bump: u8,
|
|
pub bus_5_bump: u8,
|
|
pub bus_6_bump: u8,
|
|
pub bus_7_bump: u8,
|
|
pub config_bump: u8,
|
|
pub metadata_bump: u8,
|
|
pub mint_bump: u8,
|
|
pub treasury_bump: u8,
|
|
}
|
|
|
|
instruction!(OreInstruction, Claim);
|
|
instruction!(OreInstruction, Close);
|
|
instruction!(OreInstruction, Mine);
|
|
instruction!(OreInstruction, Open);
|
|
instruction!(OreInstruction, Reset);
|
|
instruction!(OreInstruction, Stake);
|
|
instruction!(OreInstruction, Update);
|
|
instruction!(OreInstruction, Upgrade);
|
|
instruction!(OreInstruction, Initialize);
|
|
|
|
/// Builds an auth instruction.
|
|
pub fn auth(proof: Pubkey) -> Instruction {
|
|
Instruction {
|
|
program_id: NOOP_PROGRAM_ID,
|
|
accounts: vec![],
|
|
data: proof.to_bytes().to_vec(),
|
|
}
|
|
}
|
|
|
|
/// Builds a claim instruction.
|
|
pub fn claim(signer: Pubkey, beneficiary: Pubkey, amount: u64) -> Instruction {
|
|
let proof = proof_pda(signer).0;
|
|
let treasury_tokens = spl_associated_token_account::get_associated_token_address(
|
|
&TREASURY_ADDRESS,
|
|
&MINT_ADDRESS,
|
|
);
|
|
Instruction {
|
|
program_id: crate::id(),
|
|
accounts: vec![
|
|
AccountMeta::new(signer, true),
|
|
AccountMeta::new(beneficiary, false),
|
|
AccountMeta::new(proof, false),
|
|
AccountMeta::new_readonly(TREASURY_ADDRESS, false),
|
|
AccountMeta::new(treasury_tokens, false),
|
|
AccountMeta::new_readonly(spl_token::id(), false),
|
|
],
|
|
data: Claim {
|
|
amount: amount.to_le_bytes(),
|
|
}
|
|
.to_bytes(),
|
|
}
|
|
}
|
|
|
|
/// Builds a close instruction.
|
|
pub fn close(signer: Pubkey) -> Instruction {
|
|
let proof = proof_pda(signer).0;
|
|
Instruction {
|
|
program_id: crate::id(),
|
|
accounts: vec![
|
|
AccountMeta::new(signer, true),
|
|
AccountMeta::new(proof, false),
|
|
AccountMeta::new_readonly(solana_program::system_program::id(), false),
|
|
],
|
|
data: Close {}.to_bytes(),
|
|
}
|
|
}
|
|
|
|
/// Builds a mine instruction.
|
|
pub fn mine(signer: Pubkey, authority: Pubkey, bus: Pubkey, solution: Solution) -> Instruction {
|
|
let proof = proof_pda(authority).0;
|
|
Instruction {
|
|
program_id: crate::id(),
|
|
accounts: vec![
|
|
AccountMeta::new(signer, true),
|
|
AccountMeta::new(bus, false),
|
|
AccountMeta::new_readonly(CONFIG_ADDRESS, false),
|
|
AccountMeta::new(proof, false),
|
|
AccountMeta::new_readonly(sysvar::instructions::id(), false),
|
|
AccountMeta::new_readonly(sysvar::slot_hashes::id(), false),
|
|
],
|
|
data: Mine {
|
|
digest: solution.d,
|
|
nonce: solution.n,
|
|
}
|
|
.to_bytes(),
|
|
}
|
|
}
|
|
|
|
/// Builds an open instruction.
|
|
pub fn open(signer: Pubkey, miner: Pubkey, payer: Pubkey) -> Instruction {
|
|
let proof_pda = proof_pda(signer);
|
|
Instruction {
|
|
program_id: crate::id(),
|
|
accounts: vec![
|
|
AccountMeta::new(signer, true),
|
|
AccountMeta::new_readonly(miner, false),
|
|
AccountMeta::new(payer, true),
|
|
AccountMeta::new(proof_pda.0, false),
|
|
AccountMeta::new_readonly(solana_program::system_program::id(), false),
|
|
AccountMeta::new_readonly(sysvar::slot_hashes::id(), false),
|
|
],
|
|
data: Open { bump: proof_pda.1 }.to_bytes(),
|
|
}
|
|
}
|
|
|
|
/// Builds a reset instruction.
|
|
pub fn reset(signer: Pubkey) -> Instruction {
|
|
let treasury_tokens = spl_associated_token_account::get_associated_token_address(
|
|
&TREASURY_ADDRESS,
|
|
&MINT_ADDRESS,
|
|
);
|
|
Instruction {
|
|
program_id: crate::id(),
|
|
accounts: vec![
|
|
AccountMeta::new(signer, true),
|
|
AccountMeta::new(BUS_ADDRESSES[0], false),
|
|
AccountMeta::new(BUS_ADDRESSES[1], false),
|
|
AccountMeta::new(BUS_ADDRESSES[2], false),
|
|
AccountMeta::new(BUS_ADDRESSES[3], false),
|
|
AccountMeta::new(BUS_ADDRESSES[4], false),
|
|
AccountMeta::new(BUS_ADDRESSES[5], false),
|
|
AccountMeta::new(BUS_ADDRESSES[6], false),
|
|
AccountMeta::new(BUS_ADDRESSES[7], false),
|
|
AccountMeta::new(CONFIG_ADDRESS, false),
|
|
AccountMeta::new(MINT_ADDRESS, false),
|
|
AccountMeta::new(TREASURY_ADDRESS, false),
|
|
AccountMeta::new(treasury_tokens, false),
|
|
AccountMeta::new_readonly(spl_token::id(), false),
|
|
],
|
|
data: Reset {}.to_bytes(),
|
|
}
|
|
}
|
|
|
|
/// Build a stake instruction.
|
|
pub fn stake(signer: Pubkey, sender: Pubkey, amount: u64) -> Instruction {
|
|
let proof = proof_pda(signer).0;
|
|
let treasury_tokens = spl_associated_token_account::get_associated_token_address(
|
|
&TREASURY_ADDRESS,
|
|
&MINT_ADDRESS,
|
|
);
|
|
Instruction {
|
|
program_id: crate::id(),
|
|
accounts: vec![
|
|
AccountMeta::new(signer, true),
|
|
AccountMeta::new(proof, false),
|
|
AccountMeta::new(sender, false),
|
|
AccountMeta::new(treasury_tokens, false),
|
|
AccountMeta::new_readonly(spl_token::id(), false),
|
|
],
|
|
data: Stake {
|
|
amount: amount.to_le_bytes(),
|
|
}
|
|
.to_bytes(),
|
|
}
|
|
}
|
|
|
|
// Build an update instruction.
|
|
pub fn update(signer: Pubkey, miner: Pubkey) -> Instruction {
|
|
let proof = proof_pda(signer).0;
|
|
Instruction {
|
|
program_id: crate::id(),
|
|
accounts: vec![
|
|
AccountMeta::new(signer, true),
|
|
AccountMeta::new_readonly(miner, false),
|
|
AccountMeta::new(proof, false),
|
|
],
|
|
data: Update {}.to_bytes(),
|
|
}
|
|
}
|
|
|
|
// Build an upgrade instruction.
|
|
pub fn upgrade(signer: Pubkey, beneficiary: Pubkey, sender: Pubkey, amount: u64) -> Instruction {
|
|
Instruction {
|
|
program_id: crate::id(),
|
|
accounts: vec![
|
|
AccountMeta::new(signer, true),
|
|
AccountMeta::new(beneficiary, false),
|
|
AccountMeta::new(MINT_ADDRESS, false),
|
|
AccountMeta::new(MINT_V1_ADDRESS, false),
|
|
AccountMeta::new(sender, false),
|
|
AccountMeta::new(TREASURY_ADDRESS, false),
|
|
AccountMeta::new_readonly(spl_token::id(), false),
|
|
],
|
|
data: Upgrade {
|
|
amount: amount.to_le_bytes(),
|
|
}
|
|
.to_bytes(),
|
|
}
|
|
}
|
|
|
|
/// Builds an initialize instruction.
|
|
pub fn initialize(signer: Pubkey) -> Instruction {
|
|
let bus_pdas = [
|
|
bus_pda(0),
|
|
bus_pda(1),
|
|
bus_pda(2),
|
|
bus_pda(3),
|
|
bus_pda(4),
|
|
bus_pda(5),
|
|
bus_pda(6),
|
|
bus_pda(7),
|
|
];
|
|
let config_pda = config_pda();
|
|
let mint_pda = Pubkey::find_program_address(&[MINT, MINT_NOISE.as_slice()], &crate::id());
|
|
let treasury_pda = treasury_pda();
|
|
let treasury_tokens =
|
|
spl_associated_token_account::get_associated_token_address(&treasury_pda.0, &mint_pda.0);
|
|
let metadata_pda = Pubkey::find_program_address(
|
|
&[
|
|
METADATA,
|
|
mpl_token_metadata::ID.as_ref(),
|
|
mint_pda.0.as_ref(),
|
|
],
|
|
&mpl_token_metadata::ID,
|
|
);
|
|
Instruction {
|
|
program_id: crate::id(),
|
|
accounts: vec![
|
|
AccountMeta::new(signer, true),
|
|
AccountMeta::new(bus_pdas[0].0, false),
|
|
AccountMeta::new(bus_pdas[1].0, false),
|
|
AccountMeta::new(bus_pdas[2].0, false),
|
|
AccountMeta::new(bus_pdas[3].0, false),
|
|
AccountMeta::new(bus_pdas[4].0, false),
|
|
AccountMeta::new(bus_pdas[5].0, false),
|
|
AccountMeta::new(bus_pdas[6].0, false),
|
|
AccountMeta::new(bus_pdas[7].0, false),
|
|
AccountMeta::new(config_pda.0, false),
|
|
AccountMeta::new(metadata_pda.0, false),
|
|
AccountMeta::new(mint_pda.0, false),
|
|
AccountMeta::new(treasury_pda.0, false),
|
|
AccountMeta::new(treasury_tokens, false),
|
|
AccountMeta::new_readonly(system_program::id(), false),
|
|
AccountMeta::new_readonly(spl_token::id(), false),
|
|
AccountMeta::new_readonly(spl_associated_token_account::id(), false),
|
|
AccountMeta::new_readonly(mpl_token_metadata::ID, false),
|
|
AccountMeta::new_readonly(sysvar::rent::id(), false),
|
|
],
|
|
data: Initialize {
|
|
bus_0_bump: bus_pdas[0].1,
|
|
bus_1_bump: bus_pdas[1].1,
|
|
bus_2_bump: bus_pdas[2].1,
|
|
bus_3_bump: bus_pdas[3].1,
|
|
bus_4_bump: bus_pdas[4].1,
|
|
bus_5_bump: bus_pdas[5].1,
|
|
bus_6_bump: bus_pdas[6].1,
|
|
bus_7_bump: bus_pdas[7].1,
|
|
config_bump: config_pda.1,
|
|
metadata_bump: metadata_pda.1,
|
|
mint_bump: mint_pda.1,
|
|
treasury_bump: treasury_pda.1,
|
|
}
|
|
.to_bytes(),
|
|
}
|
|
}
|