From 416efcb788d442e344730fa9168878d0f408b629 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Fri, 17 Jan 2025 14:58:54 -0500 Subject: [PATCH] fix key image types --- .../cuprated/src/rpc/handlers/other_json.rs | 4 +-- .../cuprated/src/rpc/service/blockchain.rs | 23 ++++++++++++++--- binaries/cuprated/src/rpc/service/txpool.rs | 25 ++++++++++++++++++- consensus/src/transactions.rs | 8 +++--- consensus/tests/verify_correct_txs.rs | 4 +-- storage/txpool/src/service/interface.rs | 20 +++++++++++++-- 6 files changed, 68 insertions(+), 16 deletions(-) diff --git a/binaries/cuprated/src/rpc/handlers/other_json.rs b/binaries/cuprated/src/rpc/handlers/other_json.rs index 0b01b14..c4c6c7b 100644 --- a/binaries/cuprated/src/rpc/handlers/other_json.rs +++ b/binaries/cuprated/src/rpc/handlers/other_json.rs @@ -306,7 +306,7 @@ async fn is_key_image_spent( let mut spent_status = Vec::with_capacity(key_images.len()); // Check the blockchain for key image spend status. - blockchain::key_images_spent(&mut state.blockchain_read, key_images.clone()) + blockchain::key_images_spent_vec(&mut state.blockchain_read, key_images.clone()) .await? .into_iter() .for_each(|ki| { @@ -332,7 +332,7 @@ async fn is_key_image_spent( // Check if the remaining unspent key images exist in the transaction pool. if !key_images.is_empty() { - txpool::key_images_spent(&mut state.txpool_read, key_images, !restricted) + txpool::key_images_spent_vec(&mut state.txpool_read, key_images, !restricted) .await? .into_iter() .for_each(|ki| { diff --git a/binaries/cuprated/src/rpc/service/blockchain.rs b/binaries/cuprated/src/rpc/service/blockchain.rs index 4f6402e..c339187 100644 --- a/binaries/cuprated/src/rpc/service/blockchain.rs +++ b/binaries/cuprated/src/rpc/service/blockchain.rs @@ -124,7 +124,7 @@ pub async fn next_chain_entry( blockchain_read: &mut BlockchainReadHandle, block_hashes: Vec<[u8; 32]>, len: usize, -) -> Result<(Vec<[u8; 32]>, Option>), Error> { +) -> Result<(Vec<[u8; 32]>, usize), Error> { let BlockchainResponse::NextChainEntry { block_ids, chain_height, @@ -274,8 +274,8 @@ pub async fn number_outputs_with_amount( /// [`BlockchainReadRequest::KeyImagesSpent`] pub async fn key_images_spent( blockchain_read: &mut BlockchainReadHandle, - key_images: Vec<[u8; 32]>, -) -> Result, Error> { + key_images: HashSet<[u8; 32]>, +) -> Result { let BlockchainResponse::KeyImagesSpent(status) = blockchain_read .ready() .await? @@ -288,6 +288,23 @@ pub async fn key_images_spent( Ok(status) } +/// [`BlockchainReadRequest::KeyImagesSpentVec`] +pub async fn key_images_spent_vec( + blockchain_read: &mut BlockchainReadHandle, + key_images: Vec<[u8; 32]>, +) -> Result, Error> { + let BlockchainResponse::KeyImagesSpentVec(status) = blockchain_read + .ready() + .await? + .call(BlockchainReadRequest::KeyImagesSpentVec(key_images)) + .await? + else { + unreachable!(); + }; + + Ok(status) +} + /// [`BlockchainReadRequest::CompactChainHistory`] pub async fn compact_chain_history( blockchain_read: &mut BlockchainReadHandle, diff --git a/binaries/cuprated/src/rpc/service/txpool.rs b/binaries/cuprated/src/rpc/service/txpool.rs index 88a75d4..b13a3fe 100644 --- a/binaries/cuprated/src/rpc/service/txpool.rs +++ b/binaries/cuprated/src/rpc/service/txpool.rs @@ -1,6 +1,6 @@ //! Functions to send [`TxpoolReadRequest`]s. -use std::{convert::Infallible, num::NonZero}; +use std::{collections::HashSet, convert::Infallible, num::NonZero}; use anyhow::{anyhow, Error}; use monero_serai::transaction::Transaction; @@ -109,6 +109,29 @@ pub async fn txs_by_hash( /// [`TxpoolReadRequest::KeyImagesSpent`] pub async fn key_images_spent( + txpool_read: &mut TxpoolReadHandle, + key_images: HashSet<[u8; 32]>, + include_sensitive_txs: bool, +) -> Result { + let TxpoolReadResponse::KeyImagesSpent(status) = txpool_read + .ready() + .await + .map_err(|e| anyhow!(e))? + .call(TxpoolReadRequest::KeyImagesSpent { + key_images, + include_sensitive_txs, + }) + .await + .map_err(|e| anyhow!(e))? + else { + unreachable!(); + }; + + Ok(status) +} + +/// [`TxpoolReadRequest::KeyImagesSpentVec`] +pub async fn key_images_spent_vec( txpool_read: &mut TxpoolReadHandle, key_images: Vec<[u8; 32]>, include_sensitive_txs: bool, diff --git a/consensus/src/transactions.rs b/consensus/src/transactions.rs index f2d2349..f29c852 100644 --- a/consensus/src/transactions.rs +++ b/consensus/src/transactions.rs @@ -232,18 +232,16 @@ where }) })?; - let BlockchainResponse::KeyImagesSpent(kis_status) = database + let BlockchainResponse::KeyImagesSpent(kis_spent) = database .ready() .await? - .call(BlockchainReadRequest::KeyImagesSpent( - spent_kis.into_iter().collect(), - )) + .call(BlockchainReadRequest::KeyImagesSpent(spent_kis)) .await? else { panic!("Database sent incorrect response!"); }; - if kis_status.contains(&true) { + if kis_spent { tracing::debug!("One or more key images in batch already spent."); return Err(ConsensusError::Transaction(TransactionError::KeyImageSpent).into()); } diff --git a/consensus/tests/verify_correct_txs.rs b/consensus/tests/verify_correct_txs.rs index 14ba379..1fca804 100644 --- a/consensus/tests/verify_correct_txs.rs +++ b/consensus/tests/verify_correct_txs.rs @@ -45,9 +45,7 @@ fn dummy_database(outputs: BTreeMap) -> impl Database + Clon BlockchainResponse::Outputs(ret) } - BlockchainReadRequest::KeyImagesSpent(_) => { - BlockchainResponse::KeyImagesSpent(vec![false]) - } + BlockchainReadRequest::KeyImagesSpent(_) => BlockchainResponse::KeyImagesSpent(false), _ => panic!("Database request not needed for this test"), })) }) diff --git a/storage/txpool/src/service/interface.rs b/storage/txpool/src/service/interface.rs index 18d6e08..97a5292 100644 --- a/storage/txpool/src/service/interface.rs +++ b/storage/txpool/src/service/interface.rs @@ -62,8 +62,16 @@ pub enum TxpoolReadRequest { include_sensitive_txs: bool, }, - /// Check if certain key images exist in the txpool. + /// Check if any individual key images of a set exist in the txpool. KeyImagesSpent { + key_images: HashSet<[u8; 32]>, + include_sensitive_txs: bool, + }, + + /// Same as [`TxpoolReadRequest::KeyImagesSpent`] but with a [`Vec`]. + /// + /// The response will be in the same order as the request. + KeyImagesSpentVec { key_images: Vec<[u8; 32]>, include_sensitive_txs: bool, }, @@ -123,7 +131,15 @@ pub enum TxpoolReadResponse { TxsByHash(Vec), /// Response to [`TxpoolReadRequest::KeyImagesSpent`]. - KeyImagesSpent(Vec), + KeyImagesSpent(bool), + + /// Response to [`TxpoolReadRequest::KeyImagesSpentVec`]. + /// + /// Inner value is a `Vec` the same length as the input. + /// + /// The index of each entry corresponds with the request. + /// `true` means that the key image was spent. + KeyImagesSpentVec(Vec), /// Response to [`TxpoolReadRequest::Pool`]. Pool {