From de1d72b7d0b4cbdfde7c2d2401259a53ad8db4fd Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Sat, 21 Sep 2024 23:30:42 +0100 Subject: [PATCH 1/2] Calculate receipt blooms in parallel --- .../Processing/BlockProcessor.cs | 29 +++++++++++++------ .../Nethermind.Core/TransactionReceipt.cs | 3 ++ .../Tracing/BlockReceiptsTracer.cs | 2 +- .../OptimismBlockReceiptTracer.cs | 2 +- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs index e9d3dea3354..c455fc1e2d9 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Numerics; using System.Runtime.CompilerServices; @@ -12,7 +11,6 @@ using Nethermind.Blockchain; using Nethermind.Blockchain.BeaconBlockRoot; using Nethermind.Blockchain.Blocks; -using Nethermind.Blockchain.Find; using Nethermind.Blockchain.Receipts; using Nethermind.Consensus.Rewards; using Nethermind.Consensus.Validators; @@ -282,23 +280,25 @@ protected virtual TxReceipt[] ProcessBlock( IBlockTracer blockTracer, ProcessingOptions options) { - IReleaseSpec spec = _specProvider.GetSpec(block.Header); + BlockHeader header = block.Header; + IReleaseSpec spec = _specProvider.GetSpec(header); ReceiptsTracer.SetOtherTracer(blockTracer); ReceiptsTracer.StartNewBlockTrace(block); StoreBeaconRoot(block, spec); - _blockhashStore.ApplyBlockhashStateChanges(block.Header); + _blockhashStore.ApplyBlockhashStateChanges(header); _stateProvider.Commit(spec, commitStorageRoots: false); TxReceipt[] receipts = _blockTransactionsExecutor.ProcessTransactions(block, options, ReceiptsTracer, spec); + CalculateBlooms(receipts); if (spec.IsEip4844Enabled) { - block.Header.BlobGasUsed = BlobGasCalculator.CalculateBlobGas(block.Transactions); + header.BlobGasUsed = BlobGasCalculator.CalculateBlobGas(block.Transactions); } - block.Header.ReceiptsRoot = _receiptsRootCalculator.GetReceiptsRoot(receipts, spec, block.ReceiptsRoot); + header.ReceiptsRoot = _receiptsRootCalculator.GetReceiptsRoot(receipts, spec, block.ReceiptsRoot); ApplyMinerRewards(block, blockTracer, spec); _withdrawalProcessor.ProcessWithdrawals(block, spec); ReceiptsTracer.EndBlockTrace(); @@ -311,17 +311,28 @@ protected virtual TxReceipt[] ProcessBlock( block.AccountChanges = _stateProvider.GetAccountChanges(); } - if (ShouldComputeStateRoot(block.Header)) + if (ShouldComputeStateRoot(header)) { _stateProvider.RecalculateStateRoot(); - block.Header.StateRoot = _stateProvider.StateRoot; + header.StateRoot = _stateProvider.StateRoot; } - block.Header.Hash = block.Header.CalculateHash(); + header.Hash = header.CalculateHash(); return receipts; } + [MethodImpl(MethodImplOptions.NoInlining)] + private static void CalculateBlooms(TxReceipt[] receipts) + { + int index = 0; + Parallel.For(0, receipts.Length, _ => + { + int i = Interlocked.Increment(ref index) - 1; + receipts[i].CalculateBloom(); + }); + } + private void StoreBeaconRoot(Block block, IReleaseSpec spec) { try diff --git a/src/Nethermind/Nethermind.Core/TransactionReceipt.cs b/src/Nethermind/Nethermind.Core/TransactionReceipt.cs index 363f9412710..cbd3b36ad29 100644 --- a/src/Nethermind/Nethermind.Core/TransactionReceipt.cs +++ b/src/Nethermind/Nethermind.Core/TransactionReceipt.cs @@ -69,6 +69,9 @@ public TxReceipt(TxReceipt other) /// Output is either StateRoot or StatusCode depending on eip configuration. /// public bool SkipStateAndStatusInRlp { get; set; } + + public void CalculateBloom() + => Bloom = Logs?.Length == 0 ? Bloom.Empty : new Bloom(Logs); } public ref struct TxReceiptStructRef diff --git a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs index 4a8587a7690..822c8277424 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/BlockReceiptsTracer.cs @@ -78,7 +78,7 @@ protected virtual TxReceipt BuildReceipt(Address recipient, long spentGas, byte { Logs = logEntries, TxType = transaction.Type, - Bloom = logEntries.Length == 0 ? Bloom.Empty : new Bloom(logEntries), + // Bloom calculated in parallel with other receipts GasUsedTotal = Block.GasUsed, StatusCode = statusCode, Recipient = transaction.IsContractCreation ? null : recipient, diff --git a/src/Nethermind/Nethermind.Optimism/OptimismBlockReceiptTracer.cs b/src/Nethermind/Nethermind.Optimism/OptimismBlockReceiptTracer.cs index aab105b9090..208d02a35e1 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismBlockReceiptTracer.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismBlockReceiptTracer.cs @@ -53,7 +53,7 @@ protected override TxReceipt BuildReceipt(Address recipient, long spentGas, byte { Logs = logEntries, TxType = transaction.Type, - Bloom = logEntries.Length == 0 ? Bloom.Empty : new Bloom(logEntries), + // Bloom calculated in parallel with other receipts GasUsedTotal = Block.GasUsed, StatusCode = statusCode, Recipient = transaction.IsContractCreation ? null : recipient, From 01f437bf854b386a57123d4dc58167790ab1240e Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Sat, 21 Sep 2024 23:50:54 +0100 Subject: [PATCH 2/2] auto calculate bloom on request --- src/Nethermind/Nethermind.Core/TransactionReceipt.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Core/TransactionReceipt.cs b/src/Nethermind/Nethermind.Core/TransactionReceipt.cs index cbd3b36ad29..35e69692bcf 100644 --- a/src/Nethermind/Nethermind.Core/TransactionReceipt.cs +++ b/src/Nethermind/Nethermind.Core/TransactionReceipt.cs @@ -9,6 +9,8 @@ namespace Nethermind.Core { public class TxReceipt { + private Bloom? _boom; + public TxReceipt() { } @@ -60,7 +62,7 @@ public TxReceipt(TxReceipt other) /// Removed in EIP-658 /// public Hash256? PostTransactionState { get; set; } - public Bloom? Bloom { get; set; } + public Bloom? Bloom { get => _boom ?? CalculateBloom(); set => _boom = value; } public LogEntry[]? Logs { get; set; } public string? Error { get; set; } @@ -70,8 +72,8 @@ public TxReceipt(TxReceipt other) /// public bool SkipStateAndStatusInRlp { get; set; } - public void CalculateBloom() - => Bloom = Logs?.Length == 0 ? Bloom.Empty : new Bloom(Logs); + public Bloom CalculateBloom() + => _boom = Logs?.Length == 0 ? Bloom.Empty : new Bloom(Logs); } public ref struct TxReceiptStructRef