Skip to content

Commit

Permalink
Introduce transaction validator interface (phase 2) (hyperledger#5682)
Browse files Browse the repository at this point in the history
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
  • Loading branch information
fab-10 authored Jul 25, 2023
1 parent 1a7635b commit 6603ebb
Show file tree
Hide file tree
Showing 23 changed files with 544 additions and 286 deletions.
2 changes: 1 addition & 1 deletion besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,7 @@ private Optional<AccountPermissioningController> buildAccountPermissioningContro
permissioningController ->
besuController
.getProtocolSchedule()
.setTransactionFilter(permissioningController::isPermitted));
.setPermissionTransactionFilter(permissioningController::isPermitted));

return accountPermissioningController;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
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.TransactionValidatorFactory;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
Expand Down Expand Up @@ -79,6 +79,7 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

Expand All @@ -99,7 +100,10 @@ public class BesuEventsImplTest {
@Mock private EthContext mockEthContext;
@Mock private EthMessages mockEthMessages;
@Mock private EthScheduler mockEthScheduler;
@Mock private TransactionValidator mockTransactionValidator;

@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private TransactionValidatorFactory mockTransactionValidatorFactory;

@Mock private ProtocolSpec mockProtocolSpec;
@Mock private WorldStateArchive mockWorldStateArchive;
@Mock private MutableWorldState mockWorldState;
Expand Down Expand Up @@ -128,11 +132,12 @@ public void setUp() {
when(mockProtocolContext.getBlockchain()).thenReturn(blockchain);
when(mockProtocolContext.getWorldStateArchive()).thenReturn(mockWorldStateArchive);
when(mockProtocolSchedule.getByBlockHeader(any())).thenReturn(mockProtocolSpec);
when(mockProtocolSpec.getTransactionValidator()).thenReturn(mockTransactionValidator);
when(mockProtocolSpec.getTransactionValidatorFactory())
.thenReturn(mockTransactionValidatorFactory);
when(mockProtocolSpec.getFeeMarket()).thenReturn(FeeMarket.london(0L));
when(mockTransactionValidator.validate(any(), any(Optional.class), any()))
when(mockTransactionValidatorFactory.get().validate(any(), any(Optional.class), any()))
.thenReturn(ValidationResult.valid());
when(mockTransactionValidator.validateForSender(any(), any(), any()))
when(mockTransactionValidatorFactory.get().validateForSender(any(), any(), any()))
.thenReturn(ValidationResult.valid());
when(mockWorldStateArchive.getMutable(any(), anyBoolean()))
.thenReturn(Optional.of(mockWorldState));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,11 @@ public String listMilestones() {
* @param permissionTransactionFilter the transaction filter
*/
@Override
public void setTransactionFilter(final PermissionTransactionFilter permissionTransactionFilter) {
public void setPermissionTransactionFilter(
final PermissionTransactionFilter permissionTransactionFilter) {
transitionUtils.dispatchConsumerAccordingToMergeState(
protocolSchedule -> protocolSchedule.setTransactionFilter(permissionTransactionFilter));
protocolSchedule ->
protocolSchedule.setPermissionTransactionFilter(permissionTransactionFilter));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public static ProtocolSpecBuilder tangerineWhistleDefinition(
.gasCalculator(TangerineWhistleGasCalculator::new)
.transactionValidatorBuilder(
(gasCalculator, gasLimitCalculator) ->
new MainnetTransactionValidator(gasCalculator, gasLimitCalculator, true, chainId))
new TransactionValidatorFactory(gasCalculator, gasLimitCalculator, true, chainId))
.name("ClassicTangerineWhistle");
}

Expand Down Expand Up @@ -130,7 +130,7 @@ public static ProtocolSpecBuilder defuseDifficultyBombDefinition(
.difficultyCalculator(ClassicDifficultyCalculators.DIFFICULTY_BOMB_REMOVED)
.transactionValidatorBuilder(
(gasCalculator, gasLimitCalculator) ->
new MainnetTransactionValidator(gasCalculator, gasLimitCalculator, true, chainId))
new TransactionValidatorFactory(gasCalculator, gasLimitCalculator, true, chainId))
.name("DefuseDifficultyBomb");
}

Expand Down Expand Up @@ -293,7 +293,7 @@ public static ProtocolSpecBuilder magnetoDefinition(
.gasCalculator(BerlinGasCalculator::new)
.transactionValidatorBuilder(
(gasCalculator, gasLimitCalculator) ->
new MainnetTransactionValidator(
new TransactionValidatorFactory(
gasCalculator,
gasLimitCalculator,
true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,12 @@ public boolean anyMatch(final Predicate<ScheduledProtocolSpec> predicate) {
}

@Override
public void setTransactionFilter(final PermissionTransactionFilter permissionTransactionFilter) {
public void setPermissionTransactionFilter(
final PermissionTransactionFilter permissionTransactionFilter) {
protocolSpecs.forEach(
spec ->
spec.spec()
.getTransactionValidator()
.getTransactionValidatorFactory()
.setPermissionTransactionFilter(permissionTransactionFilter));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,16 +124,16 @@ public static ProtocolSpecBuilder frontierDefinition(
0))
.transactionValidatorBuilder(
(gasCalculator, gasLimitCalculator) ->
new MainnetTransactionValidator(
new TransactionValidatorFactory(
gasCalculator, gasLimitCalculator, false, Optional.empty()))
.transactionProcessorBuilder(
(gasCalculator,
transactionValidator,
transactionValidatorFactory,
contractCreationProcessor,
messageCallProcessor) ->
new MainnetTransactionProcessor(
gasCalculator,
transactionValidator,
transactionValidatorFactory,
contractCreationProcessor,
messageCallProcessor,
false,
Expand All @@ -142,12 +142,12 @@ public static ProtocolSpecBuilder frontierDefinition(
FeeMarket.legacy(),
CoinbaseFeePriceCalculator.frontier()))
.privateTransactionProcessorBuilder(
(transactionValidator,
(transactionValidatorFactory,
contractCreationProcessor,
messageCallProcessor,
privateTransactionValidator) ->
new PrivateTransactionProcessor(
transactionValidator,
transactionValidatorFactory,
contractCreationProcessor,
messageCallProcessor,
false,
Expand Down Expand Up @@ -199,7 +199,7 @@ public static ProtocolSpecBuilder homesteadDefinition(
0))
.transactionValidatorBuilder(
(gasCalculator, gasLimitCalculator) ->
new MainnetTransactionValidator(
new TransactionValidatorFactory(
gasCalculator, gasLimitCalculator, true, Optional.empty()))
.difficultyCalculator(MainnetDifficultyCalculators.HOMESTEAD)
.name("Homestead");
Expand Down Expand Up @@ -277,7 +277,7 @@ public static ProtocolSpecBuilder spuriousDragonDefinition(
SPURIOUS_DRAGON_FORCE_DELETE_WHEN_EMPTY_ADDRESSES))
.transactionValidatorBuilder(
(gasCalculator, gasLimitCalculator) ->
new MainnetTransactionValidator(gasCalculator, gasLimitCalculator, true, chainId))
new TransactionValidatorFactory(gasCalculator, gasLimitCalculator, true, chainId))
.transactionProcessorBuilder(
(gasCalculator,
transactionValidator,
Expand Down Expand Up @@ -412,7 +412,7 @@ static ProtocolSpecBuilder berlinDefinition(
.gasCalculator(BerlinGasCalculator::new)
.transactionValidatorBuilder(
(gasCalculator, gasLimitCalculator) ->
new MainnetTransactionValidator(
new TransactionValidatorFactory(
gasCalculator,
gasLimitCalculator,
true,
Expand Down Expand Up @@ -452,7 +452,7 @@ static ProtocolSpecBuilder londonDefinition(
new LondonTargetingGasLimitCalculator(londonForkBlockNumber, londonFeeMarket))
.transactionValidatorBuilder(
(gasCalculator, gasLimitCalculator) ->
new MainnetTransactionValidator(
new TransactionValidatorFactory(
gasCalculator,
gasLimitCalculator,
londonFeeMarket,
Expand Down Expand Up @@ -613,7 +613,7 @@ static ProtocolSpecBuilder shanghaiDefinition(
// Contract creation rules for EIP-3860 Limit and meter intitcode
.transactionValidatorBuilder(
(gasCalculator, gasLimitCalculator) ->
new MainnetTransactionValidator(
new TransactionValidatorFactory(
gasCalculator,
gasLimitCalculator,
londonFeeMarket,
Expand Down Expand Up @@ -696,7 +696,7 @@ static ProtocolSpecBuilder cancunDefinition(
// change to check for max data gas per block for EIP-4844
.transactionValidatorBuilder(
(gasCalculator, gasLimitCalculator) ->
new MainnetTransactionValidator(
new TransactionValidatorFactory(
gasCalculator,
gasLimitCalculator,
cancunFeeMarket,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public class MainnetTransactionProcessor {

protected final GasCalculator gasCalculator;

protected final TransactionValidator transactionValidator;
protected final TransactionValidatorFactory transactionValidatorFactory;

private final AbstractMessageProcessor contractCreationProcessor;

Expand All @@ -81,7 +81,7 @@ public class MainnetTransactionProcessor {

public MainnetTransactionProcessor(
final GasCalculator gasCalculator,
final TransactionValidator transactionValidator,
final TransactionValidatorFactory transactionValidatorFactory,
final AbstractMessageProcessor contractCreationProcessor,
final AbstractMessageProcessor messageCallProcessor,
final boolean clearEmptyAccounts,
Expand All @@ -90,7 +90,7 @@ public MainnetTransactionProcessor(
final FeeMarket feeMarket,
final CoinbaseFeePriceCalculator coinbaseFeePriceCalculator) {
this.gasCalculator = gasCalculator;
this.transactionValidator = transactionValidator;
this.transactionValidatorFactory = transactionValidatorFactory;
this.contractCreationProcessor = contractCreationProcessor;
this.messageCallProcessor = messageCallProcessor;
this.clearEmptyAccounts = clearEmptyAccounts;
Expand Down Expand Up @@ -271,6 +271,7 @@ public TransactionProcessingResult processTransaction(
final PrivateMetadataUpdater privateMetadataUpdater,
final Wei dataGasPrice) {
try {
final var transactionValidator = transactionValidatorFactory.get();
LOG.trace("Starting execution of {}", transaction);
ValidationResult<TransactionInvalidReason> validationResult =
transactionValidator.validate(
Expand Down Expand Up @@ -498,10 +499,6 @@ public TransactionProcessingResult processTransaction(
}
}

public TransactionValidator getTransactionValidator() {
return transactionValidator;
}

protected void process(final MessageFrame frame, final OperationTracer operationTracer) {
final AbstractMessageProcessor executor = getMessageProcessor(frame.getType());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.hyperledger.besu.datatypes.TransactionType;
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.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
Expand All @@ -49,40 +48,10 @@ public class MainnetTransactionValidator implements TransactionValidator {

private final Optional<BigInteger> chainId;

private Optional<PermissionTransactionFilter> permissionTransactionFilter = Optional.empty();
private final Set<TransactionType> acceptedTransactionTypes;

private final int maxInitcodeSize;

public MainnetTransactionValidator(
final GasCalculator gasCalculator,
final GasLimitCalculator gasLimitCalculator,
final boolean checkSignatureMalleability,
final Optional<BigInteger> chainId) {
this(
gasCalculator,
gasLimitCalculator,
checkSignatureMalleability,
chainId,
Set.of(TransactionType.FRONTIER));
}

public MainnetTransactionValidator(
final GasCalculator gasCalculator,
final GasLimitCalculator gasLimitCalculator,
final boolean checkSignatureMalleability,
final Optional<BigInteger> chainId,
final Set<TransactionType> acceptedTransactionTypes) {
this(
gasCalculator,
gasLimitCalculator,
FeeMarket.legacy(),
checkSignatureMalleability,
chainId,
acceptedTransactionTypes,
Integer.MAX_VALUE);
}

public MainnetTransactionValidator(
final GasCalculator gasCalculator,
final GasLimitCalculator gasLimitCalculator,
Expand Down Expand Up @@ -239,12 +208,6 @@ public ValidationResult<TransactionInvalidReason> validateForSender(
transaction.getSender()));
}

if (!isSenderAllowed(transaction, validationParams)) {
return ValidationResult.invalid(
TransactionInvalidReason.TX_SENDER_NOT_AUTHORIZED,
String.format("Sender %s is not on the Account Allowlist", transaction.getSender()));
}

return ValidationResult.valid();
}

Expand Down Expand Up @@ -286,26 +249,4 @@ private ValidationResult<TransactionInvalidReason> validateTransactionSignature(
}
return ValidationResult.valid();
}

private boolean isSenderAllowed(
final Transaction transaction, final TransactionValidationParams validationParams) {
if (validationParams.checkLocalPermissions() || validationParams.checkOnchainPermissions()) {
return permissionTransactionFilter
.map(
c ->
c.permitted(
transaction,
validationParams.checkLocalPermissions(),
validationParams.checkOnchainPermissions()))
.orElse(true);
} else {
return true;
}
}

@Override
public void setPermissionTransactionFilter(
final PermissionTransactionFilter permissionTransactionFilter) {
this.permissionTransactionFilter = Optional.of(permissionTransactionFilter);
}
}
Loading

0 comments on commit 6603ebb

Please sign in to comment.