From d51cf5122cac006b29254784916d4285d605d577 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 4 Nov 2022 16:56:40 +0100 Subject: [PATCH 01/22] Add ReportFees to tracer --- .../Tracing/BlockReceiptsTracer.cs | 20 +++++++++++++++---- .../Tracing/CancellationTxTracer.cs | 17 ++++++++++++---- .../Tracing/CompositeTxTracer.cs | 20 +++++++++++++++---- .../Nethermind.Evm/Tracing/ITxTracer.cs | 7 ++++--- .../TransactionProcessor.cs | 9 ++++++++- 5 files changed, 57 insertions(+), 16 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs index d7f3454d3de..6f52640d250 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs @@ -1,16 +1,16 @@ // 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 . @@ -195,6 +195,18 @@ public void ReportBlockHash(Keccak blockHash) => public void SetOperationMemory(List memoryTrace) => _currentTxTracer.SetOperationMemory(memoryTrace); + public void ReportFees(UInt256 fees, UInt256 burntFees) + { + Fees += fees; + BurntFees += burntFees; + if (_currentTxTracer.IsTracingReceipt) + { + _currentTxTracer.ReportFees(fees, burntFees); + } + } + + public UInt256 Fees { get; private set; } = UInt256.Zero; + public UInt256 BurntFees { get; private set; } = UInt256.Zero; private ITxTracer _currentTxTracer = NullTxTracer.Instance; private int _currentIndex; private readonly List _txReceipts = new(); @@ -236,7 +248,7 @@ public ITxTracer StartNewTxTrace(Transaction? tx) { _currentTx = tx; _currentTxTracer = _otherTracer.StartNewTxTrace(tx); - return _currentTxTracer; + return this; } public void EndTxTrace() diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs index 9abdc9b9ef7..ae03d320235 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CancellationTxTracer.cs @@ -1,19 +1,19 @@ // 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 . -// +// using System; using System.Collections.Generic; @@ -436,5 +436,14 @@ public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet. -// +// using System; using System.Collections.Generic; @@ -484,5 +484,17 @@ public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet. @@ -158,5 +158,6 @@ void LoadOperationTransientStorage(Address storageCellAddress, UInt256 storageIn void ReportRefund(long refund); void ReportExtraGasPressure(long extraGasPressure); void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet accessedStorageCells); + void ReportFees(UInt256 fees, UInt256 burntFees) { } } } diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index e59c26b52e2..00a20686b4d 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -443,9 +443,11 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra _stateProvider.CreateAccount(gasBeneficiary, fees); } + UInt256 burntFees = UInt256.Zero; + if (!transaction.IsFree() && spec.IsEip1559Enabled && spec.Eip1559FeeCollector is not null) { - UInt256 burntFees = (ulong)spentGas * block.BaseFeePerGas; + burntFees = (ulong)spentGas * block.BaseFeePerGas; if (!burntFees.IsZero) { if (_stateProvider.AccountExists(spec.Eip1559FeeCollector)) @@ -458,6 +460,11 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra } } } + + if (txTracer.IsTracingReceipt) + { + txTracer.ReportFees(fees, burntFees); + } } } From df304dc588f9133fedaa1715d67d2c3af78272ff Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 4 Nov 2022 17:03:49 +0100 Subject: [PATCH 02/22] Put fees in the header --- .../Nethermind.Consensus/Processing/BlockProcessor.cs | 2 ++ src/Nethermind/Nethermind.Core/BlockHeader.cs | 10 +++++++--- .../Nethermind.Evm/Tracing/BlockReceiptsTracer.cs | 2 ++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs index 459bd0124e0..387336bd904 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs @@ -246,6 +246,8 @@ protected virtual TxReceipt[] ProcessBlock( block.Header.StateRoot = _stateProvider.StateRoot; block.Header.Hash = block.Header.CalculateHash(); + block.Header.Fees = _receiptsTracer.Fees; + block.Header.BurntFees = _receiptsTracer.BurntFees; return receipts; } diff --git a/src/Nethermind/Nethermind.Core/BlockHeader.cs b/src/Nethermind/Nethermind.Core/BlockHeader.cs index 478f06c37f4..7061209d1ed 100644 --- a/src/Nethermind/Nethermind.Core/BlockHeader.cs +++ b/src/Nethermind/Nethermind.Core/BlockHeader.cs @@ -1,16 +1,16 @@ // 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 . @@ -83,6 +83,10 @@ public BlockHeader( // ToDo we need to set this flag after reading block from db public bool IsPostMerge { get; set; } + // transient: + public UInt256 Fees { get; set; } + public UInt256 BurntFees { get; set; } + public string ToString(string indent) { StringBuilder builder = new(); diff --git a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs index 6f52640d250..d742922010a 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs @@ -240,6 +240,8 @@ public void StartNewBlockTrace(Block block) _block = block; _currentIndex = 0; _txReceipts.Clear(); + Fees = UInt256.Zero; + BurntFees = UInt256.Zero; _otherTracer.StartNewBlockTrace(block); } From 264dd70779995ddcb2de2c655240998c83e42270 Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Tue, 8 Nov 2022 17:09:29 +0300 Subject: [PATCH 03/22] Expose api --- .../EngineModuleTests.Setup.cs | 7 ++- .../Data/V2/GetPayloadV2Result.cs | 38 ++++++++++++ .../EngineRpcModule.cs | 9 +++ .../Handlers/V2/GetPayloadV2Handler.cs | 58 +++++++++++++++++++ .../IEngineRpcModule.cs | 16 +++-- .../Nethermind.Merge.Plugin/MergePlugin.cs | 2 + 6 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 src/Nethermind/Nethermind.Merge.Plugin/Data/V2/GetPayloadV2Result.cs create mode 100644 src/Nethermind/Nethermind.Merge.Plugin/Handlers/V2/GetPayloadV2Handler.cs diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs index a277f2afd45..50d09a68fb6 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.Setup.cs @@ -31,7 +31,6 @@ using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Specs; -using Nethermind.Core.Test; using Nethermind.Core.Test.Blockchain; using Nethermind.Core.Timers; using Nethermind.Db; @@ -40,14 +39,13 @@ using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Merge.Plugin.BlockProduction; -using Nethermind.Merge.Plugin.Data; using Nethermind.Merge.Plugin.Handlers; using Nethermind.Merge.Plugin.Handlers.V1; +using Nethermind.Merge.Plugin.Handlers.V2; using Nethermind.Merge.Plugin.Synchronization; using Nethermind.Specs; using Nethermind.Specs.Forks; using Nethermind.State; -using NLog.Fluent; using NSubstitute; namespace Nethermind.Merge.Plugin.Test @@ -77,6 +75,9 @@ private IEngineRpcModule CreateEngineModule(MergeTestBlockchain chain, ISyncConf new GetPayloadV1Handler( chain.PayloadPreparationService!, chain.LogManager), + new GetPayloadV2Handler( + chain.PayloadPreparationService!, + chain.LogManager), new NewPayloadV1Handler( chain.BlockValidator, chain.BlockTree, diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/V2/GetPayloadV2Result.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/V2/GetPayloadV2Result.cs new file mode 100644 index 00000000000..fb7526dc5e9 --- /dev/null +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/V2/GetPayloadV2Result.cs @@ -0,0 +1,38 @@ +// 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 . +// + +using Nethermind.Core; +using Nethermind.Int256; +using Nethermind.Merge.Plugin.Data.V1; + +namespace Nethermind.Merge.Plugin.Data.V2; + +public class GetPayloadV2Result +{ + public ExecutionPayloadV1 ExecutionPayloadV1; + public UInt256 BlockValue; + + public GetPayloadV2Result(Block block) + { + ExecutionPayloadV1 = new(block); + BlockValue = block.Header.Fees; + } + + public override string ToString() => ExecutionPayloadV1.BlockHash == null + ? $"{ExecutionPayloadV1.BlockNumber} null" + : $"{ExecutionPayloadV1.BlockNumber} ({ExecutionPayloadV1.BlockHash}) Fees: {BlockValue}"; +} diff --git a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.cs b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.cs index 7cc0bae80c9..952fc180c52 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.cs @@ -25,6 +25,7 @@ using Nethermind.Logging; using Nethermind.Merge.Plugin.Data; using Nethermind.Merge.Plugin.Data.V1; +using Nethermind.Merge.Plugin.Data.V2; using Nethermind.Merge.Plugin.Handlers; namespace Nethermind.Merge.Plugin @@ -32,6 +33,7 @@ namespace Nethermind.Merge.Plugin public class EngineRpcModule : IEngineRpcModule { private readonly IAsyncHandler _getPayloadHandlerV1; + private readonly IAsyncHandler _getPayloadHandlerV2; private readonly IAsyncHandler _newPayloadV1Handler; private readonly IForkchoiceUpdatedV1Handler _forkchoiceUpdatedV1Handler; private readonly IHandler _executionStatusHandler; @@ -43,6 +45,7 @@ public class EngineRpcModule : IEngineRpcModule public EngineRpcModule( IAsyncHandler getPayloadHandlerV1, + IAsyncHandler getPayloadHandlerV2, IAsyncHandler newPayloadV1Handler, IForkchoiceUpdatedV1Handler forkchoiceUpdatedV1Handler, IHandler executionStatusHandler, @@ -51,6 +54,7 @@ public EngineRpcModule( ILogManager logManager) { _getPayloadHandlerV1 = getPayloadHandlerV1; + _getPayloadHandlerV2 = getPayloadHandlerV2; _newPayloadV1Handler = newPayloadV1Handler; _forkchoiceUpdatedV1Handler = forkchoiceUpdatedV1Handler; _executionStatusHandler = executionStatusHandler; @@ -69,6 +73,11 @@ public ResultWrapper engine_executionStatus() return await (_getPayloadHandlerV1.HandleAsync(payloadId)); } + public async Task> engine_getPayloadV2(byte[] payloadId) + { + return await (_getPayloadHandlerV2.HandleAsync(payloadId)); + } + public async Task> engine_newPayloadV1(ExecutionPayloadV1 executionPayload) { if (await _locker.WaitAsync(_timeout)) diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V2/GetPayloadV2Handler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V2/GetPayloadV2Handler.cs new file mode 100644 index 00000000000..996d91a9292 --- /dev/null +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V2/GetPayloadV2Handler.cs @@ -0,0 +1,58 @@ +// 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 . +// + +using System.Threading.Tasks; +using Nethermind.Core; +using Nethermind.Core.Extensions; +using Nethermind.JsonRpc; +using Nethermind.Logging; +using Nethermind.Merge.Plugin.BlockProduction; +using Nethermind.Merge.Plugin.Data.V2; + +namespace Nethermind.Merge.Plugin.Handlers.V2 +{ + public class GetPayloadV2Handler : IAsyncHandler + { + private readonly IPayloadPreparationService _payloadPreparationService; + private readonly ILogger _logger; + + public GetPayloadV2Handler(IPayloadPreparationService payloadPreparationService, ILogManager logManager) + { + _payloadPreparationService = payloadPreparationService; + _logger = logManager.GetClassLogger(); + } + + public async Task> HandleAsync(byte[] payloadId) + { + string payloadStr = payloadId.ToHexString(true); + Block? block = await _payloadPreparationService.GetPayload(payloadStr); + + if (block == null) + { + // The call MUST return -38001: Unknown payload error if the build process identified by the payloadId does not exist. + if (_logger.IsWarn) _logger.Warn($"Block production for payload with id={payloadId.ToHexString()} failed - unknown payload."); + return ResultWrapper.Fail("unknown payload", MergeErrorCodes.UnknownPayload); + } + + if (_logger.IsInfo) _logger.Info($"GetPayloadV2 result: {block.Header.ToString(BlockHeader.Format.Full)}."); + + Metrics.GetPayloadRequests++; + Metrics.NumberOfTransactionsInGetPayload = block.Transactions.Length; + return ResultWrapper.Success(new GetPayloadV2Result(block)); + } + } +} diff --git a/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.cs b/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.cs index 76f6cfa2076..6c6a1d749e4 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/IEngineRpcModule.cs @@ -1,19 +1,19 @@ // 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 . -// +// using System.Threading.Tasks; using Nethermind.Consensus.Producers; @@ -24,6 +24,7 @@ using Nethermind.JsonRpc.Modules; using Nethermind.Merge.Plugin.Data; using Nethermind.Merge.Plugin.Data.V1; +using Nethermind.Merge.Plugin.Data.V2; namespace Nethermind.Merge.Plugin { @@ -43,6 +44,13 @@ public interface IEngineRpcModule : IRpcModule IsImplemented = true)] Task> engine_getPayloadV1(byte[] payloadId); + [JsonRpcMethod( + Description = + "Returns the most recent version of an execution payload and fees with respect to the transaction set contained by the mempool.", + IsSharable = true, + IsImplemented = true)] + public Task> engine_getPayloadV2(byte[] payloadId); + [JsonRpcMethod( Description = "Verifies the payload according to the execution environment rules and returns the verification status and hash of the last valid block.", IsSharable = true, diff --git a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs index 8ce1a6d0747..887f0bb56e4 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/MergePlugin.cs @@ -39,6 +39,7 @@ using Nethermind.Merge.Plugin.BlockProduction.Boost; using Nethermind.Merge.Plugin.Handlers; using Nethermind.Merge.Plugin.Handlers.V1; +using Nethermind.Merge.Plugin.Handlers.V2; using Nethermind.Merge.Plugin.InvalidChainTracker; using Nethermind.Merge.Plugin.Synchronization; using Nethermind.Synchronization.ParallelSync; @@ -325,6 +326,7 @@ public Task InitRpcModules() IEngineRpcModule engineRpcModule = new EngineRpcModule( new GetPayloadV1Handler(payloadPreparationService, _api.LogManager), + new GetPayloadV2Handler(payloadPreparationService, _api.LogManager), new NewPayloadV1Handler( _api.BlockValidator, _api.BlockTree, From 50d16018cd0fd7f0fee5001ac1af8458d9afea83 Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Wed, 9 Nov 2022 14:37:39 +0300 Subject: [PATCH 04/22] tests --- .../EngineModuleTest.V2.cs | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTest.V2.cs diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTest.V2.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTest.V2.cs new file mode 100644 index 00000000000..dd3f9ea69eb --- /dev/null +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTest.V2.cs @@ -0,0 +1,93 @@ +// 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 . +// + +using System.Threading; +using System.Threading.Tasks; +using FluentAssertions; +using Nethermind.Consensus.Producers; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Core.Extensions; +using Nethermind.Core.Test.Builders; +using Nethermind.Crypto; +using Nethermind.Int256; +using Nethermind.JsonRpc; +using Nethermind.Merge.Plugin.Data.V1; +using Nethermind.Merge.Plugin.Data.V2; +using Nethermind.State; +using NUnit.Framework; + +namespace Nethermind.Merge.Plugin.Test; + +public partial class EngineModuleTests +{ + [Test] + public async Task getPayloadV2_empty_block_should_have_zero_value() + { + using MergeTestBlockchain chain = await CreateBlockChain(); + IEngineRpcModule rpc = CreateEngineModule(chain); + + Keccak startingHead = chain.BlockTree.HeadHash; + + ForkchoiceStateV1 forkchoiceState = new(startingHead, Keccak.Zero, startingHead); + PayloadAttributes payload = new() { Timestamp = Timestamper.UnixTime.Seconds, SuggestedFeeRecipient = Address.Zero, PrevRandao = Keccak.Zero }; + Task> forkchoiceResponse = rpc.engine_forkchoiceUpdatedV1(forkchoiceState, payload); + + byte[] payloadId = Bytes.FromHexString(forkchoiceResponse.Result.Data.PayloadId!); + ResultWrapper responseFirst = await rpc.engine_getPayloadV2(payloadId); + responseFirst.Should().NotBeNull(); + responseFirst.Result.ResultType.Should().Be(ResultType.Success); + responseFirst.Data!.BlockValue.Should().Be(0); + } + + [Test] + public async Task getPayloadV2_received_fees_should_be_equal_to_block_value_in_getPayload_result() + { + using SemaphoreSlim blockImprovementLock = new(0); + using MergeTestBlockchain chain = await CreateBlockChain(); + IEngineRpcModule rpc = CreateEngineModule(chain); + + Address feeRecipient = TestItem.AddressA; + + Keccak startingHead = chain.BlockTree.HeadHash; + uint count = 3; + int value = 10; + + PrivateKey sender = TestItem.PrivateKeyB; + Transaction[] transactions = BuildTransactions(chain, startingHead, sender, Address.Zero, count, value, out _, out _); + + chain.AddTransactions(transactions); + chain.PayloadPreparationService!.BlockImproved += (_, _) => { blockImprovementLock.Release(1); }; + + string? payloadId = rpc.engine_forkchoiceUpdatedV1( + new ForkchoiceStateV1(startingHead, Keccak.Zero, startingHead), + new PayloadAttributes() { Timestamp = 100, PrevRandao = TestItem.KeccakA, SuggestedFeeRecipient = feeRecipient }) + .Result.Data.PayloadId!; + + UInt256 startingBalance = chain.StateReader.GetBalance(chain.State.StateRoot, feeRecipient); + + await blockImprovementLock.WaitAsync(10000); + GetPayloadV2Result getPayloadResult = (await rpc.engine_getPayloadV2(Bytes.FromHexString(payloadId))).Data!; + + ResultWrapper executePayloadResult = await rpc.engine_newPayloadV1(getPayloadResult.ExecutionPayloadV1); + executePayloadResult.Data.Status.Should().Be(PayloadStatus.Valid); + + UInt256 finalBalance = chain.StateReader.GetBalance(getPayloadResult.ExecutionPayloadV1.StateRoot, feeRecipient); + + (finalBalance - startingBalance).Should().Be(getPayloadResult.BlockValue); + } +} From d76fb4f76fb4be84b2ea37158e8039851201fa18 Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Wed, 9 Nov 2022 15:42:44 +0300 Subject: [PATCH 05/22] fix tests --- src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs index d742922010a..621fbd83d6c 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs @@ -250,7 +250,7 @@ public ITxTracer StartNewTxTrace(Transaction? tx) { _currentTx = tx; _currentTxTracer = _otherTracer.StartNewTxTrace(tx); - return this; + return _currentTxTracer; } public void EndTxTrace() From 9260e632cbe87ec1feca206647047a46fb29ed13 Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Wed, 16 Nov 2022 15:25:49 +0300 Subject: [PATCH 06/22] ToString & null test --- .../EngineModuleTest.V2.cs | 14 ++++++++++++++ .../Data/V2/GetPayloadV2Result.cs | 4 +--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTest.V2.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTest.V2.cs index dd3f9ea69eb..5e6d7e433ee 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTest.V2.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTest.V2.cs @@ -90,4 +90,18 @@ public async Task getPayloadV2_received_fees_should_be_equal_to_block_value_in_g (finalBalance - startingBalance).Should().Be(getPayloadResult.BlockValue); } + + [Test] + public async Task getPayloadV2_request_unknown_payload() + { + using SemaphoreSlim blockImprovementLock = new(0); + using MergeTestBlockchain chain = await CreateBlockChain(); + IEngineRpcModule rpc = CreateEngineModule(chain); + + byte[] payloadId = Bytes.FromHexString("0x0"); + ResultWrapper responseFirst = await rpc.engine_getPayloadV2(payloadId); + responseFirst.Should().NotBeNull(); + responseFirst.Result.ResultType.Should().Be(ResultType.Failure); + responseFirst.ErrorCode.Should().Be(-38001); + } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/V2/GetPayloadV2Result.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/V2/GetPayloadV2Result.cs index fb7526dc5e9..97e328fb405 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Data/V2/GetPayloadV2Result.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/V2/GetPayloadV2Result.cs @@ -32,7 +32,5 @@ public GetPayloadV2Result(Block block) BlockValue = block.Header.Fees; } - public override string ToString() => ExecutionPayloadV1.BlockHash == null - ? $"{ExecutionPayloadV1.BlockNumber} null" - : $"{ExecutionPayloadV1.BlockNumber} ({ExecutionPayloadV1.BlockHash}) Fees: {BlockValue}"; + public override string ToString() => $"ExecutionPayloadV1: {ExecutionPayloadV1}, Fees: {BlockValue}"; } From a4261ee5b9e7f8471fe6eba05ef73426ae190728 Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Wed, 16 Nov 2022 21:38:41 +0300 Subject: [PATCH 07/22] Fees tests --- .../TransactionProcessorFeeTests.cs | 162 ++++++++++++++++++ .../OverridableReleaseSpec.cs | 26 +-- 2 files changed, 175 insertions(+), 13 deletions(-) create mode 100644 src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs new file mode 100644 index 00000000000..300cc25ce32 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs @@ -0,0 +1,162 @@ +// Copyright 2022 Demerzel Solutions Limited +// Licensed under the LGPL-3.0. For full terms, see LICENSE-LGPL in the project root. + +using FluentAssertions; +using Nethermind.Core; +using Nethermind.Core.Extensions; +using Nethermind.Core.Specs; +using Nethermind.Core.Test.Builders; +using Nethermind.Crypto; +using Nethermind.Db; +using Nethermind.Evm.Tracing; +using Nethermind.Evm.TransactionProcessing; +using Nethermind.Int256; +using Nethermind.Logging; +using Nethermind.Specs; +using Nethermind.Specs.Forks; +using Nethermind.Specs.Test; +using Nethermind.State; +using Nethermind.Trie.Pruning; +using NUnit.Framework; + +namespace Nethermind.Evm.Test; + +public class TransactionProcessorFeeTests +{ + private TestSpecProvider _specProvider; + private IEthereumEcdsa _ethereumEcdsa; + private TransactionProcessor _transactionProcessor; + private IStateProvider _stateProvider; + + [SetUp] + public void Setup() + { + OverridableReleaseSpec spec = new(London.Instance); + spec.Eip1559FeeCollector = TestItem.AddressC; + _specProvider = new TestSpecProvider(spec); + + TrieStore trieStore = new(new MemDb(), LimboLogs.Instance); + + _stateProvider = new StateProvider(trieStore, new MemDb(), LimboLogs.Instance); + _stateProvider.CreateAccount(TestItem.AddressA, 1.Ether()); + _stateProvider.Commit(_specProvider.GenesisSpec); + _stateProvider.CommitTree(0); + + StorageProvider storageProvider = new(trieStore, _stateProvider, LimboLogs.Instance); + VirtualMachine virtualMachine = new(TestBlockhashProvider.Instance, _specProvider, LimboLogs.Instance); + _transactionProcessor = new TransactionProcessor(_specProvider, _stateProvider, storageProvider, virtualMachine, + LimboLogs.Instance); + _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); + } + + [TestCase(true)] + [TestCase(false)] + public void Check_paid_fees_simple(bool isTransactionEip1559) + { + OverridableReleaseSpec spec = new(London.Instance); + spec.Eip1559FeeCollector = TestItem.AddressC; + _specProvider = new TestSpecProvider(spec); + + Transaction tx = Build.A.Transaction + .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithGasPrice(10).WithMaxFeePerGas(10) + .WithType(isTransactionEip1559 ? TxType.EIP1559 : TxType.Legacy).WithGasLimit(21000).TestObject; + Block block = Build.A.Block.WithNumber(1) + .WithBeneficiary(TestItem.AddressB).WithBaseFeePerGas(1).WithTransactions(tx).WithGasLimit(21000) + .TestObject; + + ExecuteAndCheckFees(block, tx); + } + + + [Test] + public void Check_paid_fees_multiple_transactions() + { + Transaction tx1 = Build.A.Transaction + .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithType(TxType.EIP1559) + .WithMaxFeePerGas(10).WithGasPrice(1).WithGasLimit(21000).TestObject; + Transaction tx2 = Build.A.Transaction + .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithNonce(1) + .WithGasPrice(10).WithGasLimit(21000).TestObject; + Block block = Build.A.Block.WithNumber(0).WithBaseFeePerGas(1) + .WithBeneficiary(TestItem.AddressB).WithTransactions(tx1, tx2).WithGasLimit(42000).TestObject; + + ExecuteAndCheckFees(block, tx1, tx2); + } + + + [Test] + public void Check_paid_fees_with_byte_code() + { + byte[] byteCode = Prepare.EvmCode + .CallWithValue(Address.Zero, 0, 1) + .PushData(1) + .PushData(1) + .Op(Instruction.SSTORE) + .PushData(0) + .PushData(1) + .Op(Instruction.SSTORE) + .Op(Instruction.STOP) + .Done; + Transaction tx1 = Build.A.Transaction + .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithMaxFeePerGas(10).WithGasPrice(1) + .WithType(TxType.EIP1559).WithGasLimit(21000).TestObject; + Transaction tx2 = Build.A.Transaction + .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithNonce(1).WithGasPrice(10) + .WithType(TxType.Legacy).WithGasLimit(21000).TestObject; + Transaction tx3 = Build.A.Transaction + .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithNonce(2).WithMaxFeePerGas(30).WithGasPrice(1) + .WithType(TxType.EIP1559).WithCode(byteCode) + .WithGasLimit(60000).TestObject; + Block block = Build.A.Block.WithNumber(MainnetSpecProvider.LondonBlockNumber) + .WithBeneficiary(TestItem.AddressB).WithBaseFeePerGas(1).WithTransactions(tx1, tx2, tx3) + .WithGasLimit(102000).TestObject; + + ExecuteAndCheckFees(block, tx1, tx2, tx3); + } + + + private void ExecuteAndCheckFees(Block block, params Transaction[] txs) + { + Address beneficiary = block.Beneficiary!; + IReleaseSpec spec = _specProvider.GetSpec((block.Number, block.Timestamp)); + + BlockReceiptsTracer tracer = new(); + tracer.SetOtherTracer(NullBlockTracer.Instance); + + tracer.StartNewBlockTrace(block); + + UInt256 totalBurned = UInt256.Zero; + UInt256 totalFees = UInt256.Zero; + foreach (Transaction tx in txs) + { + // Read balances of Eip1559FeeCollector and blockBeneficiary before tx execution + UInt256 startBurned = _stateProvider.AccountExists(spec.Eip1559FeeCollector!) + ? _stateProvider.GetBalance(spec.Eip1559FeeCollector!) : 0; + UInt256 starBeneficiary = _stateProvider.GetBalance(beneficiary); + + + tracer.StartNewTxTrace(tx); + _transactionProcessor.Execute(tx, block.Header, tracer); + tracer.EndTxTrace(); + + // Read balances of Eip1559FeeCollector and blockBeneficiary after tx execution + UInt256 endBurned = spec.IsEip1559Enabled ? _stateProvider.GetBalance(spec.Eip1559FeeCollector!) : 0; + UInt256 endBeneficiary = _stateProvider.GetBalance(beneficiary); + + // Calculate expected fees + UInt256 fees = endBeneficiary - starBeneficiary; + UInt256 burned = endBurned - startBurned; + + totalFees += fees; + totalBurned += burned; + + fees.Should().NotBe(0); + tracer.Fees.Should().Be(totalFees); + + burned.Should().NotBe(0); + tracer.BurntFees.Should().Be(totalBurned); + } + + tracer.EndBlockTrace(); + } +} diff --git a/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs b/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs index b845f3f7aac..48a3c9ff75d 100644 --- a/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs +++ b/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs @@ -1,19 +1,19 @@ // 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 . -// +// using Nethermind.Core; using Nethermind.Core.Specs; @@ -136,17 +136,17 @@ public bool IsEip158IgnoredAccount(Address address) private long? _overridenEip1559TransitionBlock; public long Eip1559TransitionBlock { - get - { - return _overridenEip1559TransitionBlock ?? _spec.Eip1559TransitionBlock; - } - set - { - _overridenEip1559TransitionBlock = value; - } + get => _overridenEip1559TransitionBlock ?? _spec.Eip1559TransitionBlock; + set => _overridenEip1559TransitionBlock = value; + } + + private Address? _overridenEip1559FeeCollector; + public Address? Eip1559FeeCollector + { + get => _overridenEip1559FeeCollector ?? _spec.Eip1559FeeCollector; + set => _overridenEip1559FeeCollector = value; } - public Address? Eip1559FeeCollector => _spec.Eip1559FeeCollector; public bool IsEip1153Enabled => _spec.IsEip1153Enabled; public bool IsEip3675Enabled => _spec.IsEip3675Enabled; public bool IsEip3651Enabled => _spec.IsEip3651Enabled; From 4094a576b8c9723049d395c6ad685d385a8a6c18 Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Wed, 16 Nov 2022 22:02:06 +0300 Subject: [PATCH 08/22] Add copyright --- .../TransactionProcessorFeeTests.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs index 300cc25ce32..c596a0c9b39 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs @@ -1,5 +1,19 @@ -// Copyright 2022 Demerzel Solutions Limited -// Licensed under the LGPL-3.0. For full terms, see LICENSE-LGPL in the project root. +// 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 . +// using FluentAssertions; using Nethermind.Core; From 4c1f654b9382a11f61bd7230184e1119380ee8b2 Mon Sep 17 00:00:00 2001 From: "lukasz.rozmej" Date: Fri, 18 Nov 2022 17:22:10 +0100 Subject: [PATCH 09/22] Try refactor to remove BlockHeader fields --- .../Processing/BlockProcessor.cs | 2 - src/Nethermind/Nethermind.Core/BlockHeader.cs | 4 - .../TransactionProcessorFeeTests.cs | 6 +- .../Tracing/BlockReceiptsTracer.cs | 6 - .../Nethermind.Evm/Tracing/FeesTracer.cs | 196 ++++++++++++++++++ ...sts.DelayBlockImprovementContextFactory.cs | 12 +- ...ests.MockBlockImprovementContextFactory.cs | 6 +- .../BlockImprovementContext.cs | 14 +- .../Boost/BoostBlockImprovementContext.cs | 15 +- .../IBlockImprovementContext.cs | 5 +- .../IBlockProductionContext.cs | 13 ++ .../IPayloadPreparationService.cs | 12 +- .../PayloadPreparationService.cs | 11 +- .../Data/V2/GetPayloadV2Result.cs | 4 +- .../Handlers/V1/GetPayloadV1Handler.cs | 2 +- .../Handlers/V2/GetPayloadV2Handler.cs | 7 +- 16 files changed, 263 insertions(+), 52 deletions(-) create mode 100644 src/Nethermind/Nethermind.Evm/Tracing/FeesTracer.cs create mode 100644 src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockProductionContext.cs diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs index 8a68939496f..54b058a5031 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs @@ -246,8 +246,6 @@ protected virtual TxReceipt[] ProcessBlock( block.Header.StateRoot = _stateProvider.StateRoot; block.Header.Hash = block.Header.CalculateHash(); - block.Header.Fees = _receiptsTracer.Fees; - block.Header.BurntFees = _receiptsTracer.BurntFees; return receipts; } diff --git a/src/Nethermind/Nethermind.Core/BlockHeader.cs b/src/Nethermind/Nethermind.Core/BlockHeader.cs index d10a9235fac..e4fea65e682 100644 --- a/src/Nethermind/Nethermind.Core/BlockHeader.cs +++ b/src/Nethermind/Nethermind.Core/BlockHeader.cs @@ -83,10 +83,6 @@ public BlockHeader( // ToDo we need to set this flag after reading block from db public bool IsPostMerge { get; set; } - // transient: - public UInt256 Fees { get; set; } - public UInt256 BurntFees { get; set; } - public string ToString(string indent) { StringBuilder builder = new(); diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs index c596a0c9b39..fbcc0629290 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs @@ -135,6 +135,8 @@ private void ExecuteAndCheckFees(Block block, params Transaction[] txs) IReleaseSpec spec = _specProvider.GetSpec((block.Number, block.Timestamp)); BlockReceiptsTracer tracer = new(); + FeesTracer feesTracer = new(); + tracer.SetOtherTracer(feesTracer); tracer.SetOtherTracer(NullBlockTracer.Instance); tracer.StartNewBlockTrace(block); @@ -165,10 +167,10 @@ private void ExecuteAndCheckFees(Block block, params Transaction[] txs) totalBurned += burned; fees.Should().NotBe(0); - tracer.Fees.Should().Be(totalFees); + feesTracer.Fees.Should().Be(totalFees); burned.Should().NotBe(0); - tracer.BurntFees.Should().Be(totalBurned); + feesTracer.BurntFees.Should().Be(totalBurned); } tracer.EndBlockTrace(); diff --git a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs index 621fbd83d6c..f64c4df1950 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs @@ -197,16 +197,12 @@ public void SetOperationMemory(List memoryTrace) => public void ReportFees(UInt256 fees, UInt256 burntFees) { - Fees += fees; - BurntFees += burntFees; if (_currentTxTracer.IsTracingReceipt) { _currentTxTracer.ReportFees(fees, burntFees); } } - public UInt256 Fees { get; private set; } = UInt256.Zero; - public UInt256 BurntFees { get; private set; } = UInt256.Zero; private ITxTracer _currentTxTracer = NullTxTracer.Instance; private int _currentIndex; private readonly List _txReceipts = new(); @@ -240,8 +236,6 @@ public void StartNewBlockTrace(Block block) _block = block; _currentIndex = 0; _txReceipts.Clear(); - Fees = UInt256.Zero; - BurntFees = UInt256.Zero; _otherTracer.StartNewBlockTrace(block); } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/FeesTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/FeesTracer.cs new file mode 100644 index 00000000000..af16967458f --- /dev/null +++ b/src/Nethermind/Nethermind.Evm/Tracing/FeesTracer.cs @@ -0,0 +1,196 @@ +// Copyright 2022 Demerzel Solutions Limited +// Licensed under the LGPL-3.0. For full terms, see LICENSE-LGPL in the project root. + +using System; +using System.Collections.Generic; +using Nethermind.Core; +using Nethermind.Core.Crypto; +using Nethermind.Int256; + +namespace Nethermind.Evm.Tracing; + +public class FeesTracer : IBlockTracer, ITxTracer +{ + public bool IsTracingRewards => false; + public bool IsTracingState => false; + public bool IsTracingActions => false; + public bool IsTracingOpLevelStorage => false; + public bool IsTracingMemory => false; + public bool IsTracingInstructions => false; + public bool IsTracingRefunds => false; + public bool IsTracingCode => false; + public bool IsTracingStack => false; + public bool IsTracingBlockHash => false; + public bool IsTracingAccess => false; + public bool IsTracingStorage => false; + public bool IsTracingReceipt => true; + + public UInt256 Fees { get; private set; } = UInt256.Zero; + public UInt256 BurntFees { get; private set; } = UInt256.Zero; + + public void ReportFees(UInt256 fees, UInt256 burntFees) + { + Fees += fees; + BurntFees += burntFees; + } + + public void StartNewBlockTrace(Block block) + { + Fees = UInt256.Zero; + BurntFees = UInt256.Zero; + } + + public ITxTracer StartNewTxTrace(Transaction? tx) => this; + + public void EndTxTrace() { } + + public void EndBlockTrace() { } + + public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak? stateRoot = null) { } + + public void MarkAsFailed(Address recipient, long gasSpent, byte[] output, string error, Keccak? stateRoot = null) { } + + public void ReportReward(Address author, string rewardType, UInt256 rewardValue) + { + throw new NotImplementedException(); + } + + public void ReportBalanceChange(Address address, UInt256? before, UInt256? after) + { + throw new NotImplementedException(); + } + + public void ReportCodeChange(Address address, byte[]? before, byte[]? after) + { + throw new NotImplementedException(); + } + + public void ReportNonceChange(Address address, UInt256? before, UInt256? after) + { + throw new NotImplementedException(); + } + + public void ReportAccountRead(Address address) + { + throw new NotImplementedException(); + } + public void ReportStorageChange(StorageCell storageCell, byte[] before, byte[] after) + { + throw new NotImplementedException(); + } + + public void ReportStorageRead(StorageCell storageCell) + { + throw new NotImplementedException(); + } + + public void StartOperation(int depth, long gas, Instruction opcode, int pc, bool isPostMerge = false) + { + throw new NotImplementedException(); + } + + public void ReportOperationError(EvmExceptionType error) + { + throw new NotImplementedException(); + } + + public void ReportOperationRemainingGas(long gas) + { + throw new NotImplementedException(); + } + + public void SetOperationStack(List stackTrace) + { + throw new NotImplementedException(); + } + + public void ReportStackPush(in ReadOnlySpan stackItem) + { + throw new NotImplementedException(); + } + + public void SetOperationMemory(List memoryTrace) + { + throw new NotImplementedException(); + } + + public void SetOperationMemorySize(ulong newSize) + { + throw new NotImplementedException(); + } + + public void ReportMemoryChange(long offset, in ReadOnlySpan data) + { + throw new NotImplementedException(); + } + + public void ReportStorageChange(in ReadOnlySpan key, in ReadOnlySpan value) + { + throw new NotImplementedException(); + } + + public void SetOperationStorage(Address address, UInt256 storageIndex, ReadOnlySpan newValue, ReadOnlySpan currentValue) + { + throw new NotImplementedException(); + } + + public void LoadOperationStorage(Address address, UInt256 storageIndex, ReadOnlySpan value) + { + throw new NotImplementedException(); + } + + public void ReportSelfDestruct(Address address, UInt256 balance, Address refundAddress) + { + throw new NotImplementedException(); + } + + public void ReportAction(long gas, UInt256 value, Address from, Address to, ReadOnlyMemory input, ExecutionType callType, bool isPrecompileCall = false) + { + throw new NotImplementedException(); + } + + public void ReportActionEnd(long gas, ReadOnlyMemory output) + { + throw new NotImplementedException(); + } + + public void ReportActionError(EvmExceptionType evmExceptionType) + { + throw new NotImplementedException(); + } + + public void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) + { + throw new NotImplementedException(); + } + + public void ReportBlockHash(Keccak blockHash) + { + throw new NotImplementedException(); + } + + public void ReportByteCode(byte[] byteCode) + { + throw new NotImplementedException(); + } + + public void ReportGasUpdateForVmTrace(long refund, long gasAvailable) + { + throw new NotImplementedException(); + } + + public void ReportRefund(long refund) + { + throw new NotImplementedException(); + } + + public void ReportExtraGasPressure(long extraGasPressure) + { + throw new NotImplementedException(); + } + + public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet accessedStorageCells) + { + throw new NotImplementedException(); + } +} diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs index 837c43264dd..cf882390e24 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Demerzel Solutions Limited +// 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 @@ -22,6 +22,7 @@ using Nethermind.Core; using Nethermind.Core.Extensions; using Nethermind.Evm.Tracing; +using Nethermind.Int256; using Nethermind.Merge.Plugin.BlockProduction; namespace Nethermind.Merge.Plugin.Test; @@ -58,7 +59,7 @@ public DelayBlockImprovementContext(Block currentBestBlock, DateTimeOffset startDateTime) { _cancellationTokenSource = new CancellationTokenSource(timeout); - CurrentBestBlock = currentBestBlock; + Block = currentBestBlock; StartDateTime = startDateTime; ImprovementTask = BuildBlock(blockProductionTrigger, parentHeader, payloadAttributes, delay, _cancellationTokenSource.Token); } @@ -74,14 +75,15 @@ public DelayBlockImprovementContext(Block currentBestBlock, await Task.Delay(delay, cancellationToken); if (block is not null) { - CurrentBestBlock = block; + Block = block; } - return CurrentBestBlock; + return Block; } public Task ImprovementTask { get; } - public Block? CurrentBestBlock { get; private set; } + public Block? Block { get; private set; } + public UInt256 BlockFees { get; } public bool Disposed { get; private set; } public DateTimeOffset StartDateTime { get; } diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.MockBlockImprovementContextFactory.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.MockBlockImprovementContextFactory.cs index 9ee5a978e36..cb55c608ceb 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.MockBlockImprovementContextFactory.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.MockBlockImprovementContextFactory.cs @@ -22,6 +22,7 @@ using Nethermind.Core; using Nethermind.Core.Extensions; using Nethermind.Evm.Tracing; +using Nethermind.Int256; using Nethermind.Merge.Plugin.BlockProduction; namespace Nethermind.Merge.Plugin.Test; @@ -38,14 +39,15 @@ private class MockBlockImprovementContext : IBlockImprovementContext { public MockBlockImprovementContext(Block currentBestBlock, DateTimeOffset startDateTime) { - CurrentBestBlock = currentBestBlock; + Block = currentBestBlock; StartDateTime = startDateTime; ImprovementTask = Task.FromResult((Block?)currentBestBlock); } public void Dispose() => Disposed = true; public Task ImprovementTask { get; } - public Block? CurrentBestBlock { get; } + public Block? Block { get; } + public UInt256 BlockFees { get; } public bool Disposed { get; private set; } public DateTimeOffset StartDateTime { get; } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs index 6c3b7c91b58..9f58152eece 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Demerzel Solutions Limited +// 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 @@ -22,12 +22,14 @@ using Nethermind.Core; using Nethermind.Core.Extensions; using Nethermind.Evm.Tracing; +using Nethermind.Int256; namespace Nethermind.Merge.Plugin.BlockProduction; public class BlockImprovementContext : IBlockImprovementContext { private CancellationTokenSource? _cancellationTokenSource; + private readonly FeesTracer _feesTracer = new(); public BlockImprovementContext(Block currentBestBlock, IManualBlockProductionTrigger blockProductionTrigger, @@ -37,16 +39,17 @@ public BlockImprovementContext(Block currentBestBlock, DateTimeOffset startDateTime) { _cancellationTokenSource = new CancellationTokenSource(timeout); - CurrentBestBlock = currentBestBlock; + Block = currentBestBlock; StartDateTime = startDateTime; ImprovementTask = blockProductionTrigger - .BuildBlock(parentHeader, _cancellationTokenSource.Token, NullBlockTracer.Instance, payloadAttributes) + .BuildBlock(parentHeader, _cancellationTokenSource.Token, _feesTracer, payloadAttributes) .ContinueWith(SetCurrentBestBlock, _cancellationTokenSource.Token); } public Task ImprovementTask { get; } - public Block? CurrentBestBlock { get; private set; } + public Block? Block { get; private set; } + public UInt256 BlockFees { get; private set; } private Block? SetCurrentBestBlock(Task task) { @@ -54,7 +57,8 @@ public BlockImprovementContext(Block currentBestBlock, { if (task.Result is not null) { - CurrentBestBlock = task.Result; + Block = task.Result; + BlockFees = _feesTracer.Fees; } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs index b3f786002a5..5be81e0bde1 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Demerzel Solutions Limited +// 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 @@ -34,6 +34,7 @@ public class BoostBlockImprovementContext : IBlockImprovementContext { private readonly IBoostRelay _boostRelay; private readonly IStateReader _stateReader; + private readonly FeesTracer _feesTracer = new(); private CancellationTokenSource? _cancellationTokenSource; public BoostBlockImprovementContext(Block currentBestBlock, @@ -48,7 +49,7 @@ public BoostBlockImprovementContext(Block currentBestBlock, _boostRelay = boostRelay; _stateReader = stateReader; _cancellationTokenSource = new CancellationTokenSource(timeout); - CurrentBestBlock = currentBestBlock; + Block = currentBestBlock; StartDateTime = startDateTime; ImprovementTask = StartImprovingBlock(blockProductionTrigger, parentHeader, payloadAttributes, _cancellationTokenSource.Token); } @@ -62,19 +63,21 @@ public BoostBlockImprovementContext(Block currentBestBlock, payloadAttributes = await _boostRelay.GetPayloadAttributes(payloadAttributes, cancellationToken); UInt256 balanceBefore = _stateReader.GetAccount(parentHeader.StateRoot!, payloadAttributes.SuggestedFeeRecipient)?.Balance ?? UInt256.Zero; - Block? block = await blockProductionTrigger.BuildBlock(parentHeader, cancellationToken, NullBlockTracer.Instance, payloadAttributes); + Block? block = await blockProductionTrigger.BuildBlock(parentHeader, cancellationToken, _feesTracer, payloadAttributes); if (block is not null) { - CurrentBestBlock = block; + Block = block; + BlockFees = _feesTracer.Fees; UInt256 balanceAfter = _stateReader.GetAccount(block.StateRoot!, payloadAttributes.SuggestedFeeRecipient)?.Balance ?? UInt256.Zero; await _boostRelay.SendPayload(new BoostExecutionPayloadV1 { Block = new ExecutionPayloadV1(block), Profit = balanceAfter - balanceBefore }, cancellationToken); } - return CurrentBestBlock; + return Block; } public Task ImprovementTask { get; } - public Block? CurrentBestBlock { get; private set; } + public Block? Block { get; private set; } + public UInt256 BlockFees { get; private set; } public bool Disposed { get; private set; } public DateTimeOffset StartDateTime { get; } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockImprovementContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockImprovementContext.cs index d0671394101..9df519e3bd6 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockImprovementContext.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockImprovementContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Demerzel Solutions Limited +// 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 @@ -21,10 +21,9 @@ namespace Nethermind.Merge.Plugin.BlockProduction; -public interface IBlockImprovementContext : IDisposable +public interface IBlockImprovementContext : IBlockProductionContext, IDisposable { Task ImprovementTask { get; } - Block? CurrentBestBlock { get; } bool Disposed { get; } DateTimeOffset StartDateTime { get; } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockProductionContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockProductionContext.cs new file mode 100644 index 00000000000..5383836d98a --- /dev/null +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockProductionContext.cs @@ -0,0 +1,13 @@ +// Copyright 2022 Demerzel Solutions Limited +// Licensed under the LGPL-3.0. For full terms, see LICENSE-LGPL in the project root. + +using Nethermind.Core; +using Nethermind.Int256; + +namespace Nethermind.Merge.Plugin.BlockProduction; + +public interface IBlockProductionContext +{ + Block? Block { get; } + UInt256 BlockFees { get; } +} diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IPayloadPreparationService.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IPayloadPreparationService.cs index eb2b1b3dd6a..41bcffbfa0b 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IPayloadPreparationService.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IPayloadPreparationService.cs @@ -1,19 +1,19 @@ -// Copyright (c) 2021 Demerzel Solutions Limited +// 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 . -// +// using System; using System.Threading.Tasks; @@ -26,7 +26,7 @@ public interface IPayloadPreparationService { string? StartPreparingPayload(BlockHeader parentHeader, PayloadAttributes payloadAttributes); - ValueTask GetPayload(string payloadId); + ValueTask GetPayload(string payloadId); event EventHandler? BlockImproved; } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs index 063e7c3490b..2e26a59ff72 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs @@ -26,6 +26,7 @@ using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Core.Timers; +using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Merge.Plugin.Handlers.V1; @@ -145,7 +146,7 @@ private IBlockImprovementContext CreateBlockImprovementContext(string payloadId, await Task.Delay(_improvementDelay); if (!blockImprovementContext.Disposed) // if GetPayload wasn't called for this item or it wasn't cleared { - Block newBestBlock = blockImprovementContext.CurrentBestBlock ?? currentBestBlock; + Block newBestBlock = blockImprovementContext.Block ?? currentBestBlock; ImproveBlock(payloadId, parentHeader, payloadAttributes, newBestBlock, startDateTime); } else @@ -170,7 +171,7 @@ private void CleanupOldPayloads(object? sender, EventArgs e) DateTimeOffset now = DateTimeOffset.UtcNow; if (payload.Value.StartDateTime + _cleanupOldPayloadDelay <= now) { - if (_logger.IsDebug) _logger.Info($"A new payload to remove: {payload.Key}, Current time {now:t}, Payload timestamp: {payload.Value.CurrentBestBlock?.Timestamp}"); + if (_logger.IsDebug) _logger.Info($"A new payload to remove: {payload.Key}, Current time {now:t}, Payload timestamp: {payload.Value.Block?.Timestamp}"); _payloadsToRemove.Add(payload.Key); } } @@ -214,19 +215,19 @@ private void CleanupOldPayloads(object? sender, EventArgs e) return t.Result; } - public async ValueTask GetPayload(string payloadId) + public async ValueTask GetPayload(string payloadId) { if (_payloadStorage.TryGetValue(payloadId, out IBlockImprovementContext? blockContext)) { using (blockContext) { - bool currentBestBlockIsEmpty = blockContext.CurrentBestBlock?.Transactions.Any() != true; + bool currentBestBlockIsEmpty = blockContext.Block?.Transactions.Any() != true; if (currentBestBlockIsEmpty && !blockContext.ImprovementTask.IsCompleted) { await Task.WhenAny(blockContext.ImprovementTask, Task.Delay(GetPayloadWaitForFullBlockMillisecondsDelay)); } - return blockContext.CurrentBestBlock; + return blockContext; } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/V2/GetPayloadV2Result.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/V2/GetPayloadV2Result.cs index 97e328fb405..14dac666ab0 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Data/V2/GetPayloadV2Result.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/V2/GetPayloadV2Result.cs @@ -26,10 +26,10 @@ public class GetPayloadV2Result public ExecutionPayloadV1 ExecutionPayloadV1; public UInt256 BlockValue; - public GetPayloadV2Result(Block block) + public GetPayloadV2Result(Block block, UInt256 blockFees) { ExecutionPayloadV1 = new(block); - BlockValue = block.Header.Fees; + BlockValue = blockFees; } public override string ToString() => $"ExecutionPayloadV1: {ExecutionPayloadV1}, Fees: {BlockValue}"; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V1/GetPayloadV1Handler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V1/GetPayloadV1Handler.cs index ec9c482d8d1..8a4d45de4eb 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V1/GetPayloadV1Handler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V1/GetPayloadV1Handler.cs @@ -53,7 +53,7 @@ public GetPayloadV1Handler(IPayloadPreparationService payloadPreparationService, public async Task> HandleAsync(byte[] payloadId) { string payloadStr = payloadId.ToHexString(true); - Block? block = await _payloadPreparationService.GetPayload(payloadStr); + Block? block = (await _payloadPreparationService.GetPayload(payloadStr))?.Block; if (block is null) { diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V2/GetPayloadV2Handler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V2/GetPayloadV2Handler.cs index 996d91a9292..78daaaf719b 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V2/GetPayloadV2Handler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V2/GetPayloadV2Handler.cs @@ -39,9 +39,10 @@ public GetPayloadV2Handler(IPayloadPreparationService payloadPreparationService, public async Task> HandleAsync(byte[] payloadId) { string payloadStr = payloadId.ToHexString(true); - Block? block = await _payloadPreparationService.GetPayload(payloadStr); + IBlockProductionContext? blockContext = await _payloadPreparationService.GetPayload(payloadStr); + Block? block = blockContext?.Block; - if (block == null) + if (block is null) { // The call MUST return -38001: Unknown payload error if the build process identified by the payloadId does not exist. if (_logger.IsWarn) _logger.Warn($"Block production for payload with id={payloadId.ToHexString()} failed - unknown payload."); @@ -52,7 +53,7 @@ public GetPayloadV2Handler(IPayloadPreparationService payloadPreparationService, Metrics.GetPayloadRequests++; Metrics.NumberOfTransactionsInGetPayload = block.Transactions.Length; - return ResultWrapper.Success(new GetPayloadV2Result(block)); + return ResultWrapper.Success(new GetPayloadV2Result(block, blockContext!.BlockFees)); } } } From 129a2c8d73e70f59d266423249406651e1f688c2 Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Sat, 19 Nov 2022 12:35:51 +0300 Subject: [PATCH 10/22] Adjust tests --- .../EngineModuleTests.V1.PayloadProduction.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.PayloadProduction.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.PayloadProduction.cs index 9b7189a0b63..6089e4f4ce9 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.PayloadProduction.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.PayloadProduction.cs @@ -224,7 +224,9 @@ public async Task getPayload_correctlyEncodeTransactions() Block block = Build.A.Block.WithTransactions( Build.A.Transaction.WithTo(TestItem.AddressD).SignedAndResolved(TestItem.PrivateKeyA).TestObject, Build.A.Transaction.WithTo(TestItem.AddressD).WithType(TxType.EIP1559).WithMaxFeePerGas(20).SignedAndResolved(TestItem.PrivateKeyA).TestObject).TestObject; - payloadPreparationService.GetPayload(Arg.Any()).Returns(block); + IBlockProductionContext improvementContext = Substitute.For(); + improvementContext.Block.Returns(block); + payloadPreparationService.GetPayload(Arg.Any()).Returns(improvementContext); using MergeTestBlockchain chain = await CreateBlockChain(null, payloadPreparationService); IEngineRpcModule rpc = CreateEngineModule(chain); @@ -320,7 +322,7 @@ public async Task getPayloadV1_picks_transactions_from_pool_constantly_improving List transactionsLength = improvementContextFactory.CreatedContexts .Select(c => - c.CurrentBestBlock?.Transactions.Length).ToList(); + c.Block?.Transactions.Length).ToList(); transactionsLength.Should().Equal(3, 6, 11); Transaction[] txs = getPayloadResult.GetTransactions(); From 375ec8da99bb11dae2777eb5ac37113beb4f4659 Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Sat, 19 Nov 2022 13:05:21 +0300 Subject: [PATCH 11/22] Fix encoding? --- .../BlockProduction/BlockImprovementContextFactory.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContextFactory.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContextFactory.cs index 80af550238f..41b09ecc3cb 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContextFactory.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContextFactory.cs @@ -18,7 +18,6 @@ using System; using Nethermind.Consensus.Producers; using Nethermind.Core; -using Org.BouncyCastle.Asn1.Cms; namespace Nethermind.Merge.Plugin.BlockProduction; From 48e1102ea9558115dd3eba421e178e417d185bbe Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Sat, 19 Nov 2022 13:14:16 +0300 Subject: [PATCH 12/22] Fix encoding? --- ...sts.DelayBlockImprovementContextFactory.cs | 6 ++++-- .../BlockImprovementContext.cs | 2 +- .../Boost/BoostBlockImprovementContext.cs | 20 ++++++++++++------- .../IBlockImprovementContext.cs | 1 + .../IPayloadPreparationService.cs | 2 +- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs index cf882390e24..2b6557374c2 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs @@ -42,8 +42,10 @@ public DelayBlockImprovementContextFactory(IManualBlockProductionTrigger product _delay = delay; } - public IBlockImprovementContext StartBlockImprovementContext(Block currentBestBlock, BlockHeader parentHeader, PayloadAttributes payloadAttributes, DateTimeOffset startDateTime) => - new DelayBlockImprovementContext(currentBestBlock, _productionTrigger, _timeout, parentHeader, payloadAttributes, _delay, startDateTime); + public IBlockImprovementContext StartBlockImprovementContext(Block currentBestBlock, BlockHeader parentHeader, + PayloadAttributes payloadAttributes, DateTimeOffset startDateTime) => + new DelayBlockImprovementContext(currentBestBlock, _productionTrigger, _timeout, parentHeader, + payloadAttributes, _delay, startDateTime); } private class DelayBlockImprovementContext : IBlockImprovementContext diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs index 9f58152eece..ed88513ed63 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the Nethermind. If not, see . // - +// using System; using System.Threading; using System.Threading.Tasks; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs index 5be81e0bde1..2a5561c9c5e 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs @@ -16,14 +16,12 @@ // using System; -using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Nethermind.Consensus.Producers; using Nethermind.Core; using Nethermind.Core.Extensions; using Nethermind.Evm.Tracing; -using Nethermind.Facade.Proxy; using Nethermind.Int256; using Nethermind.Merge.Plugin.Data.V1; using Nethermind.State; @@ -60,16 +58,24 @@ public BoostBlockImprovementContext(Block currentBestBlock, PayloadAttributes payloadAttributes, CancellationToken cancellationToken) { - payloadAttributes = await _boostRelay.GetPayloadAttributes(payloadAttributes, cancellationToken); - UInt256 balanceBefore = _stateReader.GetAccount(parentHeader.StateRoot!, payloadAttributes.SuggestedFeeRecipient)?.Balance ?? UInt256.Zero; - Block? block = await blockProductionTrigger.BuildBlock(parentHeader, cancellationToken, _feesTracer, payloadAttributes); + UInt256 balanceBefore = + _stateReader.GetAccount(parentHeader.StateRoot!, payloadAttributes.SuggestedFeeRecipient)?.Balance ?? + UInt256.Zero; + Block? block = + await blockProductionTrigger.BuildBlock(parentHeader, cancellationToken, _feesTracer, payloadAttributes); if (block is not null) { Block = block; BlockFees = _feesTracer.Fees; - UInt256 balanceAfter = _stateReader.GetAccount(block.StateRoot!, payloadAttributes.SuggestedFeeRecipient)?.Balance ?? UInt256.Zero; - await _boostRelay.SendPayload(new BoostExecutionPayloadV1 { Block = new ExecutionPayloadV1(block), Profit = balanceAfter - balanceBefore }, cancellationToken); + UInt256 balanceAfter = + _stateReader.GetAccount(block.StateRoot!, payloadAttributes.SuggestedFeeRecipient)?.Balance ?? + UInt256.Zero; + await _boostRelay.SendPayload( + new BoostExecutionPayloadV1 + { + Block = new ExecutionPayloadV1(block), Profit = balanceAfter - balanceBefore + }, cancellationToken); } return Block; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockImprovementContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockImprovementContext.cs index 9df519e3bd6..a61c1ebc986 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockImprovementContext.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockImprovementContext.cs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the Nethermind. If not, see . // +// using System; using System.Threading.Tasks; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IPayloadPreparationService.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IPayloadPreparationService.cs index 41bcffbfa0b..d069d784670 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IPayloadPreparationService.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IPayloadPreparationService.cs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the Nethermind. If not, see . // - +// using System; using System.Threading.Tasks; using Nethermind.Consensus.Producers; From 306abc4c7021d01def9030f8ee1109950e291fd4 Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Sat, 19 Nov 2022 14:25:32 +0300 Subject: [PATCH 13/22] Fix encoding? --- .../Boost/BoostBlockImprovementContext.cs | 96 +------------------ 1 file changed, 1 insertion(+), 95 deletions(-) diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs index 2a5561c9c5e..5f282702bb0 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs @@ -1,95 +1 @@ -// 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 . -// - -using System; -using System.Threading; -using System.Threading.Tasks; -using Nethermind.Consensus.Producers; -using Nethermind.Core; -using Nethermind.Core.Extensions; -using Nethermind.Evm.Tracing; -using Nethermind.Int256; -using Nethermind.Merge.Plugin.Data.V1; -using Nethermind.State; - -namespace Nethermind.Merge.Plugin.BlockProduction.Boost; - -public class BoostBlockImprovementContext : IBlockImprovementContext -{ - private readonly IBoostRelay _boostRelay; - private readonly IStateReader _stateReader; - private readonly FeesTracer _feesTracer = new(); - private CancellationTokenSource? _cancellationTokenSource; - - public BoostBlockImprovementContext(Block currentBestBlock, - IManualBlockProductionTrigger blockProductionTrigger, - TimeSpan timeout, - BlockHeader parentHeader, - PayloadAttributes payloadAttributes, - IBoostRelay boostRelay, - IStateReader stateReader, - DateTimeOffset startDateTime) - { - _boostRelay = boostRelay; - _stateReader = stateReader; - _cancellationTokenSource = new CancellationTokenSource(timeout); - Block = currentBestBlock; - StartDateTime = startDateTime; - ImprovementTask = StartImprovingBlock(blockProductionTrigger, parentHeader, payloadAttributes, _cancellationTokenSource.Token); - } - - private async Task StartImprovingBlock( - IManualBlockProductionTrigger blockProductionTrigger, - BlockHeader parentHeader, - PayloadAttributes payloadAttributes, - CancellationToken cancellationToken) - { - payloadAttributes = await _boostRelay.GetPayloadAttributes(payloadAttributes, cancellationToken); - UInt256 balanceBefore = - _stateReader.GetAccount(parentHeader.StateRoot!, payloadAttributes.SuggestedFeeRecipient)?.Balance ?? - UInt256.Zero; - Block? block = - await blockProductionTrigger.BuildBlock(parentHeader, cancellationToken, _feesTracer, payloadAttributes); - if (block is not null) - { - Block = block; - BlockFees = _feesTracer.Fees; - UInt256 balanceAfter = - _stateReader.GetAccount(block.StateRoot!, payloadAttributes.SuggestedFeeRecipient)?.Balance ?? - UInt256.Zero; - await _boostRelay.SendPayload( - new BoostExecutionPayloadV1 - { - Block = new ExecutionPayloadV1(block), Profit = balanceAfter - balanceBefore - }, cancellationToken); - } - - return Block; - } - - public Task ImprovementTask { get; } - public Block? Block { get; private set; } - public UInt256 BlockFees { get; private set; } - public bool Disposed { get; private set; } - public DateTimeOffset StartDateTime { get; } - - public void Dispose() - { - Disposed = true; - CancellationTokenExtensions.CancelDisposeAndClear(ref _cancellationTokenSource); - } -} + \ No newline at end of file From e9bcf530e97ae35116e620fbce92df8ada174428 Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Sat, 19 Nov 2022 14:46:40 +0300 Subject: [PATCH 14/22] Revert commits --- ...sts.DelayBlockImprovementContextFactory.cs | 6 +- .../BlockImprovementContext.cs | 2 +- .../BlockImprovementContextFactory.cs | 1 + .../Boost/BoostBlockImprovementContext.cs | 90 ++++++++++++++++++- .../IBlockImprovementContext.cs | 1 - .../IPayloadPreparationService.cs | 2 +- 6 files changed, 94 insertions(+), 8 deletions(-) diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs index 2b6557374c2..cf882390e24 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs @@ -42,10 +42,8 @@ public DelayBlockImprovementContextFactory(IManualBlockProductionTrigger product _delay = delay; } - public IBlockImprovementContext StartBlockImprovementContext(Block currentBestBlock, BlockHeader parentHeader, - PayloadAttributes payloadAttributes, DateTimeOffset startDateTime) => - new DelayBlockImprovementContext(currentBestBlock, _productionTrigger, _timeout, parentHeader, - payloadAttributes, _delay, startDateTime); + public IBlockImprovementContext StartBlockImprovementContext(Block currentBestBlock, BlockHeader parentHeader, PayloadAttributes payloadAttributes, DateTimeOffset startDateTime) => + new DelayBlockImprovementContext(currentBestBlock, _productionTrigger, _timeout, parentHeader, payloadAttributes, _delay, startDateTime); } private class DelayBlockImprovementContext : IBlockImprovementContext diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs index ed88513ed63..9f58152eece 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the Nethermind. If not, see . // -// + using System; using System.Threading; using System.Threading.Tasks; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContextFactory.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContextFactory.cs index 41b09ecc3cb..80af550238f 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContextFactory.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContextFactory.cs @@ -18,6 +18,7 @@ using System; using Nethermind.Consensus.Producers; using Nethermind.Core; +using Org.BouncyCastle.Asn1.Cms; namespace Nethermind.Merge.Plugin.BlockProduction; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs index 5f282702bb0..5be81e0bde1 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs @@ -1 +1,89 @@ - \ No newline at end of file +// 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 . +// + +using System; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Nethermind.Consensus.Producers; +using Nethermind.Core; +using Nethermind.Core.Extensions; +using Nethermind.Evm.Tracing; +using Nethermind.Facade.Proxy; +using Nethermind.Int256; +using Nethermind.Merge.Plugin.Data.V1; +using Nethermind.State; + +namespace Nethermind.Merge.Plugin.BlockProduction.Boost; + +public class BoostBlockImprovementContext : IBlockImprovementContext +{ + private readonly IBoostRelay _boostRelay; + private readonly IStateReader _stateReader; + private readonly FeesTracer _feesTracer = new(); + private CancellationTokenSource? _cancellationTokenSource; + + public BoostBlockImprovementContext(Block currentBestBlock, + IManualBlockProductionTrigger blockProductionTrigger, + TimeSpan timeout, + BlockHeader parentHeader, + PayloadAttributes payloadAttributes, + IBoostRelay boostRelay, + IStateReader stateReader, + DateTimeOffset startDateTime) + { + _boostRelay = boostRelay; + _stateReader = stateReader; + _cancellationTokenSource = new CancellationTokenSource(timeout); + Block = currentBestBlock; + StartDateTime = startDateTime; + ImprovementTask = StartImprovingBlock(blockProductionTrigger, parentHeader, payloadAttributes, _cancellationTokenSource.Token); + } + + private async Task StartImprovingBlock( + IManualBlockProductionTrigger blockProductionTrigger, + BlockHeader parentHeader, + PayloadAttributes payloadAttributes, + CancellationToken cancellationToken) + { + + payloadAttributes = await _boostRelay.GetPayloadAttributes(payloadAttributes, cancellationToken); + UInt256 balanceBefore = _stateReader.GetAccount(parentHeader.StateRoot!, payloadAttributes.SuggestedFeeRecipient)?.Balance ?? UInt256.Zero; + Block? block = await blockProductionTrigger.BuildBlock(parentHeader, cancellationToken, _feesTracer, payloadAttributes); + if (block is not null) + { + Block = block; + BlockFees = _feesTracer.Fees; + UInt256 balanceAfter = _stateReader.GetAccount(block.StateRoot!, payloadAttributes.SuggestedFeeRecipient)?.Balance ?? UInt256.Zero; + await _boostRelay.SendPayload(new BoostExecutionPayloadV1 { Block = new ExecutionPayloadV1(block), Profit = balanceAfter - balanceBefore }, cancellationToken); + } + + return Block; + } + + public Task ImprovementTask { get; } + public Block? Block { get; private set; } + public UInt256 BlockFees { get; private set; } + public bool Disposed { get; private set; } + public DateTimeOffset StartDateTime { get; } + + public void Dispose() + { + Disposed = true; + CancellationTokenExtensions.CancelDisposeAndClear(ref _cancellationTokenSource); + } +} diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockImprovementContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockImprovementContext.cs index a61c1ebc986..9df519e3bd6 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockImprovementContext.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockImprovementContext.cs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU Lesser General Public License // along with the Nethermind. If not, see . // -// using System; using System.Threading.Tasks; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IPayloadPreparationService.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IPayloadPreparationService.cs index d069d784670..41bcffbfa0b 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IPayloadPreparationService.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IPayloadPreparationService.cs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the Nethermind. If not, see . // -// + using System; using System.Threading.Tasks; using Nethermind.Consensus.Producers; From d72a0fdcd1c71cd4443cb525aa123d64a96709a0 Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Sat, 19 Nov 2022 15:18:09 +0300 Subject: [PATCH 15/22] Fix encoding --- .../EngineModuleTests.DelayBlockImprovementContextFactory.cs | 2 +- .../BlockProduction/BlockImprovementContext.cs | 2 +- .../BlockProduction/Boost/BoostBlockImprovementContext.cs | 2 +- .../BlockProduction/IBlockImprovementContext.cs | 2 +- .../BlockProduction/IPayloadPreparationService.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs index cf882390e24..a47d3f2231f 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Demerzel Solutions Limited +// 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 diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs index 9f58152eece..37e0d4974a3 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Demerzel Solutions Limited +// 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 diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs index 5be81e0bde1..61ce07ff388 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Demerzel Solutions Limited +// 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 diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockImprovementContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockImprovementContext.cs index 9df519e3bd6..6699f375b35 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockImprovementContext.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockImprovementContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Demerzel Solutions Limited +// 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 diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IPayloadPreparationService.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IPayloadPreparationService.cs index 41bcffbfa0b..3dbe21987ce 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IPayloadPreparationService.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IPayloadPreparationService.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Demerzel Solutions Limited +// 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 From bb5f75336624b7f6f001f3688043169c56a0c712 Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Sat, 19 Nov 2022 18:14:24 +0300 Subject: [PATCH 16/22] Fix tests --- .../Nethermind.Consensus/Processing/BlockchainProcessor.cs | 2 -- .../Nethermind.Evm.Test/TransactionProcessorFeeTests.cs | 1 - 2 files changed, 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockchainProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockchainProcessor.cs index 0f83e435225..40030d860ea 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockchainProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockchainProcessor.cs @@ -18,7 +18,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.Threading; using System.Threading.Tasks; using Nethermind.Blockchain; @@ -26,7 +25,6 @@ using Nethermind.Core; using Nethermind.Core.Attributes; using Nethermind.Core.Crypto; -using Nethermind.Db; using Nethermind.Evm.Tracing; using Nethermind.Evm.Tracing.GethStyle; using Nethermind.Evm.Tracing.ParityStyle; diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs index fbcc0629290..0d159f16386 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs @@ -137,7 +137,6 @@ private void ExecuteAndCheckFees(Block block, params Transaction[] txs) BlockReceiptsTracer tracer = new(); FeesTracer feesTracer = new(); tracer.SetOtherTracer(feesTracer); - tracer.SetOtherTracer(NullBlockTracer.Instance); tracer.StartNewBlockTrace(block); From ede813d605df4479003775deee6b66e03ae8302e Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Tue, 22 Nov 2022 19:42:14 +0300 Subject: [PATCH 17/22] Fix copyright --- .../TransactionProcessorFeeTests.cs | 18 ++---------------- .../Data/V2/GetPayloadV2Result.cs | 18 ++---------------- .../Handlers/V2/GetPayloadV2Handler.cs | 18 ++---------------- 3 files changed, 6 insertions(+), 48 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs index 0d159f16386..9211d608eaa 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs @@ -1,19 +1,5 @@ -// 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 . -// +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only using FluentAssertions; using Nethermind.Core; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Data/V2/GetPayloadV2Result.cs b/src/Nethermind/Nethermind.Merge.Plugin/Data/V2/GetPayloadV2Result.cs index 14dac666ab0..fb9eeb84b25 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Data/V2/GetPayloadV2Result.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Data/V2/GetPayloadV2Result.cs @@ -1,19 +1,5 @@ -// 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 . -// +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only using Nethermind.Core; using Nethermind.Int256; diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V2/GetPayloadV2Handler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V2/GetPayloadV2Handler.cs index 78daaaf719b..f2d9a525fe1 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V2/GetPayloadV2Handler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V2/GetPayloadV2Handler.cs @@ -1,19 +1,5 @@ -// 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 . -// +// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only using System.Threading.Tasks; using Nethermind.Core; From 15142d8d33ee7dca6601bdcb70e52b843f346142 Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Wed, 23 Nov 2022 20:31:59 +0300 Subject: [PATCH 18/22] IsTracingFees & Tests --- .../Executor/UserOperationTracer.cs | 8 +- .../TestAllTracerWithOutput.cs | 7 +- .../TransactionProcessorFeeTests.cs | 164 ++++++++++++------ .../Nethermind.Evm/Tracing/AccessTxTracer.cs | 8 +- .../Tracing/AlwaysCancelTxTracer.cs | 2 + .../Tracing/BlockReceiptsTracer.cs | 3 +- .../Tracing/CallOutputTracer.cs | 6 + .../Tracing/CancellationTxTracer.cs | 9 +- .../Tracing/CompositeTxTracer.cs | 4 +- .../Tracing/EstimateGasTracer.cs | 6 + .../Nethermind.Evm/Tracing/FeesTracer.cs | 3 +- .../Nethermind.Evm/Tracing/GasEstimator.cs | 7 +- .../Tracing/GethStyle/GethLikeTxTracer.cs | 6 + .../Nethermind.Evm/Tracing/ITxTracer.cs | 7 +- .../Nethermind.Evm/Tracing/NullTxTracer.cs | 4 + .../Tracing/ParityStyle/ParityLikeTxTracer.cs | 6 + .../Tracing/Proofs/ProofTxTracer.cs | 6 + .../TransactionProcessor.cs | 5 +- .../Nethermind.Mev/BeneficiaryTracer.cs | 4 +- .../Execution/TxBundleSimulator.cs | 8 +- 20 files changed, 207 insertions(+), 66 deletions(-) diff --git a/src/Nethermind/Nethermind.AccountAbstraction/Executor/UserOperationTracer.cs b/src/Nethermind/Nethermind.AccountAbstraction/Executor/UserOperationTracer.cs index 81a1bdd7feb..570538d0b49 100644 --- a/src/Nethermind/Nethermind.AccountAbstraction/Executor/UserOperationTracer.cs +++ b/src/Nethermind/Nethermind.AccountAbstraction/Executor/UserOperationTracer.cs @@ -1,5 +1,5 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only +// SPDX-License-Identifier: LGPL-3.0-only using System; using System.Collections.Generic; @@ -77,6 +77,7 @@ public UserOperationTxTracer( public bool IsTracingStorage => false; public bool IsTracingBlockHash => false; public bool IsTracingAccess => true; + public bool IsTracingFees => false; public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak? stateRoot = null) @@ -330,5 +331,10 @@ private void AddToAccessedStorage(Address address, UInt256 index) AccessedStorage.Add(address, new HashSet { index }); } + + public void ReportFees(UInt256 fees, UInt256 burntFees) + { + throw new NotImplementedException(); + } } } diff --git a/src/Nethermind/Nethermind.Evm.Test/TestAllTracerWithOutput.cs b/src/Nethermind/Nethermind.Evm.Test/TestAllTracerWithOutput.cs index 139a2bfc107..7872875a89f 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TestAllTracerWithOutput.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TestAllTracerWithOutput.cs @@ -1,5 +1,5 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only +// SPDX-License-Identifier: LGPL-3.0-only using System; using System.Collections.Generic; @@ -24,6 +24,7 @@ public class TestAllTracerWithOutput : ITxTracer public bool IsTracingStorage => true; public bool IsTracingBlockHash => true; public bool IsTracingAccess { get; set; } = true; + public bool IsTracingFees => true; public byte[] ReturnValue { get; set; } @@ -165,5 +166,9 @@ public void ReportExtraGasPressure(long extraGasPressure) public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet accessedStorageCells) { } + + public void ReportFees(UInt256 fees, UInt256 burntFees) + { + } } } diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs index 9211d608eaa..129b158cab4 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs @@ -1,16 +1,16 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; +using System.Threading; using FluentAssertions; using Nethermind.Core; using Nethermind.Core.Extensions; -using Nethermind.Core.Specs; using Nethermind.Core.Test.Builders; using Nethermind.Crypto; using Nethermind.Db; using Nethermind.Evm.Tracing; using Nethermind.Evm.TransactionProcessing; -using Nethermind.Int256; using Nethermind.Logging; using Nethermind.Specs; using Nethermind.Specs.Forks; @@ -27,13 +27,13 @@ public class TransactionProcessorFeeTests private IEthereumEcdsa _ethereumEcdsa; private TransactionProcessor _transactionProcessor; private IStateProvider _stateProvider; + private OverridableReleaseSpec _spec; [SetUp] public void Setup() { - OverridableReleaseSpec spec = new(London.Instance); - spec.Eip1559FeeCollector = TestItem.AddressC; - _specProvider = new TestSpecProvider(spec); + _spec = new(London.Instance); + _specProvider = new TestSpecProvider(_spec); TrieStore trieStore = new(new MemDb(), LimboLogs.Instance); @@ -49,13 +49,16 @@ public void Setup() _ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId, LimboLogs.Instance); } - [TestCase(true)] - [TestCase(false)] - public void Check_paid_fees_simple(bool isTransactionEip1559) + [TestCase(true, true)] + [TestCase(false, true)] + [TestCase(true, false)] + [TestCase(false, false)] + public void Check_paid_fees_simple(bool isTransactionEip1559, bool withFeeCollector) { - OverridableReleaseSpec spec = new(London.Instance); - spec.Eip1559FeeCollector = TestItem.AddressC; - _specProvider = new TestSpecProvider(spec); + if (withFeeCollector) + { + _spec.Eip1559FeeCollector = TestItem.AddressC; + } Transaction tx = Build.A.Transaction .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithGasPrice(10).WithMaxFeePerGas(10) @@ -64,23 +67,45 @@ public void Check_paid_fees_simple(bool isTransactionEip1559) .WithBeneficiary(TestItem.AddressB).WithBaseFeePerGas(1).WithTransactions(tx).WithGasLimit(21000) .TestObject; - ExecuteAndCheckFees(block, tx); + FeesTracer tracer = new(); + CompositeBlockTracer compositeTracer = new(); + compositeTracer.Add(tracer); + compositeTracer.Add(NullBlockTracer.Instance); + + ExecuteAndTrace(block, compositeTracer); + + tracer.Fees.Should().Be(189000); + tracer.BurntFees.Should().Be(21000); } - [Test] - public void Check_paid_fees_multiple_transactions() + [TestCase(false)] + [TestCase(true)] + public void Check_paid_fees_multiple_transactions(bool withFeeCollector) { + if (withFeeCollector) + { + _spec.Eip1559FeeCollector = TestItem.AddressC; + } + Transaction tx1 = Build.A.Transaction .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithType(TxType.EIP1559) - .WithMaxFeePerGas(10).WithGasPrice(1).WithGasLimit(21000).TestObject; - Transaction tx2 = Build.A.Transaction + .WithMaxFeePerGas(3).WithMaxPriorityFeePerGas(1).WithGasLimit(21000).TestObject; + Transaction tx2 = Build.A.Transaction.WithType(TxType.Legacy) .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithNonce(1) .WithGasPrice(10).WithGasLimit(21000).TestObject; - Block block = Build.A.Block.WithNumber(0).WithBaseFeePerGas(1) + Block block = Build.A.Block.WithNumber(0).WithBaseFeePerGas(2) .WithBeneficiary(TestItem.AddressB).WithTransactions(tx1, tx2).WithGasLimit(42000).TestObject; - ExecuteAndCheckFees(block, tx1, tx2); + FeesTracer tracer = new(); + ExecuteAndTrace(block, tracer); + + // tx1: 1 * 21000 + // tx2: (10 - 2) * 21000 = 168000 + tracer.Fees.Should().Be(189000); + + block.GasUsed.Should().Be(42000); + tracer.BurntFees.Should().Be(84000); } @@ -98,66 +123,101 @@ public void Check_paid_fees_with_byte_code() .Op(Instruction.STOP) .Done; Transaction tx1 = Build.A.Transaction - .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithMaxFeePerGas(10).WithGasPrice(1) + .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithMaxFeePerGas(3).WithMaxPriorityFeePerGas(2) .WithType(TxType.EIP1559).WithGasLimit(21000).TestObject; Transaction tx2 = Build.A.Transaction .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithNonce(1).WithGasPrice(10) .WithType(TxType.Legacy).WithGasLimit(21000).TestObject; Transaction tx3 = Build.A.Transaction - .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithNonce(2).WithMaxFeePerGas(30).WithGasPrice(1) + .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithNonce(2).WithMaxFeePerGas(2).WithMaxPriorityFeePerGas(1) .WithType(TxType.EIP1559).WithCode(byteCode) .WithGasLimit(60000).TestObject; Block block = Build.A.Block.WithNumber(MainnetSpecProvider.LondonBlockNumber) .WithBeneficiary(TestItem.AddressB).WithBaseFeePerGas(1).WithTransactions(tx1, tx2, tx3) .WithGasLimit(102000).TestObject; - ExecuteAndCheckFees(block, tx1, tx2, tx3); - } + FeesTracer tracer = new(); + ExecuteAndTrace(block, tracer); + + // tx1: 2 * 21000 + // tx2: (10 - 1) * 21000 + // tx3: 1 * 60000 + tracer.Fees.Should().Be(291000); + block.GasUsed.Should().Be(102000); + tracer.BurntFees.Should().Be(102000); + } - private void ExecuteAndCheckFees(Block block, params Transaction[] txs) + [TestCase(false)] + [TestCase(true)] + public void Should_stop_when_cancellation(bool withCanselation) { - Address beneficiary = block.Beneficiary!; - IReleaseSpec spec = _specProvider.GetSpec((block.Number, block.Timestamp)); + Transaction tx1 = Build.A.Transaction + .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithType(TxType.EIP1559) + .WithMaxFeePerGas(3).WithMaxPriorityFeePerGas(1).WithGasLimit(21000).TestObject; + Transaction tx2 = Build.A.Transaction.WithType(TxType.Legacy) + .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithNonce(1) + .WithGasPrice(10).WithGasLimit(21000).TestObject; + Block block = Build.A.Block.WithNumber(0).WithBaseFeePerGas(2) + .WithBeneficiary(TestItem.AddressB).WithTransactions(tx1, tx2).WithGasLimit(42000).TestObject; - BlockReceiptsTracer tracer = new(); FeesTracer feesTracer = new(); - tracer.SetOtherTracer(feesTracer); - tracer.StartNewBlockTrace(block); + CancellationTokenSource source = new(); + CancellationToken token = source.Token; - UInt256 totalBurned = UInt256.Zero; - UInt256 totalFees = UInt256.Zero; - foreach (Transaction tx in txs) - { - // Read balances of Eip1559FeeCollector and blockBeneficiary before tx execution - UInt256 startBurned = _stateProvider.AccountExists(spec.Eip1559FeeCollector!) - ? _stateProvider.GetBalance(spec.Eip1559FeeCollector!) : 0; - UInt256 starBeneficiary = _stateProvider.GetBalance(beneficiary); + CancellationBlockTracer cancellationBlockTracer = new(feesTracer, token); + BlockReceiptsTracer blockTracer = new(); + blockTracer.SetOtherTracer(cancellationBlockTracer); - tracer.StartNewTxTrace(tx); - _transactionProcessor.Execute(tx, block.Header, tracer); - tracer.EndTxTrace(); + blockTracer.StartNewBlockTrace(block); + { + var txTracer = blockTracer.StartNewTxTrace(tx1); + _transactionProcessor.Execute(tx1, block.Header, txTracer); + blockTracer.EndTxTrace(); + } - // Read balances of Eip1559FeeCollector and blockBeneficiary after tx execution - UInt256 endBurned = spec.IsEip1559Enabled ? _stateProvider.GetBalance(spec.Eip1559FeeCollector!) : 0; - UInt256 endBeneficiary = _stateProvider.GetBalance(beneficiary); + if (withCanselation) + { + source.Cancel(); + } - // Calculate expected fees - UInt256 fees = endBeneficiary - starBeneficiary; - UInt256 burned = endBurned - startBurned; + try + { + var txTracer = blockTracer.StartNewTxTrace(tx2); + _transactionProcessor.Execute(tx2, block.Header, txTracer); + blockTracer.EndTxTrace(); + blockTracer.EndBlockTrace(); + } + catch (OperationCanceledException) { } - totalFees += fees; - totalBurned += burned; + if (withCanselation) + { + // tx1: 1 * 21000 + feesTracer.Fees.Should().Be(21000); + feesTracer.BurntFees.Should().Be(42000); + } + else + { + // tx2: (10 - 2) * 21000 = 168000 + feesTracer.Fees.Should().Be(189000); + feesTracer.BurntFees.Should().Be(84000); + } + } - fees.Should().NotBe(0); - feesTracer.Fees.Should().Be(totalFees); + private void ExecuteAndTrace(Block block, IBlockTracer otherTracer) + { + BlockReceiptsTracer tracer = new(); + tracer.SetOtherTracer(otherTracer); - burned.Should().NotBe(0); - feesTracer.BurntFees.Should().Be(totalBurned); + tracer.StartNewBlockTrace(block); + foreach (Transaction tx in block.Transactions) + { + var txTracer = tracer.StartNewTxTrace(tx); + _transactionProcessor.Execute(tx, block.Header, txTracer); + tracer.EndTxTrace(); } - tracer.EndBlockTrace(); } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/AccessTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/AccessTxTracer.cs index 1587e708b64..c28574df5c4 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/AccessTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/AccessTxTracer.cs @@ -1,5 +1,5 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only +// SPDX-License-Identifier: LGPL-3.0-only using System; using System.Collections.Generic; @@ -30,6 +30,7 @@ public class AccessTxTracer : ITxTracer public bool IsTracingStack => false; public bool IsTracingBlockHash => false; public bool IsTracingAccess => true; + public bool IsTracingFees => false; public AccessTxTracer(params Address[] addressesToOptimize) { @@ -212,6 +213,11 @@ public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet k.Key, v => (IReadOnlySet)v.Value)); } + public void ReportFees(UInt256 fees, UInt256 burntFees) + { + throw new NotImplementedException(); + } + public long GasSpent { get; set; } public AccessList? AccessList { get; private set; } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs index 22c826b3027..4704a54c86d 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs @@ -40,6 +40,7 @@ public static AlwaysCancelTxTracer Instance public bool IsTracingStorage => true; public bool IsTracingBlockHash => true; public bool IsTracingAccess => true; + public bool IsTracingFees => true; public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak stateRoot = null) => throw new OperationCanceledException(ErrorMessage); @@ -93,5 +94,6 @@ public static AlwaysCancelTxTracer Instance public void ReportRefund(long refund) => throw new OperationCanceledException(ErrorMessage); public void ReportExtraGasPressure(long extraGasPressure) => throw new OperationCanceledException(ErrorMessage); public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet accessedStorageCells) => throw new OperationCanceledException(ErrorMessage); + public void ReportFees(UInt256 fees, UInt256 burntFees) => throw new OperationCanceledException(ErrorMessage); } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs index 8cc86846390..2aa661649fb 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs @@ -27,6 +27,7 @@ public class BlockReceiptsTracer : IBlockTracer, ITxTracer, IJournal public bool IsTracingBlockHash => _currentTxTracer.IsTracingBlockHash; public bool IsTracingAccess => _currentTxTracer.IsTracingAccess; + public bool IsTracingFees => _currentTxTracer.IsTracingFees; private IBlockTracer _otherTracer = NullBlockTracer.Instance; @@ -184,7 +185,7 @@ public void SetOperationMemory(List memoryTrace) => public void ReportFees(UInt256 fees, UInt256 burntFees) { - if (_currentTxTracer.IsTracingReceipt) + if (_currentTxTracer.IsTracingFees) { _currentTxTracer.ReportFees(fees, burntFees); } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/CallOutputTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/CallOutputTracer.cs index 2b2b467376e..b6c035eb3f8 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/CallOutputTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/CallOutputTracer.cs @@ -24,6 +24,7 @@ public class CallOutputTracer : ITxTracer public bool IsTracingStorage => false; public bool IsTracingBlockHash => false; public bool IsTracingAccess => false; + public bool IsTracingFees => false; public byte[] ReturnValue { get; set; } @@ -187,5 +188,10 @@ public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet _innerTracer; @@ -108,6 +109,12 @@ public bool IsTracingAccess init => _isTracingBlockAccess = value; } + public bool IsTracingFees + { + get => _isTracingFees || _innerTracer.IsTracingFees; + init => _isTracingFees = value; + } + public void ReportBalanceChange(Address address, UInt256? before, UInt256? after) { _token.ThrowIfCancellationRequested(); @@ -426,7 +433,7 @@ public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet txTracers) IsTracingBlockHash |= t.IsTracingBlockHash; IsTracingStorage |= t.IsTracingStorage; IsTracingAccess |= t.IsTracingAccess; + IsTracingFees |= t.IsTracingFees; } } @@ -50,6 +51,7 @@ public CompositeTxTracer(IList txTracers) public bool IsTracingStack { get; } public bool IsTracingBlockHash { get; } public bool IsTracingAccess { get; } + public bool IsTracingFees { get; } public void ReportBalanceChange(Address address, UInt256? before, UInt256? after) { @@ -476,7 +478,7 @@ public void ReportFees(UInt256 fees, UInt256 burntFees) for (int index = 0; index < _txTracers.Count; index++) { ITxTracer innerTracer = _txTracers[index]; - if (innerTracer.IsTracingReceipt) + if (innerTracer.IsTracingFees) { innerTracer.ReportFees(fees, burntFees); } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/EstimateGasTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/EstimateGasTracer.cs index c68e7b64376..ca74037670c 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/EstimateGasTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/EstimateGasTracer.cs @@ -31,6 +31,7 @@ public EstimateGasTracer() public bool IsTracingStorage => false; public bool IsTracingBlockHash => false; public bool IsTracingAccess => false; + public bool IsTracingFees => false; public byte[] ReturnValue { get; set; } @@ -292,5 +293,10 @@ public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet false; public bool IsTracingAccess => false; public bool IsTracingStorage => false; - public bool IsTracingReceipt => true; + public bool IsTracingReceipt => false; + public bool IsTracingFees => true; public UInt256 Fees { get; private set; } = UInt256.Zero; public UInt256 BurntFees { get; private set; } = UInt256.Zero; diff --git a/src/Nethermind/Nethermind.Evm/Tracing/GasEstimator.cs b/src/Nethermind/Nethermind.Evm/Tracing/GasEstimator.cs index 10ef41f62ba..9c6c4ded485 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/GasEstimator.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/GasEstimator.cs @@ -49,7 +49,7 @@ public long Estimate(Transaction tx, BlockHeader header, EstimateGasTracer gasTr UInt256 senderBalance = _stateProvider.GetBalance(tx.SenderAddress); - // Calculate and return additional gas required in case of insufficient funds. + // Calculate and return additional gas required in case of insufficient funds. if (tx.Value != UInt256.Zero && tx.Value >= senderBalance) { return gasTracer.CalculateAdditionalGasRequired(tx, releaseSpec); @@ -109,6 +109,7 @@ public OutOfGasTracer() public bool IsTracingStorage => false; public bool IsTracingBlockHash => false; public bool IsTracingAccess => false; + public bool IsTracingFees => false; public bool OutOfGas { get; set; } @@ -256,6 +257,10 @@ public void SetOperationMemory(List memoryTrace) { } + public void ReportFees(UInt256 fees, UInt256 burntFees) + { + throw new NotImplementedException(); + } } } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/GethStyle/GethLikeTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/GethStyle/GethLikeTxTracer.cs index 095ed1b7648..c89822b8492 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/GethStyle/GethLikeTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/GethStyle/GethLikeTxTracer.cs @@ -35,6 +35,7 @@ public GethLikeTxTracer(GethTraceOptions options) public bool IsTracingStack { get; } public bool IsTracingBlockHash => false; public bool IsTracingAccess => false; + public bool IsTracingFees => false; public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak? stateRoot = null) { @@ -233,6 +234,11 @@ public void SetOperationMemory(List memoryTrace) _traceEntry.Memory = memoryTrace; } + public void ReportFees(UInt256 fees, UInt256 burntFees) + { + throw new NotImplementedException(); + } + public GethLikeTxTrace BuildResult() { return _trace; diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs index 272ad1bbf3f..e6bc2a03ee3 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ITxTracer.cs @@ -53,6 +53,11 @@ public interface ITxTracer : IStateTracer, IStorageTracer /// bool IsTracingAccess { get; } + /// + /// Traces fees and burned fees + /// + bool IsTracingFees { get; } + void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak? stateRoot = null); void MarkAsFailed(Address recipient, long gasSpent, byte[] output, string error, Keccak? stateRoot = null); @@ -145,6 +150,6 @@ void LoadOperationTransientStorage(Address storageCellAddress, UInt256 storageIn void ReportRefund(long refund); void ReportExtraGasPressure(long extraGasPressure); void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet accessedStorageCells); - void ReportFees(UInt256 fees, UInt256 burntFees) { } + void ReportFees(UInt256 fees, UInt256 burntFees); } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/NullTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/NullTxTracer.cs index f4936ec2bfc..967bff26331 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/NullTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/NullTxTracer.cs @@ -28,6 +28,7 @@ private NullTxTracer() { } public bool IsTracingStorage => false; public bool IsTracingBlockHash => false; public bool IsTracingAccess => false; + public bool IsTracingFees => false; public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak? stateRoot = null) => throw new InvalidOperationException(ErrorMessage); @@ -111,5 +112,8 @@ public void ReportExtraGasPressure(long extraGasPressure) public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet accessedStorageCells) => throw new InvalidOperationException(ErrorMessage); + + public void ReportFees(UInt256 fees, UInt256 burntFees) + => throw new InvalidOperationException(ErrorMessage); } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs index 23ba24b6547..e0960caa7ed 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs @@ -76,6 +76,7 @@ public ParityLikeTxTracer(Block block, Transaction? tx, ParityTraceTypes parityT public bool IsTracingStorage { get; } public bool IsTracingBlockHash => false; public bool IsTracingAccess => false; + public bool IsTracingFees => false; private static string GetCallType(ExecutionType executionType) { @@ -520,5 +521,10 @@ public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet false; public bool IsTracingState => true; public bool IsTracingStorage => true; + public bool IsTracingFees => false; public void ReportActionEnd(long gas, Address deploymentAddress, ReadOnlyMemory deployedCode) { @@ -217,5 +218,10 @@ public void ReportActionError(EvmExceptionType evmExceptionType) { throw new NotSupportedException(); } + + public void ReportFees(UInt256 fees, UInt256 burntFees) + { + throw new NotImplementedException(); + } } } diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index 24c0f3cf3ac..c0533f075df 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -430,11 +430,10 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra _stateProvider.CreateAccount(gasBeneficiary, fees); } - UInt256 burntFees = UInt256.Zero; + UInt256 burntFees = (ulong)spentGas * block.BaseFeePerGas; if (!transaction.IsFree() && spec.IsEip1559Enabled && spec.Eip1559FeeCollector is not null) { - burntFees = (ulong)spentGas * block.BaseFeePerGas; if (!burntFees.IsZero) { if (_stateProvider.AccountExists(spec.Eip1559FeeCollector)) @@ -448,7 +447,7 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra } } - if (txTracer.IsTracingReceipt) + if (txTracer.IsTracingFees) { txTracer.ReportFees(fees, burntFees); } diff --git a/src/Nethermind/Nethermind.Mev/BeneficiaryTracer.cs b/src/Nethermind/Nethermind.Mev/BeneficiaryTracer.cs index 99a4605961f..530e8955211 100644 --- a/src/Nethermind/Nethermind.Mev/BeneficiaryTracer.cs +++ b/src/Nethermind/Nethermind.Mev/BeneficiaryTracer.cs @@ -1,5 +1,5 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only +// SPDX-License-Identifier: LGPL-3.0-only using System; using System.Collections.Generic; @@ -45,6 +45,7 @@ public void EndBlockTrace() { } public bool IsTracingStack => false; public bool IsTracingBlockHash => false; public bool IsTracingAccess => false; + public bool IsTracingFees => false; public void ReportReward(Address author, string rewardType, UInt256 rewardValue) { } public void ReportCodeChange(Address address, byte[]? before, byte[]? after) { } public void ReportNonceChange(Address address, UInt256? before, UInt256? after) { } @@ -75,5 +76,6 @@ public void ReportGasUpdateForVmTrace(long refund, long gasAvailable) { } public void ReportRefund(long refund) { } public void ReportExtraGasPressure(long extraGasPressure) { } public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet accessedStorageCells) { } + public void ReportFees(UInt256 fees, UInt256 burntFees) { } } } diff --git a/src/Nethermind/Nethermind.Mev/Execution/TxBundleSimulator.cs b/src/Nethermind/Nethermind.Mev/Execution/TxBundleSimulator.cs index faa7f3a3453..ebd882c0bcd 100644 --- a/src/Nethermind/Nethermind.Mev/Execution/TxBundleSimulator.cs +++ b/src/Nethermind/Nethermind.Mev/Execution/TxBundleSimulator.cs @@ -1,5 +1,5 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited -// SPDX-License-Identifier: LGPL-3.0-only +// SPDX-License-Identifier: LGPL-3.0-only using System; using System.Collections; @@ -212,6 +212,7 @@ public BundleTxTracer(Address beneficiary, Transaction? transaction, int index) public long GasSpent { get; set; } public UInt256? BeneficiaryBalanceBefore { get; private set; } public UInt256? BeneficiaryBalanceAfter { get; private set; } + public bool IsTracingFees => false; public bool Success { get; private set; } public string? Error { get; private set; } @@ -370,6 +371,11 @@ public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet Date: Wed, 23 Nov 2022 20:34:13 +0300 Subject: [PATCH 19/22] Fix spaces --- src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs index 4704a54c86d..fee3b37a2d2 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/AlwaysCancelTxTracer.cs @@ -94,6 +94,6 @@ public static AlwaysCancelTxTracer Instance public void ReportRefund(long refund) => throw new OperationCanceledException(ErrorMessage); public void ReportExtraGasPressure(long extraGasPressure) => throw new OperationCanceledException(ErrorMessage); public void ReportAccess(IReadOnlySet
accessedAddresses, IReadOnlySet accessedStorageCells) => throw new OperationCanceledException(ErrorMessage); - public void ReportFees(UInt256 fees, UInt256 burntFees) => throw new OperationCanceledException(ErrorMessage); + public void ReportFees(UInt256 fees, UInt256 burntFees) => throw new OperationCanceledException(ErrorMessage); } } From be4e00dd694b50976b1e319c6b6a6e30cc6d37d5 Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Wed, 23 Nov 2022 20:59:59 +0300 Subject: [PATCH 20/22] Fix tests --- .../Nethermind.State.Test.Runner/StateTestTxTracer.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Nethermind/Nethermind.State.Test.Runner/StateTestTxTracer.cs b/src/Nethermind/Nethermind.State.Test.Runner/StateTestTxTracer.cs index ca88ed663a8..edf8f65f956 100644 --- a/src/Nethermind/Nethermind.State.Test.Runner/StateTestTxTracer.cs +++ b/src/Nethermind/Nethermind.State.Test.Runner/StateTestTxTracer.cs @@ -31,6 +31,7 @@ public class StateTestTxTracer : ITxTracer bool IStorageTracer.IsTracingStorage => false; public bool IsTracingBlockHash { get; } = false; public bool IsTracingAccess { get; } = false; + public bool IsTracingFees => false; public void MarkAsSuccess(Address recipient, long gasSpent, byte[] output, LogEntry[] logs, Keccak stateRoot = null) { @@ -232,5 +233,10 @@ public StateTestTxTrace BuildResult() { return _trace; } + + public void ReportFees(UInt256 fees, UInt256 burntFees) + { + throw new NotImplementedException(); + } } } From 17bdd062578c9bba58b45b2b6eb46f3ac828a3ee Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Mon, 28 Nov 2022 15:11:22 +0300 Subject: [PATCH 21/22] Fix free transaction & rename CurrentBestBlock --- .../TransactionProcessing/TransactionProcessor.cs | 4 ++-- ...gineModuleTests.DelayBlockImprovementContextFactory.cs | 8 ++++---- ...ngineModuleTests.MockBlockImprovementContextFactory.cs | 4 ++-- .../EngineModuleTests.V1.PayloadProduction.cs | 4 ++-- .../BlockProduction/BlockImprovementContext.cs | 6 +++--- .../BlockProduction/Boost/BoostBlockImprovementContext.cs | 8 ++++---- .../BlockProduction/IBlockProductionContext.cs | 2 +- .../BlockProduction/PayloadPreparationService.cs | 6 +++--- .../Handlers/V1/GetPayloadV1Handler.cs | 2 +- .../Handlers/V2/GetPayloadV2Handler.cs | 2 +- 10 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index c0533f075df..c92cc928d63 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -430,9 +430,9 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra _stateProvider.CreateAccount(gasBeneficiary, fees); } - UInt256 burntFees = (ulong)spentGas * block.BaseFeePerGas; + UInt256 burntFees = !transaction.IsFree() ? (ulong)spentGas * block.BaseFeePerGas : 0; - if (!transaction.IsFree() && spec.IsEip1559Enabled && spec.Eip1559FeeCollector is not null) + if (spec.IsEip1559Enabled && spec.Eip1559FeeCollector is not null) { if (!burntFees.IsZero) { diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs index b4f03480a81..b6fce670c01 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.DelayBlockImprovementContextFactory.cs @@ -45,7 +45,7 @@ public DelayBlockImprovementContext(Block currentBestBlock, DateTimeOffset startDateTime) { _cancellationTokenSource = new CancellationTokenSource(timeout); - Block = currentBestBlock; + CurrentBestBlock = currentBestBlock; StartDateTime = startDateTime; ImprovementTask = BuildBlock(blockProductionTrigger, parentHeader, payloadAttributes, delay, _cancellationTokenSource.Token); } @@ -61,14 +61,14 @@ public DelayBlockImprovementContext(Block currentBestBlock, await Task.Delay(delay, cancellationToken); if (block is not null) { - Block = block; + CurrentBestBlock = block; } - return Block; + return CurrentBestBlock; } public Task ImprovementTask { get; } - public Block? Block { get; private set; } + public Block? CurrentBestBlock { get; private set; } public UInt256 BlockFees { get; } public bool Disposed { get; private set; } public DateTimeOffset StartDateTime { get; } diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.MockBlockImprovementContextFactory.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.MockBlockImprovementContextFactory.cs index f68d46c9a87..45bf4a58515 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.MockBlockImprovementContextFactory.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.MockBlockImprovementContextFactory.cs @@ -25,14 +25,14 @@ private class MockBlockImprovementContext : IBlockImprovementContext { public MockBlockImprovementContext(Block currentBestBlock, DateTimeOffset startDateTime) { - Block = currentBestBlock; + CurrentBestBlock = currentBestBlock; StartDateTime = startDateTime; ImprovementTask = Task.FromResult((Block?)currentBestBlock); } public void Dispose() => Disposed = true; public Task ImprovementTask { get; } - public Block? Block { get; } + public Block? CurrentBestBlock { get; } public UInt256 BlockFees { get; } public bool Disposed { get; private set; } public DateTimeOffset StartDateTime { get; } diff --git a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.PayloadProduction.cs b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.PayloadProduction.cs index dc926f9445a..886a99702d0 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.PayloadProduction.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V1.PayloadProduction.cs @@ -211,7 +211,7 @@ public async Task getPayload_correctlyEncodeTransactions() Build.A.Transaction.WithTo(TestItem.AddressD).SignedAndResolved(TestItem.PrivateKeyA).TestObject, Build.A.Transaction.WithTo(TestItem.AddressD).WithType(TxType.EIP1559).WithMaxFeePerGas(20).SignedAndResolved(TestItem.PrivateKeyA).TestObject).TestObject; IBlockProductionContext improvementContext = Substitute.For(); - improvementContext.Block.Returns(block); + improvementContext.CurrentBestBlock.Returns(block); payloadPreparationService.GetPayload(Arg.Any()).Returns(improvementContext); using MergeTestBlockchain chain = await CreateBlockChain(null, payloadPreparationService); @@ -308,7 +308,7 @@ public async Task getPayloadV1_picks_transactions_from_pool_constantly_improving List transactionsLength = improvementContextFactory.CreatedContexts .Select(c => - c.Block?.Transactions.Length).ToList(); + c.CurrentBestBlock?.Transactions.Length).ToList(); transactionsLength.Should().Equal(3, 6, 11); Transaction[] txs = getPayloadResult.GetTransactions(); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs index dedcaee50d2..059ad02f220 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/BlockImprovementContext.cs @@ -25,7 +25,7 @@ public BlockImprovementContext(Block currentBestBlock, DateTimeOffset startDateTime) { _cancellationTokenSource = new CancellationTokenSource(timeout); - Block = currentBestBlock; + CurrentBestBlock = currentBestBlock; StartDateTime = startDateTime; ImprovementTask = blockProductionTrigger .BuildBlock(parentHeader, _cancellationTokenSource.Token, _feesTracer, payloadAttributes) @@ -34,7 +34,7 @@ public BlockImprovementContext(Block currentBestBlock, public Task ImprovementTask { get; } - public Block? Block { get; private set; } + public Block? CurrentBestBlock { get; private set; } public UInt256 BlockFees { get; private set; } private Block? SetCurrentBestBlock(Task task) @@ -43,7 +43,7 @@ public BlockImprovementContext(Block currentBestBlock, { if (task.Result is not null) { - Block = task.Result; + CurrentBestBlock = task.Result; BlockFees = _feesTracer.Fees; } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs index 94784ab5ab5..809179efde7 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/Boost/BoostBlockImprovementContext.cs @@ -35,7 +35,7 @@ public BoostBlockImprovementContext(Block currentBestBlock, _boostRelay = boostRelay; _stateReader = stateReader; _cancellationTokenSource = new CancellationTokenSource(timeout); - Block = currentBestBlock; + CurrentBestBlock = currentBestBlock; StartDateTime = startDateTime; ImprovementTask = StartImprovingBlock(blockProductionTrigger, parentHeader, payloadAttributes, _cancellationTokenSource.Token); } @@ -52,17 +52,17 @@ public BoostBlockImprovementContext(Block currentBestBlock, Block? block = await blockProductionTrigger.BuildBlock(parentHeader, cancellationToken, _feesTracer, payloadAttributes); if (block is not null) { - Block = block; + CurrentBestBlock = block; BlockFees = _feesTracer.Fees; UInt256 balanceAfter = _stateReader.GetAccount(block.StateRoot!, payloadAttributes.SuggestedFeeRecipient)?.Balance ?? UInt256.Zero; await _boostRelay.SendPayload(new BoostExecutionPayloadV1 { Block = new ExecutionPayloadV1(block), Profit = balanceAfter - balanceBefore }, cancellationToken); } - return Block; + return CurrentBestBlock; } public Task ImprovementTask { get; } - public Block? Block { get; private set; } + public Block? CurrentBestBlock { get; private set; } public UInt256 BlockFees { get; private set; } public bool Disposed { get; private set; } public DateTimeOffset StartDateTime { get; } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockProductionContext.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockProductionContext.cs index 5383836d98a..0d410c1f844 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockProductionContext.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/IBlockProductionContext.cs @@ -8,6 +8,6 @@ namespace Nethermind.Merge.Plugin.BlockProduction; public interface IBlockProductionContext { - Block? Block { get; } + Block? CurrentBestBlock { get; } UInt256 BlockFees { get; } } diff --git a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs index a278413bb96..ca4fa60b30f 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/BlockProduction/PayloadPreparationService.cs @@ -132,7 +132,7 @@ private IBlockImprovementContext CreateBlockImprovementContext(string payloadId, await Task.Delay(_improvementDelay); if (!blockImprovementContext.Disposed) // if GetPayload wasn't called for this item or it wasn't cleared { - Block newBestBlock = blockImprovementContext.Block ?? currentBestBlock; + Block newBestBlock = blockImprovementContext.CurrentBestBlock ?? currentBestBlock; ImproveBlock(payloadId, parentHeader, payloadAttributes, newBestBlock, startDateTime); } else @@ -157,7 +157,7 @@ private void CleanupOldPayloads(object? sender, EventArgs e) DateTimeOffset now = DateTimeOffset.UtcNow; if (payload.Value.StartDateTime + _cleanupOldPayloadDelay <= now) { - if (_logger.IsDebug) _logger.Info($"A new payload to remove: {payload.Key}, Current time {now:t}, Payload timestamp: {payload.Value.Block?.Timestamp}"); + if (_logger.IsDebug) _logger.Info($"A new payload to remove: {payload.Key}, Current time {now:t}, Payload timestamp: {payload.Value.CurrentBestBlock?.Timestamp}"); _payloadsToRemove.Add(payload.Key); } } @@ -207,7 +207,7 @@ private void CleanupOldPayloads(object? sender, EventArgs e) { using (blockContext) { - bool currentBestBlockIsEmpty = blockContext.Block?.Transactions.Any() != true; + bool currentBestBlockIsEmpty = blockContext.CurrentBestBlock?.Transactions.Any() != true; if (currentBestBlockIsEmpty && !blockContext.ImprovementTask.IsCompleted) { await Task.WhenAny(blockContext.ImprovementTask, Task.Delay(GetPayloadWaitForFullBlockMillisecondsDelay)); diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V1/GetPayloadV1Handler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V1/GetPayloadV1Handler.cs index 30e08d3c8da..e5861c6fe93 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V1/GetPayloadV1Handler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V1/GetPayloadV1Handler.cs @@ -39,7 +39,7 @@ public GetPayloadV1Handler(IPayloadPreparationService payloadPreparationService, public async Task> HandleAsync(byte[] payloadId) { string payloadStr = payloadId.ToHexString(true); - Block? block = (await _payloadPreparationService.GetPayload(payloadStr))?.Block; + Block? block = (await _payloadPreparationService.GetPayload(payloadStr))?.CurrentBestBlock; if (block is null) { diff --git a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V2/GetPayloadV2Handler.cs b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V2/GetPayloadV2Handler.cs index f2d9a525fe1..7127f5deb82 100644 --- a/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V2/GetPayloadV2Handler.cs +++ b/src/Nethermind/Nethermind.Merge.Plugin/Handlers/V2/GetPayloadV2Handler.cs @@ -26,7 +26,7 @@ public GetPayloadV2Handler(IPayloadPreparationService payloadPreparationService, { string payloadStr = payloadId.ToHexString(true); IBlockProductionContext? blockContext = await _payloadPreparationService.GetPayload(payloadStr); - Block? block = blockContext?.Block; + Block? block = blockContext?.CurrentBestBlock; if (block is null) { From b77639dadffdab6f6cb57e42acabb6127a063446 Mon Sep 17 00:00:00 2001 From: Nikita Mescheryakov Date: Mon, 28 Nov 2022 17:18:37 +0300 Subject: [PATCH 22/22] Free transaction test --- .../TransactionProcessorFeeTests.cs | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs index 129b158cab4..584917c1d82 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorFeeTests.cs @@ -53,7 +53,7 @@ public void Setup() [TestCase(false, true)] [TestCase(true, false)] [TestCase(false, false)] - public void Check_paid_fees_simple(bool isTransactionEip1559, bool withFeeCollector) + public void Check_fees_with_fee_collector(bool isTransactionEip1559, bool withFeeCollector) { if (withFeeCollector) { @@ -150,7 +150,7 @@ public void Check_paid_fees_with_byte_code() [TestCase(false)] [TestCase(true)] - public void Should_stop_when_cancellation(bool withCanselation) + public void Should_stop_when_cancellation(bool withCancellation) { Transaction tx1 = Build.A.Transaction .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithType(TxType.EIP1559) @@ -178,7 +178,7 @@ public void Should_stop_when_cancellation(bool withCanselation) blockTracer.EndTxTrace(); } - if (withCanselation) + if (withCancellation) { source.Cancel(); } @@ -192,7 +192,7 @@ public void Should_stop_when_cancellation(bool withCanselation) } catch (OperationCanceledException) { } - if (withCanselation) + if (withCancellation) { // tx1: 1 * 21000 feesTracer.Fees.Should().Be(21000); @@ -206,6 +206,29 @@ public void Should_stop_when_cancellation(bool withCanselation) } } + [Test] + public void Check_fees_with_free_transaction() + { + Transaction tx1 = Build.A.Transaction + .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithType(TxType.EIP1559) + .WithMaxFeePerGas(3).WithMaxPriorityFeePerGas(1).WithGasLimit(21000).TestObject; + Transaction tx2 = Build.A.Transaction + .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA).WithNonce(1).WithIsServiceTransaction(true) + .WithType(TxType.EIP1559).WithMaxFeePerGas(3) + .WithMaxPriorityFeePerGas(1).WithGasLimit(21000).TestObject; + Transaction tx3 = new SystemTransaction(); + Block block = Build.A.Block.WithNumber(0).WithBaseFeePerGas(1) + .WithBeneficiary(TestItem.AddressB).WithTransactions(tx1, tx2, tx3).WithGasLimit(42000).TestObject; + + FeesTracer tracer = new(); + ExecuteAndTrace(block, tracer); + + tracer.Fees.Should().Be(42000); + + block.GasUsed.Should().Be(42000); + tracer.BurntFees.Should().Be(21000); + } + private void ExecuteAndTrace(Block block, IBlockTracer otherTracer) { BlockReceiptsTracer tracer = new();