From 4ba94f4bb7f58e30cb64d51baa9581b4985ce639 Mon Sep 17 00:00:00 2001 From: Boog900 <54e72d8a-345f-4599-bd90-c6b9bc7d0ec5@aleeas.com> Date: Sun, 13 Oct 2024 01:50:48 +0100 Subject: [PATCH] Add tx blob hash table --- Cargo.lock | 1 + storage/txpool/Cargo.toml | 1 + storage/txpool/src/free.rs | 16 +++++++++++++++- storage/txpool/src/ops/tx_write.rs | 9 +++++++++ storage/txpool/src/service/interface.rs | 7 ++----- storage/txpool/src/tables.rs | 10 ++++++++-- 6 files changed, 36 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5e597f8..6742abe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -910,6 +910,7 @@ dependencies = [ "monero-serai", "rayon", "serde", + "sha3", "tempfile", "thiserror", "tokio", diff --git a/storage/txpool/Cargo.toml b/storage/txpool/Cargo.toml index 70211d9..923060e 100644 --- a/storage/txpool/Cargo.toml +++ b/storage/txpool/Cargo.toml @@ -29,6 +29,7 @@ bytemuck = { workspace = true, features = ["must_cast", "derive" bitflags = { workspace = true, features = ["std", "serde", "bytemuck"] } thiserror = { workspace = true } hex = { workspace = true } +sha3 = { workspace = true, features = ["std"] } tower = { workspace = true, optional = true } rayon = { workspace = true, optional = true } diff --git a/storage/txpool/src/free.rs b/storage/txpool/src/free.rs index d394002..e04e350 100644 --- a/storage/txpool/src/free.rs +++ b/storage/txpool/src/free.rs @@ -1,9 +1,11 @@ //! General free functions (related to the tx-pool database). //---------------------------------------------------------------------------------------------------- Import +use sha3::{Digest, Sha3_256}; + use cuprate_database::{ConcreteEnv, Env, EnvInner, InitError, RuntimeError, TxRw}; -use crate::{config::Config, tables::OpenTables}; +use crate::{config::Config, tables::OpenTables, types::TransactionBlobHash}; //---------------------------------------------------------------------------------------------------- Free functions /// Open the txpool database using the passed [`Config`]. @@ -60,3 +62,15 @@ pub fn open(config: Config) -> Result { Ok(env) } + +/// Calculate the transaction blob hash. +/// +/// This value is supposed to be quick to compute just based of the tx-blob without needing to parse the tx. +/// +/// The exact way the hash is calculated is not stable and is subject to change, as such it should not be exposed +/// as a way to interact with Cuprate externally. +pub fn transaction_blob_hash(tx_blob: &[u8]) -> TransactionBlobHash { + let mut hasher = Sha3_256::new(); + hasher.update(tx_blob); + hasher.finalize().into() +} diff --git a/storage/txpool/src/ops/tx_write.rs b/storage/txpool/src/ops/tx_write.rs index 9885b9c..7b3b9a6 100644 --- a/storage/txpool/src/ops/tx_write.rs +++ b/storage/txpool/src/ops/tx_write.rs @@ -8,6 +8,7 @@ use cuprate_database::{DatabaseRw, RuntimeError, StorableVec}; use cuprate_types::TransactionVerificationData; use crate::{ + free::transaction_blob_hash, ops::{ key_images::{add_tx_key_images, remove_tx_key_images}, TxPoolWriteError, @@ -56,6 +57,10 @@ pub fn add_transaction( let kis_table = tables.spent_key_images_mut(); add_tx_key_images(&tx.tx.prefix().inputs, &tx.tx_hash, kis_table)?; + // Add the blob hash to table 4. + let blob_hash = transaction_blob_hash(&tx.tx_blob); + tables.known_blob_hashes_mut().put(&blob_hash, &())?; + Ok(()) } @@ -79,5 +84,9 @@ pub fn remove_transaction( let kis_table = tables.spent_key_images_mut(); remove_tx_key_images(&tx.prefix().inputs, kis_table)?; + // Remove the blob hash from table 4. + let blob_hash = transaction_blob_hash(&tx_blob); + tables.known_blob_hashes_mut().delete(&blob_hash)?; + Ok(()) } diff --git a/storage/txpool/src/service/interface.rs b/storage/txpool/src/service/interface.rs index cfcd8da..a5d6634 100644 --- a/storage/txpool/src/service/interface.rs +++ b/storage/txpool/src/service/interface.rs @@ -16,7 +16,7 @@ pub enum TxpoolReadRequest { /// A request for the [`TransactionVerificationData`] of a transaction in the tx pool. TxVerificationData(TransactionHash), /// A request to filter (remove) all **known** transactions from the set. - /// + /// /// The hash is **not** the transaction hash, it is the hash of the serialized tx-blob. FilterKnownTxBlobHashes(HashSet), } @@ -26,10 +26,7 @@ pub enum TxpoolReadRequest { #[expect(clippy::large_enum_variant)] pub enum TxpoolReadResponse { /// A response containing the raw bytes of a transaction. - TxBlob { - tx_blob: Vec, - state_stem: bool, - }, + TxBlob { tx_blob: Vec, state_stem: bool }, /// A response of [`TransactionVerificationData`]. TxVerificationData(TransactionVerificationData), /// The response for [`TxpoolReadRequest::FilterKnownTxBlobHashes`]. diff --git a/storage/txpool/src/tables.rs b/storage/txpool/src/tables.rs index dbb686a..2ab3262 100644 --- a/storage/txpool/src/tables.rs +++ b/storage/txpool/src/tables.rs @@ -16,7 +16,9 @@ //! accessing _all_ tables defined here at once. use cuprate_database::{define_tables, StorableVec}; -use crate::types::{KeyImage, RawCachedVerificationState, TransactionHash, TransactionInfo}; +use crate::types::{ + KeyImage, RawCachedVerificationState, TransactionBlobHash, TransactionHash, TransactionInfo, +}; define_tables! { /// Serialized transaction blobs. @@ -41,5 +43,9 @@ define_tables! { /// /// This table contains the spent key images from all transactions in the pool. 3 => SpentKeyImages, - KeyImage => TransactionHash + KeyImage => TransactionHash, + + /// Transaction blob hashes that are in the pool. + 4 => KnownBlobHashes, + TransactionBlobHash => (), }