Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Conflict Detection in Parallelization by Considering Slots to Reduce False Positives #7923

Merged
merged 15 commits into from
Feb 17, 2025
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- Add TLS/mTLS options and configure the GraphQL HTTP service[#7910](https://github.com/hyperledger/besu/pull/7910)
- Allow plugins to propose transactions during block creation [#8268](https://github.com/hyperledger/besu/pull/8268)
- Update `eth_getLogs` to return a `Block not found` error when the requested block is not found. [#8290](https://github.com/hyperledger/besu/pull/8290)
- Improve Conflict Detection in Parallelization by Considering Slots to Reduce False Positives. [#7923](https://github.com/hyperledger/besu/pull/7923)
### Bug fixes
- Upgrade Netty to version 4.1.118 to fix CVE-2025-24970 [#8275](https://github.com/hyperledger/besu/pull/8275)
- Add missing RPC method `debug_accountRange` to `RpcMethod.java` and implemented its handler. [#8153](https://github.com/hyperledger/besu/issues/8153)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ private void handleFailedBlockProcessing(
protected BlockProcessingResult processBlock(
final ProtocolContext context, final MutableWorldState worldState, final Block block) {

return blockProcessor.processBlock(context.getBlockchain(), worldState, block);
return blockProcessor.processBlock(context, context.getBlockchain(), worldState, block);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.BlockProcessingOutputs;
import org.hyperledger.besu.ethereum.BlockProcessingResult;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
Expand Down Expand Up @@ -95,6 +96,7 @@ protected AbstractBlockProcessor(

@Override
public BlockProcessingResult processBlock(
final ProtocolContext protocolContext,
final Blockchain blockchain,
final MutableWorldState worldState,
final BlockHeader blockHeader,
Expand All @@ -103,6 +105,7 @@ public BlockProcessingResult processBlock(
final Optional<List<Withdrawal>> maybeWithdrawals,
final PrivateMetadataUpdater privateMetadataUpdater) {
return processBlock(
protocolContext,
blockchain,
worldState,
blockHeader,
Expand All @@ -114,6 +117,7 @@ public BlockProcessingResult processBlock(
}

protected BlockProcessingResult processBlock(
final ProtocolContext protocolContext,
final Blockchain blockchain,
final MutableWorldState worldState,
final BlockHeader blockHeader,
Expand Down Expand Up @@ -151,7 +155,7 @@ protected BlockProcessingResult processBlock(

final Optional<PreprocessingContext> preProcessingContext =
preprocessingBlockFunction.run(
worldState,
protocolContext,
privateMetadataUpdater,
blockHeader,
transactions,
Expand Down Expand Up @@ -342,7 +346,7 @@ public interface PreprocessingContext {}

public interface PreprocessingFunction {
Optional<PreprocessingContext> run(
final MutableWorldState worldState,
final ProtocolContext protocolContext,
final PrivateMetadataUpdater privateMetadataUpdater,
final BlockHeader blockHeader,
final List<Transaction> transactions,
Expand All @@ -354,7 +358,7 @@ class NoPreprocessing implements PreprocessingFunction {

@Override
public Optional<PreprocessingContext> run(
final MutableWorldState worldState,
final ProtocolContext protocolContext,
final PrivateMetadataUpdater privateMetadataUpdater,
final BlockHeader blockHeader,
final List<Transaction> transactions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.BlockProcessingResult;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeader;
Expand Down Expand Up @@ -68,14 +69,19 @@ default boolean isFailed() {
/**
* Processes the block.
*
* @param protocolContext the current context of the protocol
* @param blockchain the blockchain to append the block to
* @param worldState the world state to apply changes to
* @param block the block to process
* @return the block processing result
*/
default BlockProcessingResult processBlock(
final Blockchain blockchain, final MutableWorldState worldState, final Block block) {
final ProtocolContext protocolContext,
final Blockchain blockchain,
final MutableWorldState worldState,
final Block block) {
return processBlock(
protocolContext,
blockchain,
worldState,
block.getHeader(),
Expand All @@ -88,6 +94,7 @@ default BlockProcessingResult processBlock(
/**
* Processes the block.
*
* @param protocolContext the current context of the protocol
* @param blockchain the blockchain to append the block to
* @param worldState the world state to apply changes to
* @param blockHeader the block header for the block
Expand All @@ -96,18 +103,27 @@ default BlockProcessingResult processBlock(
* @return the block processing result
*/
default BlockProcessingResult processBlock(
final ProtocolContext protocolContext,
final Blockchain blockchain,
final MutableWorldState worldState,
final BlockHeader blockHeader,
final List<Transaction> transactions,
final List<BlockHeader> ommers) {
return processBlock(
blockchain, worldState, blockHeader, transactions, ommers, Optional.empty(), null);
protocolContext,
blockchain,
worldState,
blockHeader,
transactions,
ommers,
Optional.empty(),
null);
}

/**
* Processes the block.
*
* @param protocolContext the current context of the protocol
* @param blockchain the blockchain to append the block to
* @param worldState the world state to apply changes to
* @param blockHeader the block header for the block
Expand All @@ -118,6 +134,7 @@ default BlockProcessingResult processBlock(
* @return the block processing result
*/
BlockProcessingResult processBlock(
ProtocolContext protocolContext,
Blockchain blockchain,
MutableWorldState worldState,
BlockHeader blockHeader,
Expand All @@ -129,13 +146,15 @@ BlockProcessingResult processBlock(
/**
* Processes the block when running Besu in GoQuorum-compatible mode
*
* @param protocolContext the current context of the protocol
* @param blockchain the blockchain to append the block to
* @param worldState the world state to apply public transactions to
* @param privateWorldState the private world state to apply private transaction to
* @param block the block to process
* @return the block processing result
*/
default BlockProcessingResult processBlock(
final ProtocolContext protocolContext,
final Blockchain blockchain,
final MutableWorldState worldState,
final MutableWorldState privateWorldState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.BlockProcessingResult;
import org.hyperledger.besu.ethereum.MainnetBlockValidator;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MiningConfiguration;
Expand Down Expand Up @@ -1101,6 +1102,7 @@ private record DaoBlockProcessor(BlockProcessor wrapped) implements BlockProcess

@Override
public BlockProcessingResult processBlock(
final ProtocolContext protocolContext,
final Blockchain blockchain,
final MutableWorldState worldState,
final BlockHeader blockHeader,
Expand All @@ -1110,6 +1112,7 @@ public BlockProcessingResult processBlock(
final PrivateMetadataUpdater privateMetadataUpdater) {
updateWorldStateForDao(worldState);
return wrapped.processBlock(
protocolContext,
blockchain,
worldState,
blockHeader,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.hyperledger.besu.enclave.EnclaveClientException;
import org.hyperledger.besu.enclave.types.ReceiveResponse;
import org.hyperledger.besu.ethereum.BlockProcessingResult;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
Expand Down Expand Up @@ -83,6 +84,7 @@ public void setPublicWorldStateArchive(final WorldStateArchive publicWorldStateA

@Override
public BlockProcessingResult processBlock(
final ProtocolContext protocolContext,
final Blockchain blockchain,
final MutableWorldState worldState,
final BlockHeader blockHeader,
Expand All @@ -102,6 +104,7 @@ public BlockProcessingResult processBlock(

final BlockProcessingResult result =
blockProcessor.processBlock(
protocolContext,
blockchain,
worldState,
blockHeader,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.BlockProcessingResult;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
Expand All @@ -31,7 +32,7 @@
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder;
import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.DiffBasedWorldState;
import org.hyperledger.besu.ethereum.trie.diffbased.common.provider.DiffBasedWorldStateProvider;
import org.hyperledger.besu.evm.blockhash.BlockHashLookup;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import org.hyperledger.besu.metrics.BesuMetricCategory;
Expand Down Expand Up @@ -137,6 +138,7 @@ protected TransactionProcessingResult getTransactionProcessingResult(

@Override
public BlockProcessingResult processBlock(
final ProtocolContext protocolContext,
final Blockchain blockchain,
final MutableWorldState worldState,
final BlockHeader blockHeader,
Expand All @@ -146,6 +148,7 @@ public BlockProcessingResult processBlock(
final PrivateMetadataUpdater privateMetadataUpdater) {
final BlockProcessingResult blockProcessingResult =
super.processBlock(
protocolContext,
blockchain,
worldState,
blockHeader,
Expand All @@ -154,13 +157,15 @@ public BlockProcessingResult processBlock(
maybeWithdrawals,
privateMetadataUpdater,
new ParallelTransactionPreprocessing());

if (blockProcessingResult.isFailed()) {
// Fallback to non-parallel processing if there is a block processing exception .
LOG.info(
"Parallel transaction processing failure. Falling back to non-parallel processing for block #{} ({})",
blockHeader.getNumber(),
blockHeader.getBlockHash());
return super.processBlock(
protocolContext,
blockchain,
worldState,
blockHeader,
Expand Down Expand Up @@ -209,20 +214,20 @@ class ParallelTransactionPreprocessing implements PreprocessingFunction {

@Override
public Optional<PreprocessingContext> run(
final MutableWorldState worldState,
final ProtocolContext protocolContext,
final PrivateMetadataUpdater privateMetadataUpdater,
final BlockHeader blockHeader,
final List<Transaction> transactions,
final Address miningBeneficiary,
final BlockHashLookup blockHashLookup,
final Wei blobGasPrice) {
if ((worldState instanceof DiffBasedWorldState)) {
if ((protocolContext.getWorldStateArchive() instanceof DiffBasedWorldStateProvider)) {
ParallelizedConcurrentTransactionProcessor parallelizedConcurrentTransactionProcessor =
new ParallelizedConcurrentTransactionProcessor(transactionProcessor);
// When enabled, runAsyncBlock performs non-conflicting parallel execution of transactions
// in the background using an optimistic approach.
// runAsyncBlock, if activated, facilitates the non-blocking parallel execution of
// transactions in the background through an optimistic strategy.
parallelizedConcurrentTransactionProcessor.runAsyncBlock(
worldState,
protocolContext,
blockHeader,
transactions,
miningBeneficiary,
Expand Down
Loading