From 722398f1371d99e51d5980773bed57d4bf5f9e0a Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 26 Jul 2024 22:52:19 +0000 Subject: [PATCH] update comment --- program/src/auth.rs | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/program/src/auth.rs b/program/src/auth.rs index 0cab01b..cc6fa10 100644 --- a/program/src/auth.rs +++ b/program/src/auth.rs @@ -27,48 +27,68 @@ pub fn process_auth<'a, 'info>(accounts: &'a [AccountInfo<'info>], _data: &[u8]) Ok(()) } -/// Require that only the declared proof can be processed in this transaction. +/// Get the authenticated pubkey. /// -/// The intent here is to disincentivize sybil. As long as a user can fit multiple hashes in a single +/// The intent here is to disincentivize sybil. If a user can fit multiple hashes into a single /// transaction, there is a financial incentive to sybil multiple keypairs and pack as many hashes /// as possible into each transaction to minimize fee / hash. /// /// If each transaction is limited to one hash only, then a user will minimize their fee / hash /// by allocating all their hashpower to finding the single most difficult hash they can. /// +/// We solve this by "authenticating" the proof account on every mine instruction. That is, +/// every transaction with a `mine` instruction needs to include an `auth` instruction that +/// specifies the proof account that will be used. The `auth` instruction must be first ORE +/// instruction in the transaction. The `mine` instruction should error out if the provided proof +/// account doesn't match the authenticated address. +/// /// Errors if: -/// - Fails to find and parse the declared proof pubkey in the second instruction -/// of the transaction +/// - Fails to find and parse an authentication address. pub fn authenticate(data: &[u8]) -> Result, SanitizeError> { // Start the current byte index at 0 let mut curr = 0; let num_instructions = read_u16(&mut curr, data)?; let pc = curr; + + // Iterate through the top-level instructions for i in 0..num_instructions as usize { + // Get byte counter curr = pc + i * 2; curr = read_u16(&mut curr, data)? as usize; + + // Read num accounts on this ix let num_accounts = read_u16(&mut curr, data)? as usize; - let mut ac = curr; + + // Hold a pointer to the first account in the accounts array + let mut ac = curr + 1; + + // Read the instruction program id curr += num_accounts * 33; let program_id = read_pubkey(&mut curr, data)?; + + // We only need to introspect on the first ore ix if program_id.eq(&ore_api::ID) { curr += 2; + + // Parse the instruction data if let Ok(ix) = OreInstruction::try_from(read_u8(&mut curr, data)?) { - // Validate ix is an auth + // Return immediately if the ix is not an auth if ix.ne(&OreInstruction::Auth) { return Ok(None); } - // Valid num accounts is correct + + // Valid the num accounts is expected if num_accounts.ne(&1) { return Ok(None); } - // Return provided pubkey + + // Return the address of the authenticated account let address = read_pubkey(&mut ac, data)?; return Ok(Some(address)); - } else { - // Otherwise return - return Ok(None); } + + // Return if instruction data can't be parsed + return Ok(None); } }