diff --git a/besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java b/besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java index 4ce430e787d..68170f3258c 100644 --- a/besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java +++ b/besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java @@ -48,9 +48,9 @@ import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolFactory; import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions; -import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; +import org.hyperledger.besu.ethereum.mainnet.TransactionValidator; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage; @@ -99,7 +99,7 @@ public class BesuEventsImplTest { @Mock private EthContext mockEthContext; @Mock private EthMessages mockEthMessages; @Mock private EthScheduler mockEthScheduler; - @Mock private MainnetTransactionValidator mockTransactionValidator; + @Mock private TransactionValidator mockTransactionValidator; @Mock private ProtocolSpec mockProtocolSpec; @Mock private WorldStateArchive mockWorldStateArchive; @Mock private MutableWorldState mockWorldState; diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java index f934e4cd30d..0b2a2f5a372 100644 --- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java +++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java @@ -18,8 +18,8 @@ import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.Difficulty; +import org.hyperledger.besu.ethereum.core.PermissionTransactionFilter; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; -import org.hyperledger.besu.ethereum.core.TransactionFilter; import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; @@ -216,12 +216,12 @@ public String listMilestones() { /** * Sets transaction filter. * - * @param transactionFilter the transaction filter + * @param permissionTransactionFilter the transaction filter */ @Override - public void setTransactionFilter(final TransactionFilter transactionFilter) { + public void setTransactionFilter(final PermissionTransactionFilter permissionTransactionFilter) { transitionUtils.dispatchConsumerAccordingToMergeState( - protocolSchedule -> protocolSchedule.setTransactionFilter(transactionFilter)); + protocolSchedule -> protocolSchedule.setTransactionFilter(permissionTransactionFilter)); } /** 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..8ea908e5889 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 @@ -115,6 +115,7 @@ public class EthGetTransactionReceiptTest { null, Optional.empty(), null, + true, true); private final ProtocolSpec statusTransactionTypeSpec = new ProtocolSpec( @@ -144,6 +145,7 @@ public class EthGetTransactionReceiptTest { null, Optional.empty(), null, + true, true); @SuppressWarnings("unchecked") diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/transaction/pool/PendingTransactionFilterTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/transaction/pool/PendingPermissionTransactionFilterTest.java similarity index 98% rename from ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/transaction/pool/PendingTransactionFilterTest.java rename to ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/transaction/pool/PendingPermissionTransactionFilterTest.java index 13c68f7c903..64db24b674a 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/transaction/pool/PendingTransactionFilterTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/transaction/pool/PendingPermissionTransactionFilterTest.java @@ -45,7 +45,7 @@ import org.junit.runners.Parameterized; @RunWith(Parameterized.class) -public class PendingTransactionFilterTest { +public class PendingPermissionTransactionFilterTest { @Parameterized.Parameters public static Collection data() { @@ -97,7 +97,7 @@ public static Collection data() { private final int limit; private final List expectedListOfTransactionHash; - public PendingTransactionFilterTest( + public PendingPermissionTransactionFilterTest( final List filters, final int limit, final List expectedListOfTransactionHash) { 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 88a2fc4573d..e4701f848ec 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 @@ -43,6 +43,7 @@ import java.util.ArrayList; import java.util.EnumMap; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -78,15 +79,12 @@ */ public class BlockTransactionSelector { - public record TransactionValidationResult( - Transaction transaction, ValidationResult validationResult) {} - public static class TransactionSelectionResults { private final List transactions = Lists.newArrayList(); private final Map> transactionsByType = new EnumMap<>(TransactionType.class); private final List receipts = Lists.newArrayList(); - private final List invalidTransactions = Lists.newArrayList(); + private final Map invalidTransactions = new HashMap<>(); private final List selectionResults = Lists.newArrayList(); private long cumulativeGasUsed = 0; private long cumulativeDataGasUsed = 0; @@ -114,9 +112,8 @@ private void update( } private void updateWithInvalidTransaction( - final Transaction transaction, - final ValidationResult validationResult) { - invalidTransactions.add(new TransactionValidationResult(transaction, validationResult)); + final Transaction transaction, final TransactionInvalidReason invalidReason) { + invalidTransactions.put(transaction, invalidReason); } public List getTransactions() { @@ -139,7 +136,7 @@ public long getCumulativeDataGasUsed() { return cumulativeDataGasUsed; } - public List getInvalidTransactions() { + public Map getInvalidTransactions() { return invalidTransactions; } @@ -278,7 +275,7 @@ public TransactionSelectionResults buildTransactionListForBlock() { .log(); pendingTransactions.selectTransactions( pendingTransaction -> { - final var res = evaluateTransaction(pendingTransaction, false); + final var res = evaluateTransaction(pendingTransaction); transactionSelectionResults.addSelectionResult(res); return res; }); @@ -298,7 +295,7 @@ public TransactionSelectionResults buildTransactionListForBlock() { public TransactionSelectionResults evaluateTransactions(final List transactions) { transactions.forEach( transaction -> - transactionSelectionResults.addSelectionResult(evaluateTransaction(transaction, true))); + transactionSelectionResults.addSelectionResult(evaluateTransaction(transaction))); return transactionSelectionResults; } @@ -311,8 +308,7 @@ public TransactionSelectionResults evaluateTransactions(final List * the space remaining in the block. * */ - private TransactionSelectionResult evaluateTransaction( - final Transaction transaction, final boolean reportFutureNonceTransactionsAsInvalid) { + private TransactionSelectionResult evaluateTransaction(final Transaction transaction) { if (isCancelled.get()) { throw new CancellationException("Cancelled during transaction selection."); } @@ -393,12 +389,9 @@ private TransactionSelectionResult evaluateTransaction( } return txSelectionResult; } else { + transactionSelectionResults.updateWithInvalidTransaction( + transaction, effectiveResult.getValidationResult().getInvalidReason()); - final boolean isIncorrectNonce = isIncorrectNonce(effectiveResult.getValidationResult()); - if (!isIncorrectNonce || reportFutureNonceTransactionsAsInvalid) { - transactionSelectionResults.updateWithInvalidTransaction( - transaction, effectiveResult.getValidationResult()); - } return transactionSelectionResultForInvalidResult( transaction, effectiveResult.getValidationResult()); } @@ -472,10 +465,6 @@ private boolean isTransientValidationError(final TransactionInvalidReason invali || invalidReason.equals(TransactionInvalidReason.NONCE_TOO_HIGH); } - private boolean isIncorrectNonce(final ValidationResult result) { - return result.getInvalidReason().equals(TransactionInvalidReason.NONCE_TOO_HIGH); - } - private boolean transactionTooLargeForBlock(final Transaction transaction) { final long dataGasUsed = gasCalculator.dataGasCost(transaction.getBlobCount()); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/TransactionFilter.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/PermissionTransactionFilter.java similarity index 88% rename from ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/TransactionFilter.java rename to ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/PermissionTransactionFilter.java index ec51812db1a..bb2784e9805 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/TransactionFilter.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/PermissionTransactionFilter.java @@ -1,5 +1,6 @@ /* - * Copyright ConsenSys AG. + * + * Copyright Hyperledger Besu Contributors. * * 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 @@ -11,11 +12,12 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 + * */ package org.hyperledger.besu.ethereum.core; @FunctionalInterface -public interface TransactionFilter { +public interface PermissionTransactionFilter { boolean permitted( Transaction transaction, boolean checkLocalPermissions, boolean checkOnchainPermissions); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicProtocolSpecs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicProtocolSpecs.java index bb99bd72390..4aa97733f9c 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicProtocolSpecs.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicProtocolSpecs.java @@ -72,6 +72,7 @@ public static ProtocolSpecBuilder tangerineWhistleDefinition( final EvmConfiguration evmConfiguration) { return MainnetProtocolSpecs.homesteadDefinition( contractSizeLimit, configStackSizeLimit, evmConfiguration) + .isReplayProtectionSupported(true) .gasCalculator(TangerineWhistleGasCalculator::new) .transactionValidatorBuilder( (gasCalculator, gasLimitCalculator) -> diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolSchedule.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolSchedule.java index a2de85905f3..b2cdc9ac06c 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolSchedule.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolSchedule.java @@ -20,8 +20,8 @@ import static com.google.common.base.Preconditions.checkArgument; import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.core.PermissionTransactionFilter; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; -import org.hyperledger.besu.ethereum.core.TransactionFilter; import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec.BlockNumberProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec.TimestampProtocolSpec; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; @@ -111,9 +111,12 @@ public boolean anyMatch(final Predicate predicate) { } @Override - public void setTransactionFilter(final TransactionFilter transactionFilter) { + public void setTransactionFilter(final PermissionTransactionFilter permissionTransactionFilter) { protocolSpecs.forEach( - spec -> spec.spec().getTransactionValidator().setTransactionFilter(transactionFilter)); + spec -> + spec.spec() + .getTransactionValidator() + .setPermissionTransactionFilter(permissionTransactionFilter)); } @Override diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java index 18417763bd4..e5b7a032bae 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java @@ -257,6 +257,7 @@ public static ProtocolSpecBuilder spuriousDragonDefinition( final int stackSizeLimit = configStackSizeLimit.orElse(MessageFrame.DEFAULT_MAX_STACK_SIZE); return tangerineWhistleDefinition(OptionalInt.empty(), configStackSizeLimit, evmConfiguration) + .isReplayProtectionSupported(true) .gasCalculator(SpuriousDragonGasCalculator::new) .skipZeroBlockRewards(true) .messageCallProcessorBuilder( diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java index 181b43e91f5..407c6850daf 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java @@ -64,7 +64,7 @@ public class MainnetTransactionProcessor { protected final GasCalculator gasCalculator; - protected final MainnetTransactionValidator transactionValidator; + protected final TransactionValidator transactionValidator; private final AbstractMessageProcessor contractCreationProcessor; @@ -81,7 +81,7 @@ public class MainnetTransactionProcessor { public MainnetTransactionProcessor( final GasCalculator gasCalculator, - final MainnetTransactionValidator transactionValidator, + final TransactionValidator transactionValidator, final AbstractMessageProcessor contractCreationProcessor, final AbstractMessageProcessor messageCallProcessor, final boolean clearEmptyAccounts, @@ -498,7 +498,7 @@ public TransactionProcessingResult processTransaction( } } - public MainnetTransactionValidator getTransactionValidator() { + public TransactionValidator getTransactionValidator() { return transactionValidator; } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java index 549828ac906..710e24601fd 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java @@ -21,8 +21,8 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.GasLimitCalculator; +import org.hyperledger.besu.ethereum.core.PermissionTransactionFilter; import org.hyperledger.besu.ethereum.core.Transaction; -import org.hyperledger.besu.ethereum.core.TransactionFilter; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; import org.hyperledger.besu.evm.account.Account; @@ -39,7 +39,7 @@ *

The {@link MainnetTransactionValidator} performs the intrinsic gas cost check on the given * {@link Transaction}. */ -public class MainnetTransactionValidator { +public class MainnetTransactionValidator implements TransactionValidator { private final GasCalculator gasCalculator; private final GasLimitCalculator gasLimitCalculator; @@ -49,7 +49,7 @@ public class MainnetTransactionValidator { private final Optional chainId; - private Optional transactionFilter = Optional.empty(); + private Optional permissionTransactionFilter = Optional.empty(); private final Set acceptedTransactionTypes; private final int maxInitcodeSize; @@ -100,16 +100,7 @@ public MainnetTransactionValidator( this.maxInitcodeSize = maxInitcodeSize; } - /** - * Asserts whether a transaction is valid. - * - * @param transaction the transaction to validate - * @param baseFee optional baseFee - * @param transactionValidationParams Validation parameters that will be used - * @return An empty {@link Optional} if the transaction is considered valid; otherwise an {@code - * Optional} containing a {@link TransactionInvalidReason} that identifies why the transaction - * is invalid. - */ + @Override public ValidationResult validate( final Transaction transaction, final Optional baseFee, @@ -199,6 +190,7 @@ private ValidationResult validateCostAndFee( return ValidationResult.valid(); } + @Override public ValidationResult validateForSender( final Transaction transaction, final Account sender, @@ -256,11 +248,7 @@ public ValidationResult validateForSender( return ValidationResult.valid(); } - public boolean isReplayProtectionSupported() { - return chainId.isPresent(); - } - - public ValidationResult validateTransactionSignature( + private ValidationResult validateTransactionSignature( final Transaction transaction) { if (chainId.isPresent() && (transaction.getChainId().isPresent() && !transaction.getChainId().equals(chainId))) { @@ -302,7 +290,7 @@ public ValidationResult validateTransactionSignature( private boolean isSenderAllowed( final Transaction transaction, final TransactionValidationParams validationParams) { if (validationParams.checkLocalPermissions() || validationParams.checkOnchainPermissions()) { - return transactionFilter + return permissionTransactionFilter .map( c -> c.permitted( @@ -315,30 +303,9 @@ private boolean isSenderAllowed( } } - public void setTransactionFilter(final TransactionFilter transactionFilter) { - this.transactionFilter = Optional.of(transactionFilter); - } - - /** - * Asserts whether a transaction is valid for the sender account's current state. - * - *

Note: {@code validate} should be called before getting the sender {@link Account} used in - * this method to ensure that a sender can be extracted from the {@link Transaction}. - * - * @param transaction the transaction to validateMessageFrame.State.COMPLETED_FAILED - * @param sender the sender account state to validate against - * @param allowFutureNonce if true, transactions with nonce equal or higher than the account nonce - * will be considered valid (used when received transactions in the transaction pool). If - * false, only a transaction with the nonce equals the account nonce will be considered valid - * (used when processing transactions). - * @return An empty {@link Optional} if the transaction is considered valid; otherwise an {@code - * Optional} containing a {@link TransactionInvalidReason} that identifies why the transaction - * is invalid. - */ - public ValidationResult validateForSender( - final Transaction transaction, final Account sender, final boolean allowFutureNonce) { - final TransactionValidationParams validationParams = - ImmutableTransactionValidationParams.builder().isAllowFutureNonce(allowFutureNonce).build(); - return validateForSender(transaction, sender, validationParams); + @Override + public void setPermissionTransactionFilter( + final PermissionTransactionFilter permissionTransactionFilter) { + this.permissionTransactionFilter = Optional.of(permissionTransactionFilter); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PrivacySupportingProtocolSchedule.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PrivacySupportingProtocolSchedule.java index d841e4b9eba..aed9a52f7b9 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PrivacySupportingProtocolSchedule.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PrivacySupportingProtocolSchedule.java @@ -17,12 +17,12 @@ package org.hyperledger.besu.ethereum.mainnet; -import org.hyperledger.besu.ethereum.core.TransactionFilter; +import org.hyperledger.besu.ethereum.core.PermissionTransactionFilter; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; public interface PrivacySupportingProtocolSchedule { - void setTransactionFilter(final TransactionFilter transactionFilter); + void setTransactionFilter(final PermissionTransactionFilter permissionTransactionFilter); void setPublicWorldStateArchiveForPrivacyBlockProcessor( final WorldStateArchive publicWorldStateArchive); 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..8805ad556e0 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 @@ -38,7 +38,7 @@ public class ProtocolSpec { private final GasLimitCalculator gasLimitCalculator; - private final MainnetTransactionValidator transactionValidator; + private final TransactionValidator transactionValidator; private final MainnetTransactionProcessor transactionProcessor; @@ -81,6 +81,7 @@ public class ProtocolSpec { private final DepositsValidator depositsValidator; private final boolean isPoS; + private final boolean isReplayProtectionSupported; /** * Creates a new protocol specification instance. * @@ -111,11 +112,13 @@ 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 isReplayProtectionSupported indicates whether the current spec supports replay + * protection */ public ProtocolSpec( final String name, final EVM evm, - final MainnetTransactionValidator transactionValidator, + final TransactionValidator transactionValidator, final MainnetTransactionProcessor transactionProcessor, final PrivateTransactionProcessor privateTransactionProcessor, final BlockHeaderValidator blockHeaderValidator, @@ -139,7 +142,8 @@ public ProtocolSpec( final WithdrawalsValidator withdrawalsValidator, final Optional withdrawalsProcessor, final DepositsValidator depositsValidator, - final boolean isPoS) { + final boolean isPoS, + final boolean isReplayProtectionSupported) { this.name = name; this.evm = evm; this.transactionValidator = transactionValidator; @@ -167,6 +171,7 @@ public ProtocolSpec( this.withdrawalsProcessor = withdrawalsProcessor; this.depositsValidator = depositsValidator; this.isPoS = isPoS; + this.isReplayProtectionSupported = isReplayProtectionSupported; } /** @@ -183,12 +188,12 @@ public String getName() { * * @return the transaction validator */ - public MainnetTransactionValidator getTransactionValidator() { + public TransactionValidator getTransactionValidator() { return transactionValidator; } public boolean isReplayProtectionSupported() { - return transactionValidator.isReplayProtectionSupported(); + return isReplayProtectionSupported; } /** 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 b71ccbda046..60787068dbb 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 @@ -53,7 +53,7 @@ public class ProtocolSpecBuilder { private DifficultyCalculator difficultyCalculator; private EvmConfiguration evmConfiguration; private BiFunction evmBuilder; - private BiFunction + private BiFunction transactionValidatorBuilder; private Function blockHeaderValidatorBuilder; private Function ommerHeaderValidatorBuilder; @@ -81,6 +81,7 @@ public class ProtocolSpecBuilder { private BadBlockManager badBlockManager; private PoWHasher powHasher = PoWHasher.ETHASH_LIGHT; private boolean isPoS = false; + private boolean isReplayProtectionSupported = false; public ProtocolSpecBuilder gasCalculator(final Supplier gasCalculatorBuilder) { this.gasCalculatorBuilder = gasCalculatorBuilder; @@ -125,7 +126,7 @@ public ProtocolSpecBuilder evmBuilder( } public ProtocolSpecBuilder transactionValidatorBuilder( - final BiFunction + final BiFunction transactionValidatorBuilder) { this.transactionValidatorBuilder = transactionValidatorBuilder; return this; @@ -270,6 +271,12 @@ public ProtocolSpecBuilder isPoS(final boolean isPoS) { return this; } + public ProtocolSpecBuilder isReplayProtectionSupported( + final boolean isReplayProtectionSupported) { + this.isReplayProtectionSupported = isReplayProtectionSupported; + return this; + } + public ProtocolSpec build(final ProtocolSchedule protocolSchedule) { checkNotNull(gasCalculatorBuilder, "Missing gasCalculator"); checkNotNull(gasLimitCalculator, "Missing gasLimitCalculator"); @@ -302,7 +309,7 @@ public ProtocolSpec build(final ProtocolSchedule protocolSchedule) { final EVM evm = evmBuilder.apply(gasCalculator, evmConfiguration); final PrecompiledContractConfiguration precompiledContractConfiguration = new PrecompiledContractConfiguration(gasCalculator, privacyParameters); - final MainnetTransactionValidator transactionValidator = + final TransactionValidator transactionValidator = transactionValidatorBuilder.apply(gasCalculator, gasLimitCalculator); final AbstractMessageProcessor contractCreationProcessor = contractCreationProcessorBuilder.apply(gasCalculator, evm); @@ -374,11 +381,12 @@ public ProtocolSpec build(final ProtocolSchedule protocolSchedule) { withdrawalsValidator, Optional.ofNullable(withdrawalsProcessor), depositsValidator, - isPoS); + isPoS, + isReplayProtectionSupported); } private PrivateTransactionProcessor createPrivateTransactionProcessor( - final MainnetTransactionValidator transactionValidator, + final TransactionValidator transactionValidator, final AbstractMessageProcessor contractCreationProcessor, final AbstractMessageProcessor messageCallProcessor, final PrecompileContractRegistry precompileContractRegistry) { @@ -435,14 +443,14 @@ private BlockHeaderValidator createBlockHeaderValidator( public interface TransactionProcessorBuilder { MainnetTransactionProcessor apply( GasCalculator gasCalculator, - MainnetTransactionValidator transactionValidator, + TransactionValidator transactionValidator, AbstractMessageProcessor contractCreationProcessor, AbstractMessageProcessor messageCallProcessor); } public interface PrivateTransactionProcessorBuilder { PrivateTransactionProcessor apply( - MainnetTransactionValidator transactionValidator, + TransactionValidator transactionValidator, AbstractMessageProcessor contractCreationProcessor, AbstractMessageProcessor messageCallProcessor, PrivateTransactionValidator privateTransactionValidator); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/TransactionValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/TransactionValidator.java new file mode 100644 index 00000000000..81514f0edde --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/TransactionValidator.java @@ -0,0 +1,65 @@ +/* + * Copyright Hyperledger Besu Contributors. + * + * 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.mainnet; + +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.PermissionTransactionFilter; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; +import org.hyperledger.besu.evm.account.Account; + +import java.util.Optional; + +public interface TransactionValidator { + + /** + * Asserts whether a transaction is valid. + * + * @param transaction the transaction to validate + * @param baseFee optional baseFee + * @param transactionValidationParams Validation parameters that will be used + * @return the result of the validation, in case of invalid transaction the invalid reason is + * present + */ + ValidationResult validate( + Transaction transaction, + Optional baseFee, + TransactionValidationParams transactionValidationParams); + + /** + * Asserts whether a transaction is valid for the sender account's current state. + * + *

Note: {@code validate} should be called before getting the sender {@link Account} used in + * this method to ensure that a sender can be extracted from the {@link Transaction}. + * + * @param transaction the transaction to validate + * @param sender the account of the sender of the transaction + * @param validationParams to customize the validation according to different scenarios, like + * processing block, adding to the txpool, etc... + * @return the result of the validation, in case of invalid transaction the invalid reason is + * present + */ + ValidationResult validateForSender( + Transaction transaction, Account sender, TransactionValidationParams validationParams); + + /** + * Set the permission transaction filter. This way of setting the filter is deprecated and will be + * removed. + * + * @param permissionTransactionFilter the permission transaction filter + */ + @Deprecated + void setPermissionTransactionFilter(PermissionTransactionFilter permissionTransactionFilter); +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionProcessor.java index 4628ef6b151..fdbeb19bf70 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionProcessor.java @@ -20,7 +20,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; -import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator; +import org.hyperledger.besu.ethereum.mainnet.TransactionValidator; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; @@ -49,7 +49,7 @@ public class PrivateTransactionProcessor { private static final Logger LOG = LoggerFactory.getLogger(PrivateTransactionProcessor.class); @SuppressWarnings("unused") - private final MainnetTransactionValidator transactionValidator; + private final TransactionValidator transactionValidator; private final PrivateTransactionValidator privateTransactionValidator; @@ -63,7 +63,7 @@ public class PrivateTransactionProcessor { private final boolean clearEmptyAccounts; public PrivateTransactionProcessor( - final MainnetTransactionValidator transactionValidator, + final TransactionValidator transactionValidator, final AbstractMessageProcessor contractCreationProcessor, final AbstractMessageProcessor messageCallProcessor, final boolean clearEmptyAccounts, diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java index ce555391570..508448bc4ab 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java @@ -53,7 +53,7 @@ public class MainnetTransactionProcessorTest { private static final int MAX_STACK_SIZE = 1024; private final GasCalculator gasCalculator = new LondonGasCalculator(); - @Mock private MainnetTransactionValidator transactionValidator; + @Mock private TransactionValidator transactionValidator; @Mock private AbstractMessageProcessor contractCreationProcessor; @Mock private AbstractMessageProcessor messageCallProcessor; diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidatorTest.java index 868c39d5370..672b93c5edf 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidatorTest.java @@ -15,6 +15,8 @@ package org.hyperledger.besu.ethereum.mainnet; import static org.assertj.core.api.Assertions.assertThat; +import static org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams.processingBlockParams; +import static org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams.transactionPoolParams; import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.GAS_PRICE_BELOW_CURRENT_BASE_FEE; import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.INVALID_TRANSACTION_FORMAT; import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.MAX_PRIORITY_FEE_PER_GAS_EXCEEDS_MAX_FEE_PER_GAS; @@ -33,8 +35,8 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.GasLimitCalculator; +import org.hyperledger.besu.ethereum.core.PermissionTransactionFilter; import org.hyperledger.besu.ethereum.core.Transaction; -import org.hyperledger.besu.ethereum.core.TransactionFilter; import org.hyperledger.besu.ethereum.core.TransactionTestFixture; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; @@ -63,7 +65,7 @@ public class MainnetTransactionValidatorTest { private static final KeyPair senderKeys = SIGNATURE_ALGORITHM.get().generateKeyPair(); private static final TransactionValidationParams transactionValidationParams = - TransactionValidationParams.processingBlockParams; + processingBlockParams; @Mock private GasCalculator gasCalculator; @@ -74,7 +76,7 @@ public class MainnetTransactionValidatorTest { @Test public void shouldRejectTransactionIfIntrinsicGasExceedsGasLimit() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), false, Optional.empty()); final Transaction transaction = @@ -91,7 +93,7 @@ public void shouldRejectTransactionIfIntrinsicGasExceedsGasLimit() { @Test public void shouldRejectTransactionWhenTransactionHasChainIdAndValidatorDoesNot() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), false, Optional.empty()); assertThat(validator.validate(basicTransaction, Optional.empty(), transactionValidationParams)) @@ -102,7 +104,7 @@ public void shouldRejectTransactionWhenTransactionHasChainIdAndValidatorDoesNot( @Test public void shouldRejectTransactionWhenTransactionHasIncorrectChainId() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), @@ -114,51 +116,51 @@ public void shouldRejectTransactionWhenTransactionHasIncorrectChainId() { @Test public void shouldRejectTransactionWhenSenderAccountDoesNotExist() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), false, Optional.of(BigInteger.ONE)); - assertThat(validator.validateForSender(basicTransaction, null, false)) + assertThat(validator.validateForSender(basicTransaction, null, processingBlockParams)) .isEqualTo(ValidationResult.invalid(TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE)); } @Test public void shouldRejectTransactionWhenTransactionNonceBelowAccountNonce() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), false, Optional.of(BigInteger.ONE)); final Account account = accountWithNonce(basicTransaction.getNonce() + 1); - assertThat(validator.validateForSender(basicTransaction, account, false)) + assertThat(validator.validateForSender(basicTransaction, account, processingBlockParams)) .isEqualTo(ValidationResult.invalid(TransactionInvalidReason.NONCE_TOO_LOW)); } @Test public void shouldRejectTransactionWhenTransactionNonceAboveAccountNonceAndFutureNonceIsNotAllowed() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), false, Optional.of(BigInteger.ONE)); final Account account = accountWithNonce(basicTransaction.getNonce() - 1); - assertThat(validator.validateForSender(basicTransaction, account, false)) + assertThat(validator.validateForSender(basicTransaction, account, processingBlockParams)) .isEqualTo(ValidationResult.invalid(TransactionInvalidReason.NONCE_TOO_HIGH)); } @Test public void shouldAcceptTransactionWhenTransactionNonceAboveAccountNonceAndFutureNonceIsAllowed() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), false, Optional.of(BigInteger.ONE)); final Account account = accountWithNonce(basicTransaction.getNonce() - 1); - assertThat(validator.validateForSender(basicTransaction, account, true)) + assertThat(validator.validateForSender(basicTransaction, account, transactionPoolParams)) .isEqualTo(ValidationResult.valid()); } @Test public void shouldRejectTransactionWhenNonceExceedsMaximumAllowedNonce() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), false, Optional.of(BigInteger.ONE)); @@ -166,13 +168,13 @@ public void shouldRejectTransactionWhenNonceExceedsMaximumAllowedNonce() { new TransactionTestFixture().nonce(11).createTransaction(senderKeys); final Account account = accountWithNonce(5); - assertThat(validator.validateForSender(transaction, account, false)) + assertThat(validator.validateForSender(transaction, account, processingBlockParams)) .isEqualTo(ValidationResult.invalid(TransactionInvalidReason.NONCE_TOO_HIGH)); } @Test public void transactionWithNullSenderCanBeValidIfGasPriceAndValueIsZero() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), false, Optional.of(BigInteger.ONE)); @@ -181,16 +183,18 @@ public void transactionWithNullSenderCanBeValidIfGasPriceAndValueIsZero() { final Address arbitrarySender = Address.fromHexString("1"); builder.gasPrice(Wei.ZERO).nonce(0).sender(arbitrarySender).value(Wei.ZERO); - assertThat(validator.validateForSender(builder.createTransaction(senderKeyPair), null, false)) + assertThat( + validator.validateForSender( + builder.createTransaction(senderKeyPair), null, processingBlockParams)) .isEqualTo(ValidationResult.valid()); } @Test public void shouldRejectTransactionIfAccountIsNotEOA() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), false, Optional.empty()); - validator.setTransactionFilter(transactionFilter(false)); + validator.setPermissionTransactionFilter(transactionFilter(false)); Account invalidEOA = when(account(basicTransaction.getUpfrontCost(0L), basicTransaction.getNonce()) @@ -198,38 +202,42 @@ public void shouldRejectTransactionIfAccountIsNotEOA() { .thenReturn(Hash.fromHexStringLenient("0xdeadbeef")) .getMock(); - assertThat(validator.validateForSender(basicTransaction, invalidEOA, true)) + assertThat(validator.validateForSender(basicTransaction, invalidEOA, transactionPoolParams)) .isEqualTo(ValidationResult.invalid(TransactionInvalidReason.TX_SENDER_NOT_AUTHORIZED)); } @Test public void shouldRejectTransactionIfAccountIsNotPermitted() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), false, Optional.empty()); - validator.setTransactionFilter(transactionFilter(false)); + validator.setPermissionTransactionFilter(transactionFilter(false)); - assertThat(validator.validateForSender(basicTransaction, accountWithNonce(0), true)) + assertThat( + validator.validateForSender( + basicTransaction, accountWithNonce(0), transactionPoolParams)) .isEqualTo(ValidationResult.invalid(TransactionInvalidReason.TX_SENDER_NOT_AUTHORIZED)); } @Test public void shouldAcceptValidTransactionIfAccountIsPermitted() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), false, Optional.empty()); - validator.setTransactionFilter(transactionFilter(true)); + validator.setPermissionTransactionFilter(transactionFilter(true)); - assertThat(validator.validateForSender(basicTransaction, accountWithNonce(0), true)) + assertThat( + validator.validateForSender( + basicTransaction, accountWithNonce(0), transactionPoolParams)) .isEqualTo(ValidationResult.valid()); } @Test public void shouldRejectTransactionWithMaxFeeTimesGasLimitGreaterThanBalance() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), false, Optional.empty()); - validator.setTransactionFilter(transactionFilter(true)); + validator.setPermissionTransactionFilter(transactionFilter(true)); assertThat( validator.validateForSender( @@ -245,13 +253,13 @@ public void shouldRejectTransactionWithMaxFeeTimesGasLimitGreaterThanBalance() { .chainId(BigInteger.ONE) .signAndBuild(new SECP256K1().generateKeyPair()), account(Wei.of(100), 0), - true)) + transactionPoolParams)) .isEqualTo(ValidationResult.invalid(UPFRONT_COST_EXCEEDS_BALANCE)); } @Test public void shouldRejectTransactionWithMaxPriorityFeeGreaterThanMaxFee() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), @@ -263,7 +271,7 @@ public void shouldRejectTransactionWithMaxPriorityFeeGreaterThanMaxFee() { TransactionType.FRONTIER, TransactionType.ACCESS_LIST, TransactionType.EIP1559 }), Integer.MAX_VALUE); - validator.setTransactionFilter(transactionFilter(true)); + validator.setPermissionTransactionFilter(transactionFilter(true)); final Transaction transaction = Transaction.builder() @@ -292,17 +300,18 @@ public void shouldPropagateCorrectStateChangeParamToTransactionFilter() { ArgumentCaptor.forClass(Boolean.class); final ArgumentCaptor stateChangeOnchainParamCaptor = ArgumentCaptor.forClass(Boolean.class); - final TransactionFilter transactionFilter = mock(TransactionFilter.class); - when(transactionFilter.permitted( + final PermissionTransactionFilter permissionTransactionFilter = + mock(PermissionTransactionFilter.class); + when(permissionTransactionFilter.permitted( any(Transaction.class), stateChangeLocalParamCaptor.capture(), stateChangeOnchainParamCaptor.capture())) .thenReturn(true); - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), false, Optional.empty()); - validator.setTransactionFilter(transactionFilter); + validator.setPermissionTransactionFilter(permissionTransactionFilter); final TransactionValidationParams validationParams = ImmutableTransactionValidationParams.builder().checkOnchainPermissions(true).build(); @@ -315,12 +324,13 @@ public void shouldPropagateCorrectStateChangeParamToTransactionFilter() { @Test public void shouldNotCheckAccountPermissionIfBothValidationParamsCheckPermissionsAreFalse() { - final TransactionFilter transactionFilter = mock(TransactionFilter.class); + final PermissionTransactionFilter permissionTransactionFilter = + mock(PermissionTransactionFilter.class); - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), false, Optional.empty()); - validator.setTransactionFilter(transactionFilter); + validator.setPermissionTransactionFilter(permissionTransactionFilter); final TransactionValidationParams validationParams = ImmutableTransactionValidationParams.builder() @@ -333,12 +343,12 @@ public void shouldNotCheckAccountPermissionIfBothValidationParamsCheckPermission assertThat(validator.validateForSender(basicTransaction, accountWithNonce(0), validationParams)) .isEqualTo(ValidationResult.valid()); - verifyNoInteractions(transactionFilter); + verifyNoInteractions(permissionTransactionFilter); } @Test public void shouldAcceptOnlyTransactionsInAcceptedTransactionTypes() { - final MainnetTransactionValidator frontierValidator = + final TransactionValidator frontierValidator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), @@ -348,7 +358,7 @@ public void shouldAcceptOnlyTransactionsInAcceptedTransactionTypes() { Set.of(TransactionType.FRONTIER), Integer.MAX_VALUE); - final MainnetTransactionValidator eip1559Validator = + final TransactionValidator eip1559Validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), @@ -381,7 +391,7 @@ public void shouldAcceptOnlyTransactionsInAcceptedTransactionTypes() { @Test public void shouldRejectTransactionIfEIP1559TransactionGasPriceLessBaseFee() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), @@ -405,7 +415,7 @@ public void shouldRejectTransactionIfEIP1559TransactionGasPriceLessBaseFee() { @Test public void shouldAcceptZeroGasPriceTransactionIfBaseFeeIsZero() { final Optional zeroBaseFee = Optional.of(Wei.ZERO); - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), @@ -428,7 +438,7 @@ public void shouldAcceptZeroGasPriceTransactionIfBaseFeeIsZero() { @Test public void shouldAcceptValidEIP1559() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), @@ -453,7 +463,7 @@ public void shouldAcceptValidEIP1559() { @Test public void shouldValidate1559TransactionWithPriceLowerThanBaseFeeForTransactionPool() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), @@ -479,7 +489,7 @@ public void shouldValidate1559TransactionWithPriceLowerThanBaseFeeForTransaction @Test public void shouldRejectTooLargeInitcode() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), @@ -506,7 +516,7 @@ public void shouldRejectTooLargeInitcode() { @Test public void shouldAcceptTransactionWithAtLeastOneBlob() { - final MainnetTransactionValidator validator = + final TransactionValidator validator = new MainnetTransactionValidator( gasCalculator, GasLimitCalculator.constant(), @@ -538,10 +548,11 @@ private Account account(final Wei balance, final long nonce) { return account; } - private TransactionFilter transactionFilter(final boolean permitted) { - final TransactionFilter transactionFilter = mock(TransactionFilter.class); - when(transactionFilter.permitted(any(Transaction.class), anyBoolean(), anyBoolean())) + private PermissionTransactionFilter transactionFilter(final boolean permitted) { + final PermissionTransactionFilter permissionTransactionFilter = + mock(PermissionTransactionFilter.class); + when(permissionTransactionFilter.permitted(any(Transaction.class), anyBoolean(), anyBoolean())) .thenReturn(permitted); - return transactionFilter; + return permissionTransactionFilter; } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java index 7b16d8717d6..0d2f58220f9 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java @@ -30,9 +30,9 @@ import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.eth.manager.EthContext; import org.hyperledger.besu.ethereum.eth.manager.EthPeer; -import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; +import org.hyperledger.besu.ethereum.mainnet.TransactionValidator; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; @@ -353,7 +353,7 @@ private static void logReAddedTransactions( .log(); } - private MainnetTransactionValidator getTransactionValidator() { + private TransactionValidator getTransactionValidator() { return protocolSchedule .getByBlockHeader(protocolContext.getBlockchain().getChainHeadHeader()) .getTransactionValidator(); diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTest.java index 4312b63c329..5b4a11f441d 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTest.java @@ -58,10 +58,10 @@ import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; import org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer; import org.hyperledger.besu.ethereum.eth.messages.EthPV65; -import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; +import org.hyperledger.besu.ethereum.mainnet.TransactionValidator; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; @@ -97,7 +97,7 @@ public abstract class AbstractTransactionPoolTest { private static final KeyPair KEY_PAIR2 = SignatureAlgorithmFactory.getInstance().generateKeyPair(); - @Mock protected MainnetTransactionValidator transactionValidator; + @Mock protected TransactionValidator transactionValidator; @Mock protected PendingTransactionAddedListener listener; @Mock protected MiningParameters miningParameters; @Mock protected TransactionsMessageSender transactionsMessageSender; diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionsLayeredPendingTransactionsTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionsLayeredPendingTransactionsTest.java index 20e61b50d3f..b10b4dcf7c5 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionsLayeredPendingTransactionsTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionsLayeredPendingTransactionsTest.java @@ -58,10 +58,10 @@ import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; import org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer; import org.hyperledger.besu.ethereum.eth.messages.EthPV65; -import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; +import org.hyperledger.besu.ethereum.mainnet.TransactionValidator; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; @@ -93,7 +93,7 @@ public abstract class AbstractTransactionsLayeredPendingTransactionsTest { private static final KeyPair KEY_PAIR2 = SignatureAlgorithmFactory.getInstance().generateKeyPair(); - @Mock protected MainnetTransactionValidator transactionValidator; + @Mock protected TransactionValidator transactionValidator; @Mock protected PendingTransactionAddedListener listener; @Mock protected MiningParameters miningParameters; @Mock protected TransactionsMessageSender transactionsMessageSender; diff --git a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/core/TransactionTest.java b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/core/TransactionTest.java index 3cc53650024..fd595cfb158 100644 --- a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/core/TransactionTest.java +++ b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/core/TransactionTest.java @@ -17,7 +17,7 @@ import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator; +import org.hyperledger.besu.ethereum.mainnet.TransactionValidator; import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import org.hyperledger.besu.ethereum.referencetests.ReferenceTestProtocolSchedules; @@ -50,7 +50,7 @@ public class TransactionTest { private static final ReferenceTestProtocolSchedules REFERENCE_TEST_PROTOCOL_SCHEDULES = ReferenceTestProtocolSchedules.create(); - private static MainnetTransactionValidator transactionValidator(final String name) { + private static TransactionValidator transactionValidator(final String name) { return REFERENCE_TEST_PROTOCOL_SCHEDULES .getByName(name) .getByBlockHeader(BlockHeaderBuilder.createDefault().buildBlockHeader()) 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 09f99f16281..a4f27328f9c 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 @@ -19,8 +19,8 @@ import org.hyperledger.besu.ethereum.MainnetBlockValidator; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockImporter; +import org.hyperledger.besu.ethereum.core.PermissionTransactionFilter; import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; -import org.hyperledger.besu.ethereum.core.TransactionFilter; import org.hyperledger.besu.ethereum.mainnet.BlockProcessor; import org.hyperledger.besu.ethereum.mainnet.MainnetBlockImporter; import org.hyperledger.besu.ethereum.mainnet.MainnetBlockProcessor; @@ -86,7 +86,8 @@ public ProtocolSpec getByBlockHeader(final ProcessableBlockHeader blockHeader) { original.getWithdrawalsValidator(), original.getWithdrawalsProcessor(), original.getDepositsValidator(), - original.isPoS()); + original.isPoS(), + original.isReplayProtectionSupported()); } @Override @@ -120,8 +121,8 @@ public String listMilestones() { } @Override - public void setTransactionFilter(final TransactionFilter transactionFilter) { - delegate.setTransactionFilter(transactionFilter); + public void setTransactionFilter(final PermissionTransactionFilter permissionTransactionFilter) { + delegate.setTransactionFilter(permissionTransactionFilter); } @Override