From 759d38089f2dcd2a24f891de661887f04bc7cb4a Mon Sep 17 00:00:00 2001 From: Stefan Date: Tue, 4 Apr 2023 17:09:35 +1000 Subject: [PATCH 1/3] add block limit Signed-off-by: Stefan --- .../cli/options/unstable/LineaOptions.java | 20 +++++++++-- .../methods/EthGetTransactionReceiptTest.java | 7 ++-- .../blockcreation/AbstractBlockCreator.java | 3 +- .../BlockTransactionSelector.java | 34 ++++++++++++++++++- .../AbstractBlockTransactionSelectorTest.java | 7 ++-- .../besu/ethereum/linea/LineaParameters.java | 12 +++++-- .../ethereum/mainnet/LineaProtocolSpecs.java | 2 ++ .../besu/ethereum/mainnet/ProtocolSpec.java | 12 ++++++- .../ethereum/mainnet/ProtocolSpecBuilder.java | 10 +++++- .../NoRewardProtocolScheduleWrapper.java | 4 ++- 10 files changed, 98 insertions(+), 13 deletions(-) diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/LineaOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/LineaOptions.java index 33cd94219ab..b599661ea80 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/LineaOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/LineaOptions.java @@ -11,6 +11,8 @@ public class LineaOptions implements CLIOptions { private static final String TRANSACTION_MAX_CALLDATA_SIZE = "--Xtransaction-max-calldata-size"; + private static final String BLOCK_MAX_CALLDATA_SIZE = "--Xblock-max-calldata-size"; + ; public static LineaOptions create() { return new LineaOptions(); @@ -24,20 +26,34 @@ public static LineaOptions create() { "If specified, overrides the max size in bytes allowed in the transaction calldata field, specified by the current hard fork") private Integer transactionMaxCalldataSize; + @CommandLine.Option( + hidden = true, + names = {BLOCK_MAX_CALLDATA_SIZE}, + paramLabel = "", + description = + "If specified, overrides the max size in bytes allowed in the transaction calldata field, specified by the current hard fork") + private Integer blockMaxCalldataSize; + public Optional getTransactionMaxCalldataSize() { return Optional.ofNullable(transactionMaxCalldataSize); } + public Optional getBlockMaxCalldataSize() { + return Optional.ofNullable(blockMaxCalldataSize); + } + @Override public LineaParameters toDomainObject() { - return new LineaParameters(transactionMaxCalldataSize); + return new LineaParameters(transactionMaxCalldataSize, blockMaxCalldataSize); } @Override public List getCLIOptions() { - final List cliOptions = new ArrayList<>(1); + final List cliOptions = new ArrayList<>(2); getTransactionMaxCalldataSize() .ifPresent(size -> cliOptions.add(TRANSACTION_MAX_CALLDATA_SIZE + "=" + size)); + getBlockMaxCalldataSize() + .ifPresent(size -> cliOptions.add(BLOCK_MAX_CALLDATA_SIZE + "=" + size)); return cliOptions; } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java index def0693a75b..2c4883bbf7a 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java @@ -36,6 +36,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.TransactionReceipt; +import org.hyperledger.besu.ethereum.linea.LineaParameters; import org.hyperledger.besu.ethereum.mainnet.PoWHasher; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; @@ -115,7 +116,8 @@ public class EthGetTransactionReceiptTest { null, Optional.empty(), null, - true); + true, + LineaParameters.DEFAULT); private final ProtocolSpec statusTransactionTypeSpec = new ProtocolSpec( "status", @@ -144,7 +146,8 @@ public class EthGetTransactionReceiptTest { null, Optional.empty(), null, - true); + true, + LineaParameters.DEFAULT); @SuppressWarnings("unchecked") private final ProtocolSchedule protocolSchedule = mock(ProtocolSchedule.class); diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java index d5e693220a9..7015377a652 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java @@ -304,7 +304,8 @@ private BlockTransactionSelector.TransactionSelectionResults selectTransactions( dataGasPrice, protocolSpec.getFeeMarket(), protocolSpec.getGasCalculator(), - protocolSpec.getGasLimitCalculator()); + protocolSpec.getGasLimitCalculator(), + protocolSpec.getLineaParameters()); if (transactions.isPresent()) { return selector.evaluateTransactions(transactions.get()); diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockTransactionSelector.java index a7704281e7f..9a6973f3865 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockTransactionSelector.java @@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions.TransactionSelectionResult; +import org.hyperledger.besu.ethereum.linea.LineaParameters; import org.hyperledger.besu.ethereum.mainnet.AbstractBlockProcessor; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator; @@ -45,7 +46,9 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.concurrent.CancellationException; +import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -75,6 +78,12 @@ * not cleared between executions of buildTransactionListForBlock(). */ public class BlockTransactionSelector { + + private final int blockMaxCalldataSize; + private final Function> + lineaMaxCalldataSizeEnforcer; + private int blockCalldataSum; + public static class TransactionValidationResult { private final Transaction transaction; private final ValidationResult validationResult; @@ -240,7 +249,8 @@ public BlockTransactionSelector( final Wei dataGasPrice, final FeeMarket feeMarket, final GasCalculator gasCalculator, - final GasLimitCalculator gasLimitCalculator) { + final GasLimitCalculator gasLimitCalculator, + final LineaParameters lineaParameters) { this.transactionProcessor = transactionProcessor; this.blockchain = blockchain; this.worldState = worldState; @@ -255,6 +265,13 @@ public BlockTransactionSelector( this.feeMarket = feeMarket; this.gasCalculator = gasCalculator; this.gasLimitCalculator = gasLimitCalculator; + if (lineaParameters.maybeBlockCalldataMaxSize().isPresent()) { + blockMaxCalldataSize = lineaParameters.maybeBlockCalldataMaxSize().getAsInt(); + lineaMaxCalldataSizeEnforcer = (t) -> maxCalldataEnforcer(t); + } else { + blockMaxCalldataSize = 0; + lineaMaxCalldataSizeEnforcer = (t) -> Optional.empty(); + } } /* @@ -304,6 +321,12 @@ private TransactionSelectionResult evaluateTransaction( throw new CancellationException("Cancelled during transaction selection."); } + final Optional maybeResult = + lineaMaxCalldataSizeEnforcer.apply(transaction); + if (maybeResult.isPresent()) { + return maybeResult.get(); + } + if (transactionTooLargeForBlock(transaction)) { LOG.atTrace() .setMessage("Transaction {} too large to select for block creation") @@ -534,4 +557,13 @@ private boolean blockOccupancyAboveThreshold() { occupancyRatio); return occupancyRatio >= minBlockOccupancyRatio; } + + private Optional maxCalldataEnforcer(final Transaction transaction) { + this.blockCalldataSum += transaction.getPayload().size(); + if (blockCalldataSum > blockMaxCalldataSize) { + return Optional.of(TransactionSelectionResult.COMPLETE_OPERATION); + } else { + return Optional.empty(); + } + } } diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java index cbac5409a08..674030daa82 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java @@ -44,6 +44,7 @@ import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions; import org.hyperledger.besu.ethereum.eth.transactions.sorter.BaseFeePendingTransactionsSorter; +import org.hyperledger.besu.ethereum.linea.LineaParameters; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; @@ -264,7 +265,8 @@ public void useSingleGasSpaceForAllTransactions() { Wei.ZERO, FeeMarket.london(0L), new LondonGasCalculator(), - GasLimitCalculator.constant()); + GasLimitCalculator.constant(), + LineaParameters.DEFAULT); // this should fill up all the block space final Transaction fillingLegacyTx = @@ -469,7 +471,8 @@ protected BlockTransactionSelector createBlockSelector( dataGasPrice, getFeeMarket(), new LondonGasCalculator(), - GasLimitCalculator.constant()); + GasLimitCalculator.constant(), + LineaParameters.DEFAULT); return selector; } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/linea/LineaParameters.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/linea/LineaParameters.java index 92541a539d4..43c2e71540b 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/linea/LineaParameters.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/linea/LineaParameters.java @@ -5,18 +5,26 @@ import java.util.OptionalInt; public class LineaParameters { - public static final LineaParameters DEFAULT = new LineaParameters(null); + public static final LineaParameters DEFAULT = new LineaParameters(null, null); private final OptionalInt transactionCalldataMaxSize; + private final OptionalInt blockCalldataMaxSize; - public LineaParameters(final Integer transactionCalldataMaxSize) { + public LineaParameters( + final Integer transactionCalldataMaxSize, final Integer blockCalldataMaxSize) { this.transactionCalldataMaxSize = isNull(transactionCalldataMaxSize) ? OptionalInt.empty() : OptionalInt.of(transactionCalldataMaxSize); + this.blockCalldataMaxSize = + isNull(blockCalldataMaxSize) ? OptionalInt.empty() : OptionalInt.of(blockCalldataMaxSize); } public OptionalInt maybeTransactionCalldataMaxSize() { return transactionCalldataMaxSize; } + + public OptionalInt maybeBlockCalldataMaxSize() { + return blockCalldataMaxSize; + } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/LineaProtocolSpecs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/LineaProtocolSpecs.java index 0444c83e50b..8a631ec410e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/LineaProtocolSpecs.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/LineaProtocolSpecs.java @@ -12,6 +12,7 @@ import java.util.Set; public class LineaProtocolSpecs { + public static final int DEFAULT_BLOCK_MAX_CALLDATA_SIZE = 1000000; private static final int LINEA_MAX_TX_CALLDATA_SIZE = 10000; // fake value replace with the actual one when known @@ -52,6 +53,7 @@ static ProtocolSpecBuilder lineaDefinition( TransactionType.EIP1559), quorumCompatibilityMode, txCalldataMaxSize)) + .lineaParameters(lineaParameters) .name("Linea"); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpec.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpec.java index 652acc26c49..6bf8069ac0e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpec.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpec.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions; import org.hyperledger.besu.ethereum.core.BlockImporter; +import org.hyperledger.besu.ethereum.linea.LineaParameters; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor; import org.hyperledger.besu.evm.EVM; @@ -81,6 +82,8 @@ public class ProtocolSpec { private final DepositsValidator depositsValidator; private final boolean isPoS; + private final LineaParameters lineaParameters; + /** * Creates a new protocol specification instance. * @@ -111,6 +114,7 @@ public class ProtocolSpec { * @param withdrawalsProcessor the Withdrawals processor to use * @param depositsValidator the withdrawals validator to use * @param isPoS indicates whether the current spec is PoS + * @param lineaParameters linea parameters */ public ProtocolSpec( final String name, @@ -139,7 +143,8 @@ public ProtocolSpec( final WithdrawalsValidator withdrawalsValidator, final Optional withdrawalsProcessor, final DepositsValidator depositsValidator, - final boolean isPoS) { + final boolean isPoS, + final LineaParameters lineaParameters) { this.name = name; this.evm = evm; this.transactionValidator = transactionValidator; @@ -167,6 +172,7 @@ public ProtocolSpec( this.withdrawalsProcessor = withdrawalsProcessor; this.depositsValidator = depositsValidator; this.isPoS = isPoS; + this.lineaParameters = lineaParameters; } /** @@ -387,4 +393,8 @@ public DepositsValidator getDepositsValidator() { public boolean isPoS() { return isPoS; } + + public LineaParameters getLineaParameters() { + return lineaParameters; + } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java index eb44c07f310..4efbbae711f 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java @@ -27,6 +27,7 @@ import org.hyperledger.besu.ethereum.core.BlockImporter; import org.hyperledger.besu.ethereum.core.GoQuorumPrivacyParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters; +import org.hyperledger.besu.ethereum.linea.LineaParameters; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.precompiles.privacy.FlexiblePrivacyPrecompiledContract; import org.hyperledger.besu.ethereum.mainnet.precompiles.privacy.PrivacyPluginPrecompiledContract; @@ -82,6 +83,7 @@ public class ProtocolSpecBuilder { private BadBlockManager badBlockManager; private PoWHasher powHasher = PoWHasher.ETHASH_LIGHT; private boolean isPoS = false; + private LineaParameters lineaParameters = LineaParameters.DEFAULT; public ProtocolSpecBuilder gasCalculator(final Supplier gasCalculatorBuilder) { this.gasCalculatorBuilder = gasCalculatorBuilder; @@ -271,6 +273,11 @@ public ProtocolSpecBuilder isPoS(final boolean isPoS) { return this; } + public ProtocolSpecBuilder lineaParameters(final LineaParameters lineaParameters) { + this.lineaParameters = lineaParameters; + return this; + } + public ProtocolSpec build(final HeaderBasedProtocolSchedule protocolSchedule) { checkNotNull(gasCalculatorBuilder, "Missing gasCalculator"); checkNotNull(gasLimitCalculator, "Missing gasLimitCalculator"); @@ -379,7 +386,8 @@ public ProtocolSpec build(final HeaderBasedProtocolSchedule protocolSchedule) { withdrawalsValidator, Optional.ofNullable(withdrawalsProcessor), depositsValidator, - isPoS); + isPoS, + lineaParameters); } private PrivateTransactionProcessor createPrivateTransactionProcessor( diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java index 7e1c2078cd9..a8bc421e5d7 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockImporter; import org.hyperledger.besu.ethereum.core.TransactionFilter; +import org.hyperledger.besu.ethereum.linea.LineaParameters; import org.hyperledger.besu.ethereum.mainnet.BlockProcessor; import org.hyperledger.besu.ethereum.mainnet.MainnetBlockImporter; import org.hyperledger.besu.ethereum.mainnet.MainnetBlockProcessor; @@ -86,7 +87,8 @@ public ProtocolSpec getByBlockNumber(final long number) { original.getWithdrawalsValidator(), original.getWithdrawalsProcessor(), original.getDepositsValidator(), - original.isPoS()); + original.isPoS(), + LineaParameters.DEFAULT); } @Override From 1d6745037ef8cb43a7cc9b39401b57037bc5b055 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Tue, 4 Apr 2023 19:40:43 +0200 Subject: [PATCH 2/3] Replace lineaParameters with blockMaxCalldataSize Signed-off-by: Fabio Di Fabio --- .../methods/EthGetTransactionReceiptTest.java | 5 +-- .../blockcreation/AbstractBlockCreator.java | 2 +- .../BlockTransactionSelector.java | 39 ++++++------------- .../AbstractBlockTransactionSelectorTest.java | 5 +-- .../ethereum/mainnet/LineaProtocolSpecs.java | 12 ++++-- .../besu/ethereum/mainnet/ProtocolSpec.java | 13 +++---- .../ethereum/mainnet/ProtocolSpecBuilder.java | 9 ++--- .../NoRewardProtocolScheduleWrapper.java | 3 +- 8 files changed, 36 insertions(+), 52 deletions(-) diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java index 2c4883bbf7a..9754cc5eb5b 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java @@ -36,7 +36,6 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.TransactionReceipt; -import org.hyperledger.besu.ethereum.linea.LineaParameters; import org.hyperledger.besu.ethereum.mainnet.PoWHasher; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; @@ -117,7 +116,7 @@ public class EthGetTransactionReceiptTest { Optional.empty(), null, true, - LineaParameters.DEFAULT); + -1); private final ProtocolSpec statusTransactionTypeSpec = new ProtocolSpec( "status", @@ -147,7 +146,7 @@ public class EthGetTransactionReceiptTest { Optional.empty(), null, true, - LineaParameters.DEFAULT); + -1); @SuppressWarnings("unchecked") private final ProtocolSchedule protocolSchedule = mock(ProtocolSchedule.class); diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java index 7015377a652..ad579dd97f5 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java @@ -305,7 +305,7 @@ private BlockTransactionSelector.TransactionSelectionResults selectTransactions( protocolSpec.getFeeMarket(), protocolSpec.getGasCalculator(), protocolSpec.getGasLimitCalculator(), - protocolSpec.getLineaParameters()); + protocolSpec.getBlockMaxCalldataSize()); if (transactions.isPresent()) { return selector.evaluateTransactions(transactions.get()); diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockTransactionSelector.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockTransactionSelector.java index 9a6973f3865..643015edfc7 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockTransactionSelector.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockTransactionSelector.java @@ -24,7 +24,6 @@ import org.hyperledger.besu.ethereum.core.TransactionReceipt; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions.TransactionSelectionResult; -import org.hyperledger.besu.ethereum.linea.LineaParameters; import org.hyperledger.besu.ethereum.mainnet.AbstractBlockProcessor; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator; @@ -46,9 +45,8 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Optional; import java.util.concurrent.CancellationException; -import java.util.function.Function; +import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -79,11 +77,6 @@ */ public class BlockTransactionSelector { - private final int blockMaxCalldataSize; - private final Function> - lineaMaxCalldataSizeEnforcer; - private int blockCalldataSum; - public static class TransactionValidationResult { private final Transaction transaction; private final ValidationResult validationResult; @@ -231,7 +224,9 @@ public String toTraceLog() { private final FeeMarket feeMarket; private final GasCalculator gasCalculator; private final GasLimitCalculator gasLimitCalculator; - + private final int blockMaxCalldataSize; + private final Predicate maxCalldataSizeChecker; + private int blockCalldataSum; private final TransactionSelectionResults transactionSelectionResult = new TransactionSelectionResults(); @@ -250,7 +245,7 @@ public BlockTransactionSelector( final FeeMarket feeMarket, final GasCalculator gasCalculator, final GasLimitCalculator gasLimitCalculator, - final LineaParameters lineaParameters) { + final int blockMaxCalldataSize) { this.transactionProcessor = transactionProcessor; this.blockchain = blockchain; this.worldState = worldState; @@ -265,13 +260,9 @@ public BlockTransactionSelector( this.feeMarket = feeMarket; this.gasCalculator = gasCalculator; this.gasLimitCalculator = gasLimitCalculator; - if (lineaParameters.maybeBlockCalldataMaxSize().isPresent()) { - blockMaxCalldataSize = lineaParameters.maybeBlockCalldataMaxSize().getAsInt(); - lineaMaxCalldataSizeEnforcer = (t) -> maxCalldataEnforcer(t); - } else { - blockMaxCalldataSize = 0; - lineaMaxCalldataSizeEnforcer = (t) -> Optional.empty(); - } + this.blockMaxCalldataSize = blockMaxCalldataSize; + this.maxCalldataSizeChecker = + (blockMaxCalldataSize >= 0) ? this::transactionCalldataTooLarge : t -> false; } /* @@ -321,10 +312,8 @@ private TransactionSelectionResult evaluateTransaction( throw new CancellationException("Cancelled during transaction selection."); } - final Optional maybeResult = - lineaMaxCalldataSizeEnforcer.apply(transaction); - if (maybeResult.isPresent()) { - return maybeResult.get(); + if (maxCalldataSizeChecker.test(transaction)) { + return TransactionSelectionResult.COMPLETE_OPERATION; } if (transactionTooLargeForBlock(transaction)) { @@ -558,12 +547,8 @@ private boolean blockOccupancyAboveThreshold() { return occupancyRatio >= minBlockOccupancyRatio; } - private Optional maxCalldataEnforcer(final Transaction transaction) { + private boolean transactionCalldataTooLarge(final Transaction transaction) { this.blockCalldataSum += transaction.getPayload().size(); - if (blockCalldataSum > blockMaxCalldataSize) { - return Optional.of(TransactionSelectionResult.COMPLETE_OPERATION); - } else { - return Optional.empty(); - } + return blockCalldataSum > blockMaxCalldataSize; } } diff --git a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java index 674030daa82..d28d0b65d67 100644 --- a/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java @@ -44,7 +44,6 @@ import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions; import org.hyperledger.besu.ethereum.eth.transactions.sorter.BaseFeePendingTransactionsSorter; -import org.hyperledger.besu.ethereum.linea.LineaParameters; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; @@ -266,7 +265,7 @@ public void useSingleGasSpaceForAllTransactions() { FeeMarket.london(0L), new LondonGasCalculator(), GasLimitCalculator.constant(), - LineaParameters.DEFAULT); + -1); // this should fill up all the block space final Transaction fillingLegacyTx = @@ -472,7 +471,7 @@ protected BlockTransactionSelector createBlockSelector( getFeeMarket(), new LondonGasCalculator(), GasLimitCalculator.constant(), - LineaParameters.DEFAULT); + -1); return selector; } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/LineaProtocolSpecs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/LineaProtocolSpecs.java index 8a631ec410e..3c7e099d159 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/LineaProtocolSpecs.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/LineaProtocolSpecs.java @@ -12,8 +12,9 @@ import java.util.Set; public class LineaProtocolSpecs { - public static final int DEFAULT_BLOCK_MAX_CALLDATA_SIZE = 1000000; - private static final int LINEA_MAX_TX_CALLDATA_SIZE = + private static final int LINEA_BLOCK_MAX_CALLDATA_SIZE = + 1000000; // fake value replace with the actual one when known + private static final int LINEA_TX_MAX_CALLDATA_SIZE = 10000; // fake value replace with the actual one when known private LineaProtocolSpecs() {} @@ -28,8 +29,11 @@ static ProtocolSpecBuilder lineaDefinition( final EvmConfiguration evmConfiguration, final LineaParameters lineaParameters) { + // calldata limits overridden? final int txCalldataMaxSize = - lineaParameters.maybeTransactionCalldataMaxSize().orElse(LINEA_MAX_TX_CALLDATA_SIZE); + lineaParameters.maybeTransactionCalldataMaxSize().orElse(LINEA_TX_MAX_CALLDATA_SIZE); + final int blockCalldataMaxSize = + lineaParameters.maybeBlockCalldataMaxSize().orElse(LINEA_BLOCK_MAX_CALLDATA_SIZE); return MainnetProtocolSpecs.parisDefinition( chainId, @@ -53,7 +57,7 @@ static ProtocolSpecBuilder lineaDefinition( TransactionType.EIP1559), quorumCompatibilityMode, txCalldataMaxSize)) - .lineaParameters(lineaParameters) + .blockMaxCalldataSize(blockCalldataMaxSize) .name("Linea"); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpec.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpec.java index 6bf8069ac0e..89b59a95cf3 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpec.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpec.java @@ -20,7 +20,6 @@ import org.hyperledger.besu.ethereum.chain.BadBlockManager; import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions; import org.hyperledger.besu.ethereum.core.BlockImporter; -import org.hyperledger.besu.ethereum.linea.LineaParameters; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor; import org.hyperledger.besu.evm.EVM; @@ -82,7 +81,7 @@ public class ProtocolSpec { private final DepositsValidator depositsValidator; private final boolean isPoS; - private final LineaParameters lineaParameters; + private final int blockMaxCalldataSize; /** * Creates a new protocol specification instance. @@ -114,7 +113,7 @@ public class ProtocolSpec { * @param withdrawalsProcessor the Withdrawals processor to use * @param depositsValidator the withdrawals validator to use * @param isPoS indicates whether the current spec is PoS - * @param lineaParameters linea parameters + * @param blockMaxCalldataSize max size of the sum of all transactions' call data */ public ProtocolSpec( final String name, @@ -144,7 +143,7 @@ public ProtocolSpec( final Optional withdrawalsProcessor, final DepositsValidator depositsValidator, final boolean isPoS, - final LineaParameters lineaParameters) { + final int blockMaxCalldataSize) { this.name = name; this.evm = evm; this.transactionValidator = transactionValidator; @@ -172,7 +171,7 @@ public ProtocolSpec( this.withdrawalsProcessor = withdrawalsProcessor; this.depositsValidator = depositsValidator; this.isPoS = isPoS; - this.lineaParameters = lineaParameters; + this.blockMaxCalldataSize = blockMaxCalldataSize; } /** @@ -394,7 +393,7 @@ public boolean isPoS() { return isPoS; } - public LineaParameters getLineaParameters() { - return lineaParameters; + public int getBlockMaxCalldataSize() { + return blockMaxCalldataSize; } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java index 4efbbae711f..b3948479963 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java @@ -27,7 +27,6 @@ import org.hyperledger.besu.ethereum.core.BlockImporter; import org.hyperledger.besu.ethereum.core.GoQuorumPrivacyParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters; -import org.hyperledger.besu.ethereum.linea.LineaParameters; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.precompiles.privacy.FlexiblePrivacyPrecompiledContract; import org.hyperledger.besu.ethereum.mainnet.precompiles.privacy.PrivacyPluginPrecompiledContract; @@ -83,7 +82,7 @@ public class ProtocolSpecBuilder { private BadBlockManager badBlockManager; private PoWHasher powHasher = PoWHasher.ETHASH_LIGHT; private boolean isPoS = false; - private LineaParameters lineaParameters = LineaParameters.DEFAULT; + private int blockMaxCalldataSize = -1; public ProtocolSpecBuilder gasCalculator(final Supplier gasCalculatorBuilder) { this.gasCalculatorBuilder = gasCalculatorBuilder; @@ -273,8 +272,8 @@ public ProtocolSpecBuilder isPoS(final boolean isPoS) { return this; } - public ProtocolSpecBuilder lineaParameters(final LineaParameters lineaParameters) { - this.lineaParameters = lineaParameters; + public ProtocolSpecBuilder blockMaxCalldataSize(final int blockCalldataMaxSize) { + this.blockMaxCalldataSize = blockCalldataMaxSize; return this; } @@ -387,7 +386,7 @@ public ProtocolSpec build(final HeaderBasedProtocolSchedule protocolSchedule) { Optional.ofNullable(withdrawalsProcessor), depositsValidator, isPoS, - lineaParameters); + blockMaxCalldataSize); } private PrivateTransactionProcessor createPrivateTransactionProcessor( diff --git a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java index a8bc421e5d7..5d7c8d467fd 100644 --- a/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java +++ b/ethereum/retesteth/src/main/java/org/hyperledger/besu/ethereum/retesteth/NoRewardProtocolScheduleWrapper.java @@ -20,7 +20,6 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockImporter; import org.hyperledger.besu.ethereum.core.TransactionFilter; -import org.hyperledger.besu.ethereum.linea.LineaParameters; import org.hyperledger.besu.ethereum.mainnet.BlockProcessor; import org.hyperledger.besu.ethereum.mainnet.MainnetBlockImporter; import org.hyperledger.besu.ethereum.mainnet.MainnetBlockProcessor; @@ -88,7 +87,7 @@ public ProtocolSpec getByBlockNumber(final long number) { original.getWithdrawalsProcessor(), original.getDepositsValidator(), original.isPoS(), - LineaParameters.DEFAULT); + original.getBlockMaxCalldataSize()); } @Override From 3a035156a450806a39e863d4139b55318e671574 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Wed, 5 Apr 2023 10:25:19 +0200 Subject: [PATCH 3/3] Fix description of --Xblock-max-calldata-size option Signed-off-by: Fabio Di Fabio --- .../org/hyperledger/besu/cli/options/unstable/LineaOptions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/LineaOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/LineaOptions.java index b599661ea80..6316c6a166a 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/LineaOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/unstable/LineaOptions.java @@ -31,7 +31,7 @@ public static LineaOptions create() { names = {BLOCK_MAX_CALLDATA_SIZE}, paramLabel = "", description = - "If specified, overrides the max size in bytes allowed in the transaction calldata field, specified by the current hard fork") + "If specified, overrides the max size in bytes of the sum of all transaction calldata fields contained in a block, specified by the current hard fork") private Integer blockMaxCalldataSize; public Optional getTransactionMaxCalldataSize() {