Update EIP-1559 implementation according to the latest changes (#1281)

Signed-off-by: Karim TAAM <karim.t2am@gmail.com>
Co-authored-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>
pull/1314/head
matkt 4 years ago committed by GitHub
parent 34b8683244
commit 5c375289a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      besu/src/test/java/org/hyperledger/besu/services/BesuEventsImplTest.java
  2. 22
      config/src/main/java/org/hyperledger/besu/config/experimental/ExperimentalEIPs.java
  3. 10
      consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/BlockHeaderValidationRulesetFactory.java
  4. 1
      consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueBlockHashing.java
  5. 39
      consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueProtocolSchedule.java
  6. 19
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransaction.java
  7. 38
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/util/DomainObjectDecodeUtils.java
  8. 4
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java
  9. 32
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockTransactionSelector.java
  10. 53
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/fees/EIP1559.java
  11. 14
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/fees/FeeMarket.java
  12. 36
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/fees/FeeMarketConfig.java
  13. 20
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/fees/TransactionGasBudgetCalculator.java
  14. 3
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/fees/TransactionPriceCalculator.java
  15. 27
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractBlockProcessor.java
  16. 11
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
  17. 11
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java
  18. 16
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java
  19. 7
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java
  20. 6
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/TransactionValidator.java
  21. 64
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/EIP1559BlockHeaderGasLimitValidationRule.java
  22. 4
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/EIP1559BlockHeaderGasPriceValidationRule.java
  23. 16
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/TransactionTestFixture.java
  24. 3
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/TransactionTest.java
  25. 118
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/fees/EIP1559BaseFeeTest.java
  26. 40
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/fees/EIP1559Test.java
  27. 79
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/fees/TransactionGasBudgetCalculatorTest.java
  28. 2
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessorTest.java
  29. 68
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidatorTest.java
  30. 110
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/EIP1559BlockHeaderGasLimitValidationRuleTest.java
  31. 22
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/EIP1559BlockHeaderGasPriceValidationRuleTest.java
  32. 704
      ethereum/core/src/test/resources/org/hyperledger/besu/ethereum/core/fees/basefee-test.json
  33. 2
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java
  34. 4
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolFactoryTest.java
  35. 35
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPoolTest.java

@ -73,6 +73,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@SuppressWarnings("unchecked")
@RunWith(MockitoJUnitRunner.class)
public class BesuEventsImplTest {
@ -118,7 +119,8 @@ public class BesuEventsImplTest {
when(mockProtocolContext.getWorldStateArchive()).thenReturn(mockWorldStateArchive);
when(mockProtocolSchedule.getByBlockNumber(anyLong())).thenReturn(mockProtocolSpec);
when(mockProtocolSpec.getTransactionValidator()).thenReturn(mockTransactionValidator);
when(mockTransactionValidator.validate(any())).thenReturn(ValidationResult.valid());
when(mockTransactionValidator.validate(any(), any(Optional.class)))
.thenReturn(ValidationResult.valid());
when(mockTransactionValidator.validateForSender(any(), any(), any()))
.thenReturn(ValidationResult.valid());
when(mockWorldStateArchive.get(any())).thenReturn(Optional.of(mockWorldState));

@ -55,31 +55,13 @@ public class ExperimentalEIPs {
@Option(
hidden = true,
names = {"--Xeip1559-target-gas-used"},
names = {"--Xeip1559-migration-duration-in-blocks"},
arity = "1")
public static Long targetGasUsed = 10000000L;
@Option(
hidden = true,
names = {"--Xeip1559-slack-coefficient"},
arity = "1")
public static Long slackCoefficient = 2L;
@Option(
hidden = true,
names = {"--Xeip1559-decay-range"},
arity = "1")
public static Long decayRange = 1000000L;
public static Long migrationDurationInBlocks = 800000L;
@Option(
hidden = true,
names = {"--Xeip1559-initial-base-fee"},
arity = "1")
public static Long initialBasefee = 1000000000L;
@Option(
hidden = true,
names = {"--Xeip1559-per-tx-gas-limit"},
arity = "1")
public static Long perTxGasLimit = 8000000L;
}

@ -14,6 +14,7 @@
*/
package org.hyperledger.besu.consensus.clique;
import org.hyperledger.besu.config.experimental.ExperimentalEIPs;
import org.hyperledger.besu.consensus.clique.headervalidationrules.CliqueDifficultyValidationRule;
import org.hyperledger.besu.consensus.clique.headervalidationrules.CliqueExtraDataValidationRule;
import org.hyperledger.besu.consensus.clique.headervalidationrules.CoinbaseHeaderValidationRule;
@ -22,9 +23,11 @@ import org.hyperledger.besu.consensus.clique.headervalidationrules.VoteValidatio
import org.hyperledger.besu.consensus.common.EpochManager;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Hash;
import org.hyperledger.besu.ethereum.core.fees.EIP1559;
import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.AncestryValidationRule;
import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.ConstantFieldValidationRule;
import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.EIP1559BlockHeaderGasPriceValidationRule;
import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.GasLimitRangeAndDeltaValidationRule;
import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.GasUsageValidationRule;
import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.TimestampBoundedByFutureParameter;
@ -61,4 +64,11 @@ public class BlockHeaderValidationRulesetFactory {
.addRule(new SignerRateLimitValidationRule())
.addRule(new CoinbaseHeaderValidationRule(epochManager));
}
public static BlockHeaderValidator.Builder cliqueEip1559BlockHeaderValidator(
final long secondsBetweenBlocks, final EpochManager epochManager, final EIP1559 eip1559) {
ExperimentalEIPs.eip1559MustBeEnabled();
return cliqueBlockHeaderValidator(secondsBetweenBlocks, epochManager)
.addRule((new EIP1559BlockHeaderGasPriceValidationRule(eip1559)));
}
}

@ -92,6 +92,7 @@ public class CliqueBlockHashing {
out.writeBytes(extraDataSerializer.get());
out.writeBytes(header.getMixHash());
out.writeLong(header.getNonce());
header.getBaseFee().ifPresent(out::writeLongScalar);
out.endList();
return out.encoded();
}

@ -16,6 +16,7 @@ package org.hyperledger.besu.consensus.clique;
import org.hyperledger.besu.config.CliqueConfigOptions;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.experimental.ExperimentalEIPs;
import org.hyperledger.besu.consensus.common.EpochManager;
import org.hyperledger.besu.crypto.NodeKey;
import org.hyperledger.besu.ethereum.MainnetBlockValidator;
@ -23,6 +24,8 @@ import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.Util;
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.core.fees.EIP1559;
import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockBodyValidator;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockImporter;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
@ -30,6 +33,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder;
import java.math.BigInteger;
import java.util.Optional;
/** Defines the protocol behaviours for a blockchain using Clique. */
public class CliqueProtocolSchedule {
@ -51,12 +55,22 @@ public class CliqueProtocolSchedule {
}
final EpochManager epochManager = new EpochManager(cliqueConfig.getEpochLength());
final Optional<EIP1559> eip1559 =
ExperimentalEIPs.eip1559Enabled
? Optional.of(new EIP1559(config.getEIP1559BlockNumber().orElse(0)))
: Optional.empty();
return new ProtocolScheduleBuilder(
config,
DEFAULT_CHAIN_ID,
builder ->
applyCliqueSpecificModifications(
epochManager, cliqueConfig.getBlockPeriodSeconds(), localNodeAddress, builder),
epochManager,
cliqueConfig.getBlockPeriodSeconds(),
localNodeAddress,
builder,
eip1559),
privacyParameters,
isRevertReasonEnabled)
.createProtocolSchedule();
@ -73,14 +87,14 @@ public class CliqueProtocolSchedule {
final EpochManager epochManager,
final long secondsBetweenBlocks,
final Address localNodeAddress,
final ProtocolSpecBuilder specBuilder) {
final ProtocolSpecBuilder specBuilder,
final Optional<EIP1559> eip1559) {
return specBuilder
.blockHeaderValidatorBuilder(
BlockHeaderValidationRulesetFactory.cliqueBlockHeaderValidator(
secondsBetweenBlocks, epochManager))
getBlockHeaderValidator(epochManager, secondsBetweenBlocks, eip1559))
.ommerHeaderValidatorBuilder(
BlockHeaderValidationRulesetFactory.cliqueBlockHeaderValidator(
secondsBetweenBlocks, epochManager))
getBlockHeaderValidator(epochManager, secondsBetweenBlocks, eip1559))
.blockBodyValidatorBuilder(MainnetBlockBodyValidator::new)
.blockValidatorBuilder(MainnetBlockValidator::new)
.blockImporterBuilder(MainnetBlockImporter::new)
@ -90,4 +104,17 @@ public class CliqueProtocolSchedule {
.miningBeneficiaryCalculator(CliqueHelpers::getProposerOfBlock)
.blockHeaderFunctions(new CliqueBlockHeaderFunctions());
}
private static BlockHeaderValidator.Builder getBlockHeaderValidator(
final EpochManager epochManager,
final long secondsBetweenBlocks,
final Optional<EIP1559> eip1559) {
if (ExperimentalEIPs.eip1559Enabled && eip1559.isPresent()) {
return BlockHeaderValidationRulesetFactory.cliqueEip1559BlockHeaderValidator(
secondsBetweenBlocks, epochManager, eip1559.get());
} else {
return BlockHeaderValidationRulesetFactory.cliqueBlockHeaderValidator(
secondsBetweenBlocks, epochManager);
}
}
}

@ -22,24 +22,19 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.util.DomainObjectDecodeUtils;
import org.hyperledger.besu.ethereum.core.Hash;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidator.TransactionInvalidReason;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.ethereum.rlp.RLPException;
import java.util.function.Supplier;
import com.google.common.base.Suppliers;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tuweni.bytes.Bytes;
public class EthSendRawTransaction implements JsonRpcMethod {
private static final Logger LOG = LogManager.getLogger();
private final boolean sendEmptyHashOnInvalidBlock;
private final Supplier<TransactionPool> transactionPool;
@ -69,7 +64,7 @@ public class EthSendRawTransaction implements JsonRpcMethod {
final Transaction transaction;
try {
transaction = decodeRawTransaction(rawTransaction);
transaction = DomainObjectDecodeUtils.decodeRawTransaction(rawTransaction);
} catch (final InvalidJsonRpcRequestException e) {
return new JsonRpcErrorResponse(
requestContext.getRequest().getId(), JsonRpcError.INVALID_PARAMS);
@ -89,14 +84,4 @@ public class EthSendRawTransaction implements JsonRpcMethod {
requestContext.getRequest().getId(),
JsonRpcErrorConverter.convertTransactionInvalidReason(errorReason)));
}
private Transaction decodeRawTransaction(final String hash)
throws InvalidJsonRpcRequestException {
try {
return Transaction.readFrom(RLP.input(Bytes.fromHexString(hash)));
} catch (final IllegalArgumentException | RLPException e) {
LOG.debug(e);
throw new InvalidJsonRpcRequestException("Invalid raw transaction hex", e);
}
}
}

@ -0,0 +1,38 @@
/*
* Copyright ConsenSys AG.
*
* 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.api.util;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcRequestException;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.ethereum.rlp.RLPException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tuweni.bytes.Bytes;
public class DomainObjectDecodeUtils {
private static final Logger LOG = LogManager.getLogger();
public static Transaction decodeRawTransaction(final String rlp)
throws InvalidJsonRpcRequestException {
try {
return Transaction.readFrom(RLP.input(Bytes.fromHexString(rlp)));
} catch (final IllegalArgumentException | RLPException e) {
LOG.debug(e);
throw new InvalidJsonRpcRequestException("Invalid raw transaction hex", e);
}
}
}

@ -270,7 +270,9 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
} else {
baseFee =
eip1559.computeBaseFee(
parentHeader.getBaseFee().orElseThrow(), parentHeader.getGasUsed());
parentHeader.getBaseFee().orElseThrow(),
parentHeader.getGasUsed(),
eip1559.targetGasUsed(parentHeader));
}
}
return BlockHeaderBuilder.create()

@ -24,7 +24,6 @@ import org.hyperledger.besu.ethereum.core.TransactionReceipt;
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.core.WorldUpdater;
import org.hyperledger.besu.ethereum.core.fees.EIP1559;
import org.hyperledger.besu.ethereum.core.fees.FeeMarket;
import org.hyperledger.besu.ethereum.core.fees.TransactionPriceCalculator;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions.TransactionSelectionResult;
@ -65,7 +64,6 @@ public class BlockTransactionSelector {
private final Wei minTransactionGasPrice;
private final Double minBlockOccupancyRatio;
private static final FeeMarket EIP_1559_FEE_MARKET = FeeMarket.eip1559();
public static class TransactionSelectionResults {
@ -240,12 +238,10 @@ public class BlockTransactionSelector {
final long cumulativeGasUsed;
if (ExperimentalEIPs.eip1559Enabled && eip1559.isPresent()) {
cumulativeGasUsed =
transactionSelectionResult.frontierCumulativeGasUsed
+ transactionSelectionResult.eip1559CumulativeGasUsed
+ gasUsedByTransaction;
transactionSelectionResult.getTotalCumulativeGasUsed() + gasUsedByTransaction;
} else {
cumulativeGasUsed =
transactionSelectionResult.frontierCumulativeGasUsed + gasUsedByTransaction;
transactionSelectionResult.getFrontierCumulativeGasUsed() + gasUsedByTransaction;
}
transactionSelectionResult.update(
@ -258,34 +254,26 @@ public class BlockTransactionSelector {
final long blockGasRemaining;
if (ExperimentalEIPs.eip1559Enabled && eip1559.isPresent()) {
if (transaction.isEIP1559Transaction()) {
blockGasRemaining =
processableBlockHeader.getGasLimit()
- transactionSelectionResult.getEip1559CumulativeGasUsed();
} else {
blockGasRemaining =
EIP_1559_FEE_MARKET.getMaxGas()
- processableBlockHeader.getGasLimit()
- transactionSelectionResult.getFrontierCumulativeGasUsed();
}
blockGasRemaining =
processableBlockHeader.getGasLimit()
- transactionSelectionResult.getTotalCumulativeGasUsed();
} else {
blockGasRemaining =
processableBlockHeader.getGasLimit()
- transactionSelectionResult.getFrontierCumulativeGasUsed();
}
return (transaction.getGasLimit() > blockGasRemaining);
return transaction.getGasLimit() > blockGasRemaining;
}
private boolean blockOccupancyAboveThreshold() {
final double gasUsed, gasAvailable;
gasAvailable = processableBlockHeader.getGasLimit();
if (ExperimentalEIPs.eip1559Enabled && eip1559.isPresent()) {
gasUsed =
transactionSelectionResult.getFrontierCumulativeGasUsed()
+ transactionSelectionResult.getEip1559CumulativeGasUsed();
gasAvailable = EIP_1559_FEE_MARKET.getMaxGas();
gasUsed = transactionSelectionResult.getTotalCumulativeGasUsed();
} else {
gasUsed = transactionSelectionResult.getFrontierCumulativeGasUsed();
gasAvailable = processableBlockHeader.getGasLimit();
}
return (gasUsed / gasAvailable) >= minBlockOccupancyRatio;
}

@ -21,6 +21,7 @@ import static org.hyperledger.besu.ethereum.core.AcceptedTransactionTypes.FRONTI
import org.hyperledger.besu.config.experimental.ExperimentalEIPs;
import org.hyperledger.besu.ethereum.core.AcceptedTransactionTypes;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction;
public class EIP1559 {
@ -31,16 +32,18 @@ public class EIP1559 {
public EIP1559(final long forkBlockNumber) {
initialForkBlknum = forkBlockNumber;
finalForkBlknum = initialForkBlknum + feeMarket.getDecayRange();
finalForkBlknum = initialForkBlknum + feeMarket.getMigrationDurationInBlocks();
}
public long computeBaseFee(final long parentBaseFee, final long parentBlockGasUsed) {
public long computeBaseFee(
final long parentBaseFee, final long parentBlockGasUsed, final long targetGasUsed) {
guardActivation();
long delta = parentBlockGasUsed - feeMarket.getTargetGasUsed();
assert targetGasUsed != 0L;
long delta = parentBlockGasUsed - targetGasUsed;
long baseFee =
parentBaseFee
+ floorDiv(
floorDiv(parentBaseFee * delta, feeMarket.getTargetGasUsed()),
floorDiv(parentBaseFee * delta, targetGasUsed),
feeMarket.getBasefeeMaxChangeDenominator());
boolean neg = false;
long diff = baseFee - parentBaseFee;
@ -69,18 +72,25 @@ public class EIP1559 {
<= Math.max(1, parentBaseFee / feeMarket.getBasefeeMaxChangeDenominator());
}
public long eip1559GasPool(final long blockNumber) {
public long eip1559GasPool(final long blockNumber, final long gasLimit) {
guardActivation();
final long eip1559GasTarget;
if (blockNumber >= finalForkBlknum) {
return feeMarket.getMaxGas();
eip1559GasTarget = gasLimit * 2;
} else {
eip1559GasTarget =
(gasLimit / 2)
+ (gasLimit / 2)
* (blockNumber - initialForkBlknum)
/ feeMarket.getMigrationDurationInBlocks();
}
return (feeMarket.getMaxGas() / 2)
+ ((blockNumber - initialForkBlknum) * feeMarket.getGasIncrementAmount());
return eip1559GasTarget * 2;
}
public long legacyGasPool(final long blockNumber) {
public long legacyGasPool(final long blockNumber, final long gasLimit) {
guardActivation();
return feeMarket.getMaxGas() - eip1559GasPool(blockNumber);
return gasLimit - (eip1559GasPool(blockNumber, gasLimit) / 2);
}
public boolean isEIP1559(final long blockNumber) {
@ -135,4 +145,27 @@ public class EIP1559 {
throw new RuntimeException("EIP-1559 is not enabled");
}
}
public long targetGasUsed(final BlockHeader header) {
guardActivation();
final long blockNumber = header.getNumber();
final long migrationDuration = feeMarket.getMigrationDurationInBlocks();
final long gasTarget = header.getGasLimit();
return targetGasUsed(blockNumber, migrationDuration, gasTarget, initialForkBlknum);
}
public static long targetGasUsed(
final long blockNumber,
final long migrationDuration,
final long gasTarget,
final long forkBlock) {
final long blocksSinceStartOfMigration = blockNumber - forkBlock;
final long halfGasTarget = floorDiv(gasTarget, 2L);
return (blockNumber < forkBlock)
? 0L
: (blockNumber > forkBlock + migrationDuration)
? gasTarget
: halfGasTarget
+ floorDiv(halfGasTarget * blocksSinceStartOfMigration, migrationDuration);
}
}

@ -20,24 +20,14 @@ public interface FeeMarket {
long getBasefeeMaxChangeDenominator();
long getTargetGasUsed();
long getMaxGas();
long getDecayRange();
long getGasIncrementAmount();
long getMigrationDurationInBlocks();
long getInitialBasefee();
long getSlackCoefficient();
static FeeMarket eip1559() {
return new FeeMarketConfig(
ExperimentalEIPs.basefeeMaxChangeDenominator,
ExperimentalEIPs.targetGasUsed,
ExperimentalEIPs.slackCoefficient,
ExperimentalEIPs.decayRange,
ExperimentalEIPs.migrationDurationInBlocks,
ExperimentalEIPs.initialBasefee);
}
}

@ -16,26 +16,14 @@ package org.hyperledger.besu.ethereum.core.fees;
public class FeeMarketConfig implements FeeMarket {
private final long basefeeMaxChangeDenominator;
private final long targetGasUsed;
private final long decayRange;
private final long initialBasefee;
private final long slackCoefficient;
private final long maxGas;
private final long gasIncrementAmount;
public FeeMarketConfig(
final long basefeeMaxChangeDenominator,
final long targetGasUsed,
final long slackCoefficient,
final long decayRange,
final long initialBasefee) {
final long basefeeMaxChangeDenominator, final long decayRange, final long initialBasefee) {
this.basefeeMaxChangeDenominator = basefeeMaxChangeDenominator;
this.targetGasUsed = targetGasUsed;
this.slackCoefficient = slackCoefficient;
this.decayRange = decayRange;
this.initialBasefee = initialBasefee;
this.maxGas = slackCoefficient * targetGasUsed;
this.gasIncrementAmount = this.maxGas / 2 / this.decayRange;
}
@Override
@ -44,32 +32,12 @@ public class FeeMarketConfig implements FeeMarket {
}
@Override
public long getTargetGasUsed() {
return targetGasUsed;
}
@Override
public long getMaxGas() {
return maxGas;
}
@Override
public long getDecayRange() {
public long getMigrationDurationInBlocks() {
return decayRange;
}
@Override
public long getGasIncrementAmount() {
return gasIncrementAmount;
}
@Override
public long getInitialBasefee() {
return initialBasefee;
}
@Override
public long getSlackCoefficient() {
return slackCoefficient;
}
}

@ -14,38 +14,40 @@
*/
package org.hyperledger.besu.ethereum.core.fees;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction;
@FunctionalInterface
public interface TransactionGasBudgetCalculator {
boolean hasBudget(
final Transaction transaction, final BlockHeader blockHeader, final long gasUsed);
final Transaction transaction,
final long blockNumber,
final long gasLimit,
final long gasUsed);
static TransactionGasBudgetCalculator frontier() {
return gasBudgetCalculator((blockHeader, ignored) -> blockHeader.getGasLimit());
return gasBudgetCalculator((blockNumber, gasLimit, ignored) -> gasLimit);
}
static TransactionGasBudgetCalculator eip1559(final EIP1559 eip1559) {
return gasBudgetCalculator(
(blockHeader, transaction) ->
(blockNumber, gasLimit, transaction) ->
transaction.isEIP1559Transaction()
? eip1559.eip1559GasPool(blockHeader.getNumber())
: eip1559.legacyGasPool(blockHeader.getNumber()));
? eip1559.eip1559GasPool(blockNumber, gasLimit)
: eip1559.legacyGasPool(blockNumber, gasLimit));
}
static TransactionGasBudgetCalculator gasBudgetCalculator(
final BlockGasLimitCalculator blockGasLimitCalculator) {
return (transaction, blockHeader, gasUsed) -> {
return (transaction, blockNumber, gasLimit, gasUsed) -> {
final long remainingGasBudget =
blockGasLimitCalculator.apply(blockHeader, transaction) - gasUsed;
blockGasLimitCalculator.apply(blockNumber, gasLimit, transaction) - gasUsed;
return Long.compareUnsigned(transaction.getGasLimit(), remainingGasBudget) <= 0;
};
}
@FunctionalInterface
interface BlockGasLimitCalculator {
long apply(BlockHeader blockHeader, Transaction transaction);
long apply(final long blockNumber, final long gasLimit, Transaction transaction);
}
}

@ -31,6 +31,9 @@ public interface TransactionPriceCalculator {
static TransactionPriceCalculator eip1559() {
return (transaction, maybeBaseFee) -> {
if (transaction.isFrontierTransaction()) {
return transaction.getGasPrice();
}
ExperimentalEIPs.eip1559MustBeEnabled();
final Wei gasPremium =
Wei.of((BigInteger) transaction.getGasPremium().orElseThrow().getValue());

@ -14,6 +14,7 @@
*/
package org.hyperledger.besu.ethereum.mainnet;
import org.hyperledger.besu.config.experimental.ExperimentalEIPs;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.ethereum.core.BlockHeader;
@ -114,12 +115,20 @@ public abstract class AbstractBlockProcessor implements BlockProcessor {
final List<Transaction> transactions,
final List<BlockHeader> ommers) {
long gasUsed = 0;
long legacyGasUsed = 0;
long eip1556GasUsed = 0;
final List<TransactionReceipt> receipts = new ArrayList<>();
for (final Transaction transaction : transactions) {
final long remainingGasBudget = blockHeader.getGasLimit() - gasUsed;
if (!gasBudgetCalculator.hasBudget(transaction, blockHeader, gasUsed)) {
long currentGasUsed;
if (ExperimentalEIPs.eip1559Enabled && transaction.isEIP1559Transaction()) {
currentGasUsed = eip1556GasUsed;
} else {
currentGasUsed = legacyGasUsed;
}
final long remainingGasBudget = blockHeader.getGasLimit() - currentGasUsed;
if (!gasBudgetCalculator.hasBudget(
transaction, blockHeader.getNumber(), blockHeader.getGasLimit(), currentGasUsed)) {
LOG.warn(
"Transaction processing error: transaction gas limit {} exceeds available block budget remaining {}",
transaction.getGasLimit(),
@ -147,9 +156,17 @@ public abstract class AbstractBlockProcessor implements BlockProcessor {
}
worldStateUpdater.commit();
gasUsed = transaction.getGasLimit() - result.getGasRemaining() + gasUsed;
currentGasUsed = transaction.getGasLimit() - result.getGasRemaining() + currentGasUsed;
if (ExperimentalEIPs.eip1559Enabled && transaction.isEIP1559Transaction()) {
eip1556GasUsed = currentGasUsed;
} else {
legacyGasUsed = currentGasUsed;
}
final TransactionReceipt transactionReceipt =
transactionReceiptFactory.create(result, worldState, gasUsed);
transactionReceiptFactory.create(result, worldState, legacyGasUsed + eip1556GasUsed);
receipts.add(transactionReceipt);
}

@ -357,14 +357,13 @@ public abstract class MainnetProtocolSpecs {
// TODO EIP-1559 change for the actual fork name when known
static ProtocolSpecBuilder eip1559Definition(
final Optional<BigInteger> chainId,
final Optional<TransactionPriceCalculator> transactionPriceCalculator,
final OptionalInt contractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions) {
ExperimentalEIPs.eip1559MustBeEnabled();
final int stackSizeLimit = configStackSizeLimit.orElse(MessageFrame.DEFAULT_MAX_STACK_SIZE);
final TransactionPriceCalculator transactionPriceCalculator =
TransactionPriceCalculator.eip1559();
final EIP1559 eip1559 = new EIP1559(genesisConfigOptions.getEIP1559BlockNumber().orElse(0));
return muirGlacierDefinition(
chainId, contractSizeLimit, configStackSizeLimit, enableRevertReason)
@ -372,6 +371,7 @@ public abstract class MainnetProtocolSpecs {
gasCalculator ->
new MainnetTransactionValidator(
gasCalculator,
transactionPriceCalculator,
true,
chainId,
Optional.of(eip1559),
@ -389,10 +389,10 @@ public abstract class MainnetProtocolSpecs {
true,
stackSizeLimit,
Account.DEFAULT_VERSION,
transactionPriceCalculator,
transactionPriceCalculator.orElseThrow(),
CoinbaseFeePriceCalculator.eip1559()))
.name("EIP-1559")
.transactionPriceCalculator(transactionPriceCalculator)
.transactionPriceCalculator(transactionPriceCalculator.orElseThrow())
.eip1559(Optional.of(eip1559))
.gasBudgetCalculator(TransactionGasBudgetCalculator.eip1559(eip1559))
.blockHeaderValidatorBuilder(MainnetBlockHeaderValidator.createEip1559Validator(eip1559))
@ -403,12 +403,14 @@ public abstract class MainnetProtocolSpecs {
// TODO EIP-1559 change for the actual fork name when known
static ProtocolSpecBuilder eip1559FinalizedDefinition(
final Optional<BigInteger> chainId,
final Optional<TransactionPriceCalculator> transactionPriceCalculator,
final OptionalInt contractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions) {
return eip1559Definition(
chainId,
transactionPriceCalculator,
contractSizeLimit,
configStackSizeLimit,
enableRevertReason,
@ -417,6 +419,7 @@ public abstract class MainnetProtocolSpecs {
gasCalculator ->
new MainnetTransactionValidator(
gasCalculator,
transactionPriceCalculator,
true,
chainId,
Optional.of(

@ -211,7 +211,7 @@ public class MainnetTransactionProcessor implements TransactionProcessor {
LOG.trace("Starting execution of {}", transaction);
ValidationResult<TransactionValidator.TransactionInvalidReason> validationResult =
transactionValidator.validate(transaction);
transactionValidator.validate(transaction, blockHeader.getBaseFee());
// Make sure the transaction is intrinsically valid before trying to
// compare against a sender account (because the transaction may not
// be signed correctly to extract the sender).
@ -355,7 +355,7 @@ public class MainnetTransactionProcessor implements TransactionProcessor {
final MutableAccount coinbase = worldState.getOrCreate(miningBeneficiary).getMutable();
final Gas coinbaseFee = Gas.of(transaction.getGasLimit()).minus(refunded);
if (blockHeader.getBaseFee().isPresent()) {
if (blockHeader.getBaseFee().isPresent() && transaction.isEIP1559Transaction()) {
final Wei baseFee = Wei.of(blockHeader.getBaseFee().get());
if (transactionGasPrice.compareTo(baseFee) < 0) {
return Result.failed(
@ -367,9 +367,12 @@ public class MainnetTransactionProcessor implements TransactionProcessor {
Optional.empty());
}
}
final CoinbaseFeePriceCalculator coinbaseCreditService =
transaction.isFrontierTransaction()
? CoinbaseFeePriceCalculator.frontier()
: coinbaseFeePriceCalculator;
final Wei coinbaseWeiDelta =
coinbaseFeePriceCalculator.price(
coinbaseFee, transactionGasPrice, blockHeader.getBaseFee());
coinbaseCreditService.price(coinbaseFee, transactionGasPrice, blockHeader.getBaseFee());
coinbase.incrementBalance(coinbaseWeiDelta);

@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionFilter;
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.core.fees.EIP1559;
import org.hyperledger.besu.ethereum.core.fees.TransactionPriceCalculator;
import org.hyperledger.besu.ethereum.vm.GasCalculator;
import java.math.BigInteger;
@ -37,6 +38,7 @@ import java.util.Optional;
public class MainnetTransactionValidator implements TransactionValidator {
private final GasCalculator gasCalculator;
private final Optional<TransactionPriceCalculator> transactionPriceCalculator;
private final boolean disallowSignatureMalleability;
@ -52,6 +54,7 @@ public class MainnetTransactionValidator implements TransactionValidator {
final Optional<BigInteger> chainId) {
this(
gasCalculator,
Optional.empty(),
checkSignatureMalleability,
chainId,
Optional.empty(),
@ -60,11 +63,13 @@ public class MainnetTransactionValidator implements TransactionValidator {
public MainnetTransactionValidator(
final GasCalculator gasCalculator,
final Optional<TransactionPriceCalculator> transactionPriceCalculator,
final boolean checkSignatureMalleability,
final Optional<BigInteger> chainId,
final Optional<EIP1559> maybeEip1559,
final AcceptedTransactionTypes acceptedTransactionTypes) {
this.gasCalculator = gasCalculator;
this.transactionPriceCalculator = transactionPriceCalculator;
this.disallowSignatureMalleability = checkSignatureMalleability;
this.chainId = chainId;
this.maybeEip1559 = maybeEip1559;
@ -72,7 +77,8 @@ public class MainnetTransactionValidator implements TransactionValidator {
}
@Override
public ValidationResult<TransactionInvalidReason> validate(final Transaction transaction) {
public ValidationResult<TransactionInvalidReason> validate(
final Transaction transaction, final Optional<Long> baseFee) {
final ValidationResult<TransactionInvalidReason> signatureResult =
validateTransactionSignature(transaction);
if (!signatureResult.isValid()) {
@ -88,6 +94,14 @@ public class MainnetTransactionValidator implements TransactionValidator {
"transaction format is invalid, accepted transaction types are %s",
acceptedTransactionTypes.toString()));
}
if (transaction.isEIP1559Transaction()) {
final Wei price = transactionPriceCalculator.orElseThrow().price(transaction, baseFee);
if (price.compareTo(Wei.of(baseFee.orElseThrow())) < 0) {
return ValidationResult.invalid(
TransactionInvalidReason.INVALID_TRANSACTION_FORMAT,
String.format("gasPrice is less than the current BaseFee"));
}
}
}
final Gas intrinsicGasCost = gasCalculator.transactionIntrinsicGasCost(transaction);

@ -18,6 +18,7 @@ import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.experimental.ExperimentalEIPs;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.fees.FeeMarket;
import org.hyperledger.besu.ethereum.core.fees.TransactionPriceCalculator;
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator;
import java.math.BigInteger;
@ -175,11 +176,14 @@ public class ProtocolScheduleBuilder {
}
if (ExperimentalEIPs.eip1559Enabled) {
final Optional<TransactionPriceCalculator> transactionPriceCalculator =
Optional.of(TransactionPriceCalculator.eip1559());
addProtocolSpec(
protocolSchedule,
config.getEIP1559BlockNumber(),
MainnetProtocolSpecs.eip1559Definition(
chainId,
transactionPriceCalculator,
config.getContractSizeLimit(),
config.getEvmStackSize(),
isRevertReasonEnabled,
@ -191,9 +195,10 @@ public class ProtocolScheduleBuilder {
config
.getEIP1559BlockNumber()
.orElseThrow(() -> new RuntimeException("EIP-1559 must be enabled"))
+ feeMarket.getDecayRange()),
+ feeMarket.getMigrationDurationInBlocks()),
MainnetProtocolSpecs.eip1559FinalizedDefinition(
chainId,
transactionPriceCalculator,
config.getContractSizeLimit(),
config.getEvmStackSize(),
isRevertReasonEnabled,

@ -18,6 +18,8 @@ import org.hyperledger.besu.ethereum.core.Account;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionFilter;
import java.util.Optional;
/** Validates transaction based on some criteria. */
public interface TransactionValidator {
@ -25,11 +27,13 @@ public interface TransactionValidator {
* Asserts whether a transaction is valid.
*
* @param transaction the transaction to validate
* @param baseFee optional baseFee
* @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.
*/
ValidationResult<TransactionInvalidReason> validate(Transaction transaction);
ValidationResult<TransactionInvalidReason> validate(
Transaction transaction, Optional<Long> baseFee);
/**
* Asserts whether a transaction is valid for the sender accounts current state.

@ -1,64 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.headervalidationrules;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.fees.EIP1559;
import org.hyperledger.besu.ethereum.core.fees.FeeMarket;
import org.hyperledger.besu.ethereum.mainnet.DetachedBlockHeaderValidationRule;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class EIP1559BlockHeaderGasLimitValidationRule implements DetachedBlockHeaderValidationRule {
private static final Logger LOG = LogManager.getLogger();
private final EIP1559 eip1559;
private final FeeMarket feeMarket = FeeMarket.eip1559();
public EIP1559BlockHeaderGasLimitValidationRule(final EIP1559 eip1559) {
this.eip1559 = eip1559;
}
@Override
public boolean validate(final BlockHeader header, final BlockHeader parent) {
if (!eip1559.isEIP1559(header.getNumber())) {
return true;
}
if (eip1559.isEIP1559Finalized(header.getNumber())) {
if (header.getGasLimit() != feeMarket.getMaxGas()) {
LOG.trace(
"Invalid block header: gas limit {} does not equal expected gas limit {}",
header.getGasLimit(),
feeMarket.getMaxGas());
return false;
} else {
return true;
}
}
final long numberOfIncrements = header.getNumber() - eip1559.getForkBlock();
final long expectedGasLimit =
(feeMarket.getMaxGas() / 2) + (numberOfIncrements * feeMarket.getGasIncrementAmount());
if (header.getGasLimit() != expectedGasLimit) {
LOG.trace(
"Invalid block header: gas limit {} does not equal expected gas limit {}",
header.getGasLimit(),
expectedGasLimit);
return false;
}
return true;
}
}

@ -47,7 +47,9 @@ public class EIP1559BlockHeaderGasPriceValidationRule implements DetachedBlockHe
parent.getBaseFee().orElseThrow(EIP1559MissingBaseFeeFromBlockHeader::new);
final Long currentBaseFee =
header.getBaseFee().orElseThrow(EIP1559MissingBaseFeeFromBlockHeader::new);
final long baseFee = eip1559.computeBaseFee(parentBaseFee, parent.getGasUsed());
final long targetGasUsed = eip1559.targetGasUsed(parent);
final long baseFee =
eip1559.computeBaseFee(parentBaseFee, parent.getGasUsed(), targetGasUsed);
if (baseFee != header.getBaseFee().orElseThrow()) {
LOG.trace(
"Invalid block header: basefee {} does not equal expected basefee {}",

@ -38,6 +38,9 @@ public class TransactionTestFixture {
private Optional<BigInteger> chainId = Optional.of(BigInteger.valueOf(2018));
private Optional<Wei> gasPremium = Optional.empty();
private Optional<Wei> feeCap = Optional.empty();
public Transaction createTransaction(final KeyPair keys) {
final Transaction.Builder builder = Transaction.builder();
builder
@ -51,6 +54,9 @@ public class TransactionTestFixture {
to.ifPresent(builder::to);
chainId.ifPresent(builder::chainId);
gasPremium.ifPresent(builder::gasPremium);
feeCap.ifPresent(builder::feeCap);
return builder.signAndBuild(keys);
}
@ -93,4 +99,14 @@ public class TransactionTestFixture {
this.chainId = chainId;
return this;
}
public TransactionTestFixture gasPremium(final Optional<Wei> gasPremium) {
this.gasPremium = gasPremium;
return this;
}
public TransactionTestFixture feeCap(final Optional<Wei> feeCap) {
this.feeCap = feeCap;
return this;
}
}

@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.vm.ReferenceTestProtocolSchedules;
import org.hyperledger.besu.testutil.JsonTestParameters;
import java.util.Collection;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
import org.junit.Test;
@ -108,7 +109,7 @@ public class TransactionTest {
// Test transaction deserialization (will throw an exception if it fails).
final Transaction transaction = Transaction.readFrom(RLP.input(rlp));
if (!transactionValidator(milestone).validate(transaction).isValid()) {
if (!transactionValidator(milestone).validate(transaction, Optional.empty()).isValid()) {
throw new RuntimeException(String.format("Transaction is invalid %s", transaction));
}

@ -14,13 +14,19 @@
*/
package org.hyperledger.besu.ethereum.core.fees;
import static com.google.common.base.Preconditions.checkState;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.config.experimental.ExperimentalEIPs;
import java.util.Arrays;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Charsets;
import com.google.common.io.Resources;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@ -31,43 +37,47 @@ import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class EIP1559BaseFeeTest {
private static final long MARKER_BASE_FEE = 1049238967;
private final EIP1559 eip1559 = new EIP1559(0L);
private static final FeeMarket FEE_MARKET = FeeMarket.eip1559();
private final EIP1559 eip1559 = new EIP1559(0);
@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(
new Object[][] {
{
FEE_MARKET.getInitialBasefee(),
FEE_MARKET.getTargetGasUsed(),
FEE_MARKET.getInitialBasefee()
},
{FEE_MARKET.getInitialBasefee(), 7000000, 962500000},
{1100000000, FEE_MARKET.getTargetGasUsed(), 1100000000},
{1100000000, 9000000, 1086250000},
{1086250000, 9000000, 1072671875},
{1072671875, 9000000, 1059263476},
{1059263476, 10001000, 1059276716},
{1059276716, 16000000, 1138722469},
{MARKER_BASE_FEE, 0, 918084097},
{MARKER_BASE_FEE, 5, 918084161},
{MARKER_BASE_FEE, 5000, 918149673},
{MARKER_BASE_FEE, 500000, 924641839},
{MARKER_BASE_FEE, FEE_MARKET.getTargetGasUsed(), MARKER_BASE_FEE},
{MARKER_BASE_FEE, FEE_MARKET.getMaxGas(), 1180393837}
});
try {
final List<Object[]> data = new ArrayList<>();
final String testFilePath = "basefee-test.json";
final URL testFileUrl = EIP1559BaseFeeTest.class.getResource(testFilePath);
checkState(testFileUrl != null, "Cannot find test file " + testFilePath);
final String testSuiteJson = Resources.toString(testFileUrl, Charsets.UTF_8);
final ObjectMapper objectMapper = new ObjectMapper();
final Eip1559BaseFeeTestCase[] testCases =
objectMapper.readValue(testSuiteJson, Eip1559BaseFeeTestCase[].class);
for (final Eip1559BaseFeeTestCase testCase : testCases) {
data.add(
new Object[] {
testCase.parentBaseFee,
testCase.parentGasUsed,
testCase.parentTargetGasUsed,
testCase.expectedBaseFee
});
}
return data;
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
private final long parentBaseFee;
private final long parentGasUsed;
private final long parentTargetGasUsed;
private final long expectedBaseFee;
public EIP1559BaseFeeTest(
final long parentBaseFee, final long parentGasUsed, final long expectedBaseFee) {
final long parentBaseFee,
final long parentGasUsed,
final long parentTargetGasUsed,
final long expectedBaseFee) {
this.parentBaseFee = parentBaseFee;
this.parentGasUsed = parentGasUsed;
this.parentTargetGasUsed = parentTargetGasUsed;
this.expectedBaseFee = expectedBaseFee;
}
@ -83,6 +93,60 @@ public class EIP1559BaseFeeTest {
@Test
public void assertThatBaseFeeIsCorrect() {
assertThat(eip1559.computeBaseFee(parentBaseFee, parentGasUsed)).isEqualTo(expectedBaseFee);
assertThat(eip1559.computeBaseFee(parentBaseFee, parentGasUsed, parentTargetGasUsed))
.isEqualTo(expectedBaseFee);
}
private static class Eip1559BaseFeeTestCase {
private long parentBaseFee;
private long parentGasUsed;
private long parentTargetGasUsed;
private long expectedBaseFee;
public Eip1559BaseFeeTestCase() {}
public Eip1559BaseFeeTestCase(
final long parentBaseFee,
final long parentGasUsed,
final long parentTargetGasUsed,
final long expectedBaseFee) {
this.parentBaseFee = parentBaseFee;
this.parentGasUsed = parentGasUsed;
this.parentTargetGasUsed = parentTargetGasUsed;
this.expectedBaseFee = expectedBaseFee;
}
public long getParentBaseFee() {
return parentBaseFee;
}
public long getParentGasUsed() {
return parentGasUsed;
}
public long getParentTargetGasUsed() {
return parentTargetGasUsed;
}
public long getExpectedBaseFee() {
return expectedBaseFee;
}
public void setParentBaseFee(final long parentBaseFee) {
this.parentBaseFee = parentBaseFee;
}
public void setParentGasUsed(final long parentGasUsed) {
this.parentGasUsed = parentGasUsed;
}
public void setParentTargetGasUsed(final long parentTargetGasUsed) {
this.parentTargetGasUsed = parentTargetGasUsed;
}
public void setExpectedBaseFee(final long expectedBaseFee) {
this.expectedBaseFee = expectedBaseFee;
}
}
}

@ -33,6 +33,8 @@ public class EIP1559Test {
private static final long FORK_BLOCK = 783L;
private final EIP1559 eip1559 = new EIP1559(FORK_BLOCK);
private final FeeMarket feeMarket = FeeMarket.eip1559();
private static final long MAX_GAS = 20000000L;
private static final long TARGET_GAS_USED = 10000000L;
@Before
public void setUp() {
@ -48,7 +50,7 @@ public class EIP1559Test {
public void assertThatBaseFeeDecreasesWhenBelowTargetGasUsed() {
assertThat(
eip1559.computeBaseFee(
feeMarket.getInitialBasefee(), feeMarket.getTargetGasUsed() - 1000000L))
feeMarket.getInitialBasefee(), TARGET_GAS_USED - 1000000L, TARGET_GAS_USED))
.isLessThan(feeMarket.getInitialBasefee())
.isEqualTo(987500000L);
}
@ -57,14 +59,15 @@ public class EIP1559Test {
public void assertThatBaseFeeIncreasesWhenAboveTargetGasUsed() {
assertThat(
eip1559.computeBaseFee(
feeMarket.getInitialBasefee(), feeMarket.getTargetGasUsed() + 1000000L))
feeMarket.getInitialBasefee(), TARGET_GAS_USED + 1000000L, TARGET_GAS_USED))
.isGreaterThan(feeMarket.getInitialBasefee())
.isEqualTo(1012500000L);
}
@Test
public void assertThatBaseFeeDoesNotChangeWhenAtTargetGasUsed() {
assertThat(eip1559.computeBaseFee(feeMarket.getInitialBasefee(), feeMarket.getTargetGasUsed()))
assertThat(
eip1559.computeBaseFee(feeMarket.getInitialBasefee(), TARGET_GAS_USED, TARGET_GAS_USED))
.isEqualTo(feeMarket.getInitialBasefee());
}
@ -83,18 +86,26 @@ public class EIP1559Test {
@Test
public void eip1559GasPool() {
assertThat(eip1559.eip1559GasPool(FORK_BLOCK + 1))
.isEqualTo((feeMarket.getMaxGas() / 2) + feeMarket.getGasIncrementAmount());
assertThat(eip1559.eip1559GasPool(FORK_BLOCK + 1) + eip1559.legacyGasPool(FORK_BLOCK + 1))
.isEqualTo(feeMarket.getMaxGas());
// LEGACY_GAS_LIMIT: BLOCK_GAS_TARGET - EIP1559_GAS_TARGET. The maximum amount of gas legacy
// transactions can use in a given block.
// EIP1559_GAS_LIMIT: EIP1559_GAS_TARGET * 2. The maximum amount of gas EIP-1559 transactions
// can use in a given block.
assertThat(eip1559.eip1559GasPool(FORK_BLOCK + 1, MAX_GAS)).isEqualTo(20000024L);
assertThat(
eip1559.eip1559GasPool(FORK_BLOCK + 1, MAX_GAS)
+ eip1559.legacyGasPool(FORK_BLOCK + 1, MAX_GAS))
.isEqualTo((MAX_GAS - 20000024L / 2) + 20000024L);
}
@Test
public void legacyGasPool() {
assertThat(eip1559.legacyGasPool(FORK_BLOCK + 1))
.isEqualTo((feeMarket.getMaxGas() / 2) - feeMarket.getGasIncrementAmount());
assertThat(eip1559.eip1559GasPool(FORK_BLOCK + 1) + eip1559.legacyGasPool(FORK_BLOCK + 1))
.isEqualTo(feeMarket.getMaxGas());
// LEGACY_GAS_LIMIT: BLOCK_GAS_TARGET - EIP1559_GAS_TARGET. The maximum amount of gas legacy
// transactions can use in a given block.
assertThat(eip1559.legacyGasPool(FORK_BLOCK + 1, MAX_GAS)).isEqualTo(9999988L);
assertThat(
eip1559.eip1559GasPool(FORK_BLOCK + 1, MAX_GAS)
+ eip1559.legacyGasPool(FORK_BLOCK + 1, MAX_GAS))
.isEqualTo(9999988L + (MAX_GAS - 9999988L) * 2);
}
@Test
@ -109,12 +120,15 @@ public class EIP1559Test {
@Test
public void givenBlockAfterEIPFinalized_whenIsEIP1559Finalized_returnsTrue() {
assertThat(eip1559.isEIP1559Finalized(FORK_BLOCK + feeMarket.getDecayRange())).isTrue();
assertThat(eip1559.isEIP1559Finalized(FORK_BLOCK + feeMarket.getMigrationDurationInBlocks()))
.isTrue();
}
@Test
public void givenBlockBeforeEIPFinalized_whenIsEIP1559Finalized_returnsFalse() {
assertThat(eip1559.isEIP1559Finalized(FORK_BLOCK + feeMarket.getDecayRange() - 1)).isFalse();
assertThat(
eip1559.isEIP1559Finalized(FORK_BLOCK + feeMarket.getMigrationDurationInBlocks() - 1))
.isFalse();
}
@Test

@ -19,7 +19,6 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.config.experimental.ExperimentalEIPs;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction;
import java.util.Arrays;
@ -40,6 +39,7 @@ public class TransactionGasBudgetCalculatorTest {
private static final TransactionGasBudgetCalculator EIP1559_CALCULATOR =
TransactionGasBudgetCalculator.eip1559(new EIP1559(EIP_1559_FORK_BLOCK));
private static final FeeMarket FEE_MARKET = FeeMarket.eip1559();
private static final long MAX_GAS = 20000000L;
private final TransactionGasBudgetCalculator gasBudgetCalculator;
private final boolean isEIP1559;
@ -68,81 +68,58 @@ public class TransactionGasBudgetCalculatorTest {
@Parameterized.Parameters
public static Collection<Object[]> data() {
// LEGACY_INITIAL_GAS_LIMIT: BLOCK_GAS_TARGET / 2. The maximum amount of gas that legacy
// transactions can use in INITIAL_FORK_BLOCK_NUMBER
// EIP1559_INITIAL_GAS_TARGET: BLOCK_GAS_TARGET / 2. The maximum amount of gas that EIP-1559
// transactions can use in INITIAL_FORK_BLOCK_NUMBER.
// EIP1559_GAS_LIMIT: EIP1559_GAS_TARGET * 2. The maximum amount of gas EIP-1559 transactions
// can use in a given block.
return Arrays.asList(
new Object[][] {
{FRONTIER_CALCULATOR, false, 5L, 1L, 10L, 0L, true},
{FRONTIER_CALCULATOR, false, 11L, 1L, 10L, 0L, false},
{FRONTIER_CALCULATOR, false, 5L, 1L, 10L, 6L, false},
{EIP1559_CALCULATOR, false, 5L, EIP_1559_FORK_BLOCK, 10L, 0L, true},
{
EIP1559_CALCULATOR,
false,
(FEE_MARKET.getMaxGas() / 2) + 1,
1L,
FEE_MARKET.getMaxGas(),
0L,
false
},
{
EIP1559_CALCULATOR,
false,
(FEE_MARKET.getMaxGas() / 2) - 1,
EIP_1559_FORK_BLOCK,
10L,
2L,
false
},
{
EIP1559_CALCULATOR,
true,
(FEE_MARKET.getMaxGas() / 2) + 1,
EIP_1559_FORK_BLOCK,
FEE_MARKET.getMaxGas(),
0L,
false
},
{EIP1559_CALCULATOR, false, (MAX_GAS / 2), 1L, MAX_GAS, 0L, true},
{EIP1559_CALCULATOR, false, (MAX_GAS / 2) + 1, 1L, MAX_GAS, 0L, false},
{EIP1559_CALCULATOR, false, (MAX_GAS / 2) - 1, EIP_1559_FORK_BLOCK, 10L, 2L, false},
{EIP1559_CALCULATOR, true, (MAX_GAS / 2) + 1, EIP_1559_FORK_BLOCK, MAX_GAS, 0L, true},
{EIP1559_CALCULATOR, true, MAX_GAS + 1, EIP_1559_FORK_BLOCK, MAX_GAS, 0L, false},
{EIP1559_CALCULATOR, true, MAX_GAS, EIP_1559_FORK_BLOCK, MAX_GAS, 0L, true},
{EIP1559_CALCULATOR, true, (MAX_GAS / 2) - 1, EIP_1559_FORK_BLOCK, 10L, 2L, false},
{
EIP1559_CALCULATOR,
true,
(FEE_MARKET.getMaxGas() / 2) - 1,
EIP_1559_FORK_BLOCK,
10L,
2L,
false
},
{
EIP1559_CALCULATOR,
true,
(FEE_MARKET.getMaxGas() / 2) + FEE_MARKET.getGasIncrementAmount(),
(MAX_GAS / 2) + MAX_GAS / 2 / FEE_MARKET.getMigrationDurationInBlocks(),
EIP_1559_FORK_BLOCK + 1,
FEE_MARKET.getMaxGas(),
MAX_GAS,
0L,
true
},
{
EIP1559_CALCULATOR,
true,
(FEE_MARKET.getMaxGas() / 2) + FEE_MARKET.getGasIncrementAmount() + 1,
(MAX_GAS / 2) + MAX_GAS / 2 / FEE_MARKET.getMigrationDurationInBlocks() + 1,
EIP_1559_FORK_BLOCK + 1,
FEE_MARKET.getMaxGas(),
MAX_GAS,
0L,
false
true
},
{
EIP1559_CALCULATOR,
false,
(FEE_MARKET.getMaxGas() / 2) - FEE_MARKET.getGasIncrementAmount(),
(MAX_GAS / 2) - MAX_GAS / 2 / FEE_MARKET.getMigrationDurationInBlocks(),
EIP_1559_FORK_BLOCK + 1,
FEE_MARKET.getMaxGas(),
MAX_GAS,
0L,
true
},
{
EIP1559_CALCULATOR,
false,
(FEE_MARKET.getMaxGas() / 2) - FEE_MARKET.getGasIncrementAmount() + 1,
(MAX_GAS / 2) - MAX_GAS / 2 / FEE_MARKET.getMigrationDurationInBlocks() + 1,
EIP_1559_FORK_BLOCK + 1,
FEE_MARKET.getMaxGas(),
MAX_GAS,
0L,
false
}
@ -164,18 +141,12 @@ public class TransactionGasBudgetCalculatorTest {
assertThat(
gasBudgetCalculator.hasBudget(
transaction(isEIP1559, transactionGasLimit),
blockHeader(blockNumber, blockHeaderGasLimit),
blockNumber,
blockHeaderGasLimit,
gasUsed))
.isEqualTo(expectedHasBudget);
}
private BlockHeader blockHeader(final long blockNumber, final long gasLimit) {
final BlockHeader blockHeader = mock(BlockHeader.class);
when(blockHeader.getNumber()).thenReturn(blockNumber);
when(blockHeader.getGasLimit()).thenReturn(gasLimit);
return blockHeader;
}
private Transaction transaction(final boolean isEIP1559, final long gasLimit) {
final Transaction transaction = mock(Transaction.class);
when(transaction.isEIP1559Transaction()).thenReturn(isEIP1559);

@ -94,7 +94,7 @@ public class MainnetTransactionProcessorTest {
private ArgumentCaptor<TransactionValidationParams> transactionValidationParamCaptor() {
final ArgumentCaptor<TransactionValidationParams> txValidationParamCaptor =
ArgumentCaptor.forClass(TransactionValidationParams.class);
when(transactionValidator.validate(any())).thenReturn(ValidationResult.valid());
when(transactionValidator.validate(any(), any())).thenReturn(ValidationResult.valid());
// returning invalid transaction to halt method execution
when(transactionValidator.validateForSender(any(), any(), txValidationParamCaptor.capture()))
.thenReturn(

@ -33,6 +33,7 @@ import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.core.fees.EIP1559;
import org.hyperledger.besu.ethereum.core.fees.FeeMarket;
import org.hyperledger.besu.ethereum.core.fees.TransactionPriceCalculator;
import org.hyperledger.besu.ethereum.vm.GasCalculator;
import java.math.BigInteger;
@ -51,6 +52,9 @@ public class MainnetTransactionValidatorTest {
private static final KeyPair senderKeys = KeyPair.generate();
@Mock private GasCalculator gasCalculator;
@Mock private TransactionPriceCalculator transactionPriceCalculator;
final FeeMarket feeMarket = FeeMarket.eip1559();
private final Transaction basicTransaction =
@ -74,7 +78,7 @@ public class MainnetTransactionValidatorTest {
.createTransaction(senderKeys);
when(gasCalculator.transactionIntrinsicGasCost(transaction)).thenReturn(Gas.of(50));
assertThat(validator.validate(transaction))
assertThat(validator.validate(transaction, Optional.empty()))
.isEqualTo(
ValidationResult.invalid(
TransactionValidator.TransactionInvalidReason.INTRINSIC_GAS_EXCEEDS_GAS_LIMIT));
@ -84,7 +88,7 @@ public class MainnetTransactionValidatorTest {
public void shouldRejectTransactionWhenTransactionHasChainIdAndValidatorDoesNot() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(gasCalculator, false, Optional.empty());
assertThat(validator.validate(basicTransaction))
assertThat(validator.validate(basicTransaction, Optional.empty()))
.isEqualTo(
ValidationResult.invalid(
TransactionValidator.TransactionInvalidReason
@ -95,7 +99,7 @@ public class MainnetTransactionValidatorTest {
public void shouldRejectTransactionWhenTransactionHasIncorrectChainId() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(gasCalculator, false, Optional.of(BigInteger.valueOf(2)));
assertThat(validator.validate(basicTransaction))
assertThat(validator.validate(basicTransaction, Optional.empty()))
.isEqualTo(
ValidationResult.invalid(TransactionValidator.TransactionInvalidReason.WRONG_CHAIN_ID));
}
@ -245,6 +249,7 @@ public class MainnetTransactionValidatorTest {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
Optional.of(transactionPriceCalculator),
false,
Optional.empty(),
Optional.of(eip1559),
@ -254,13 +259,68 @@ public class MainnetTransactionValidatorTest {
.gasLimit(21000)
.chainId(Optional.empty())
.createTransaction(senderKeys);
assertThat(validator.validate(transaction))
assertThat(validator.validate(transaction, Optional.empty()))
.isEqualTo(
ValidationResult.invalid(
TransactionValidator.TransactionInvalidReason.INVALID_TRANSACTION_FORMAT));
ExperimentalEIPs.eip1559Enabled = false;
}
@Test
public void shouldRejectTransactionIfEIP1559TransactionGasPriceLessBaseFee() {
final long forkBlock = 845L;
final EIP1559 eip1559 = new EIP1559(forkBlock);
ExperimentalEIPs.eip1559Enabled = true;
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
Optional.of(transactionPriceCalculator),
false,
Optional.empty(),
Optional.of(eip1559),
AcceptedTransactionTypes.FEE_MARKET_TRANSACTIONS);
final Transaction transaction =
new TransactionTestFixture()
.gasPremium(Optional.of(Wei.of(1)))
.feeCap(Optional.of(Wei.of(1)))
.chainId(Optional.empty())
.createTransaction(senderKeys);
final Optional<Long> basefee = Optional.of(150000L);
when(transactionPriceCalculator.price(transaction, basefee)).thenReturn(Wei.of(1));
assertThat(validator.validate(transaction, basefee))
.isEqualTo(
ValidationResult.invalid(
TransactionValidator.TransactionInvalidReason.INVALID_TRANSACTION_FORMAT));
ExperimentalEIPs.eip1559Enabled = false;
}
@Test
public void shouldAcceptValidEIP1559() {
final long forkBlock = 845L;
final EIP1559 eip1559 = new EIP1559(forkBlock);
ExperimentalEIPs.eip1559Enabled = true;
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
Optional.of(transactionPriceCalculator),
false,
Optional.empty(),
Optional.of(eip1559),
AcceptedTransactionTypes.FEE_MARKET_TRANSACTIONS);
final Transaction transaction =
new TransactionTestFixture()
.gasPremium(Optional.of(Wei.of(1)))
.feeCap(Optional.of(Wei.of(1)))
.chainId(Optional.empty())
.createTransaction(senderKeys);
final Optional<Long> basefee = Optional.of(150000L);
when(transactionPriceCalculator.price(transaction, basefee)).thenReturn(Wei.of(160000L));
when(gasCalculator.transactionIntrinsicGasCost(transaction)).thenReturn(Gas.of(50));
assertThat(validator.validate(transaction, basefee)).isEqualTo(ValidationResult.valid());
ExperimentalEIPs.eip1559Enabled = false;
}
private Account accountWithNonce(final long nonce) {
return account(basicTransaction.getUpfrontCost(), nonce);
}

@ -1,110 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.headervalidationrules;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Java6Assertions.assertThatThrownBy;
import static org.hyperledger.besu.ethereum.mainnet.headervalidationrules.EIP1559Helper.blockHeader;
import static org.hyperledger.besu.ethereum.mainnet.headervalidationrules.EIP1559Helper.disableEIP1559;
import static org.hyperledger.besu.ethereum.mainnet.headervalidationrules.EIP1559Helper.enableEIP1559;
import org.hyperledger.besu.config.experimental.ExperimentalEIPs;
import org.hyperledger.besu.ethereum.core.fees.EIP1559;
import org.hyperledger.besu.ethereum.core.fees.FeeMarket;
import java.util.Optional;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class EIP1559BlockHeaderGasLimitValidationRuleTest {
private static final long FORK_BLOCK = 800L;
private final EIP1559 eip1559 = new EIP1559(FORK_BLOCK);
private EIP1559BlockHeaderGasLimitValidationRule validationRule;
private final FeeMarket feeMarket = FeeMarket.eip1559();
private long finalizedForkBlock;
@Before
public void setUp() {
validationRule = new EIP1559BlockHeaderGasLimitValidationRule(eip1559);
finalizedForkBlock = FORK_BLOCK + feeMarket.getDecayRange();
}
@After
public void reset() {
ExperimentalEIPs.eip1559Enabled = ExperimentalEIPs.EIP1559_ENABLED_DEFAULT_VALUE;
}
@Test
public void eipActivationShouldBeGuardedProperly() {
disableEIP1559();
assertThatThrownBy(
() -> validationRule.validate(blockHeader(FORK_BLOCK - 1, 0, Optional.empty()), null))
.isInstanceOf(RuntimeException.class)
.hasMessageContaining("EIP-1559 is not enabled");
}
@Test
public void shouldReturnTrueBeforeFork() {
enableEIP1559();
assertThat(validationRule.validate(blockHeader(FORK_BLOCK - 1, 0, Optional.empty()), null))
.isTrue();
}
@Test
public void shouldReturnTrueIfMaxGasLimitAfterFinalizedFork() {
enableEIP1559();
assertThat(
validationRule.validate(
blockHeader(finalizedForkBlock + 1, 0, Optional.empty(), feeMarket.getMaxGas()),
null))
.isTrue();
}
@Test
public void shouldReturnFalseIfNotMaxGasLimitAfterFinalizedFork() {
enableEIP1559();
assertThat(
validationRule.validate(
blockHeader(finalizedForkBlock + 1, 0, Optional.empty(), feeMarket.getMaxGas() - 1),
null))
.isFalse();
}
@Test
public void shouldReturnTrueIfValidGasLimitAfterFork() {
enableEIP1559();
assertThat(
validationRule.validate(
blockHeader(
FORK_BLOCK + 1,
0,
Optional.empty(),
(feeMarket.getMaxGas() / 2) + feeMarket.getGasIncrementAmount()),
null))
.isTrue();
}
@Test
public void shouldReturnFalseIfInvalidGasLimitAfterFork() {
enableEIP1559();
assertThat(
validationRule.validate(
blockHeader(FORK_BLOCK + 1, 0, Optional.empty(), feeMarket.getMaxGas() - 1), null))
.isFalse();
}
}

@ -94,26 +94,4 @@ public class EIP1559BlockHeaderGasPriceValidationRuleTest {
.isFalse();
disableEIP1559();
}
@Test
public void shouldReturnTrueIfValidBaseFeeAfterForkBlock() {
enableEIP1559();
assertThat(
validationRule.validate(
blockHeader(FORK_BLOCK + 1, 0, Optional.of(987500000L)),
blockHeader(FORK_BLOCK, 9000000L, Optional.of(feeMarket.getInitialBasefee()))))
.isTrue();
disableEIP1559();
}
@Test
public void shouldReturnFalseIfInvalidBaseFeeAfterForkBlock() {
enableEIP1559();
assertThat(
validationRule.validate(
blockHeader(FORK_BLOCK + 1, 0, Optional.of(987500001L)),
blockHeader(FORK_BLOCK, 9000000L, Optional.of(feeMarket.getInitialBasefee()))))
.isFalse();
disableEIP1559();
}
}

@ -0,0 +1,704 @@
[
{
"parentBaseFee":1000000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":1000000,
"expectedBaseFee":1125000000
},
{
"parentBaseFee":1000000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":2000000,
"expectedBaseFee":1125000000
},
{
"parentBaseFee":1000000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":3000000,
"expectedBaseFee":1125000000
},
{
"parentBaseFee":1000000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":4000000,
"expectedBaseFee":1125000000
},
{
"parentBaseFee":1000000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":5000000,
"expectedBaseFee":1125000000
},
{
"parentBaseFee":1000000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":6000000,
"expectedBaseFee":1083333333
},
{
"parentBaseFee":1000000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":7000000,
"expectedBaseFee":1053571428
},
{
"parentBaseFee":1000000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":8000000,
"expectedBaseFee":1031250000
},
{
"parentBaseFee":1000000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":9000000,
"expectedBaseFee":1013888888
},
{
"parentBaseFee":1000000000,
"parentGasUsed":7000000,
"parentTargetGasUsed":1000000,
"expectedBaseFee":1125000000
},
{
"parentBaseFee":1000000000,
"parentGasUsed":7000000,
"parentTargetGasUsed":2000000,
"expectedBaseFee":1125000000
},
{
"parentBaseFee":1000000000,
"parentGasUsed":7000000,
"parentTargetGasUsed":3000000,
"expectedBaseFee":1125000000
},
{
"parentBaseFee":1000000000,
"parentGasUsed":7000000,
"parentTargetGasUsed":4000000,
"expectedBaseFee":1093750000
},
{
"parentBaseFee":1000000000,
"parentGasUsed":7000000,
"parentTargetGasUsed":5000000,
"expectedBaseFee":1050000000
},
{
"parentBaseFee":1000000000,
"parentGasUsed":7000000,
"parentTargetGasUsed":6000000,
"expectedBaseFee":1020833333
},
{
"parentBaseFee":1000000000,
"parentGasUsed":7000000,
"parentTargetGasUsed":7000000,
"expectedBaseFee":1000000000
},
{
"parentBaseFee":1000000000,
"parentGasUsed":7000000,
"parentTargetGasUsed":8000000,
"expectedBaseFee":984375000
},
{
"parentBaseFee":1000000000,
"parentGasUsed":7000000,
"parentTargetGasUsed":9000000,
"expectedBaseFee":972222222
},
{
"parentBaseFee":1100000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":1000000,
"expectedBaseFee":1237500000
},
{
"parentBaseFee":1100000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":2000000,
"expectedBaseFee":1237500000
},
{
"parentBaseFee":1100000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":3000000,
"expectedBaseFee":1237500000
},
{
"parentBaseFee":1100000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":4000000,
"expectedBaseFee":1237500000
},
{
"parentBaseFee":1100000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":5000000,
"expectedBaseFee":1237500000
},
{
"parentBaseFee":1100000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":6000000,
"expectedBaseFee":1191666666
},
{
"parentBaseFee":1100000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":7000000,
"expectedBaseFee":1158928571
},
{
"parentBaseFee":1100000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":8000000,
"expectedBaseFee":1134375000
},
{
"parentBaseFee":1100000000,
"parentGasUsed":10000000,
"parentTargetGasUsed":9000000,
"expectedBaseFee":1115277777
},
{
"parentBaseFee":1100000000,
"parentGasUsed":9000000,
"parentTargetGasUsed":1000000,
"expectedBaseFee":1237500000
},
{
"parentBaseFee":1100000000,
"parentGasUsed":9000000,
"parentTargetGasUsed":2000000,
"expectedBaseFee":1237500000
},
{
"parentBaseFee":1100000000,
"parentGasUsed":9000000,
"parentTargetGasUsed":3000000,
"expectedBaseFee":1237500000
},
{
"parentBaseFee":1100000000,
"parentGasUsed":9000000,
"parentTargetGasUsed":4000000,
"expectedBaseFee":1237500000
},
{
"parentBaseFee":1100000000,
"parentGasUsed":9000000,
"parentTargetGasUsed":5000000,
"expectedBaseFee":1210000000
},
{
"parentBaseFee":1100000000,
"parentGasUsed":9000000,
"parentTargetGasUsed":6000000,
"expectedBaseFee":1168750000
},
{
"parentBaseFee":1100000000,
"parentGasUsed":9000000,
"parentTargetGasUsed":7000000,
"expectedBaseFee":1139285714
},
{
"parentBaseFee":1100000000,
"parentGasUsed":9000000,
"parentTargetGasUsed":8000000,
"expectedBaseFee":1117187500
},
{
"parentBaseFee":1100000000,
"parentGasUsed":9000000,
"parentTargetGasUsed":9000000,
"expectedBaseFee":1100000000
},
{
"parentBaseFee":1086250000,
"parentGasUsed":9000000,
"parentTargetGasUsed":1000000,
"expectedBaseFee":1222031250
},
{
"parentBaseFee":1086250000,
"parentGasUsed":9000000,
"parentTargetGasUsed":2000000,
"expectedBaseFee":1222031250
},
{
"parentBaseFee":1086250000,
"parentGasUsed":9000000,
"parentTargetGasUsed":3000000,
"expectedBaseFee":1222031250
},
{
"parentBaseFee":1086250000,
"parentGasUsed":9000000,
"parentTargetGasUsed":4000000,
"expectedBaseFee":1222031250
},
{
"parentBaseFee":1086250000,
"parentGasUsed":9000000,
"parentTargetGasUsed":5000000,
"expectedBaseFee":1194875000
},
{
"parentBaseFee":1086250000,
"parentGasUsed":9000000,
"parentTargetGasUsed":6000000,
"expectedBaseFee":1154140625
},
{
"parentBaseFee":1086250000,
"parentGasUsed":9000000,
"parentTargetGasUsed":7000000,
"expectedBaseFee":1125044642
},
{
"parentBaseFee":1086250000,
"parentGasUsed":9000000,
"parentTargetGasUsed":8000000,
"expectedBaseFee":1103222656
},
{
"parentBaseFee":1086250000,
"parentGasUsed":9000000,
"parentTargetGasUsed":9000000,
"expectedBaseFee":1086250000
},
{
"parentBaseFee":1072671875,
"parentGasUsed":9000000,
"parentTargetGasUsed":1000000,
"expectedBaseFee":1206755859
},
{
"parentBaseFee":1072671875,
"parentGasUsed":9000000,
"parentTargetGasUsed":2000000,
"expectedBaseFee":1206755859
},
{
"parentBaseFee":1072671875,
"parentGasUsed":9000000,
"parentTargetGasUsed":3000000,
"expectedBaseFee":1206755859
},
{
"parentBaseFee":1072671875,
"parentGasUsed":9000000,
"parentTargetGasUsed":4000000,
"expectedBaseFee":1206755859
},
{
"parentBaseFee":1072671875,
"parentGasUsed":9000000,
"parentTargetGasUsed":5000000,
"expectedBaseFee":1179939062
},
{
"parentBaseFee":1072671875,
"parentGasUsed":9000000,
"parentTargetGasUsed":6000000,
"expectedBaseFee":1139713867
},
{
"parentBaseFee":1072671875,
"parentGasUsed":9000000,
"parentTargetGasUsed":7000000,
"expectedBaseFee":1110981584
},
{
"parentBaseFee":1072671875,
"parentGasUsed":9000000,
"parentTargetGasUsed":8000000,
"expectedBaseFee":1089432373
},
{
"parentBaseFee":1072671875,
"parentGasUsed":9000000,
"parentTargetGasUsed":9000000,
"expectedBaseFee":1072671875
},
{
"parentBaseFee":1059263476,
"parentGasUsed":10001000,
"parentTargetGasUsed":1000000,
"expectedBaseFee":1191671410
},
{
"parentBaseFee":1059263476,
"parentGasUsed":10001000,
"parentTargetGasUsed":2000000,
"expectedBaseFee":1191671410
},
{
"parentBaseFee":1059263476,
"parentGasUsed":10001000,
"parentTargetGasUsed":3000000,
"expectedBaseFee":1191671410
},
{
"parentBaseFee":1059263476,
"parentGasUsed":10001000,
"parentTargetGasUsed":4000000,
"expectedBaseFee":1191671410
},
{
"parentBaseFee":1059263476,
"parentGasUsed":10001000,
"parentTargetGasUsed":5000000,
"expectedBaseFee":1191671410
},
{
"parentBaseFee":1059263476,
"parentGasUsed":10001000,
"parentTargetGasUsed":6000000,
"expectedBaseFee":1147557500
},
{
"parentBaseFee":1059263476,
"parentGasUsed":10001000,
"parentTargetGasUsed":7000000,
"expectedBaseFee":1116028649
},
{
"parentBaseFee":1059263476,
"parentGasUsed":10001000,
"parentTargetGasUsed":8000000,
"expectedBaseFee":1092382010
},
{
"parentBaseFee":1059263476,
"parentGasUsed":10001000,
"parentTargetGasUsed":9000000,
"expectedBaseFee":1073990180
},
{
"parentBaseFee":1059276716,
"parentGasUsed":16000000,
"parentTargetGasUsed":1000000,
"expectedBaseFee":1191686305
},
{
"parentBaseFee":1059276716,
"parentGasUsed":16000000,
"parentTargetGasUsed":2000000,
"expectedBaseFee":1191686305
},
{
"parentBaseFee":1059276716,
"parentGasUsed":16000000,
"parentTargetGasUsed":3000000,
"expectedBaseFee":1191686305
},
{
"parentBaseFee":1059276716,
"parentGasUsed":16000000,
"parentTargetGasUsed":4000000,
"expectedBaseFee":1191686305
},
{
"parentBaseFee":1059276716,
"parentGasUsed":16000000,
"parentTargetGasUsed":5000000,
"expectedBaseFee":1191686305
},
{
"parentBaseFee":1059276716,
"parentGasUsed":16000000,
"parentTargetGasUsed":6000000,
"expectedBaseFee":1191686305
},
{
"parentBaseFee":1059276716,
"parentGasUsed":16000000,
"parentTargetGasUsed":7000000,
"expectedBaseFee":1191686305
},
{
"parentBaseFee":1059276716,
"parentGasUsed":16000000,
"parentTargetGasUsed":8000000,
"expectedBaseFee":1191686305
},
{
"parentBaseFee":1059276716,
"parentGasUsed":16000000,
"parentTargetGasUsed":9000000,
"expectedBaseFee":1162261952
},
{
"parentBaseFee":1049238967,
"parentGasUsed":0,
"parentTargetGasUsed":1000000,
"expectedBaseFee":918084097
},
{
"parentBaseFee":1049238967,
"parentGasUsed":0,
"parentTargetGasUsed":2000000,
"expectedBaseFee":918084097
},
{
"parentBaseFee":1049238967,
"parentGasUsed":0,
"parentTargetGasUsed":3000000,
"expectedBaseFee":918084097
},
{
"parentBaseFee":1049238967,
"parentGasUsed":0,
"parentTargetGasUsed":4000000,
"expectedBaseFee":918084097
},
{
"parentBaseFee":1049238967,
"parentGasUsed":0,
"parentTargetGasUsed":5000000,
"expectedBaseFee":918084097
},
{
"parentBaseFee":1049238967,
"parentGasUsed":0,
"parentTargetGasUsed":6000000,
"expectedBaseFee":918084097
},
{
"parentBaseFee":1049238967,
"parentGasUsed":0,
"parentTargetGasUsed":7000000,
"expectedBaseFee":918084097
},
{
"parentBaseFee":1049238967,
"parentGasUsed":0,
"parentTargetGasUsed":8000000,
"expectedBaseFee":918084097
},
{
"parentBaseFee":1049238967,
"parentGasUsed":0,
"parentTargetGasUsed":9000000,
"expectedBaseFee":918084097
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5,
"parentTargetGasUsed":1000000,
"expectedBaseFee":918084751
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5,
"parentTargetGasUsed":2000000,
"expectedBaseFee":918084424
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5,
"parentTargetGasUsed":3000000,
"expectedBaseFee":918084314
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5,
"parentTargetGasUsed":4000000,
"expectedBaseFee":918084260
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5,
"parentTargetGasUsed":5000000,
"expectedBaseFee":918084227
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5,
"parentTargetGasUsed":6000000,
"expectedBaseFee":918084205
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5,
"parentTargetGasUsed":7000000,
"expectedBaseFee":918084189
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5,
"parentTargetGasUsed":8000000,
"expectedBaseFee":918084178
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5,
"parentTargetGasUsed":9000000,
"expectedBaseFee":918084168
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5000,
"parentTargetGasUsed":1000000,
"expectedBaseFee":918739870
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5000,
"parentTargetGasUsed":2000000,
"expectedBaseFee":918411983
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5000,
"parentTargetGasUsed":3000000,
"expectedBaseFee":918302687
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5000,
"parentTargetGasUsed":4000000,
"expectedBaseFee":918248039
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5000,
"parentTargetGasUsed":5000000,
"expectedBaseFee":918215250
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5000,
"parentTargetGasUsed":6000000,
"expectedBaseFee":918193391
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5000,
"parentTargetGasUsed":7000000,
"expectedBaseFee":918177778
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5000,
"parentTargetGasUsed":8000000,
"expectedBaseFee":918166067
},
{
"parentBaseFee":1049238967,
"parentGasUsed":5000,
"parentTargetGasUsed":9000000,
"expectedBaseFee":918156959
},
{
"parentBaseFee":1049238967,
"parentGasUsed":500000,
"parentTargetGasUsed":1000000,
"expectedBaseFee":983661531
},
{
"parentBaseFee":1049238967,
"parentGasUsed":500000,
"parentTargetGasUsed":2000000,
"expectedBaseFee":950872813
},
{
"parentBaseFee":1049238967,
"parentGasUsed":500000,
"parentTargetGasUsed":3000000,
"expectedBaseFee":939943241
},
{
"parentBaseFee":1049238967,
"parentGasUsed":500000,
"parentTargetGasUsed":4000000,
"expectedBaseFee":934478454
},
{
"parentBaseFee":1049238967,
"parentGasUsed":500000,
"parentTargetGasUsed":5000000,
"expectedBaseFee":931199583
},
{
"parentBaseFee":1049238967,
"parentGasUsed":500000,
"parentTargetGasUsed":6000000,
"expectedBaseFee":929013668
},
{
"parentBaseFee":1049238967,
"parentGasUsed":500000,
"parentTargetGasUsed":7000000,
"expectedBaseFee":927452301
},
{
"parentBaseFee":1049238967,
"parentGasUsed":500000,
"parentTargetGasUsed":8000000,
"expectedBaseFee":926281275
},
{
"parentBaseFee":1049238967,
"parentGasUsed":500000,
"parentTargetGasUsed":9000000,
"expectedBaseFee":925370477
},
{
"parentBaseFee":1049238967,
"parentGasUsed":10000000,
"parentTargetGasUsed":1000000,
"expectedBaseFee":1180393837
},
{
"parentBaseFee":1049238967,
"parentGasUsed":10000000,
"parentTargetGasUsed":2000000,
"expectedBaseFee":1180393837
},
{
"parentBaseFee":1049238967,
"parentGasUsed":10000000,
"parentTargetGasUsed":3000000,
"expectedBaseFee":1180393837
},
{
"parentBaseFee":1049238967,
"parentGasUsed":10000000,
"parentTargetGasUsed":4000000,
"expectedBaseFee":1180393837
},
{
"parentBaseFee":1049238967,
"parentGasUsed":10000000,
"parentTargetGasUsed":5000000,
"expectedBaseFee":1180393837
},
{
"parentBaseFee":1049238967,
"parentGasUsed":10000000,
"parentTargetGasUsed":6000000,
"expectedBaseFee":1136675547
},
{
"parentBaseFee":1049238967,
"parentGasUsed":10000000,
"parentTargetGasUsed":7000000,
"expectedBaseFee":1105448197
},
{
"parentBaseFee":1049238967,
"parentGasUsed":10000000,
"parentTargetGasUsed":8000000,
"expectedBaseFee":1082027684
},
{
"parentBaseFee":1049238967,
"parentGasUsed":10000000,
"parentTargetGasUsed":9000000,
"expectedBaseFee":1063811730
}
]

@ -251,7 +251,7 @@ public class TransactionPool implements BlockAddedObserver {
final Transaction transaction) {
final BlockHeader chainHeadBlockHeader = getChainHeadBlockHeader();
final ValidationResult<TransactionInvalidReason> basicValidationResult =
getTransactionValidator().validate(transaction);
getTransactionValidator().validate(transaction, chainHeadBlockHeader.getBaseFee());
if (!basicValidationResult.isValid()) {
return basicValidationResult;
}

@ -57,6 +57,7 @@ import java.util.Optional;
import org.junit.Test;
@SuppressWarnings("unchecked")
public class TransactionPoolFactoryTest {
@Test
@ -159,7 +160,8 @@ public class TransactionPoolFactoryTest {
when(pendingTransactions.addLocalTransaction(any())).thenReturn(TransactionAddedStatus.ADDED);
when(protocolSpec.getTransactionValidator()).thenReturn(transactionValidator);
when(schedule.getByBlockNumber(anyLong())).thenReturn(protocolSpec);
when(transactionValidator.validate(any())).thenReturn(ValidationResult.valid());
when(transactionValidator.validate(any(), any(Optional.class)))
.thenReturn(ValidationResult.valid());
when(transactionValidator.validateForSender(any(), any(), any()))
.thenReturn(ValidationResult.valid());
when(worldStateArchive.get(any())).thenReturn(Optional.of(worldState));

@ -77,6 +77,7 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
@SuppressWarnings("unchecked")
public class TransactionPoolTest {
private static final int MAX_TRANSACTIONS = 5;
@ -312,7 +313,7 @@ public class TransactionPoolTest {
@Test
public void shouldNotAddRemoteTransactionsThatAreInvalidAccordingToInvariantChecks() {
givenTransactionIsValid(transaction2);
when(transactionValidator.validate(eq(transaction1)))
when(transactionValidator.validate(eq(transaction1), any(Optional.class)))
.thenReturn(ValidationResult.invalid(NONCE_TOO_LOW));
transactionPool.addRemoteTransactions(asList(transaction1, transaction2));
@ -325,7 +326,7 @@ public class TransactionPoolTest {
@Test
public void shouldNotAddRemoteTransactionsThatAreInvalidAccordingToStateDependentChecks() {
givenTransactionIsValid(transaction2);
when(transactionValidator.validate(eq(transaction1))).thenReturn(valid());
when(transactionValidator.validate(eq(transaction1), any(Optional.class))).thenReturn(valid());
when(transactionValidator.validateForSender(transaction1, null, true))
.thenReturn(ValidationResult.invalid(NONCE_TOO_LOW));
@ -343,7 +344,8 @@ public class TransactionPoolTest {
final Transaction transaction2 = builder.nonce(2).createTransaction(KEY_PAIR1);
final Transaction transaction3 = builder.nonce(3).createTransaction(KEY_PAIR1);
when(transactionValidator.validate(any(Transaction.class))).thenReturn(valid());
when(transactionValidator.validate(any(Transaction.class), any(Optional.class)))
.thenReturn(valid());
when(transactionValidator.validateForSender(
eq(transaction1), nullable(Account.class), any(TransactionValidationParams.class)))
.thenReturn(valid());
@ -371,7 +373,8 @@ public class TransactionPoolTest {
final Transaction transaction2 = builder.nonce(2).createTransaction(KEY_PAIR1);
final Transaction transaction3 = builder.nonce(3).createTransaction(KEY_PAIR1);
when(transactionValidator.validate(any(Transaction.class))).thenReturn(valid());
when(transactionValidator.validate(any(Transaction.class), any(Optional.class)))
.thenReturn(valid());
when(transactionValidator.validateForSender(
eq(transaction1), nullable(Account.class), any(TransactionValidationParams.class)))
.thenReturn(valid());
@ -426,7 +429,8 @@ public class TransactionPoolTest {
final Transaction transaction2 =
builder.nonce(1).gasPrice(Wei.of(5)).createTransaction(KEY_PAIR1);
when(transactionValidator.validate(any(Transaction.class))).thenReturn(valid());
when(transactionValidator.validate(any(Transaction.class), any(Optional.class)))
.thenReturn(valid());
when(transactionValidator.validateForSender(
eq(transaction1), nullable(Account.class), any(TransactionValidationParams.class)))
.thenReturn(valid());
@ -450,7 +454,8 @@ public class TransactionPoolTest {
final Transaction transaction2 =
builder.nonce(1).gasPrice(Wei.of(5)).createTransaction(KEY_PAIR1);
when(transactionValidator.validate(any(Transaction.class))).thenReturn(valid());
when(transactionValidator.validate(any(Transaction.class), any(Optional.class)))
.thenReturn(valid());
when(transactionValidator.validateForSender(
eq(transaction1), nullable(Account.class), any(TransactionValidationParams.class)))
.thenReturn(valid());
@ -508,7 +513,7 @@ public class TransactionPoolTest {
when(peerPendingTransactionTracker.isPeerSupported(peer, EthProtocol.ETH65)).thenReturn(false);
when(peerPendingTransactionTracker.isPeerSupported(validPeer, EthProtocol.ETH65))
.thenReturn(true);
when(transactionValidator.validate(any())).thenReturn(valid());
when(transactionValidator.validate(any(), any(Optional.class))).thenReturn(valid());
transactionPool.addTransactionHash(transaction1.getHash());
transactionPool.handleConnect(peer);
verify(peerPendingTransactionTracker, never()).addToPeerSendQueue(peer, transaction1.getHash());
@ -551,7 +556,8 @@ public class TransactionPoolTest {
final Transaction transaction2 = builder.nonce(2).createTransaction(KEY_PAIR1);
final Transaction transaction3 = builder.nonce(3).createTransaction(KEY_PAIR1);
when(transactionValidator.validate(any(Transaction.class))).thenReturn(valid());
when(transactionValidator.validate(any(Transaction.class), any(Optional.class)))
.thenReturn(valid());
when(transactionValidator.validateForSender(
eq(transaction1), nullable(Account.class), any(TransactionValidationParams.class)))
.thenReturn(valid());
@ -577,7 +583,8 @@ public class TransactionPoolTest {
final Transaction transaction2 = builder.nonce(2).createTransaction(KEY_PAIR1);
final Transaction transaction3 = builder.nonce(3).createTransaction(KEY_PAIR1);
when(transactionValidator.validate(any(Transaction.class))).thenReturn(valid());
when(transactionValidator.validate(any(Transaction.class), any(Optional.class)))
.thenReturn(valid());
when(transactionValidator.validateForSender(
eq(transaction1), nullable(Account.class), any(TransactionValidationParams.class)))
.thenReturn(valid());
@ -619,7 +626,8 @@ public class TransactionPoolTest {
final TransactionTestFixture builder = new TransactionTestFixture();
final Transaction transactionLocal = builder.nonce(1).createTransaction(KEY_PAIR1);
final Transaction transactionRemote = builder.nonce(2).createTransaction(KEY_PAIR1);
when(transactionValidator.validate(any(Transaction.class))).thenReturn(valid());
when(transactionValidator.validate(any(Transaction.class), any(Optional.class)))
.thenReturn(valid());
when(transactionValidator.validateForSender(
any(Transaction.class),
nullable(Account.class),
@ -641,7 +649,7 @@ public class TransactionPoolTest {
public void shouldCallValidatorWithExpectedValidationParameters() {
final ArgumentCaptor<TransactionValidationParams> txValidationParamCaptor =
ArgumentCaptor.forClass(TransactionValidationParams.class);
when(transactionValidator.validate(eq(transaction1))).thenReturn(valid());
when(transactionValidator.validate(eq(transaction1), any(Optional.class))).thenReturn(valid());
when(transactionValidator.validateForSender(any(), any(), txValidationParamCaptor.capture()))
.thenReturn(valid());
@ -675,7 +683,8 @@ public class TransactionPoolTest {
metricsSystem,
Optional.empty(),
TransactionPoolConfiguration.builder().txFeeCap(Wei.ZERO).build());
when(transactionValidator.validate(any(Transaction.class))).thenReturn(valid());
when(transactionValidator.validate(any(Transaction.class), any(Optional.class)))
.thenReturn(valid());
when(transactionValidator.validateForSender(
any(Transaction.class),
nullable(Account.class),
@ -772,7 +781,7 @@ public class TransactionPoolTest {
}
private void givenTransactionIsValid(final Transaction transaction) {
when(transactionValidator.validate(eq(transaction))).thenReturn(valid());
when(transactionValidator.validate(eq(transaction), any(Optional.class))).thenReturn(valid());
when(transactionValidator.validateForSender(
eq(transaction), nullable(Account.class), any(TransactionValidationParams.class)))
.thenReturn(valid());

Loading…
Cancel
Save