diff --git a/src/eth/executor/evm_input.rs b/src/eth/executor/evm_input.rs index 54a3e80d2..4a8bc6294 100644 --- a/src/eth/executor/evm_input.rs +++ b/src/eth/executor/evm_input.rs @@ -157,3 +157,16 @@ impl EvmInput { self.to.is_some() && not(self.data.is_empty()) } } + +impl PartialEq<(&TransactionInput, &PendingBlockHeader)> for EvmInput { + fn eq(&self, other: &(&TransactionInput, &PendingBlockHeader)) -> bool { + self.block_number == other.1.number + && self.block_timestamp == *other.1.timestamp + && self.chain_id == other.0.chain_id + && self.data == other.0.input + && self.from == other.0.signer + && self.nonce.is_some_and(|inner| inner == other.0.nonce) + && self.value == other.0.value + && self.to == other.0.to + } +} diff --git a/src/eth/storage/temporary/inmemory.rs b/src/eth/storage/temporary/inmemory.rs index 015628eef..995c54f7f 100644 --- a/src/eth/storage/temporary/inmemory.rs +++ b/src/eth/storage/temporary/inmemory.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use parking_lot::RwLock; +use parking_lot::RwLockUpgradableReadGuard; use crate::eth::executor::EvmInput; use crate::eth::primitives::Account; @@ -121,11 +122,10 @@ impl TemporaryStorage for InMemoryTemporaryStorage { fn save_pending_execution(&self, tx: TransactionExecution, check_conflicts: bool) -> Result<(), StratusError> { // check conflicts - let mut pending_block = self.pending_block.write(); + let pending_block = self.pending_block.upgradable_read(); if let TransactionExecution::Local(tx) = &tx { - let expected_input = EvmInput::from_eth_transaction(&tx.input, &pending_block.block.header); - - if expected_input != tx.evm_input { + if tx.evm_input != (&tx.input, &pending_block.block.header) { + let expected_input = EvmInput::from_eth_transaction(&tx.input, &pending_block.block.header); return Err(StratusError::TransactionEvmInputMismatch { expected: Box::new(expected_input), actual: Box::new(tx.evm_input.clone()), @@ -133,6 +133,8 @@ impl TemporaryStorage for InMemoryTemporaryStorage { } } + let mut pending_block = RwLockUpgradableReadGuard::::upgrade(pending_block); + if check_conflicts { if let Some(conflicts) = self.check_conflicts(tx.execution())? { return Err(StratusError::TransactionConflict(conflicts.into()));