diff --git a/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs b/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs index 5b17f0ccb60..ee59bc99ace 100644 --- a/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs +++ b/src/Nethermind/Nethermind.AuRa.Test/Contract/TxPriorityContractTests.cs @@ -59,6 +59,7 @@ public async Task mingas_empty_after_init() } [Test] + [Retry(3)] public async Task whitelist_should_return_correctly() { using TxPermissionContractBlockchainWithBlocks chain = await TestContractBlockchain.ForTest(); diff --git a/src/Nethermind/Nethermind.Consensus/Processing/OverridableTxProcessingEnv.cs b/src/Nethermind/Nethermind.Consensus/Processing/OverridableTxProcessingEnv.cs index eed81454245..d39a8700f6e 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/OverridableTxProcessingEnv.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/OverridableTxProcessingEnv.cs @@ -51,17 +51,12 @@ protected virtual ITransactionProcessor CreateTransactionProcessor() => IOverridableTxProcessingScope IOverridableTxProcessorSource.Build(Hash256 stateRoot) => Build(stateRoot); - public OverridableTxProcessingScope Build(Hash256 stateRoot) - { - Hash256 originalStateRoot = StateProvider.StateRoot; - StateProvider.StateRoot = stateRoot; - return new(CodeInfoRepository, TransactionProcessor, StateProvider, originalStateRoot); - } + public OverridableTxProcessingScope Build(Hash256 stateRoot) => new(CodeInfoRepository, TransactionProcessor, StateProvider, stateRoot); IOverridableTxProcessingScope IOverridableTxProcessorSource.BuildAndOverride(BlockHeader header, Dictionary? stateOverride) { OverridableTxProcessingScope scope = Build(header.StateRoot ?? throw new ArgumentException($"Block {header.Hash} state root is null", nameof(header))); - if (stateOverride != null) + if (stateOverride is not null) { scope.WorldState.ApplyStateOverrides(scope.CodeInfoRepository, stateOverride, SpecProvider.GetSpec(header), header.Number); header.StateRoot = scope.WorldState.StateRoot; diff --git a/src/Nethermind/Nethermind.Consensus/Processing/OverridableTxProcessingScope.cs b/src/Nethermind/Nethermind.Consensus/Processing/OverridableTxProcessingScope.cs index 057f75e92c3..e026acc1e4c 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/OverridableTxProcessingScope.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/OverridableTxProcessingScope.cs @@ -8,22 +8,34 @@ namespace Nethermind.Consensus.Processing; -public class OverridableTxProcessingScope( - IOverridableCodeInfoRepository codeInfoRepository, - ITransactionProcessor transactionProcessor, - IOverridableWorldState worldState, - Hash256 originalStateRoot -) : IOverridableTxProcessingScope +public class OverridableTxProcessingScope : IOverridableTxProcessingScope { - public IOverridableCodeInfoRepository CodeInfoRepository => codeInfoRepository; - public ITransactionProcessor TransactionProcessor => transactionProcessor; - public IWorldState WorldState => worldState; + private readonly IOverridableCodeInfoRepository _codeInfoRepository; + private readonly ITransactionProcessor _transactionProcessor; + private readonly IOverridableWorldState _worldState; - public void Dispose() + public OverridableTxProcessingScope(IOverridableCodeInfoRepository codeInfoRepository, + ITransactionProcessor transactionProcessor, + IOverridableWorldState worldState, + Hash256 stateRoot) { - worldState.StateRoot = originalStateRoot; - worldState.Reset(); - worldState.ResetOverrides(); - codeInfoRepository.ResetOverrides(); + _codeInfoRepository = codeInfoRepository; + _transactionProcessor = transactionProcessor; + _worldState = worldState; + Reset(); + _worldState.StateRoot = stateRoot; + } + + public IOverridableCodeInfoRepository CodeInfoRepository => _codeInfoRepository; + public ITransactionProcessor TransactionProcessor => _transactionProcessor; + public IWorldState WorldState => _worldState; + + public void Dispose() => Reset(); + + private void Reset() + { + _worldState.Reset(); + _worldState.ResetOverrides(); + _codeInfoRepository.ResetOverrides(); } } diff --git a/src/Nethermind/Nethermind.Consensus/Tracing/GethStyleTracer.cs b/src/Nethermind/Nethermind.Consensus/Tracing/GethStyleTracer.cs index d7d8682793b..d606bf0f084 100644 --- a/src/Nethermind/Nethermind.Consensus/Tracing/GethStyleTracer.cs +++ b/src/Nethermind/Nethermind.Consensus/Tracing/GethStyleTracer.cs @@ -83,9 +83,6 @@ public GethLikeTxTrace Trace(Hash256 blockHash, int txIndex, GethTraceOptions op try { - Dictionary? stateOverride = options.StateOverrides; - using IOverridableTxProcessingScope? scope = _env.BuildAndOverride(block.Header, stateOverride); - return Trace(block, tx.Hash, cancellationToken, options, ProcessingOptions.TraceTransactions); } finally @@ -125,16 +122,20 @@ public GethLikeTxTrace Trace(Hash256 blockHash, int txIndex, GethTraceOptions op if (tx.Hash is null) throw new InvalidOperationException("Cannot trace transactions without tx hash set."); block = block.WithReplacedBodyCloned(BlockBody.WithOneTransactionOnly(tx)); - IBlockTracer blockTracer = CreateOptionsTracer(block.Header, options with { TxHash = tx.Hash }); - try - { - _processor.Process(block, ProcessingOptions.Trace, blockTracer.WithCancellation(cancellationToken)); - return blockTracer.BuildResult().SingleOrDefault(); - } - catch + lock (_env) //env shouldn't be shared, but can't find the root cause where it could be { - blockTracer.TryDispose(); - throw; + using IOverridableTxProcessingScope scope = _env.BuildAndOverride(block.Header, options.StateOverrides); + IBlockTracer blockTracer = CreateOptionsTracer(block.Header, options with { TxHash = tx.Hash }); + try + { + _processor.Process(block, ProcessingOptions.Trace, blockTracer.WithCancellation(cancellationToken)); + return blockTracer.BuildResult().SingleOrDefault(); + } + catch + { + blockTracer.TryDispose(); + throw; + } } } @@ -178,10 +179,9 @@ public IEnumerable TraceBadBlockToFile(Hash256 blockHash, GethTraceOptio ArgumentNullException.ThrowIfNull(options); var block = _badBlockStore - .GetAll() - .Where(b => b.Hash == blockHash) - .FirstOrDefault() - ?? throw new InvalidOperationException($"No historical block found for {blockHash}"); + .GetAll() + .FirstOrDefault(b => b.Hash == blockHash) + ?? throw new InvalidOperationException($"No historical block found for {blockHash}"); var tracer = new GethLikeBlockFileTracer(block, options, _fileSystem); @@ -195,17 +195,21 @@ public IEnumerable TraceBadBlockToFile(Hash256 blockHash, GethTraceOptio { ArgumentNullException.ThrowIfNull(txHash); - IBlockTracer tracer = CreateOptionsTracer(block.Header, options with { TxHash = txHash }); - - try - { - _processor.Process(block, processingOptions, tracer.WithCancellation(cancellationToken)); - return tracer.BuildResult().SingleOrDefault(); - } - catch + lock (_env) //env shouldn't be shared, but can't find the root cause where it could be { - tracer.TryDispose(); - throw; + using IOverridableTxProcessingScope scope = _env.BuildAndOverride(block.Header, options.StateOverrides); + IBlockTracer tracer = CreateOptionsTracer(block.Header, options with { TxHash = txHash }); + + try + { + _processor.Process(block, processingOptions, tracer.WithCancellation(cancellationToken)); + return tracer.BuildResult().SingleOrDefault(); + } + catch + { + tracer.TryDispose(); + throw; + } } } @@ -232,16 +236,20 @@ private IReadOnlyCollection TraceBlock(Block? block, GethTraceO if (!_blockTree.IsMainChain(parent.Hash)) throw new InvalidOperationException("Cannot trace orphaned blocks"); } - IBlockTracer tracer = CreateOptionsTracer(block.Header, options); - try + lock (_env) //env shouldn't be shared, but can't find the root cause where it could be { - _processor.Process(block, ProcessingOptions.Trace, tracer.WithCancellation(cancellationToken)); - return tracer.BuildResult(); - } - catch - { - tracer.TryDispose(); - throw; + using IOverridableTxProcessingScope scope = _env.BuildAndOverride(block.Header, options.StateOverrides); + IBlockTracer tracer = CreateOptionsTracer(block.Header, options); + try + { + _processor.Process(block, ProcessingOptions.Trace, tracer.WithCancellation(cancellationToken)); + return tracer.BuildResult(); + } + catch + { + tracer.TryDispose(); + throw; + } } } diff --git a/src/Nethermind/Nethermind.Evm/StateOverridesExtensions.cs b/src/Nethermind/Nethermind.Evm/StateOverridesExtensions.cs index 95fea8ff3eb..8bb93c0e172 100644 --- a/src/Nethermind/Nethermind.Evm/StateOverridesExtensions.cs +++ b/src/Nethermind/Nethermind.Evm/StateOverridesExtensions.cs @@ -43,6 +43,7 @@ public static void ApplyStateOverrides( state.Commit(spec); state.CommitTree(blockNumber); state.RecalculateStateRoot(); + } private static void UpdateState(this IWorldState stateProvider, AccountOverride accountOverride, Address address) diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedTests.cs index d7ccfdce5d4..a0afbe2a3ac 100644 --- a/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedTests.cs +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastSync/StateSyncFeedTests.cs @@ -394,6 +394,7 @@ public async Task When_empty_response_received_return_lesser_quality() } [Test] + [Parallelizable(ParallelScope.None)] // TODO: Investigate why it fails with parralelization public async Task When_empty_response_received_with_no_peer_return_not_allocated() { DbContext dbContext = new(_logger, _logManager);