From d8f8f49f728e23c40b7e8c88f7827999256adc87 Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 19 Sep 2025 10:17:19 -0700 Subject: [PATCH] log --- api/src/event.rs | 38 +++++++++++-------------------- api/src/instruction.rs | 14 +++++------- api/src/sdk.rs | 17 +++++++++++++- cli/src/main.rs | 24 ++++++++++++++++++++ program/src/initialize.rs | 2 -- program/src/log.rs | 15 +++++++++++++ program/src/reset.rs | 47 ++++++++++++++++++++++++++++++++++++--- 7 files changed, 118 insertions(+), 39 deletions(-) create mode 100644 program/src/log.rs diff --git a/api/src/event.rs b/api/src/event.rs index 9f59a2e..8b996d1 100644 --- a/api/src/event.rs +++ b/api/src/event.rs @@ -2,7 +2,6 @@ use steel::*; pub enum OreEvent { Reset = 0, - Mine = 2, } #[repr(C)] @@ -11,11 +10,8 @@ pub struct ResetEvent { /// The event discriminator. pub disc: u64, - /// The authority of the swap. - pub authority: Pubkey, - /// The block that was opened for trading. - pub block_id: u64, + pub round_id: u64, /// The start slot of the next block. pub start_slot: u64, @@ -23,34 +19,26 @@ pub struct ResetEvent { /// The end slot of the next block. pub end_slot: u64, - /// The timestamp of the event. - pub ts: i64, -} + /// The winning square of the round. + pub winning_square: u64, -#[repr(C)] -#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)] -pub struct MineEvent { - /// The event discriminator. - pub disc: u64, + /// The top miner of the round. + pub top_miner: Pubkey, - /// The authority of the mine. - pub authority: Pubkey, + /// The total amount of SOL prospected in the round. + pub total_prospects: u64, - /// The block that was mined. - pub block_id: u64, + /// The total amount of SOL put in the ORE vault. + pub total_vaulted: u64, - /// The nonce that was mined. - pub nonce: u64, + /// The total amount of SOL won by miners for the round. + pub total_winnings: u64, - /// The total hashpower the miner had. - pub hashpower: u64, - - /// Whether or not the miner is the new best. - pub is_best: u64, + /// The total amount of ORE minted for the round. + pub total_minted: u64, /// The timestamp of the event. pub ts: i64, } event!(ResetEvent); -event!(MineEvent); diff --git a/api/src/instruction.rs b/api/src/instruction.rs index 123cde2..1f20f58 100644 --- a/api/src/instruction.rs +++ b/api/src/instruction.rs @@ -8,12 +8,13 @@ pub enum OreInstruction { ClaimSOL = 1, ClaimORE = 2, Initialize = 3, + Log = 4, Prospect = 5, Redeem = 6, Reset = 7, // Admin - SetAdmin = 8, + SetAdmin = 9, SetFeeCollector = 10, // Seeker @@ -42,7 +43,7 @@ pub struct Initialize {} #[repr(C)] #[derive(Clone, Copy, Debug, Pod, Zeroable)] -pub struct InitializeSquares {} +pub struct Log {} #[repr(C)] #[derive(Clone, Copy, Debug, Pod, Zeroable)] @@ -115,17 +116,14 @@ pub struct SetSniperFeeDuration { #[derive(Clone, Copy, Debug, Pod, Zeroable)] pub struct ClaimSeeker {} -#[repr(C)] -#[derive(Clone, Copy, Debug, Pod, Zeroable)] -pub struct MigrateSquares {} - instruction!(OreInstruction, Boost); instruction!(OreInstruction, ClaimSOL); instruction!(OreInstruction, ClaimORE); +instruction!(OreInstruction, Initialize); +instruction!(OreInstruction, Log); +instruction!(OreInstruction, Prospect); instruction!(OreInstruction, Redeem); instruction!(OreInstruction, Reset); -instruction!(OreInstruction, Prospect); -instruction!(OreInstruction, Initialize); instruction!(OreInstruction, SetAdmin); instruction!(OreInstruction, SetFeeCollector); instruction!(OreInstruction, ClaimSeeker); diff --git a/api/src/sdk.rs b/api/src/sdk.rs index 2634136..c8da142 100644 --- a/api/src/sdk.rs +++ b/api/src/sdk.rs @@ -2,11 +2,25 @@ use spl_associated_token_account::get_associated_token_address; use steel::*; use crate::{ - consts::{BOOST_RESERVE_TOKEN, MINT_ADDRESS, TREASURY_ADDRESS}, + consts::{BOARD, BOOST_RESERVE_TOKEN, MINT_ADDRESS, TREASURY_ADDRESS}, instruction::*, state::*, }; +pub fn log(signer: Pubkey, msg: &[u8]) -> Instruction { + let mut data = Log {}.to_bytes(); + data.extend_from_slice(msg); + Instruction { + program_id: crate::ID, + accounts: vec![AccountMeta::new(signer, true)], + data: data, + } +} + +pub fn program_log(accounts: &[AccountInfo], msg: &[u8]) -> Result<(), ProgramError> { + invoke_signed(&log(*accounts[0].key, msg), accounts, &crate::ID, &[BOARD]) +} + // let [signer_info, config_info, mint_info, reserve_tokens_info, treasury_info, system_program, token_program] = pub fn boost(signer: Pubkey) -> Instruction { @@ -135,6 +149,7 @@ pub fn reset(signer: Pubkey, miners: Vec) -> Instruction { AccountMeta::new(treasury_tokens_address, false), AccountMeta::new_readonly(system_program::ID, false), AccountMeta::new_readonly(spl_token::ID, false), + AccountMeta::new_readonly(crate::ID, false), AccountMeta::new_readonly(sysvar::slot_hashes::ID, false), ]; for miner in miners { diff --git a/cli/src/main.rs b/cli/src/main.rs index da450b5..ea638c3 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -16,6 +16,7 @@ use solana_sdk::{ slot_hashes::SlotHashes, transaction::Transaction, }; +use spl_associated_token_account::get_associated_token_address; use steel::{AccountDeserialize, Clock, Discriminator}; #[tokio::main] @@ -78,6 +79,9 @@ async fn main() { "set_fee_collector" => { set_fee_collector(&rpc, &payer).await.unwrap(); } + "ata" => { + ata(&rpc, &payer).await.unwrap(); + } "claim_seeker" => { claim_seeker(&rpc, &payer).await.unwrap(); } @@ -88,6 +92,26 @@ async fn main() { }; } +async fn ata( + rpc: &RpcClient, + payer: &solana_sdk::signer::keypair::Keypair, +) -> Result<(), anyhow::Error> { + let user = pubkey!("TatxmzjCpMFurJuPbw4kGXK25MSYUVLgFy5A1o76mwS"); + let token = pubkey!("8H8rPiWW4iTFCfEkSnf7jpqeNpFfvdH9gLouAL3Fe2Zx"); + let ata = get_associated_token_address(&user, &token); + let ix = spl_associated_token_account::instruction::create_associated_token_account( + &payer.pubkey(), + &user, + &token, + &spl_token::ID, + ); + submit_transaction(rpc, payer, &[ix]).await?; + let account = rpc.get_account(&ata).await?; + println!("ATA: {}", ata); + println!("Account: {:?}", account); + Ok(()) +} + async fn boost( rpc: &RpcClient, payer: &solana_sdk::signer::keypair::Keypair, diff --git a/program/src/initialize.rs b/program/src/initialize.rs index 479a0c7..a37983a 100644 --- a/program/src/initialize.rs +++ b/program/src/initialize.rs @@ -56,8 +56,6 @@ pub fn process_initialize(accounts: &[AccountInfo<'_>], _data: &[u8]) -> Program config.admin = *signer_info.key; config.last_boost = 0; config.fee_collector = *signer_info.key; - config.sniper_fee_duration = 0; - config.fee_rate = 0; } else { config_info.as_account::(&ore_api::ID)?; } diff --git a/program/src/log.rs b/program/src/log.rs new file mode 100644 index 0000000..32663d5 --- /dev/null +++ b/program/src/log.rs @@ -0,0 +1,15 @@ +use ore_api::prelude::*; +use steel::*; + +/// No-op, use instruction data for logging w/o truncation. +pub fn process_log(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult { + // Load accounts. + let [signer_info] = accounts else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + signer_info.is_signer()?.as_account::(&ore_api::ID)?; + + // For data integrity, only the board can log messages. + + Ok(()) +} diff --git a/program/src/reset.rs b/program/src/reset.rs index 8f89337..8e9bd09 100644 --- a/program/src/reset.rs +++ b/program/src/reset.rs @@ -6,8 +6,8 @@ use steel::*; pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult { // Load accounts. let clock = Clock::get()?; - let (required_accounts, miner_accounts) = accounts.split_at(9); - let [signer_info, board_info, mint_info, square_info, treasury_info, treasury_tokens_info, system_program, token_program, slot_hashes_sysvar] = + let (required_accounts, miner_accounts) = accounts.split_at(10); + let [signer_info, board_info, mint_info, square_info, treasury_info, treasury_tokens_info, system_program, token_program, ore_program, slot_hashes_sysvar] = required_accounts else { return Err(ProgramError::NotEnoughAccountKeys); @@ -23,6 +23,7 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul treasury_tokens_info.as_associated_token_account(&treasury_info.key, &mint_info.key)?; system_program.is_program(&system_program::ID)?; token_program.is_program(&spl_token::ID)?; + ore_program.is_program(&ore_api::ID)?; slot_hashes_sysvar.is_sysvar(&sysvar::slot_hashes::ID)?; // Sample slot hash. @@ -43,6 +44,26 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul board.total_vaulted = board.total_prospects; treasury.balance += board.total_prospects; board_info.send(board.total_prospects, &treasury_info); + + // Emit event. + program_log( + &[board_info.clone(), ore_program.clone()], + ResetEvent { + disc: 0, + round_id: board.id, + start_slot: board.start_slot, + end_slot: board.end_slot, + winning_square: winning_square as u64, + top_miner: board.top_miner, + total_prospects: board.total_prospects, + total_vaulted: board.total_vaulted, + total_winnings: board.total_winnings, + total_minted: 0, + ts: clock.unix_timestamp, + } + .to_bytes(), + )?; + return Ok(()); } @@ -95,9 +116,10 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul } // Payout reward to top miner. + let mut mint_amount = 0; if let Some(i) = top_miner { let miner = miner_accounts[i].as_account_mut::(&ore_api::ID)?; - let mint_amount = ONE_ORE.min(MAX_SUPPLY - mint.supply()); + mint_amount = ONE_ORE.min(MAX_SUPPLY - mint.supply()); if mint_amount > 0 { miner.rewards_ore += mint_amount; miner.lifetime_rewards_ore += mint_amount; @@ -122,6 +144,25 @@ pub fn process_reset(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResul board_info.send(rewards_sol[i], &miner_info); } + // Emit event. + program_log( + &[board_info.clone(), ore_program.clone()], + ResetEvent { + disc: 0, + round_id: board.id, + start_slot: board.start_slot, + end_slot: board.end_slot, + winning_square: winning_square as u64, + top_miner: board.top_miner, + total_prospects: board.total_prospects, + total_vaulted: board.total_vaulted, + total_winnings: board.total_winnings, + total_minted: mint_amount, + ts: clock.unix_timestamp, + } + .to_bytes(), + )?; + Ok(()) }