diff --git a/consensus/rules/src/transactions.rs b/consensus/rules/src/transactions.rs index fbc45c826..4c24f901a 100644 --- a/consensus/rules/src/transactions.rs +++ b/consensus/rules/src/transactions.rs @@ -1,5 +1,5 @@ use monero_serai::ringct::RctType; -use std::{cmp::Ordering, collections::HashSet, sync::Arc}; +use std::cmp::Ordering; use monero_serai::transaction::{Input, Output, Timelock, Transaction}; use multiexp::BatchVerifier; diff --git a/consensus/src/block.rs b/consensus/src/block.rs index 6c60da400..5d6433183 100644 --- a/consensus/src/block.rs +++ b/consensus/src/block.rs @@ -9,32 +9,19 @@ use std::{ use cuprate_helper::asynch::rayon_spawn_async; use futures::FutureExt; -use monero_serai::{ - block::Block, - transaction::{Input, Transaction}, -}; -use rayon::prelude::*; +use monero_serai::{block::Block, transaction::Input}; use tower::{Service, ServiceExt}; -use tracing::{instrument, trace}; +use tracing::trace; -use cuprate_consensus_rules::blocks::RX_SEEDHASH_EPOCH_BLOCKS; use cuprate_consensus_rules::{ - blocks::{ - calculate_pow_hash, check_block, check_block_pow, is_randomx_seed_height, - randomx_seed_height, BlockError, RandomX, - }, + blocks::{calculate_pow_hash, check_block, check_block_pow, BlockError, RandomX}, miner_tx::MinerTxError, ConsensusError, HardFork, }; use crate::{ - context::{ - rx_vms::RandomXVM, BlockChainContextRequest, BlockChainContextResponse, - RawBlockChainContext, - }, - transactions::{ - contextual_data, TransactionVerificationData, VerifyTxRequest, VerifyTxResponse, - }, + context::{BlockChainContextRequest, BlockChainContextResponse}, + transactions::{TransactionVerificationData, VerifyTxRequest, VerifyTxResponse}, Database, ExtendedConsensusError, }; @@ -192,7 +179,8 @@ pub struct BlockVerifierService { /// The tx verifier service. tx_verifier_svc: TxV, /// The database. - database: D, + // Not use yet but will be. + _database: D, } impl BlockVerifierService @@ -217,7 +205,7 @@ where BlockVerifierService { context_svc, tx_verifier_svc, - database, + _database: database, } } } diff --git a/consensus/src/context.rs b/consensus/src/context.rs index 8462b29ce..c6e85997e 100644 --- a/consensus/src/context.rs +++ b/consensus/src/context.rs @@ -20,7 +20,6 @@ use tokio_util::sync::PollSender; use tower::Service; use cuprate_consensus_rules::{blocks::ContextToVerifyBlock, current_unix_timestamp, HardFork}; -use cuprate_helper::asynch::InfallibleOneshotReceiver; use crate::{Database, ExtendedConsensusError}; diff --git a/consensus/src/context/task.rs b/consensus/src/context/task.rs index 7c3980a0b..39654bea6 100644 --- a/consensus/src/context/task.rs +++ b/consensus/src/context/task.rs @@ -53,7 +53,7 @@ pub struct ContextTask { impl ContextTask { /// Initialize the [`ContextTask`], this will need to pull a lot of data from the database so may take a /// while to complete. - pub async fn init_context( + pub async fn init_context( cfg: ContextConfig, mut database: D, ) -> Result diff --git a/consensus/src/transactions.rs b/consensus/src/transactions.rs index 0278982e6..80714bf26 100644 --- a/consensus/src/transactions.rs +++ b/consensus/src/transactions.rs @@ -1,7 +1,6 @@ use std::{ collections::HashSet, future::Future, - ops::Deref, pin::Pin, sync::Arc, task::{Context, Poll}, @@ -9,17 +8,15 @@ use std::{ use futures::FutureExt; use monero_serai::ringct::RctType; -use monero_serai::transaction::{Timelock, Transaction}; +use monero_serai::transaction::{Input, Timelock, Transaction}; use rayon::prelude::*; -use tokio::task::JoinSet; use tower::{Service, ServiceExt}; use tracing::instrument; -use cuprate_consensus_rules::transactions::{check_decoy_info, output_unlocked}; use cuprate_consensus_rules::{ transactions::{ - check_transaction_contextual, check_transaction_semantic, TransactionError, - TxRingMembersInfo, + check_decoy_info, check_transaction_contextual, check_transaction_semantic, + output_unlocked, TransactionError, }, ConsensusError, HardFork, TxVersion, }; @@ -190,6 +187,37 @@ where { tracing::debug!("Verifying {} transactions", txs.len()); + tracing::trace!("Checking for duplicate key images"); + + let mut spent_kis = HashSet::with_capacity(txs.len()); + + txs.iter().try_for_each(|tx| { + tx.tx.prefix.inputs.iter().try_for_each(|input| { + if let Input::ToKey { key_image, .. } = input { + if !spent_kis.insert(key_image.compress().0) { + tracing::debug!("Duplicate key image found in batch."); + return Err(ConsensusError::Transaction(TransactionError::KeyImageSpent)); + } + } + + Ok(()) + }) + })?; + + let DatabaseResponse::KeyImagesSpent(kis_spent) = database + .ready() + .await? + .call(DatabaseRequest::KeyImagesSpent(spent_kis)) + .await? + else { + panic!("Database sent incorrect response!"); + }; + + if kis_spent { + tracing::debug!("One or more key images in batch already spent."); + Err(ConsensusError::Transaction(TransactionError::KeyImageSpent))?; + } + let mut verified_at_block_hashes = txs .iter() .filter_map(|txs| txs.cached_verification_state.verified_at_block_hash()) @@ -237,43 +265,9 @@ where )?; Ok(VerifyTxResponse::Ok) - - /* - let spent_kis = Arc::new(std::sync::Mutex::new(HashSet::new())); - - let cloned_spent_kis = spent_kis.clone(); - - rayon_spawn_async(move || { - txs.par_iter().try_for_each(|tx| { - verify_transaction_for_block( - tx, - current_chain_height, - time_for_time_lock, - hf, - cloned_spent_kis, - ) - }) - }) - .await?; - - let DatabaseResponse::KeyImagesSpent(kis_spent) = database - .oneshot(DatabaseRequest::KeyImagesSpent( - Arc::into_inner(spent_kis).unwrap().into_inner().unwrap(), - )) - .await? - else { - panic!("Database sent incorrect response!"); - }; - - if kis_spent { - Err(ConsensusError::Transaction(TransactionError::KeyImageSpent))?; - } - - Ok(VerifyTxResponse::Ok) - - */ } +#[allow(clippy::type_complexity)] // I don't think the return is too complex fn transactions_needing_verification( txs: Vec>, hashes_in_main_chain: HashSet<[u8; 32]>, @@ -329,7 +323,6 @@ fn transactions_needing_verification( continue; } } - _ => (), } if tx.version == TxVersion::RingSignatures { diff --git a/consensus/src/transactions/contextual_data.rs b/consensus/src/transactions/contextual_data.rs index b9c18d6e0..784a2ad4b 100644 --- a/consensus/src/transactions/contextual_data.rs +++ b/consensus/src/transactions/contextual_data.rs @@ -12,7 +12,6 @@ //! use std::{ collections::{HashMap, HashSet}, - ops::Deref, sync::Arc, };