diff --git a/src/error.rs b/src/error.rs index 597331b..63a657d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -13,12 +13,10 @@ pub enum OreError { ResetTooEarly = 2, #[error("The provided hash was invalid")] HashInvalid = 3, - #[error("The provided hash does not satisfy the difficulty requirement")] - DifficultyNotSatisfied = 4, #[error("The bus does not have enough rewards to issue at this time")] - BusRewardsInsufficient = 5, + BusRewardsInsufficient = 4, #[error("The claim amount cannot be greater than the claimable rewards")] - ClaimTooLarge = 6, + ClaimTooLarge = 5, } impl From for ProgramError { diff --git a/src/instruction.rs b/src/instruction.rs index fa60d43..3f049e8 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -197,6 +197,7 @@ pub fn register(signer: Pubkey) -> Instruction { AccountMeta::new(signer, 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: [ OreInstruction::Register.to_vec(), diff --git a/src/processor/mine.rs b/src/processor/mine.rs index d7ee705..9241ad4 100644 --- a/src/processor/mine.rs +++ b/src/processor/mine.rs @@ -116,7 +116,7 @@ pub(crate) fn validate_hash( signer.as_ref(), ]); if hash.gt(&difficulty) { - return Err(OreError::DifficultyNotSatisfied.into()); + return Err(OreError::HashInvalid.into()); } Ok(hash) } diff --git a/src/processor/register.rs b/src/processor/register.rs index 94fc9fd..5451996 100644 --- a/src/processor/register.rs +++ b/src/processor/register.rs @@ -2,7 +2,7 @@ use std::mem::size_of; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, keccak::hashv, - program_error::ProgramError, pubkey::Pubkey, system_program, + program_error::ProgramError, pubkey::Pubkey, slot_hashes::SlotHash, system_program, sysvar, }; use crate::{ @@ -32,7 +32,7 @@ pub fn process_register<'a, 'info>( let args = RegisterArgs::try_from_bytes(data)?; // Load accounts - let [signer, proof_info, system_program] = accounts else { + let [signer, proof_info, system_program, slot_hashes_info] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; load_signer(signer)?; @@ -43,6 +43,7 @@ pub fn process_register<'a, 'info>( &crate::id(), )?; load_program(system_program, system_program::id())?; + load_sysvar(slot_hashes_info, sysvar::slot_hashes::id())?; // Initialize proof create_pda( @@ -58,7 +59,11 @@ pub fn process_register<'a, 'info>( let proof = Proof::try_from_bytes_mut(&mut proof_data)?; proof.authority = *signer.key; proof.claimable_rewards = 0; - proof.hash = hashv(&[signer.key.as_ref()]).into(); + proof.hash = hashv(&[ + signer.key.as_ref(), + &slot_hashes_info.data.borrow()[0..size_of::()], + ]) + .into(); proof.total_hashes = 0; proof.total_rewards = 0; diff --git a/tests/test_mine.rs b/tests/test_mine.rs index 04faf3d..6494d5c 100644 --- a/tests/test_mine.rs +++ b/tests/test_mine.rs @@ -50,7 +50,6 @@ async fn test_mine() { let proof = Proof::try_from_bytes(&proof_account.data).unwrap(); assert_eq!(proof.authority, payer.pubkey()); assert_eq!(proof.claimable_rewards, 0); - assert_eq!(proof.hash, hashv(&[payer.pubkey().as_ref()]).into()); assert_eq!(proof.total_hashes, 0); assert_eq!(proof.total_rewards, 0); @@ -497,23 +496,6 @@ async fn test_mine_fail_bad_data() { assert!(res.is_err()); } - // Fuzz test random hashes and nonces - for _ in 0..FUZZ { - let nonce: u64 = rng.gen(); - assert_mine_tx_err( - &mut banks, - &payer, - blockhash, - payer.pubkey(), - BUS_ADDRESSES[0], - proof_address, - TREASURY_ADDRESS, - sysvar::slot_hashes::id(), - nonce, - ) - .await; - } - // Fuzz test random bus addresses for _ in 0..FUZZ { assert_mine_tx_err( @@ -615,9 +597,9 @@ fn find_next_hash(hash: KeccakHash, difficulty: KeccakHash, signer: Pubkey) -> ( let mut nonce = 0u64; loop { next_hash = hashv(&[ + nonce.to_le_bytes().as_slice(), hash.to_bytes().as_slice(), signer.to_bytes().as_slice(), - nonce.to_le_bytes().as_slice(), ]); if next_hash.le(&difficulty) { break;