diff --git a/src/Nethermind/Nethermind.Consensus/Tracing/GethStyleTracer.cs b/src/Nethermind/Nethermind.Consensus/Tracing/GethStyleTracer.cs index b22ee6dfa01..84898e0e2ca 100644 --- a/src/Nethermind/Nethermind.Consensus/Tracing/GethStyleTracer.cs +++ b/src/Nethermind/Nethermind.Consensus/Tracing/GethStyleTracer.cs @@ -12,6 +12,7 @@ using Nethermind.Consensus.Processing; using Nethermind.Core; using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Crypto; using Nethermind.Evm.Tracing; @@ -120,8 +121,15 @@ public GethLikeTxTrace Trace(Hash256 blockHash, int txIndex, GethTraceOptions op block = block.WithReplacedBodyCloned(BlockBody.WithOneTransactionOnly(tx)); IBlockTracer blockTracer = CreateOptionsTracer(block.Header, options with { TxHash = tx.Hash }); - _processor.Process(block, ProcessingOptions.Trace, blockTracer.WithCancellation(cancellationToken)); - return blockTracer.BuildResult().SingleOrDefault(); + try + { + _processor.Process(block, ProcessingOptions.Trace, blockTracer.WithCancellation(cancellationToken)); + return blockTracer.BuildResult().SingleOrDefault(); + } + finally + { + blockTracer.TryDispose(); + } } public IReadOnlyCollection TraceBlock(BlockParameter blockParameter, GethTraceOptions options, CancellationToken cancellationToken) @@ -164,9 +172,15 @@ public IEnumerable TraceBlockToFile(Hash256 blockHash, GethTraceOptions IBlockTracer tracer = CreateOptionsTracer(block.Header, options with { TxHash = txHash }); - _processor.Process(block, ProcessingOptions.Trace, tracer.WithCancellation(cancellationToken)); - - return tracer.BuildResult().SingleOrDefault(); + try + { + _processor.Process(block, ProcessingOptions.Trace, tracer.WithCancellation(cancellationToken)); + return tracer.BuildResult().SingleOrDefault(); + } + finally + { + tracer.TryDispose(); + } } private IBlockTracer CreateOptionsTracer(BlockHeader block, GethTraceOptions options) => @@ -193,8 +207,15 @@ private IReadOnlyCollection TraceBlock(Block? block, GethTraceO } IBlockTracer tracer = CreateOptionsTracer(block.Header, options); - _processor.Process(block, ProcessingOptions.Trace, tracer.WithCancellation(cancellationToken)); - return tracer.BuildResult(); + try + { + _processor.Process(block, ProcessingOptions.Trace, tracer.WithCancellation(cancellationToken)); + return tracer.BuildResult(); + } + finally + { + tracer.TryDispose(); + } } private static Block GetBlockToTrace(Rlp blockRlp) diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/GethLikeJavaScriptTracerTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/GethLikeJavaScriptTracerTests.cs index ad16e6d6509..ffb3f1ab1bc 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/GethLikeJavaScriptTracerTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/GethLikeJavaScriptTracerTests.cs @@ -24,9 +24,10 @@ public class GethLikeJavaScriptTracerTests : VirtualMachineTestsBase [TestCase("{ fault: function(log, db) { } }", TestName = "result")] [TestCase("{ fault: function(log, db) { }, result: function(ctx, db) { return null }, enter: function(frame) { } }", TestName = "exit")] [TestCase("{ fault: function(log, db) { }, result: function(ctx, db) { return null }, exit: function(frame) { } }", TestName = "enter")] - public void missing_functions(string tracer) + public void missing_functions(string tracerCode) { - Action trace = () => ExecuteBlock(GetTracer(tracer), MStore()); + using GethLikeBlockJavaScriptTracer tracer = GetTracer(tracerCode); + Action trace = () => ExecuteBlock(tracer, MStore()); trace.Should().Throw(); } @@ -39,11 +40,11 @@ public void log_operations() fault: function(log, db) { this.retVal.push('FAULT: ' + JSON.stringify(log)) }, result: function(ctx, db) { return this.retVal } }"; - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer(userTracer), MStore(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); string[] expectedStrings = { "0:PUSH32:0:79000:0", "33:PUSH1:0:78997:0", "35:MSTORE:0:78994:0", "36:PUSH32:0:78988:0", "69:PUSH1:0:78985:0", "71:MSTORE:0:78982:0", "72:STOP:0:78976:0" }; traces.CustomTracerResult?.Value.Should().BeEquivalentTo(expectedStrings); } @@ -60,11 +61,11 @@ public void log_operation_functions() fault: function(log, db) { this.retVal.push('FAULT: ' + JSON.stringify(log)) }, result: function(ctx, db) { return this.retVal } }"; - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer(userTracer), MStore(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); string[] expectedStrings = { "PUSH32 : 127 : true", "PUSH1 : 96 : true", "MSTORE : 82 : false", "PUSH32 : 127 : true", "PUSH1 : 96 : true", "MSTORE : 82 : false", "STOP : 0 : false" }; traces.CustomTracerResult?.Value.Should().BeEquivalentTo(expectedStrings); } @@ -78,11 +79,11 @@ public void log_stack_functions() fault: function(log, db) { this.retVal.push('FAULT: ' + JSON.stringify(log)) }, result: function(ctx, db) { return this.retVal } }"; - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer(userTracer), MStore(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); int[] expected = { 0, 1, 2, 0, 1, 2, 0 }; traces.CustomTracerResult?.Value.Should().BeEquivalentTo(expected); } @@ -102,11 +103,11 @@ public void log_memory_functions() fault: function(log, db) { this.retVal.push('FAULT: ' + JSON.stringify(log.getError())) }, result: function(ctx, db) { return this.retVal } }"; - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer(userTracer), MStore(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); int[] expectedResult = { 0, 32, 64 }; traces.CustomTracerResult?.Value.Should().BeEquivalentTo(expectedResult); } @@ -120,11 +121,11 @@ public void log_contract_functions() fault: function(log, db) { this.retVal.push('FAULT: ' + JSON.stringify(log)) }, result: function(ctx, db) { return this.retVal } }"; - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer(userTracer), MStore(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); traces.CustomTracerResult?.Value.Should().BeEquivalentTo("942921b14f1b1c385cd7e0cc2ef7abe5598c8358:b7705ae4c6f81b66cdb323c65f4e8133690fc099:"); } @@ -139,11 +140,11 @@ public void Js_traces_simple_filter() }"; ; - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer(userTracer), MStore(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); string[] expectedStrings = { "0:PUSH32", "33:PUSH1", "35:MSTORE", "36:PUSH32", "69:PUSH1", "71:MSTORE", "72:STOP" }; Assert.That(traces.CustomTracerResult?.Value, Is.EqualTo(expectedStrings)); } @@ -163,11 +164,11 @@ public void filter_with_conditionals() fault: function(log, db) { this.retVal.push('FAULT: ' + JSON.stringify(log)); }, result: function(ctx, db) { return this.retVal; } }"; - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer(userTracer), MStore(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); string[] expectedStrings = { "33: PUSH1", "35: MSTORE", "69: PUSH1", "71: MSTORE" }; Assert.That(traces.CustomTracerResult?.Value, Is.EqualTo(expectedStrings)); } @@ -192,11 +193,11 @@ public void storage_information() return this.retVal; } }"; - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer(userTracer), SStore_double(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); string[] expectedStrings = { "35: SSTORE 0", "71: SSTORE 20", "107: SLOAD 0", "108: STOP a01234 <- a01234" }; Assert.That(traces.CustomTracerResult?.Value, Is.EqualTo(expectedStrings)); } @@ -228,11 +229,11 @@ public void operation_results() } } """; - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer(userTracer), SStore(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); string[] expectedStrings = { "68 SSTORE 1 <- a01234", "104 SLOAD 1", "Result: a01234" }; Assert.That(traces.CustomTracerResult?.Value, Is.EqualTo(expectedStrings)); } @@ -295,11 +296,11 @@ public void calls_btn_contracts() } """; - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer(userTracer), SStore(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); string[] expectedStrings = { "68: SSTORE 942921b14f1b1c385cd7e0cc2ef7abe5598c8358:1 <- a01234", "104: SLOAD 942921b14f1b1c385cd7e0cc2ef7abe5598c8358:1", "Result: 1" }; Assert.That(traces.CustomTracerResult?.Value, Is.EqualTo(expectedStrings)); } @@ -307,33 +308,33 @@ public void calls_btn_contracts() [Test] public void noop_tracer_legacy() { - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer("noopTracer"), MStore(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); Assert.That(traces.CustomTracerResult?.Value, Has.All.Empty); } [Test] public void opcount_tracer() { - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer("opcountTracer"), MStore(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); Assert.That(traces.CustomTracerResult?.Value, Is.EqualTo(7)); } [Test] public void prestate_tracer() { - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer("prestateTracer_legacy"), NestedCalls(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); Assert.That(JsonSerializer.Serialize(traces.CustomTracerResult?.Value), Is.EqualTo("{\"942921b14f1b1c385cd7e0cc2ef7abe5598c8358\":{\"balance\":\"0x56bc75e2d63100000\",\"nonce\":0,\"code\":\"60006000600060007376e68a8696537e4141926f3e528733af9e237d6961c350f400\",\"storage\":{}},\"76e68a8696537e4141926f3e528733af9e237d69\":{\"balance\":\"0xde0b6b3a7640000\",\"nonce\":0,\"code\":\"7f7f000000000000000000000000000000000000000000000000000000000000006000527f0060005260036000f30000000000000000000000000000000000000000000000602052602960006000f000\",\"storage\":{}},\"89aa9b2ce05aaef815f25b237238c0b4ffff6ae3\":{\"balance\":\"0x0\",\"nonce\":0,\"code\":\"\",\"storage\":{}},\"b7705ae4c6f81b66cdb323c65f4e8133690fc099\":{\"balance\":\"0x56bc75e2d63100000\",\"nonce\":0,\"code\":\"\",\"storage\":{}}}")); } @@ -341,11 +342,11 @@ public void prestate_tracer() [Test] public void call_tracer() { - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer("callTracer"), NestedCalls(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); Assert.That(JsonSerializer.Serialize(traces.CustomTracerResult?.Value), Is.EqualTo("{\"type\":\"CALL\",\"from\":\"b7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"value\":\"0x1\",\"gas\":\"0x186a0\",\"gasUsed\":\"0xdbd1\",\"input\":\"\",\"output\":\"\",\"calls\":[{\"type\":\"DELEGATECALL\",\"from\":\"942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"to\":\"76e68a8696537e4141926f3e528733af9e237d69\",\"gas\":\"0xc350\",\"gasUsed\":\"0x14d07\",\"input\":\"\",\"output\":\"\",\"calls\":[{\"type\":\"CREATE\",\"from\":\"942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"to\":\"89aa9b2ce05aaef815f25b237238c0b4ffff6ae3\",\"value\":\"0x0\",\"gas\":\"0x4513\",\"gasUsed\":\"0x7f6e\",\"input\":\"7f000000000000000000000000000000000000000000000000000000000000000060005260036000f3\",\"output\":\"000000\"}]}]}")); } @@ -353,11 +354,11 @@ public void call_tracer() [Test] public void _4byte_tracer_legacy() { - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer("4byteTracer_legacy"), CallWithInput(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); Assert.That(JsonSerializer.Serialize(traces.CustomTracerResult?.Value), Is.EqualTo("{\"00000000-1\":2,\"00000000-2\":1}")); } @@ -450,11 +451,11 @@ private byte[] CallWithInput() [Test] public void complex_tracer() { - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer(ComplexTracer), Array.Empty(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); TestContext.WriteLine(GetEthereumJsonSerializer().Serialize(traces.CustomTracerResult)); } @@ -462,11 +463,11 @@ public void complex_tracer() [Test] public void complex_tracer_nested_call() { - GethLikeTxTrace traces = ExecuteBlock( + using GethLikeBlockJavaScriptTracer tracer = ExecuteBlock( GetTracer(ComplexTracer), NestedCalls(), - MainnetSpecProvider.CancunActivation) - .BuildResult().First(); + MainnetSpecProvider.CancunActivation); + GethLikeTxTrace traces = tracer.BuildResult().First(); TestContext.WriteLine(GetEthereumJsonSerializer().Serialize(traces.CustomTracerResult)); } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/GethStyle/Custom/JavaScript/GethLikeBlockJavaScriptTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/GethStyle/Custom/JavaScript/GethLikeBlockJavaScriptTracer.cs index 75cb2aade84..4f7fe879610 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/GethStyle/Custom/JavaScript/GethLikeBlockJavaScriptTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/GethStyle/Custom/JavaScript/GethLikeBlockJavaScriptTracer.cs @@ -68,8 +68,6 @@ public override void EndBlockTrace() { base.EndBlockTrace(); Engine.CurrentEngine = null; - ArrayPoolList? list = Interlocked.Exchange(ref _engines, null); - list?.Dispose(); } protected override bool ShouldTraceTx(Transaction? tx) => base.ShouldTraceTx(tx) && tx is not null; diff --git a/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs b/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs index c352b2937e1..a6b8a9560f9 100644 --- a/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs +++ b/src/Nethermind/Nethermind.Trie.Test/Pruning/TreeStoreTests.cs @@ -876,7 +876,7 @@ public async Task Will_Trigger_ReorgBoundaryEvent_On_Prune() if (i > 4) { - Assert.That(() => reorgBoundary, Is.EqualTo(i - 3).After(5000, 1)); + Assert.That(() => reorgBoundary, Is.EqualTo(i - 3).After(10000, 1)); } else {