From 789dec673ece58e10862c03d83b56b09e027a2e3 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Thu, 10 Jul 2025 11:35:46 -0300 Subject: [PATCH 1/8] remove hash attribute from Transaction and use a method instead --- .../src/merkle_tree_public/tree_leav_item.rs | 2 +- common/src/transaction.rs | 21 ++++++------ node_core/src/chain_storage/mod.rs | 1 - sequencer_core/src/lib.rs | 33 ++++++++----------- sequencer_core/src/transaction_mempool.rs | 2 +- 5 files changed, 26 insertions(+), 33 deletions(-) diff --git a/common/src/merkle_tree_public/tree_leav_item.rs b/common/src/merkle_tree_public/tree_leav_item.rs index deecaf7..1fbbb1a 100644 --- a/common/src/merkle_tree_public/tree_leav_item.rs +++ b/common/src/merkle_tree_public/tree_leav_item.rs @@ -8,7 +8,7 @@ pub trait TreeLeavItem { impl TreeLeavItem for Transaction { fn hash(&self) -> TreeHashType { - self.hash + self.hash() } } diff --git a/common/src/transaction.rs b/common/src/transaction.rs index 1a95fe3..5d115c4 100644 --- a/common/src/transaction.rs +++ b/common/src/transaction.rs @@ -26,7 +26,6 @@ pub enum TxKind { #[derive(Debug, Serialize, Deserialize, Clone)] ///General transaction object pub struct Transaction { - pub hash: TreeHashType, pub tx_kind: TxKind, ///Tx input data (public part) pub execution_input: Vec, @@ -58,6 +57,15 @@ pub struct Transaction { pub state_changes: (serde_json::Value, usize), } +impl Transaction { + pub fn hash(&self) -> TreeHashType { + let raw_data = serde_json::to_vec(&self).unwrap(); + let mut hasher = sha2::Sha256::new(); + hasher.update(&raw_data); + TreeHashType::from(hasher.finalize_fixed()) + } +} + #[derive(Debug, Serialize, Deserialize, Clone)] ///General transaction object pub struct TransactionPayload { @@ -94,16 +102,7 @@ pub struct TransactionPayload { impl From for Transaction { fn from(value: TransactionPayload) -> Self { - let raw_data = serde_json::to_vec(&value).unwrap(); - - let mut hasher = sha2::Sha256::new(); - - hasher.update(&raw_data); - - let hash = ::from(hasher.finalize_fixed()); - Self { - hash, tx_kind: value.tx_kind, execution_input: value.execution_input, execution_output: value.execution_output, @@ -217,7 +216,7 @@ impl ActionData { impl Transaction { pub fn log(&self) { - info!("Transaction hash is {:?}", hex::encode(self.hash)); + info!("Transaction hash is {:?}", hex::encode(self.hash())); info!("Transaction tx_kind is {:?}", self.tx_kind); info!("Transaction execution_input is {:?}", { if let Ok(action) = serde_json::from_slice::(&self.execution_input) { diff --git a/node_core/src/chain_storage/mod.rs b/node_core/src/chain_storage/mod.rs index f6b1343..3f61393 100644 --- a/node_core/src/chain_storage/mod.rs +++ b/node_core/src/chain_storage/mod.rs @@ -304,7 +304,6 @@ mod tests { let mut rng = rand::thread_rng(); Transaction { - hash, tx_kind: TxKind::Private, execution_input: vec![], execution_output: vec![], diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index 7a083f1..cb22626 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -75,7 +75,6 @@ impl SequencerCore { tx_roots: [[u8; 32]; 2], ) -> Result<(), TransactionMalformationErrorKind> { let Transaction { - hash, tx_kind, ref execution_input, ref execution_output, @@ -87,7 +86,7 @@ impl SequencerCore { let mempool_size = self.mempool.len(); if mempool_size >= self.sequencer_config.max_num_tx_in_block { - return Err(TransactionMalformationErrorKind::MempoolFullForRound { tx: *hash }); + return Err(TransactionMalformationErrorKind::MempoolFullForRound { tx: tx.hash() }); } let curr_sequencer_roots = self.get_tree_roots(); @@ -95,7 +94,7 @@ impl SequencerCore { if tx_roots != curr_sequencer_roots { return Err( TransactionMalformationErrorKind::ChainStateFurtherThanTransactionState { - tx: *hash, + tx: tx.hash(), }, ); } @@ -109,7 +108,7 @@ impl SequencerCore { //Public transactions can not make private operations. return Err( TransactionMalformationErrorKind::PublicTransactionChangedPrivateData { - tx: *hash, + tx: tx.hash(), }, ); } @@ -121,7 +120,7 @@ impl SequencerCore { //between public and private state. return Err( TransactionMalformationErrorKind::PrivateTransactionChangedPublicData { - tx: *hash, + tx: tx.hash(), }, ); } @@ -130,7 +129,7 @@ impl SequencerCore { }; //Tree checks - let tx_tree_check = self.store.pub_tx_store.get_tx(*hash).is_some(); + let tx_tree_check = self.store.pub_tx_store.get_tx(tx.hash()).is_some(); let nullifier_tree_check = nullifier_created_hashes .iter() .map(|nullifier_hash| { @@ -150,18 +149,18 @@ impl SequencerCore { .any(|check| check); if tx_tree_check { - return Err(TransactionMalformationErrorKind::TxHashAlreadyPresentInTree { tx: *hash }); + return Err(TransactionMalformationErrorKind::TxHashAlreadyPresentInTree { tx: tx.hash() }); } if nullifier_tree_check { return Err( - TransactionMalformationErrorKind::NullifierAlreadyPresentInTree { tx: *hash }, + TransactionMalformationErrorKind::NullifierAlreadyPresentInTree { tx: tx.hash() }, ); } if utxo_commitments_check { return Err( - TransactionMalformationErrorKind::UTXOCommitmentAlreadyPresentInTree { tx: *hash }, + TransactionMalformationErrorKind::UTXOCommitmentAlreadyPresentInTree { tx: tx.hash() }, ); } @@ -185,8 +184,6 @@ impl SequencerCore { tx: TransactionMempool, ) -> Result<(), TransactionMalformationErrorKind> { let Transaction { - // ToDo: remove hashing of transactions on node side [Issue #66] - hash: _, ref utxo_commitments_created_hashes, ref nullifier_created_hashes, .. @@ -280,7 +277,6 @@ mod tests { } fn create_dummy_transaction( - hash: TreeHashType, nullifier_created_hashes: Vec<[u8; 32]>, utxo_commitments_spent_hashes: Vec<[u8; 32]>, utxo_commitments_created_hashes: Vec<[u8; 32]>, @@ -288,7 +284,6 @@ mod tests { let mut rng = rand::thread_rng(); Transaction { - hash, tx_kind: TxKind::Private, execution_input: vec![], execution_output: vec![], @@ -306,8 +301,8 @@ mod tests { } } - fn common_setup(mut sequencer: &mut SequencerCore) { - let tx = create_dummy_transaction([12; 32], vec![[9; 32]], vec![[7; 32]], vec![[8; 32]]); + fn common_setup(sequencer: &mut SequencerCore) { + let tx = create_dummy_transaction(vec![[9; 32]], vec![[7; 32]], vec![[8; 32]]); let tx_mempool = TransactionMempool { tx }; sequencer.mempool.push_item(tx_mempool); @@ -342,7 +337,7 @@ mod tests { common_setup(&mut sequencer); - let tx = create_dummy_transaction([1; 32], vec![[91; 32]], vec![[71; 32]], vec![[81; 32]]); + let tx = create_dummy_transaction(vec![[91; 32]], vec![[71; 32]], vec![[81; 32]]); let tx_roots = sequencer.get_tree_roots(); let result = sequencer.transaction_pre_check(&tx, tx_roots); @@ -359,7 +354,7 @@ mod tests { common_setup(&mut sequencer); - let tx = create_dummy_transaction([2; 32], vec![[92; 32]], vec![[72; 32]], vec![[82; 32]]); + let tx = create_dummy_transaction(vec![[92; 32]], vec![[72; 32]], vec![[82; 32]]); let tx_roots = sequencer.get_tree_roots(); // Fill the mempool @@ -381,7 +376,7 @@ mod tests { common_setup(&mut sequencer); - let tx = create_dummy_transaction([3; 32], vec![[93; 32]], vec![[73; 32]], vec![[83; 32]]); + let tx = create_dummy_transaction(vec![[93; 32]], vec![[73; 32]], vec![[83; 32]]); let tx_roots = sequencer.get_tree_roots(); let tx_mempool = TransactionMempool { tx }; @@ -395,7 +390,7 @@ mod tests { let config = setup_sequencer_config(); let mut sequencer = SequencerCore::start_from_config(config); - let tx = create_dummy_transaction([4; 32], vec![[94; 32]], vec![[7; 32]], vec![[8; 32]]); + let tx = create_dummy_transaction(vec![[94; 32]], vec![[7; 32]], vec![[8; 32]]); let tx_mempool = TransactionMempool { tx }; sequencer.mempool.push_item(tx_mempool); diff --git a/sequencer_core/src/transaction_mempool.rs b/sequencer_core/src/transaction_mempool.rs index 8c0d720..d932b24 100644 --- a/sequencer_core/src/transaction_mempool.rs +++ b/sequencer_core/src/transaction_mempool.rs @@ -38,6 +38,6 @@ impl MemPoolItem for TransactionMempool { type Identifier = TreeHashType; fn identifier(&self) -> Self::Identifier { - self.tx.hash + self.tx.hash() } } From 16e3a682fe450a30db70f4cd7784eb73ad36ef83 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Thu, 10 Jul 2025 12:09:01 -0300 Subject: [PATCH 2/8] add test for hash function --- common/src/transaction.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/common/src/transaction.rs b/common/src/transaction.rs index 5d115c4..efe55ba 100644 --- a/common/src/transaction.rs +++ b/common/src/transaction.rs @@ -266,3 +266,41 @@ impl Transaction { ); } } + +#[cfg(test)] +mod tests { + use secp256k1_zkp::{constants::SECRET_KEY_SIZE, Tweak}; + use sha2::{digest::FixedOutput, Digest}; + + use crate::{merkle_tree_public::TreeHashType, transaction::{Transaction, TxKind}}; + + #[test] + fn test_transaction_hash_is_sha256_of_json_bytes() { + let tx = Transaction { + tx_kind: TxKind::Public, + execution_input: vec![1, 2, 3, 4], + execution_output: vec![5, 6, 7, 8], + utxo_commitments_spent_hashes: vec![[9; 32], [10; 32], [11; 32], [12; 32]], + utxo_commitments_created_hashes: vec![[13; 32]], + nullifier_created_hashes: vec![[0; 32], [1; 32], [2; 32], [3; 32]], + execution_proof_private: "loremipsum".to_string(), + encoded_data: vec![(vec![255,255,255], vec![254, 254, 254], 1)], + ephemeral_pub_key: vec![5; 32], + commitment: vec![], + tweak: Tweak::from_slice(&[7; SECRET_KEY_SIZE]).unwrap(), + secret_r: [8; 32], + sc_addr: "someAddress".to_string(), + state_changes: (serde_json::Value::Null, 10), + }; + let expected_hash = { + let data = serde_json::to_vec(&tx).unwrap(); + let mut hasher = sha2::Sha256::new(); + hasher.update(&data); + TreeHashType::from(hasher.finalize_fixed()) + }; + + let hash = tx.hash(); + + assert_eq!(expected_hash, hash); + } +} \ No newline at end of file From e1e018fcfc3216a0ffadfeb08c13edef4616013a Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Thu, 10 Jul 2025 12:13:36 -0300 Subject: [PATCH 3/8] remove redundant TransactionPayload struct --- common/src/transaction.rs | 54 ----------------------- node_core/src/lib.rs | 16 +++---- sc_core/src/transaction_payloads_tools.rs | 6 +-- 3 files changed, 11 insertions(+), 65 deletions(-) diff --git a/common/src/transaction.rs b/common/src/transaction.rs index efe55ba..0c43521 100644 --- a/common/src/transaction.rs +++ b/common/src/transaction.rs @@ -66,60 +66,6 @@ impl Transaction { } } -#[derive(Debug, Serialize, Deserialize, Clone)] -///General transaction object -pub struct TransactionPayload { - pub tx_kind: TxKind, - ///Tx input data (public part) - pub execution_input: Vec, - ///Tx output data (public_part) - pub execution_output: Vec, - ///Tx input utxo commitments - pub utxo_commitments_spent_hashes: Vec, - ///Tx output utxo commitments - pub utxo_commitments_created_hashes: Vec, - ///Tx output nullifiers - pub nullifier_created_hashes: Vec, - ///Execution proof (private part) - pub execution_proof_private: String, - ///Encoded blobs of data - pub encoded_data: Vec<(CipherText, Vec, Tag)>, - ///Transaction senders ephemeral pub key - pub ephemeral_pub_key: Vec, - ///Public (Pedersen) commitment - pub commitment: Vec, - ///tweak - pub tweak: Tweak, - ///secret_r - pub secret_r: [u8; 32], - ///Hex-encoded address of a smart contract account called - pub sc_addr: String, - ///Recorded changes in state of smart contract - /// - /// First value represents vector of changes, second is new length of a state - pub state_changes: (serde_json::Value, usize), -} - -impl From for Transaction { - fn from(value: TransactionPayload) -> Self { - Self { - tx_kind: value.tx_kind, - execution_input: value.execution_input, - execution_output: value.execution_output, - utxo_commitments_spent_hashes: value.utxo_commitments_spent_hashes, - utxo_commitments_created_hashes: value.utxo_commitments_created_hashes, - nullifier_created_hashes: value.nullifier_created_hashes, - execution_proof_private: value.execution_proof_private, - encoded_data: value.encoded_data, - ephemeral_pub_key: value.ephemeral_pub_key, - commitment: value.commitment, - tweak: value.tweak, - secret_r: value.secret_r, - sc_addr: value.sc_addr, - state_changes: value.state_changes, - } - } -} #[derive(Debug, Serialize, Deserialize)] pub struct MintMoneyPublicTx { diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index 49f1285..73775eb 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -8,7 +8,7 @@ use common::ExecutionFailureKind; use accounts::account_core::{Account, AccountAddress}; use anyhow::Result; use chain_storage::NodeChainStore; -use common::transaction::{Transaction, TransactionPayload, TxKind}; +use common::transaction::{Transaction, TxKind}; use config::NodeConfig; use log::info; use sc_core::proofs_circuits::{ @@ -246,7 +246,7 @@ impl NodeCore { let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); Ok(( - TransactionPayload { + Transaction { tx_kind: TxKind::Private, execution_input: vec![], execution_output: vec![], @@ -343,7 +343,7 @@ impl NodeCore { let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); Ok(( - TransactionPayload { + Transaction { tx_kind: TxKind::Private, execution_input: vec![], execution_output: vec![], @@ -459,7 +459,7 @@ impl NodeCore { let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); Ok(( - TransactionPayload { + Transaction { tx_kind: TxKind::Private, execution_input: vec![], execution_output: vec![], @@ -604,7 +604,7 @@ impl NodeCore { let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); Ok(( - TransactionPayload { + Transaction { tx_kind: TxKind::Private, execution_input: vec![], execution_output: vec![], @@ -727,7 +727,7 @@ impl NodeCore { let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); Ok(( - TransactionPayload { + Transaction { tx_kind: TxKind::Shielded, execution_input: serde_json::to_vec(&ActionData::SendMoneyShieldedTx( SendMoneyShieldedTx { @@ -820,7 +820,7 @@ impl NodeCore { let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); - Ok(TransactionPayload { + Ok(Transaction { tx_kind: TxKind::Deshielded, execution_input: serde_json::to_vec(&ActionData::SendMoneyDeshieldedTx( SendMoneyDeshieldedTx { @@ -1459,7 +1459,7 @@ impl NodeCore { let (tweak, secret_r, commitment) = pedersen_commitment_vec(vec_public_info); Ok(( - TransactionPayload { + Transaction { tx_kind: TxKind::Shielded, execution_input: vec![], execution_output: serde_json::to_vec(&publication).unwrap(), diff --git a/sc_core/src/transaction_payloads_tools.rs b/sc_core/src/transaction_payloads_tools.rs index 24ad8f2..4846be1 100644 --- a/sc_core/src/transaction_payloads_tools.rs +++ b/sc_core/src/transaction_payloads_tools.rs @@ -1,6 +1,6 @@ use accounts::account_core::Account; use anyhow::Result; -use common::transaction::{TransactionPayload, TxKind}; +use common::transaction::{Transaction, TxKind}; use rand::thread_rng; use risc0_zkvm::Receipt; use secp256k1_zkp::{CommitmentSecrets, PedersenCommitment, Tweak}; @@ -15,8 +15,8 @@ pub fn create_public_transaction_payload( secret_r: [u8; 32], sc_addr: String, state_changes: (serde_json::Value, usize), -) -> TransactionPayload { - TransactionPayload { +) -> Transaction { + Transaction { tx_kind: TxKind::Public, execution_input, execution_output: vec![], From f01be72d8fb152caf5a2484ccc2c2d4af3280f13 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Thu, 10 Jul 2025 12:15:37 -0300 Subject: [PATCH 4/8] move impl of hash to existing impl Transaction block --- common/src/transaction.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/common/src/transaction.rs b/common/src/transaction.rs index 0c43521..a02b692 100644 --- a/common/src/transaction.rs +++ b/common/src/transaction.rs @@ -57,16 +57,6 @@ pub struct Transaction { pub state_changes: (serde_json::Value, usize), } -impl Transaction { - pub fn hash(&self) -> TreeHashType { - let raw_data = serde_json::to_vec(&self).unwrap(); - let mut hasher = sha2::Sha256::new(); - hasher.update(&raw_data); - TreeHashType::from(hasher.finalize_fixed()) - } -} - - #[derive(Debug, Serialize, Deserialize)] pub struct MintMoneyPublicTx { pub acc: [u8; 32], @@ -161,6 +151,13 @@ impl ActionData { } impl Transaction { + pub fn hash(&self) -> TreeHashType { + let raw_data = serde_json::to_vec(&self).unwrap(); + let mut hasher = sha2::Sha256::new(); + hasher.update(&raw_data); + TreeHashType::from(hasher.finalize_fixed()) + } + pub fn log(&self) { info!("Transaction hash is {:?}", hex::encode(self.hash())); info!("Transaction tx_kind is {:?}", self.tx_kind); From b16575b407f3fb0c86b03109f35a2a13e50dee14 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Thu, 10 Jul 2025 12:16:05 -0300 Subject: [PATCH 5/8] fmt --- common/src/transaction.rs | 9 ++++++--- sequencer_core/src/lib.rs | 8 ++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/common/src/transaction.rs b/common/src/transaction.rs index a02b692..e5056f5 100644 --- a/common/src/transaction.rs +++ b/common/src/transaction.rs @@ -215,7 +215,10 @@ mod tests { use secp256k1_zkp::{constants::SECRET_KEY_SIZE, Tweak}; use sha2::{digest::FixedOutput, Digest}; - use crate::{merkle_tree_public::TreeHashType, transaction::{Transaction, TxKind}}; + use crate::{ + merkle_tree_public::TreeHashType, + transaction::{Transaction, TxKind}, + }; #[test] fn test_transaction_hash_is_sha256_of_json_bytes() { @@ -227,7 +230,7 @@ mod tests { utxo_commitments_created_hashes: vec![[13; 32]], nullifier_created_hashes: vec![[0; 32], [1; 32], [2; 32], [3; 32]], execution_proof_private: "loremipsum".to_string(), - encoded_data: vec![(vec![255,255,255], vec![254, 254, 254], 1)], + encoded_data: vec![(vec![255, 255, 255], vec![254, 254, 254], 1)], ephemeral_pub_key: vec![5; 32], commitment: vec![], tweak: Tweak::from_slice(&[7; SECRET_KEY_SIZE]).unwrap(), @@ -246,4 +249,4 @@ mod tests { assert_eq!(expected_hash, hash); } -} \ No newline at end of file +} diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index cb22626..9946504 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -149,7 +149,9 @@ impl SequencerCore { .any(|check| check); if tx_tree_check { - return Err(TransactionMalformationErrorKind::TxHashAlreadyPresentInTree { tx: tx.hash() }); + return Err( + TransactionMalformationErrorKind::TxHashAlreadyPresentInTree { tx: tx.hash() }, + ); } if nullifier_tree_check { @@ -160,7 +162,9 @@ impl SequencerCore { if utxo_commitments_check { return Err( - TransactionMalformationErrorKind::UTXOCommitmentAlreadyPresentInTree { tx: tx.hash() }, + TransactionMalformationErrorKind::UTXOCommitmentAlreadyPresentInTree { + tx: tx.hash(), + }, ); } From 81b6d3469388fbebcc9ccce36d43d2c1fc20b920 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Thu, 10 Jul 2025 12:52:48 -0300 Subject: [PATCH 6/8] add Transaction::hash inline docs --- common/src/transaction.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/common/src/transaction.rs b/common/src/transaction.rs index e5056f5..cb86661 100644 --- a/common/src/transaction.rs +++ b/common/src/transaction.rs @@ -151,6 +151,7 @@ impl ActionData { } impl Transaction { + /// Computes and returns the SHA-256 hash of the JSON-serialized representation of `self`. pub fn hash(&self) -> TreeHashType { let raw_data = serde_json::to_vec(&self).unwrap(); let mut hasher = sha2::Sha256::new(); From e286108bb5afcefc0d0cb42e0e367cabb8e0c5ee Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Thu, 10 Jul 2025 13:00:27 -0300 Subject: [PATCH 7/8] add TODO to remove unwrap --- common/src/transaction.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/src/transaction.rs b/common/src/transaction.rs index cb86661..3f2dcb2 100644 --- a/common/src/transaction.rs +++ b/common/src/transaction.rs @@ -153,6 +153,9 @@ impl ActionData { impl Transaction { /// Computes and returns the SHA-256 hash of the JSON-serialized representation of `self`. pub fn hash(&self) -> TreeHashType { + // TODO: Remove `unwrap` by implementing a `to_bytes` method + // that deterministically encodes all transaction fields to bytes + // and guarantees serialization will succeed. let raw_data = serde_json::to_vec(&self).unwrap(); let mut hasher = sha2::Sha256::new(); hasher.update(&raw_data); From b49f38ca4b2d3274018085d5a71d37bc4c0e0ba2 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Thu, 10 Jul 2025 14:35:41 -0300 Subject: [PATCH 8/8] avoid computing hash multiple times in transaction_pre_check --- sequencer_core/src/lib.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index 9946504..f2890ed 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -82,11 +82,12 @@ impl SequencerCore { ref nullifier_created_hashes, .. } = tx; + let tx_hash = tx.hash(); let mempool_size = self.mempool.len(); if mempool_size >= self.sequencer_config.max_num_tx_in_block { - return Err(TransactionMalformationErrorKind::MempoolFullForRound { tx: tx.hash() }); + return Err(TransactionMalformationErrorKind::MempoolFullForRound { tx: tx_hash }); } let curr_sequencer_roots = self.get_tree_roots(); @@ -94,7 +95,7 @@ impl SequencerCore { if tx_roots != curr_sequencer_roots { return Err( TransactionMalformationErrorKind::ChainStateFurtherThanTransactionState { - tx: tx.hash(), + tx: tx_hash, }, ); } @@ -108,7 +109,7 @@ impl SequencerCore { //Public transactions can not make private operations. return Err( TransactionMalformationErrorKind::PublicTransactionChangedPrivateData { - tx: tx.hash(), + tx: tx_hash, }, ); } @@ -120,7 +121,7 @@ impl SequencerCore { //between public and private state. return Err( TransactionMalformationErrorKind::PrivateTransactionChangedPublicData { - tx: tx.hash(), + tx: tx_hash, }, ); } @@ -129,7 +130,7 @@ impl SequencerCore { }; //Tree checks - let tx_tree_check = self.store.pub_tx_store.get_tx(tx.hash()).is_some(); + let tx_tree_check = self.store.pub_tx_store.get_tx(tx_hash).is_some(); let nullifier_tree_check = nullifier_created_hashes .iter() .map(|nullifier_hash| {