mirror of
https://github.com/d0zingcat/ore.git
synced 2026-05-13 23:16:52 +00:00
update mine transaction introspection to use declared proof
This commit is contained in:
@@ -27,6 +27,10 @@ pub enum OreError {
|
||||
CannotClose = 9,
|
||||
#[error("This account cannot be crowned because its last stake was too recent")]
|
||||
CannotCrown = 10,
|
||||
#[error("Only the declared proof can be processed in this transaction")]
|
||||
DeclaredProofMissmatch = 11,
|
||||
#[error("Failed to find and parse the declared proof from the transaction")]
|
||||
FindAndParseDeclaredProofFailed = 12,
|
||||
}
|
||||
|
||||
impl From<OreError> for ProgramError {
|
||||
|
||||
@@ -25,7 +25,7 @@ use solana_program::{
|
||||
sysvar::{self, instructions::load_current_index, Sysvar},
|
||||
};
|
||||
|
||||
use crate::utils::AccountDeserialize;
|
||||
use crate::{find_and_parse_declared_proof, utils::AccountDeserialize};
|
||||
|
||||
/// Mine is the primary workhorse instruction of the Ore program. Its responsibilities include:
|
||||
/// 1. Calculate the hash from the provided nonce.
|
||||
@@ -61,10 +61,21 @@ pub fn process_mine<'a, 'info>(
|
||||
load_sysvar(instructions_sysvar, sysvar::instructions::id())?;
|
||||
load_sysvar(slot_hashes_sysvar, sysvar::slot_hashes::id())?;
|
||||
|
||||
// Validate this is the only mine ix in the transaction.
|
||||
if !introspect_transaction(&instructions_sysvar.data.borrow()).unwrap_or(false) {
|
||||
return Err(OreError::TransactionInvalid.into());
|
||||
}
|
||||
/// Require that only the declared proof can be processed in this transaction.
|
||||
///
|
||||
/// The intent here is to disincentivize sybil. As long as a user can fit multiple hashes in 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.
|
||||
if let Ok(pubkey) = find_and_parse_declared_proof(&instructions_sysvar.data.borrow()) {
|
||||
if !pubkey.eq(proof_info.key) {
|
||||
return Err(OreError::DeclaredProofMissmatch.into());
|
||||
}
|
||||
} else {
|
||||
return Err(OreError::FindAndParseDeclaredProofFailed.into());
|
||||
};
|
||||
|
||||
// Validate epoch is active.
|
||||
let config_data = config_info.data.borrow();
|
||||
@@ -182,15 +193,6 @@ pub fn process_mine<'a, 'info>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Require that there is only one `mine` instruction per transaction and it is called from the
|
||||
/// top level of the transaction.
|
||||
///
|
||||
/// The intent here is to disincentivize sybil. As long as a user can fit multiple hashes in 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.
|
||||
fn introspect_transaction(msg: &[u8]) -> Result<bool, SanitizeError> {
|
||||
#[allow(deprecated)]
|
||||
let idx = load_current_index(msg);
|
||||
|
||||
Reference in New Issue
Block a user