From 746099cb57bac789b6acbb6c94338fab5185c64a Mon Sep 17 00:00:00 2001 From: Lukasz Rozmej Date: Mon, 2 Aug 2021 15:11:24 +0200 Subject: [PATCH] Simplify default Blockchain processor tracers, require tracers to be reusable (needed for branches), remove confusion with factories (#3266) --- .../Processing/BlockchainProcessor.cs | 6 ++- .../Processing/IBlockchainProcessor.cs | 3 +- .../Processing/OneTimeProcessor.cs | 2 +- .../Tracing/CompositeBlockTracerTests.cs | 10 ++-- .../Tracing/CompositeBlockTracer.cs | 48 ++++++++++++++----- .../Tracing/CompositeBlockTracerFactory.cs | 25 ---------- .../Nethermind.Evm/Tracing/IBlockTracer.cs | 8 +++- .../Tracing/IBlockTracerFactory.cs | 7 --- .../Nethermind.Evm/Tracing/ITracerBag.cs | 26 ++++++++++ 9 files changed, 82 insertions(+), 53 deletions(-) delete mode 100644 src/Nethermind/Nethermind.Evm/Tracing/CompositeBlockTracerFactory.cs delete mode 100644 src/Nethermind/Nethermind.Evm/Tracing/IBlockTracerFactory.cs create mode 100644 src/Nethermind/Nethermind.Evm/Tracing/ITracerBag.cs diff --git a/src/Nethermind/Nethermind.Blockchain/Processing/BlockchainProcessor.cs b/src/Nethermind/Nethermind.Blockchain/Processing/BlockchainProcessor.cs index 18e9d449166..5528a2081d1 100644 --- a/src/Nethermind/Nethermind.Blockchain/Processing/BlockchainProcessor.cs +++ b/src/Nethermind/Nethermind.Blockchain/Processing/BlockchainProcessor.cs @@ -37,7 +37,7 @@ public class BlockchainProcessor : IBlockchainProcessor, IBlockProcessingQueue public int SoftMaxRecoveryQueueSizeInTx = 10000; // adjust based on tx or gas public const int MaxProcessingQueueSize = 2000; // adjust based on tx or gas - public CompositeBlockTracerFactory BlockTracerFactory { get; } = new(); + public ITracerBag Tracers => _compositeBlockTracer; private readonly IBlockProcessor _blockProcessor; private readonly IBlockPreprocessorStep _recoveryStep; @@ -55,6 +55,8 @@ public class BlockchainProcessor : IBlockchainProcessor, IBlockProcessingQueue private DateTime _lastProcessedBlock; private int _currentRecoveryQueueSize; + private readonly CompositeBlockTracer _compositeBlockTracer = new(); + /// /// /// @@ -238,7 +240,7 @@ private void RunProcessingLoop() if (_logger.IsTrace) _logger.Trace($"Processing block {block.ToString(Block.Format.Short)})."); - Block processedBlock = Process(block, blockRef.ProcessingOptions, BlockTracerFactory.Create()); + Block processedBlock = Process(block, blockRef.ProcessingOptions, _compositeBlockTracer.GetTracer()); if (processedBlock == null) { if (_logger.IsTrace) _logger.Trace($"Failed / skipped processing {block.ToString(Block.Format.Full)}"); diff --git a/src/Nethermind/Nethermind.Blockchain/Processing/IBlockchainProcessor.cs b/src/Nethermind/Nethermind.Blockchain/Processing/IBlockchainProcessor.cs index b5af3b0870c..197989f5bfb 100644 --- a/src/Nethermind/Nethermind.Blockchain/Processing/IBlockchainProcessor.cs +++ b/src/Nethermind/Nethermind.Blockchain/Processing/IBlockchainProcessor.cs @@ -15,6 +15,7 @@ // along with the Nethermind. If not, see . using System; +using System.Collections.Generic; using System.Threading.Tasks; using Nethermind.Core; using Nethermind.Evm.Tracing; @@ -23,7 +24,7 @@ namespace Nethermind.Blockchain.Processing { public interface IBlockchainProcessor : IDisposable { - CompositeBlockTracerFactory BlockTracerFactory { get; } + ITracerBag Tracers { get; } void Start(); diff --git a/src/Nethermind/Nethermind.Blockchain/Processing/OneTimeProcessor.cs b/src/Nethermind/Nethermind.Blockchain/Processing/OneTimeProcessor.cs index 97133a5d3e5..4a79d3577a9 100644 --- a/src/Nethermind/Nethermind.Blockchain/Processing/OneTimeProcessor.cs +++ b/src/Nethermind/Nethermind.Blockchain/Processing/OneTimeProcessor.cs @@ -24,7 +24,7 @@ namespace Nethermind.Blockchain.Processing { public class OneTimeChainProcessor : IBlockchainProcessor { - public CompositeBlockTracerFactory BlockTracerFactory => _processor.BlockTracerFactory; + public ITracerBag Tracers => _processor.Tracers; private readonly IBlockchainProcessor _processor; private readonly IReadOnlyDbProvider _readOnlyDbProvider; diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/CompositeBlockTracerTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/CompositeBlockTracerTests.cs index a6bb8a83e25..a9e9484802f 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/CompositeBlockTracerTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/CompositeBlockTracerTests.cs @@ -42,8 +42,8 @@ public void Should_create_tracer_correctly() GethLikeBlockTracer gethLikeBlockTracer = new(txHash, GethTraceOptions.Default); ParityLikeBlockTracer parityLikeBlockTracer = new(txHash, ParityTraceTypes.All); - CompositeBlockTracer compositeBlockTracer = new CompositeBlockTracer( - new IBlockTracer[]{gethLikeBlockTracer, parityLikeBlockTracer}); + CompositeBlockTracer compositeBlockTracer = new CompositeBlockTracer(); + compositeBlockTracer.AddRange(gethLikeBlockTracer, parityLikeBlockTracer); compositeBlockTracer.IsTracingRewards.Should().Be(true); } @@ -63,9 +63,9 @@ public void Should_trace_properly() NullBlockTracer nullBlockTracer = NullBlockTracer.Instance; AlwaysCancelBlockTracer alwaysCancelBlockTracer = AlwaysCancelBlockTracer.Instance; - CompositeBlockTracer blockTracer = new CompositeBlockTracer( - new IBlockTracer[]{gethLikeBlockTracer, parityLikeBlockTracer, nullBlockTracer, alwaysCancelBlockTracer}); - + CompositeBlockTracer blockTracer = new CompositeBlockTracer(); + blockTracer.AddRange(gethLikeBlockTracer, parityLikeBlockTracer, nullBlockTracer, alwaysCancelBlockTracer); + blockTracer.StartNewBlockTrace(block); blockTracer.StartNewTxTrace(tx1); diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CompositeBlockTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CompositeBlockTracer.cs index a7ac941014b..56d1c6734d2 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CompositeBlockTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CompositeBlockTracer.cs @@ -23,14 +23,13 @@ namespace Nethermind.Evm.Tracing { - public class CompositeBlockTracer : IBlockTracer + public class CompositeBlockTracer : IBlockTracer, ITracerBag { - private readonly IBlockTracer[] _childTracers; - public bool IsTracingRewards { get; } + private readonly List _childTracers = new List(); + public bool IsTracingRewards { get; private set; } - public CompositeBlockTracer(IBlockTracer[] childTracers) + public CompositeBlockTracer() { - _childTracers = childTracers; IsTracingRewards = _childTracers.Any(childTracer => childTracer.IsTracingRewards); } @@ -44,7 +43,7 @@ public void EndTxTrace() public void ReportReward(Address author, string rewardType, UInt256 rewardValue) { - for (int index = 0; index < _childTracers.Length; index++) + for (int index = 0; index < _childTracers.Count; index++) { IBlockTracer childTracer = _childTracers[index]; if (childTracer.IsTracingRewards) @@ -56,7 +55,7 @@ public void ReportReward(Address author, string rewardType, UInt256 rewardValue) public void StartNewBlockTrace(Block block) { - for (int index = 0; index < _childTracers.Length; index++) + for (int index = 0; index < _childTracers.Count; index++) { IBlockTracer childTracer = _childTracers[index]; childTracer.StartNewBlockTrace(block); @@ -65,11 +64,11 @@ public void StartNewBlockTrace(Block block) public ITxTracer StartNewTxTrace(Transaction? tx) { - IBlockTracer[] childBlockTracers = _childTracers; + IList childBlockTracers = _childTracers; - List tracers = new(_childTracers.Length); + List tracers = new(childBlockTracers.Count); - for (int i = 0; i < childBlockTracers.Length; i++) + for (int i = 0; i < childBlockTracers.Count; i++) { IBlockTracer childBlockTracer = childBlockTracers[i]; ITxTracer txTracer = childBlockTracer.StartNewTxTrace(tx); @@ -84,11 +83,38 @@ public ITxTracer StartNewTxTrace(Transaction? tx) public void EndBlockTrace() { - for (int index = 0; index < _childTracers.Length; index++) + for (int index = 0; index < _childTracers.Count; index++) { IBlockTracer childTracer = _childTracers[index]; childTracer.EndBlockTrace(); } } + + public void Add(IBlockTracer tracer) + { + _childTracers.Add(tracer); + IsTracingRewards |= tracer.IsTracingRewards; + } + + public void AddRange(params IBlockTracer[] tracers) + { + _childTracers.AddRange(tracers); + IsTracingRewards |= tracers.Any(t => t.IsTracingRewards); + } + + public void Remove(IBlockTracer tracer) + { + _childTracers.Remove(tracer); + IsTracingRewards = _childTracers.Any(t => t.IsTracingRewards); + + } + + public IBlockTracer GetTracer() => + _childTracers.Count switch + { + 0 => NullBlockTracer.Instance, + 1 => _childTracers[0], + _ => this + }; } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CompositeBlockTracerFactory.cs b/src/Nethermind/Nethermind.Evm/Tracing/CompositeBlockTracerFactory.cs deleted file mode 100644 index c7124a2e091..00000000000 --- a/src/Nethermind/Nethermind.Evm/Tracing/CompositeBlockTracerFactory.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Collections.Immutable; -using System.Linq; - -namespace Nethermind.Evm.Tracing -{ - public class CompositeBlockTracerFactory : IBlockTracerFactory - { - private ImmutableArray _childFactories = ImmutableArray.Empty; - - public IBlockTracer Create() - { - return _childFactories.Length == 0 ? NullBlockTracer.Instance : new CompositeBlockTracer(_childFactories.Select(factory => factory.Create()).ToArray()); - } - - public void AddChildFactory(IBlockTracerFactory factoryToAdd) - { - _childFactories = _childFactories.Add(factoryToAdd); - } - - public void RemoveChildFactory(IBlockTracerFactory factoryToRemove) - { - _childFactories = _childFactories.Remove(factoryToRemove); - } - } -} diff --git a/src/Nethermind/Nethermind.Evm/Tracing/IBlockTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/IBlockTracer.cs index 4bc4840e033..c2949c02ba4 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/IBlockTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/IBlockTracer.cs @@ -20,12 +20,18 @@ namespace Nethermind.Evm.Tracing { + /// + /// Tracer for blocks. + /// + /// + /// This tracer should be reusable between blocks. call should reset inner tracer state. + /// public interface IBlockTracer { bool IsTracingRewards { get; } void ReportReward(Address author, string rewardType, UInt256 rewardValue); - + void StartNewBlockTrace(Block block); ITxTracer StartNewTxTrace(Transaction? tx); diff --git a/src/Nethermind/Nethermind.Evm/Tracing/IBlockTracerFactory.cs b/src/Nethermind/Nethermind.Evm/Tracing/IBlockTracerFactory.cs deleted file mode 100644 index cc817a4e12e..00000000000 --- a/src/Nethermind/Nethermind.Evm/Tracing/IBlockTracerFactory.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Nethermind.Evm.Tracing -{ - public interface IBlockTracerFactory - { - public IBlockTracer Create(); - } -} diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ITracerBag.cs b/src/Nethermind/Nethermind.Evm/Tracing/ITracerBag.cs new file mode 100644 index 00000000000..857bd08d747 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm/Tracing/ITracerBag.cs @@ -0,0 +1,26 @@ +// Copyright (c) 2021 Demerzel Solutions Limited +// This file is part of the Nethermind library. +// +// The Nethermind library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The Nethermind library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the Nethermind. If not, see . +// + +namespace Nethermind.Evm.Tracing +{ + public interface ITracerBag + { + void Add(IBlockTracer tracer); + void AddRange(params IBlockTracer[] tracers); + void Remove(IBlockTracer tracer); + } +}