Skip to content

Commit

Permalink
Correctly cache the TransactionValidator instance on creation (hyperl…
Browse files Browse the repository at this point in the history
…edger#5726)

Signed-off-by: Fabio Di Fabio <[email protected]>
  • Loading branch information
fab-10 authored Jul 31, 2023
1 parent e92e5de commit 52342e5
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,12 @@
import java.util.Optional;
import java.util.Set;

import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;

public class TransactionValidatorFactory {
private final GasCalculator gasCalculator;
private final GasLimitCalculator gasLimitCalculator;
private final FeeMarket feeMarket;
private final boolean disallowSignatureMalleability;
private final Optional<BigInteger> chainId;
private final Set<TransactionType> acceptedTransactionTypes;
private final int maxInitcodeSize;
private Optional<PermissionTransactionFilter> permissionTransactionFilter = Optional.empty();

private volatile Supplier<TransactionValidator> transactionValidatorSupplier;

public TransactionValidatorFactory(
final GasCalculator gasCalculator,
Expand Down Expand Up @@ -73,37 +68,29 @@ public TransactionValidatorFactory(
final Optional<BigInteger> chainId,
final Set<TransactionType> acceptedTransactionTypes,
final int maxInitcodeSize) {
this.gasCalculator = gasCalculator;
this.gasLimitCalculator = gasLimitCalculator;
this.feeMarket = feeMarket;
this.disallowSignatureMalleability = checkSignatureMalleability;
this.chainId = chainId;
this.acceptedTransactionTypes = acceptedTransactionTypes;
this.maxInitcodeSize = maxInitcodeSize;

this.transactionValidatorSupplier =
Suppliers.memoize(
() ->
new MainnetTransactionValidator(
gasCalculator,
gasLimitCalculator,
feeMarket,
checkSignatureMalleability,
chainId,
acceptedTransactionTypes,
maxInitcodeSize));
}

public void setPermissionTransactionFilter(
final PermissionTransactionFilter permissionTransactionFilter) {
this.permissionTransactionFilter = Optional.of(permissionTransactionFilter);
final TransactionValidator baseTxValidator = transactionValidatorSupplier.get();
transactionValidatorSupplier =
Suppliers.memoize(
() -> new PermissionTransactionValidator(baseTxValidator, permissionTransactionFilter));
}

public TransactionValidator get() {
return Suppliers.memoize(this::createTransactionValidator).get();
}

private TransactionValidator createTransactionValidator() {
final TransactionValidator baseValidator =
new MainnetTransactionValidator(
gasCalculator,
gasLimitCalculator,
feeMarket,
disallowSignatureMalleability,
chainId,
acceptedTransactionTypes,
maxInitcodeSize);
if (permissionTransactionFilter.isPresent()) {
return new PermissionTransactionValidator(baseValidator, permissionTransactionFilter.get());
}
return baseValidator;
return transactionValidatorSupplier.get();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* 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 static org.assertj.core.api.Assertions.assertThat;

import org.hyperledger.besu.ethereum.GasLimitCalculator;
import org.hyperledger.besu.ethereum.core.PermissionTransactionFilter;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;

import java.math.BigInteger;
import java.util.Optional;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class TransactionValidationFactoryTest {
private static final Optional<BigInteger> CHAIN_ID = Optional.of(BigInteger.ONE);
@Mock GasCalculator gasCalculator;
@Mock GasLimitCalculator gasLimitCalculator;
@Mock PermissionTransactionFilter permissionTransactionFilter;

@Test
public void alwaysTheSameInstanceIsReturnedOnceCreated() {
final TransactionValidatorFactory transactionValidatorFactory =
new TransactionValidatorFactory(gasCalculator, gasLimitCalculator, false, CHAIN_ID);
assertThat(transactionValidatorFactory.get()).isSameAs(transactionValidatorFactory.get());
}

@Test
public void alwaysTheSameInstanceIsReturnedOnceCreatedWithPermissionFilter() {
final TransactionValidatorFactory transactionValidatorFactory =
new TransactionValidatorFactory(gasCalculator, gasLimitCalculator, false, CHAIN_ID);
transactionValidatorFactory.setPermissionTransactionFilter(permissionTransactionFilter);
assertThat(transactionValidatorFactory.get()).isSameAs(transactionValidatorFactory.get());
}
}

0 comments on commit 52342e5

Please sign in to comment.