From 250cdeeae8a24758b219afdaab321644fef943be Mon Sep 17 00:00:00 2001 From: parazyd Date: Sat, 30 Apr 2022 20:50:17 +0200 Subject: [PATCH] consensus/proto/tx: Don't act on state transitions if the tx is known. --- src/blockchain/txstore.rs | 5 +++++ src/consensus/proto/protocol_tx.rs | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/blockchain/txstore.rs b/src/blockchain/txstore.rs index 53b36e0ad..e9c07fe0f 100644 --- a/src/blockchain/txstore.rs +++ b/src/blockchain/txstore.rs @@ -35,6 +35,11 @@ impl TxStore { Ok(ret) } + /// Check if the txstore contains a given transaction. + pub fn contains(&self, txid: blake3::Hash) -> Result { + Ok(self.0.contains_key(txid.as_bytes())?) + } + /// Fetch requested transactions from the txstore. The `strict` param /// will make the function fail if a transaction has not been found. pub fn get(&self, tx_hashes: &[blake3::Hash], strict: bool) -> Result>> { diff --git a/src/consensus/proto/protocol_tx.rs b/src/consensus/proto/protocol_tx.rs index 92b46f536..eee6e46dc 100644 --- a/src/consensus/proto/protocol_tx.rs +++ b/src/consensus/proto/protocol_tx.rs @@ -10,6 +10,7 @@ use crate::{ ProtocolJobsManager, ProtocolJobsManagerPtr, }, node::MemoryState, + util::serial::serialize, Result, }; @@ -54,6 +55,21 @@ impl ProtocolTx { debug!("ProtocolTx::handle_receive_tx() recv: {:?}", tx); let tx_copy = (*tx).clone(); + let tx_hash = blake3::hash(&serialize(&tx_copy)); + + let tx_in_txstore = + match self.state.read().await.blockchain.transactions.contains(tx_hash) { + Ok(v) => v, + Err(e) => { + error!("handle_receive_tx(): Failed querying txstore: {}", e); + continue + } + }; + + if self.state.read().await.unconfirmed_txs.contains(&tx_copy) || tx_in_txstore { + debug!("ProtocolTx::handle_receive_tx(): We have already seen this tx."); + continue + } debug!("ProtocolTx::handle_receive_tx(): Starting state transition validation"); let canon_state_clone = self.state.read().await.state_machine.lock().await.clone();