mirror of
https://github.com/d0zingcat/ore.git
synced 2026-05-13 23:16:52 +00:00
miner migration
This commit is contained in:
@@ -11,7 +11,7 @@ description = "Digial gold, unchained."
|
||||
documentation = "https://docs.rs/ore-api/latest/ore_api/"
|
||||
repository = "https://github.com/regolith-labs/ore"
|
||||
readme = "./README.md"
|
||||
keywords = ["solana", "crypto", "mining"]
|
||||
keywords = ["solana"]
|
||||
|
||||
[workspace.dependencies]
|
||||
anyhow = "1.0"
|
||||
|
||||
@@ -19,6 +19,9 @@ pub enum OreInstruction {
|
||||
SetFeeCollector = 10,
|
||||
SetFeeRate = 11,
|
||||
SetSniperFeeDuration = 12,
|
||||
|
||||
// Migration
|
||||
MigrateMinerAccount = 13,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@@ -100,6 +103,12 @@ pub struct SetSniperFeeDuration {
|
||||
pub sniper_fee_duration: [u8; 8],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
|
||||
pub struct MigrateMinerAccount {
|
||||
pub authority: [u8; 32],
|
||||
}
|
||||
|
||||
instruction!(OreInstruction, Claim);
|
||||
instruction!(OreInstruction, Open);
|
||||
instruction!(OreInstruction, Close);
|
||||
@@ -113,3 +122,4 @@ instruction!(OreInstruction, SetBlockDuration);
|
||||
instruction!(OreInstruction, SetFeeCollector);
|
||||
instruction!(OreInstruction, SetFeeRate);
|
||||
instruction!(OreInstruction, SetSniperFeeDuration);
|
||||
instruction!(OreInstruction, MigrateMinerAccount);
|
||||
|
||||
@@ -287,3 +287,20 @@ pub fn set_sniper_fee_duration(signer: Pubkey, sniper_fee_duration: u64) -> Inst
|
||||
.to_bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn migrate_miner_account(signer: Pubkey, miner: Pubkey) -> Instruction {
|
||||
let config_address = config_pda().0;
|
||||
Instruction {
|
||||
program_id: crate::ID,
|
||||
accounts: vec![
|
||||
AccountMeta::new(signer, true),
|
||||
AccountMeta::new(config_address, false),
|
||||
AccountMeta::new(miner, false),
|
||||
AccountMeta::new_readonly(system_program::ID, false),
|
||||
],
|
||||
data: MigrateMinerAccount {
|
||||
authority: miner.to_bytes(),
|
||||
}
|
||||
.to_bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,31 @@
|
||||
use steel::*;
|
||||
|
||||
use crate::state::miner_pda;
|
||||
use crate::state::{miner_pda, OreAccountOLD};
|
||||
|
||||
use super::OreAccount;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
|
||||
pub struct MinerOLD {
|
||||
/// The authority of this miner account.
|
||||
pub authority: Pubkey,
|
||||
|
||||
/// The ID of the last block this miner mined in.
|
||||
pub block_id: u64,
|
||||
|
||||
/// The amount of hashpower this miner has committed to the current block.
|
||||
pub hashpower: u64,
|
||||
|
||||
/// A user-supplied seed for random number generation.
|
||||
pub seed: [u8; 32],
|
||||
|
||||
/// The total amount of hashpower this miner has committed across all blocks.
|
||||
pub total_hashpower: u64,
|
||||
|
||||
/// The total amount of ORE this miner has mined across all blocks.
|
||||
pub total_rewards: u64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
|
||||
pub struct Miner {
|
||||
@@ -13,6 +35,9 @@ pub struct Miner {
|
||||
/// The ID of the last block this miner mined in.
|
||||
pub block_id: u64,
|
||||
|
||||
/// An account authorized to execute actions on behalf of this miner.
|
||||
pub executor: Pubkey,
|
||||
|
||||
/// The amount of hashpower this miner has committed to the current block.
|
||||
pub hashpower: u64,
|
||||
|
||||
@@ -33,3 +58,4 @@ impl Miner {
|
||||
}
|
||||
|
||||
account!(OreAccount, Miner);
|
||||
account!(OreAccountOLD, MinerOLD);
|
||||
|
||||
@@ -24,6 +24,12 @@ pub enum OreAccount {
|
||||
Treasury = 104,
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)]
|
||||
pub enum OreAccountOLD {
|
||||
MinerOLD = 103,
|
||||
}
|
||||
|
||||
pub fn block_pda(id: u64) -> (Pubkey, u8) {
|
||||
Pubkey::find_program_address(&[BLOCK, &id.to_le_bytes()], &crate::ID)
|
||||
}
|
||||
|
||||
@@ -81,6 +81,9 @@ async fn main() {
|
||||
"set_fee_collector" => {
|
||||
set_fee_collector(&rpc, &payer).await.unwrap();
|
||||
}
|
||||
"migrate" => {
|
||||
migrate(&rpc, &payer).await.unwrap();
|
||||
}
|
||||
"benchmark" => {
|
||||
benchmark_keccak().await.unwrap();
|
||||
}
|
||||
@@ -241,6 +244,36 @@ async fn set_fee_collector(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn migrate(
|
||||
rpc: &RpcClient,
|
||||
payer: &solana_sdk::signer::keypair::Keypair,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let address = std::env::var("ADDRESS").expect("Missing ADDRESS env var");
|
||||
let address = Pubkey::from_str(&address).expect("Invalid ADDRESS");
|
||||
let ix = ore_api::sdk::migrate_miner_account(payer.pubkey(), address);
|
||||
simulate_transaction(rpc, payer, &[ix]).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn migrate_all(
|
||||
rpc: &RpcClient,
|
||||
payer: &solana_sdk::signer::keypair::Keypair,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let old_miners = get_old_miners(rpc).await?;
|
||||
println!("Found {} old miners", old_miners.len());
|
||||
for (i, (miner_address, _)) in old_miners.iter().enumerate() {
|
||||
println!(
|
||||
"[{} / {}] Migrating miner {}",
|
||||
i,
|
||||
old_miners.len(),
|
||||
miner_address
|
||||
);
|
||||
let ix = ore_api::sdk::migrate_miner_account(payer.pubkey(), *miner_address);
|
||||
simulate_transaction(rpc, payer, &[ix]).await;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn log_treasury(_rpc: &RpcClient) -> Result<(), anyhow::Error> {
|
||||
let treasury_address = ore_api::state::treasury_pda().0;
|
||||
println!("Treasury");
|
||||
@@ -367,10 +400,10 @@ async fn get_market(rpc: &RpcClient) -> Result<Market, anyhow::Error> {
|
||||
Ok(*market)
|
||||
}
|
||||
|
||||
async fn get_miner(rpc: &RpcClient, authority: Pubkey) -> Result<Miner, anyhow::Error> {
|
||||
async fn get_miner(rpc: &RpcClient, authority: Pubkey) -> Result<MinerOLD, anyhow::Error> {
|
||||
let miner_pda = ore_api::state::miner_pda(authority);
|
||||
let account = rpc.get_account(&miner_pda.0).await?;
|
||||
let miner = Miner::try_from_bytes(&account.data)?;
|
||||
let miner = MinerOLD::try_from_bytes(&account.data)?;
|
||||
Ok(*miner)
|
||||
}
|
||||
|
||||
@@ -385,7 +418,18 @@ async fn get_blocks(rpc: &RpcClient) -> Result<Vec<(Pubkey, Block)>, anyhow::Err
|
||||
Ok(blocks)
|
||||
}
|
||||
|
||||
async fn _simulate_transaction(
|
||||
async fn get_old_miners(rpc: &RpcClient) -> Result<Vec<(Pubkey, MinerOLD)>, anyhow::Error> {
|
||||
let miners = get_program_accounts::<MinerOLD>(rpc, ore_api::ID, vec![]).await?;
|
||||
Ok(miners)
|
||||
}
|
||||
|
||||
async fn get_miners(rpc: &RpcClient) -> Result<Vec<(Pubkey, Miner)>, anyhow::Error> {
|
||||
let miners = get_program_accounts::<Miner>(rpc, ore_api::ID, vec![]).await?;
|
||||
Ok(miners)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
async fn simulate_transaction(
|
||||
rpc: &RpcClient,
|
||||
payer: &solana_sdk::signer::keypair::Keypair,
|
||||
instructions: &[solana_sdk::instruction::Instruction],
|
||||
|
||||
@@ -2,6 +2,7 @@ mod claim;
|
||||
mod close;
|
||||
mod initialize;
|
||||
mod log;
|
||||
mod migrate_miner_account;
|
||||
mod mine;
|
||||
mod open;
|
||||
mod reset;
|
||||
@@ -17,6 +18,7 @@ use claim::*;
|
||||
use close::*;
|
||||
use initialize::*;
|
||||
use log::*;
|
||||
use migrate_miner_account::*;
|
||||
use mine::*;
|
||||
use open::*;
|
||||
use reset::*;
|
||||
@@ -54,6 +56,9 @@ pub fn process_instruction(
|
||||
OreInstruction::SetFeeCollector => process_set_fee_collector(accounts, data)?,
|
||||
OreInstruction::SetFeeRate => process_set_fee_rate(accounts, data)?,
|
||||
OreInstruction::SetSniperFeeDuration => process_set_sniper_fee_duration(accounts, data)?,
|
||||
|
||||
// Migration
|
||||
OreInstruction::MigrateMinerAccount => process_migrate_miner_account(accounts, data)?,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
42
program/src/migrate_miner_account.rs
Normal file
42
program/src/migrate_miner_account.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
use std::mem::size_of;
|
||||
|
||||
use ore_api::prelude::*;
|
||||
use solana_program::log::sol_log;
|
||||
use steel::*;
|
||||
|
||||
/// Migrates a miner account from the old format to the new format.
|
||||
pub fn process_migrate_miner_account(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult {
|
||||
// Load accounts.
|
||||
let [signer_info, config_info, miner_info, system_program] = accounts else {
|
||||
return Err(ProgramError::NotEnoughAccountKeys);
|
||||
};
|
||||
signer_info.is_signer()?;
|
||||
config_info
|
||||
.as_account_mut::<Config>(&ore_api::ID)?
|
||||
.assert_mut(|c| c.admin == *signer_info.key)?;
|
||||
let miner = miner_info.as_account_mut::<MinerOLD>(&ore_api::ID)?;
|
||||
system_program.is_program(&system_program::ID)?;
|
||||
|
||||
// Copy old data.
|
||||
let authority = miner.authority;
|
||||
let block_id = miner.block_id;
|
||||
let hashpower = miner.hashpower;
|
||||
let seed = miner.seed;
|
||||
let total_hashpower = miner.total_hashpower;
|
||||
let total_rewards = miner.total_rewards;
|
||||
|
||||
// Reallocate new account.
|
||||
miner_info.realloc(8 + size_of::<Miner>(), false)?;
|
||||
|
||||
// Copy new data.
|
||||
let miner = miner_info.as_account_mut::<Miner>(&ore_api::ID)?;
|
||||
miner.authority = authority;
|
||||
miner.block_id = block_id;
|
||||
miner.executor = Pubkey::default();
|
||||
miner.hashpower = hashpower;
|
||||
miner.seed = seed;
|
||||
miner.total_hashpower = total_hashpower;
|
||||
miner.total_rewards = total_rewards;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user