Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.hyperledger.besu.ethereum.core.MiningConfiguration;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
import org.hyperledger.besu.ethereum.mainnet.BlockAccessListValidator;
import org.hyperledger.besu.ethereum.mainnet.BlockGasAccountingStrategy;
import org.hyperledger.besu.ethereum.mainnet.BlockGasUsedValidator;
import org.hyperledger.besu.ethereum.mainnet.CancunTargetingGasLimitCalculator;
Expand Down Expand Up @@ -178,6 +179,7 @@ public String description() {
true,
Optional.empty(),
Optional.empty(),
BlockAccessListValidator.ALWAYS_REJECT_BAL,
new DefaultStateRootCommitterFactory(),
BlockGasAccountingStrategy.FRONTIER,
BlockGasUsedValidator.FRONTIER);
Expand Down Expand Up @@ -214,6 +216,7 @@ public String description() {
true,
Optional.empty(),
Optional.empty(),
BlockAccessListValidator.ALWAYS_REJECT_BAL,
new DefaultStateRootCommitterFactory(),
BlockGasAccountingStrategy.FRONTIER,
BlockGasUsedValidator.FRONTIER);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.AbstractTransactionSelector;
import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.BlobPriceTransactionSelector;
import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.BlobSizeTransactionSelector;
import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.BlockAccessListItemBudgetTransactionSelector;
import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.BlockRlpSizeTransactionSelector;
import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.BlockSizeTransactionSelector;
import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.MinPriorityFeePerGasTransactionSelector;
Expand Down Expand Up @@ -125,6 +126,7 @@ public class BlockTransactionSelector implements BlockTransactionSelectionServic
private final long blockTxsSelectionMaxTimeNanos;
private final long pluginTxsSelectionMaxTimeNanos;
private final Optional<BlockAccessList.BlockAccessListBuilder> maybeBlockAccessListBuilder;

private WorldUpdater blockWorldStateUpdater;
private WorldUpdater txWorldStateUpdater;
private volatile TransactionEvaluationContext currTxEvaluationContext;
Expand Down Expand Up @@ -165,7 +167,8 @@ public BlockTransactionSelector(
this.selectorsStateManager = selectorsStateManager;
this.transactionSelectionService = miningConfiguration.getTransactionSelectionService();
this.transactionSelectors =
createTransactionSelectors(blockSelectionContext, selectorsStateManager);
createTransactionSelectors(
blockSelectionContext, selectorsStateManager, maybeBlockAccessListBuilder);
this.pluginTransactionSelector = pluginTransactionSelector;
this.operationTracer =
new InterruptibleOperationTracer(pluginTransactionSelector.getOperationTracer());
Expand All @@ -180,7 +183,9 @@ public BlockTransactionSelector(
}

private List<AbstractTransactionSelector> createTransactionSelectors(
final BlockSelectionContext context, final SelectorsStateManager selectorsStateManager) {
final BlockSelectionContext context,
final SelectorsStateManager selectorsStateManager,
final Optional<BlockAccessList.BlockAccessListBuilder> maybeBlockAccessListBuilder) {
return List.of(
new SkipSenderTransactionSelector(context),
new BlockSizeTransactionSelector(context, selectorsStateManager),
Expand All @@ -189,7 +194,8 @@ private List<AbstractTransactionSelector> createTransactionSelectors(
new BlobPriceTransactionSelector(context),
new MinPriorityFeePerGasTransactionSelector(context),
new BlockRlpSizeTransactionSelector(context, selectorsStateManager),
new ProcessingResultTransactionSelector(context));
new ProcessingResultTransactionSelector(context),
new BlockAccessListItemBudgetTransactionSelector(context, maybeBlockAccessListBuilder));
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright contributors to Hyperledger Besu.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.blockcreation.txselection.selectors;

import org.hyperledger.besu.ethereum.blockcreation.txselection.BlockSelectionContext;
import org.hyperledger.besu.ethereum.blockcreation.txselection.TransactionEvaluationContext;
import org.hyperledger.besu.ethereum.mainnet.BlockAccessListItemSizeCheck;
import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessList;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.plugin.data.TransactionSelectionResult;

import java.util.Optional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Rejects a transaction when applying its partial block access view would exceed the EIP-7928 item
* budget for the block (same rule as block import in {@link
* org.hyperledger.besu.ethereum.mainnet.AbstractBlockProcessor}).
*/
public class BlockAccessListItemBudgetTransactionSelector extends AbstractTransactionSelector {

private static final Logger LOG =
LoggerFactory.getLogger(BlockAccessListItemBudgetTransactionSelector.class);

private final Optional<BlockAccessList.BlockAccessListBuilder> maybeBlockAccessListBuilder;

public BlockAccessListItemBudgetTransactionSelector(
final BlockSelectionContext context,
final Optional<BlockAccessList.BlockAccessListBuilder> maybeBlockAccessListBuilder) {
super(context);
this.maybeBlockAccessListBuilder = maybeBlockAccessListBuilder;
}

@Override
public TransactionSelectionResult evaluateTransactionPreProcessing(
final TransactionEvaluationContext evaluationContext) {
return TransactionSelectionResult.SELECTED;
}

@Override
public TransactionSelectionResult evaluateTransactionPostProcessing(
final TransactionEvaluationContext evaluationContext,
final TransactionProcessingResult processingResult) {
if (maybeBlockAccessListBuilder.isEmpty()) {
return TransactionSelectionResult.SELECTED;
}
final BlockAccessList.BlockAccessListBuilder mainBuilder = maybeBlockAccessListBuilder.get();
final long itemCount;
if (processingResult.getPartialBlockAccessView().isEmpty()) {
itemCount = mainBuilder.eip7928ItemCount();
} else {
final BlockAccessList committedSnapshot = mainBuilder.build();
final BlockAccessList.BlockAccessListBuilder probe = BlockAccessList.builder();
probe.mergeFrom(committedSnapshot);
probe.apply(processingResult.getPartialBlockAccessView().get());
itemCount = probe.eip7928ItemCount();
}
final BlockAccessListItemSizeCheck itemSizeCheck =
context
.protocolSpec()
.getBlockAccessListValidator()
.validateExecutedBlockAccessListItemSize(
itemCount, context.pendingBlockHeader(), context.protocolSpec());
if (itemSizeCheck.isOverBudget()) {
LOG.trace(
"Transaction not selected: {}",
itemSizeCheck.overBudgetError().orElseThrow().errorMessage());
return TransactionSelectionResult.BLOCK_ACCESS_LIST_ITEM_BUDGET_EXCEEDED;
}
return TransactionSelectionResult.SELECTED;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessList;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
import org.hyperledger.besu.ethereum.storage.keyvalue.VariablesKeyValueStorage;
Expand Down Expand Up @@ -1682,7 +1683,27 @@ protected BlockTransactionSelector createBlockSelector(
final Address miningBeneficiary,
final Wei blobGasPrice,
final TransactionSelectionService transactionSelectionService) {
ProtocolSpec protocolSpec = protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader());
return createBlockSelector(
miningConfiguration,
transactionProcessor,
blockHeader,
miningBeneficiary,
blobGasPrice,
transactionSelectionService,
protocolSchedule,
Optional.empty());
}

protected BlockTransactionSelector createBlockSelector(
final MiningConfiguration miningConfiguration,
final MainnetTransactionProcessor transactionProcessor,
final ProcessableBlockHeader blockHeader,
final Address miningBeneficiary,
final Wei blobGasPrice,
final TransactionSelectionService transactionSelectionService,
final ProtocolSchedule schedule,
final Optional<BlockAccessList.BlockAccessListBuilder> maybeBalBuilder) {
ProtocolSpec protocolSpec = schedule.getByBlockHeader(blockchain.getChainHeadHeader());
final var selectorsStateManager = new SelectorsStateManager();
final BlockTransactionSelector selector =
new BlockTransactionSelector(
Expand All @@ -1692,15 +1713,15 @@ protected BlockTransactionSelector createBlockSelector(
worldState,
transactionPool,
blockHeader,
protocolSchedule.getByBlockHeader(blockHeader).getTransactionReceiptFactory(),
schedule.getByBlockHeader(blockHeader).getTransactionReceiptFactory(),
miningBeneficiary,
blobGasPrice,
protocolSpec,
transactionSelectionService.createPluginTransactionSelector(
blockHeader, selectorsStateManager),
ethScheduler,
selectorsStateManager,
Optional.empty());
maybeBalBuilder);

return selector;
}
Expand Down Expand Up @@ -1934,7 +1955,7 @@ public static TransactionSelectionResult invalid(final String invalidReason) {
}
}

protected enum Sender {
public enum Sender {
// it is important to keep the addresses of the senders sorted, to make the tests reproducible,
// since a different sender address can change the order in which txs are selected,
// if all the other sorting fields are equal
Expand Down
Loading
Loading