From 5a5f4eb49c42e65761e111001f6561288abea69e Mon Sep 17 00:00:00 2001 From: Abdelhamid Bakhta <45264458+abdelhamidbakhta@users.noreply.github.com> Date: Fri, 10 Apr 2020 09:33:57 +0200 Subject: [PATCH] [EIP-1559] Step 7 - Check transaction format for send raw transaction (#694) * Added changelog entries for PR: - https://github.com/hyperledger/besu/pull/430 - https://github.com/hyperledger/besu/pull/440 Signed-off-by: Abdelhamid Bakhta * Check transaction format for send raw transaction Signed-off-by: Abdelhamid Bakhta * Address PR comments Signed-off-by: Abdelhamid Bakhta * Address PR comments Signed-off-by: Abdelhamid Bakhta * remove EthSendRawTransactionTest.blokchainQueries field Signed-off-by: Abdelhamid Bakhta --- .../methods/EthSendRawTransactionTest.java | 1 - .../core/AcceptedTransactionTypes.java | 42 +++++++++++ .../besu/ethereum/core/fees/EIP1559.java | 30 +++++++- .../mainnet/MainnetBlockBodyValidator.java | 7 +- .../mainnet/MainnetProtocolSpecs.java | 31 +++++++- .../mainnet/MainnetTransactionValidator.java | 37 +++++++--- .../mainnet/ProtocolScheduleBuilder.java | 16 ++++ .../mainnet/TransactionValidator.java | 1 + .../besu/ethereum/chain/GenesisStateTest.java | 7 ++ .../core/AcceptedTransactionTypesTest.java | 74 +++++++++++++++++++ .../besu/ethereum/core/fees/EIP1559Test.java | 54 ++++++++++++++ .../MainnetTransactionValidatorTest.java | 35 ++++++++- 12 files changed, 313 insertions(+), 22 deletions(-) create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/AcceptedTransactionTypes.java create mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/AcceptedTransactionTypesTest.java diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransactionTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransactionTest.java index df413297eb3..06231814dc5 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransactionTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransactionTest.java @@ -42,7 +42,6 @@ public class EthSendRawTransactionTest { private static final String VALID_TRANSACTION = "0xf86d0485174876e800830222e0945aae326516b4f8fe08074b7e972e40a713048d62880de0b6b3a7640000801ba05d4e7998757264daab67df2ce6f7e7a0ae36910778a406ca73898c9899a32b9ea0674700d5c3d1d27f2e6b4469957dfd1a1c49bf92383d80717afc84eb05695d5b"; @Mock private TransactionPool transactionPool; - private EthSendRawTransaction method; @Before diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/AcceptedTransactionTypes.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/AcceptedTransactionTypes.java new file mode 100644 index 00000000000..a63ff76f94a --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/AcceptedTransactionTypes.java @@ -0,0 +1,42 @@ +/* + * 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.core; + +public enum AcceptedTransactionTypes { + FRONTIER_TRANSACTIONS(true, false), + FEE_MARKET_TRANSITIONAL_TRANSACTIONS(true, true), + FEE_MARKET_TRANSACTIONS(false, true); + + final boolean isFrontierAccepted; + final boolean isEIP1559Accepted; + + AcceptedTransactionTypes(final boolean isFrontierAccepted, final boolean isEIP1559Accepted) { + this.isFrontierAccepted = isFrontierAccepted; + this.isEIP1559Accepted = isEIP1559Accepted; + } + + public boolean isFrontierAccepted() { + return isFrontierAccepted; + } + + public boolean isEIP1559Accepted() { + return isEIP1559Accepted; + } + + @Override + public String toString() { + return String.format("frontier: %b / eip1559: %b", isFrontierAccepted, isEIP1559Accepted); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/fees/EIP1559.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/fees/EIP1559.java index ef42413f1e2..bb55d6c1261 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/fees/EIP1559.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/fees/EIP1559.java @@ -15,6 +15,8 @@ package org.hyperledger.besu.ethereum.core.fees; import org.hyperledger.besu.config.experimental.ExperimentalEIPs; +import org.hyperledger.besu.ethereum.core.AcceptedTransactionTypes; +import org.hyperledger.besu.ethereum.core.Transaction; public class EIP1559 { @@ -77,13 +79,33 @@ public long getForkBlock() { return initialForkBlknum; } + public boolean isValidFormat( + final Transaction transaction, final AcceptedTransactionTypes acceptedTransactionTypes) { + if (transaction == null) { + return false; + } + switch (acceptedTransactionTypes) { + case FRONTIER_TRANSACTIONS: + return transaction.isFrontierTransaction(); + case FEE_MARKET_TRANSITIONAL_TRANSACTIONS: + return transaction.isFrontierTransaction() || transaction.isEIP1559Transaction(); + case FEE_MARKET_TRANSACTIONS: + return transaction.isEIP1559Transaction(); + default: + return false; + } + } + + public boolean isValidGasLimit(final Transaction transaction) { + if (transaction == null) { + return false; + } + return transaction.getGasLimit() <= feeMarket.getPerTxGaslimit(); + } + private void guardActivation() { if (!ExperimentalEIPs.eip1559Enabled) { throw new RuntimeException("EIP-1559 is not enabled"); } } - - public FeeMarket getFeeMarket() { - return feeMarket; - } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidator.java index 458e2a77d24..035b394f8fb 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockBodyValidator.java @@ -276,11 +276,10 @@ private boolean validatePerTransactionGasLimit(final Block block) { final BlockBody body = block.getBody(); final List transactions = body.getTransactions(); for (final Transaction transaction : transactions) { - if (transaction.getGasLimit() > eip1559.getFeeMarket().getPerTxGaslimit()) { + if (!eip1559.isValidGasLimit(transaction)) { LOG.warn( - "Invalid block: transaction gas limit {} exceeds per transaction gas limit {}", - transaction.getGasLimit(), - eip1559.getFeeMarket().getPerTxGaslimit()); + "Invalid block: transaction gas limit {} exceeds per transaction gas limit", + transaction.getGasLimit()); return false; } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java index bb23d98f3bd..212cd931f21 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.config.experimental.ExperimentalEIPs; import org.hyperledger.besu.ethereum.MainnetBlockValidator; import org.hyperledger.besu.ethereum.chain.Blockchain; +import org.hyperledger.besu.ethereum.core.AcceptedTransactionTypes; import org.hyperledger.besu.ethereum.core.Account; import org.hyperledger.besu.ethereum.core.Address; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -345,7 +346,11 @@ static ProtocolSpecBuilder eip1559Definition( .transactionValidatorBuilder( gasCalculator -> new MainnetTransactionValidator( - gasCalculator, true, chainId, Optional.of(eip1559))) + gasCalculator, + true, + chainId, + Optional.of(eip1559), + AcceptedTransactionTypes.FEE_MARKET_TRANSITIONAL_TRANSACTIONS)) .name("EIP-1559"); final BlockHeaderValidator.Builder blockHeaderValidatorBuilder = eip1559ProtocolSpecBuilder.getBlockHeaderValidatorBuilder(); @@ -355,6 +360,30 @@ static ProtocolSpecBuilder eip1559Definition( return eip1559ProtocolSpecBuilder; } + // TODO EIP-1559 change for the actual fork name when known + static ProtocolSpecBuilder eip1559FinalizedDefinition( + final Optional chainId, + final OptionalInt contractSizeLimit, + final OptionalInt configStackSizeLimit, + final boolean enableRevertReason, + final GenesisConfigOptions genesisConfigOptions) { + return eip1559Definition( + chainId, + contractSizeLimit, + configStackSizeLimit, + enableRevertReason, + genesisConfigOptions) + .transactionValidatorBuilder( + gasCalculator -> + new MainnetTransactionValidator( + gasCalculator, + true, + chainId, + Optional.of( + new EIP1559(genesisConfigOptions.getEIP1559BlockNumber().orElse(0))), + AcceptedTransactionTypes.FEE_MARKET_TRANSACTIONS)); + } + private static TransactionReceipt frontierTransactionReceiptFactory( final TransactionProcessor.Result result, final WorldState worldState, final long gasUsed) { return new TransactionReceipt( diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java index fbba9a2c5ff..6604b998a1b 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java @@ -16,6 +16,7 @@ import org.hyperledger.besu.config.experimental.ExperimentalEIPs; import org.hyperledger.besu.crypto.SECP256K1; +import org.hyperledger.besu.ethereum.core.AcceptedTransactionTypes; import org.hyperledger.besu.ethereum.core.Account; import org.hyperledger.besu.ethereum.core.Gas; import org.hyperledger.besu.ethereum.core.Transaction; @@ -43,23 +44,31 @@ public class MainnetTransactionValidator implements TransactionValidator { private Optional transactionFilter = Optional.empty(); private final Optional maybeEip1559; + private final AcceptedTransactionTypes acceptedTransactionTypes; public MainnetTransactionValidator( final GasCalculator gasCalculator, final boolean checkSignatureMalleability, final Optional chainId) { - this(gasCalculator, checkSignatureMalleability, chainId, Optional.empty()); + this( + gasCalculator, + checkSignatureMalleability, + chainId, + Optional.empty(), + AcceptedTransactionTypes.FRONTIER_TRANSACTIONS); } public MainnetTransactionValidator( final GasCalculator gasCalculator, final boolean checkSignatureMalleability, final Optional chainId, - final Optional maybeEip1559) { + final Optional maybeEip1559, + final AcceptedTransactionTypes acceptedTransactionTypes) { this.gasCalculator = gasCalculator; this.disallowSignatureMalleability = checkSignatureMalleability; this.chainId = chainId; this.maybeEip1559 = maybeEip1559; + this.acceptedTransactionTypes = acceptedTransactionTypes; } @Override @@ -70,14 +79,22 @@ public ValidationResult validate(final Transaction tra return signatureResult; } - if (ExperimentalEIPs.eip1559Enabled - && maybeEip1559.isPresent() - && transaction.getGasLimit() > maybeEip1559.get().getFeeMarket().getPerTxGaslimit()) { - return ValidationResult.invalid( - TransactionInvalidReason.EXCEEDS_PER_TRANSACTION_GAS_LIMIT, - String.format( - "transaction gas limit %s exceeds per transaction gas limit %s", - transaction.getGasLimit(), maybeEip1559.get().getFeeMarket().getPerTxGaslimit())); + if (ExperimentalEIPs.eip1559Enabled && maybeEip1559.isPresent()) { + final EIP1559 eip1559 = maybeEip1559.get(); + if (!eip1559.isValidFormat(transaction, acceptedTransactionTypes)) { + return ValidationResult.invalid( + TransactionInvalidReason.INVALID_TRANSACTION_FORMAT, + String.format( + "transaction format is invalid, accepted transaction types are %s", + acceptedTransactionTypes.toString())); + } + if (!eip1559.isValidGasLimit(transaction)) { + return ValidationResult.invalid( + TransactionInvalidReason.EXCEEDS_PER_TRANSACTION_GAS_LIMIT, + String.format( + "transaction gas limit %s exceeds per transaction gas limit", + transaction.getGasLimit())); + } } final Gas intrinsicGasCost = gasCalculator.transactionIntrinsicGasCost(transaction); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java index 20f563848b0..7e8e00b81c9 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java @@ -17,6 +17,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.privacy.PrivateTransactionValidator; import java.math.BigInteger; @@ -35,6 +36,7 @@ public class ProtocolScheduleBuilder { private final Optional defaultChainId; private final PrivacyParameters privacyParameters; private final boolean isRevertReasonEnabled; + private final FeeMarket feeMarket = FeeMarket.eip1559(); public ProtocolScheduleBuilder( final GenesisConfigOptions config, @@ -171,6 +173,20 @@ public ProtocolSchedule createProtocolSchedule() { config.getEvmStackSize(), isRevertReasonEnabled, config)); + + addProtocolSpec( + protocolSchedule, + OptionalLong.of( + config + .getEIP1559BlockNumber() + .orElseThrow(() -> new RuntimeException("EIP-1559 must be enabled")) + + feeMarket.getDecayRange()), + MainnetProtocolSpecs.eip1559FinalizedDefinition( + chainId, + config.getContractSizeLimit(), + config.getEvmStackSize(), + isRevertReasonEnabled, + config)); } // specs for classic network diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/TransactionValidator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/TransactionValidator.java index 5107a4c46e9..5ad2b5b9fc4 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/TransactionValidator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/TransactionValidator.java @@ -71,6 +71,7 @@ enum TransactionInvalidReason { TX_SENDER_NOT_AUTHORIZED, CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE, EXCEEDS_PER_TRANSACTION_GAS_LIMIT, + INVALID_TRANSACTION_FORMAT, // Private Transaction Invalid Reasons PRIVATE_TRANSACTION_FAILED, PRIVATE_NONCE_TOO_LOW, diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java index 38a1301d279..9e341349a00 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/chain/GenesisStateTest.java @@ -16,6 +16,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import org.hyperledger.besu.config.experimental.ExperimentalEIPs; import org.hyperledger.besu.ethereum.core.Account; import org.hyperledger.besu.ethereum.core.Address; import org.hyperledger.besu.ethereum.core.BlockHeader; @@ -30,6 +31,7 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; import org.bouncycastle.util.encoders.Hex; +import org.junit.BeforeClass; import org.junit.Test; public final class GenesisStateTest { @@ -45,6 +47,11 @@ public final class GenesisStateTest { private static final String EXPECTED_CODE = "0x608060405260043610610116577c01000000000000000000000000000000000000000000000000000000006000350463025e7c278114610158578063173825d91461019e57806320ea8d86146101d15780632f54bf6e146101fb5780633411c81c14610242578063547415251461027b5780637065cb48146102c1578063784547a7146102f45780638b51d13f1461031e5780639ace38c214610348578063a0e67e2b14610415578063a8abe69a1461047a578063b5dc40c3146104ba578063b77bf600146104e4578063ba51a6df146104f9578063c01a8c8414610523578063c64274741461054d578063d74f8edd14610615578063dc8452cd1461062a578063e20056e61461063f578063ee22610b1461067a575b60003411156101565760408051348152905133917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c919081900360200190a25b005b34801561016457600080fd5b506101826004803603602081101561017b57600080fd5b50356106a4565b60408051600160a060020a039092168252519081900360200190f35b3480156101aa57600080fd5b50610156600480360360208110156101c157600080fd5b5035600160a060020a03166106cc565b3480156101dd57600080fd5b50610156600480360360208110156101f457600080fd5b503561083c565b34801561020757600080fd5b5061022e6004803603602081101561021e57600080fd5b5035600160a060020a03166108f6565b604080519115158252519081900360200190f35b34801561024e57600080fd5b5061022e6004803603604081101561026557600080fd5b5080359060200135600160a060020a031661090b565b34801561028757600080fd5b506102af6004803603604081101561029e57600080fd5b50803515159060200135151561092b565b60408051918252519081900360200190f35b3480156102cd57600080fd5b50610156600480360360208110156102e457600080fd5b5035600160a060020a0316610997565b34801561030057600080fd5b5061022e6004803603602081101561031757600080fd5b5035610abc565b34801561032a57600080fd5b506102af6004803603602081101561034157600080fd5b5035610b43565b34801561035457600080fd5b506103726004803603602081101561036b57600080fd5b5035610bb2565b6040518085600160a060020a0316600160a060020a031681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b838110156103d75781810151838201526020016103bf565b50505050905090810190601f1680156104045780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561042157600080fd5b5061042a610c70565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561046657818101518382015260200161044e565b505050509050019250505060405180910390f35b34801561048657600080fd5b5061042a6004803603608081101561049d57600080fd5b508035906020810135906040810135151590606001351515610cd3565b3480156104c657600080fd5b5061042a600480360360208110156104dd57600080fd5b5035610e04565b3480156104f057600080fd5b506102af610f75565b34801561050557600080fd5b506101566004803603602081101561051c57600080fd5b5035610f7b565b34801561052f57600080fd5b506101566004803603602081101561054657600080fd5b5035610ffa565b34801561055957600080fd5b506102af6004803603606081101561057057600080fd5b600160a060020a03823516916020810135918101906060810160408201356401000000008111156105a057600080fd5b8201836020820111156105b257600080fd5b803590602001918460018302840111640100000000831117156105d457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506110c5945050505050565b34801561062157600080fd5b506102af6110e4565b34801561063657600080fd5b506102af6110e9565b34801561064b57600080fd5b506101566004803603604081101561066257600080fd5b50600160a060020a03813581169160200135166110ef565b34801561068657600080fd5b506101566004803603602081101561069d57600080fd5b5035611289565b60038054829081106106b257fe5b600091825260209091200154600160a060020a0316905081565b3330146106d857600080fd5b600160a060020a038116600090815260026020526040902054819060ff16151561070157600080fd5b600160a060020a0382166000908152600260205260408120805460ff191690555b600354600019018110156107d75782600160a060020a031660038281548110151561074957fe5b600091825260209091200154600160a060020a031614156107cf5760038054600019810190811061077657fe5b60009182526020909120015460038054600160a060020a03909216918390811061079c57fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a031602179055506107d7565b600101610722565b506003805460001901906107eb9082611557565b5060035460045411156108045760035461080490610f7b565b604051600160a060020a038316907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a25050565b3360008181526002602052604090205460ff16151561085a57600080fd5b60008281526001602090815260408083203380855292529091205483919060ff16151561088657600080fd5b600084815260208190526040902060030154849060ff16156108a757600080fd5b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b60055481101561099057838015610958575060008181526020819052604090206003015460ff16155b8061097c575082801561097c575060008181526020819052604090206003015460ff165b15610988576001820191505b60010161092f565b5092915050565b3330146109a357600080fd5b600160a060020a038116600090815260026020526040902054819060ff16156109cb57600080fd5b81600160a060020a03811615156109e157600080fd5b600380549050600101600454603282111580156109fe5750818111155b8015610a0957508015155b8015610a1457508115155b1515610a1f57600080fd5b600160a060020a038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01805473ffffffffffffffffffffffffffffffffffffffff191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b600354811015610b3b5760008481526001602052604081206003805491929184908110610aea57fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff1615610b1e576001820191505b600454821415610b3357600192505050610b3e565b600101610ac1565b50505b919050565b6000805b600354811015610bac5760008381526001602052604081206003805491929184908110610b7057fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff1615610ba4576001820191505b600101610b47565b50919050565b6000602081815291815260409081902080546001808301546002808501805487516101009582161595909502600019011691909104601f8101889004880284018801909652858352600160a060020a0390931695909491929190830182828015610c5d5780601f10610c3257610100808354040283529160200191610c5d565b820191906000526020600020905b815481529060010190602001808311610c4057829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610cc857602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610caa575b505050505090505b90565b606080600554604051908082528060200260200182016040528015610d02578160200160208202803883390190505b5090506000805b600554811015610d8457858015610d32575060008181526020819052604090206003015460ff16155b80610d565750848015610d56575060008181526020819052604090206003015460ff165b15610d7c57808383815181101515610d6a57fe5b60209081029091010152600191909101905b600101610d09565b878703604051908082528060200260200182016040528015610db0578160200160208202803883390190505b5093508790505b86811015610df9578281815181101515610dcd57fe5b9060200190602002015184898303815181101515610de757fe5b60209081029091010152600101610db7565b505050949350505050565b606080600380549050604051908082528060200260200182016040528015610e36578160200160208202803883390190505b5090506000805b600354811015610eee5760008581526001602052604081206003805491929184908110610e6657fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff1615610ee6576003805482908110610ea157fe5b6000918252602090912001548351600160a060020a0390911690849084908110610ec757fe5b600160a060020a03909216602092830290910190910152600191909101905b600101610e3d565b81604051908082528060200260200182016040528015610f18578160200160208202803883390190505b509350600090505b81811015610f6d578281815181101515610f3657fe5b906020019060200201518482815181101515610f4e57fe5b600160a060020a03909216602092830290910190910152600101610f20565b505050919050565b60055481565b333014610f8757600080fd5b6003548160328211801590610f9c5750818111155b8015610fa757508015155b8015610fb257508115155b1515610fbd57600080fd5b60048390556040805184815290517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9181900360200190a1505050565b3360008181526002602052604090205460ff16151561101857600080fd5b6000828152602081905260409020548290600160a060020a0316151561103d57600080fd5b60008381526001602090815260408083203380855292529091205484919060ff161561106857600080fd5b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a36110be85611289565b5050505050565b60006110d2848484611444565b90506110dd81610ffa565b9392505050565b603281565b60045481565b3330146110fb57600080fd5b600160a060020a038216600090815260026020526040902054829060ff16151561112457600080fd5b600160a060020a038216600090815260026020526040902054829060ff161561114c57600080fd5b82600160a060020a038116151561116257600080fd5b60005b6003548110156111ee5785600160a060020a031660038281548110151561118857fe5b600091825260209091200154600160a060020a031614156111e657846003828154811015156111b357fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a031602179055506111ee565b600101611165565b50600160a060020a03808616600081815260026020526040808220805460ff1990811690915593881682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a2604051600160a060020a038516907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a25050505050565b3360008181526002602052604090205460ff1615156112a757600080fd5b60008281526001602090815260408083203380855292529091205483919060ff1615156112d357600080fd5b600084815260208190526040902060030154849060ff16156112f457600080fd5b6112fd85610abc565b156110be576000858152602081815260409182902060038101805460ff19166001908117909155815481830154600280850180548851601f6000199783161561010002979097019091169290920494850187900487028201870190975283815293956113cf95600160a060020a039093169491939283908301828280156113c55780601f1061139a576101008083540402835291602001916113c5565b820191906000526020600020905b8154815290600101906020018083116113a857829003601f168201915b5050505050611534565b156114045760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a261143c565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038101805460ff191690555b505050505050565b600083600160a060020a038116151561145c57600080fd5b60055460408051608081018252600160a060020a0388811682526020808301898152838501898152600060608601819052878152808452959095208451815473ffffffffffffffffffffffffffffffffffffffff1916941693909317835551600183015592518051949650919390926114dc926002850192910190611580565b50606091909101516003909101805460ff191691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b6000806040516020840160008287838a8c6187965a03f198975050505050505050565b81548183558181111561157b5760008381526020902061157b9181019083016115fe565b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106115c157805160ff19168380011785556115ee565b828001600101855582156115ee579182015b828111156115ee5782518255916020019190600101906115d3565b506115fa9291506115fe565b5090565b610cd091905b808211156115fa576000815560010161160456fea165627a7a7230582070d3c680a2cf749f81772e7fffa2883f27a13c65fcfff32190d7585b0c6f0ce40029"; + @BeforeClass + public static void initialize() { + ExperimentalEIPs.eip1559Enabled = false; + } + @Test public void createFromJsonWithAllocs() throws Exception { final GenesisState genesisState = diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/AcceptedTransactionTypesTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/AcceptedTransactionTypesTest.java new file mode 100644 index 00000000000..3078dfd77a0 --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/AcceptedTransactionTypesTest.java @@ -0,0 +1,74 @@ +/* + * 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.core; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hyperledger.besu.ethereum.core.AcceptedTransactionTypes.FEE_MARKET_TRANSACTIONS; +import static org.hyperledger.besu.ethereum.core.AcceptedTransactionTypes.FEE_MARKET_TRANSITIONAL_TRANSACTIONS; +import static org.hyperledger.besu.ethereum.core.AcceptedTransactionTypes.FRONTIER_TRANSACTIONS; + +import org.junit.Test; + +public class AcceptedTransactionTypesTest { + + @Test + public void givenFrontier_isFrontierAcceptedReturnsTrue() { + assertThat(FRONTIER_TRANSACTIONS.isFrontierAccepted()).isTrue(); + } + + @Test + public void givenFrontier_isEIP1559AcceptedReturnsFalse() { + assertThat(FRONTIER_TRANSACTIONS.isEIP1559Accepted()).isFalse(); + } + + @Test + public void givenTransitional_isFrontierAcceptedReturnsTrue() { + assertThat(FEE_MARKET_TRANSITIONAL_TRANSACTIONS.isFrontierAccepted()).isTrue(); + } + + @Test + public void givenTransitional_isEIP1559AcceptedReturnsTrue() { + assertThat(FEE_MARKET_TRANSITIONAL_TRANSACTIONS.isEIP1559Accepted()).isTrue(); + } + + @Test + public void givenEIP1559_isFrontierAcceptedReturnsFalse() { + assertThat(FEE_MARKET_TRANSACTIONS.isFrontierAccepted()).isFalse(); + } + + @Test + public void givenFrontier_isEIP1559AcceptedReturnsTrue() { + assertThat(FEE_MARKET_TRANSACTIONS.isEIP1559Accepted()).isTrue(); + } + + @Test + public void isEIP1559Accepted() {} + + @Test + public void testFrontierToString() { + assertThat(FRONTIER_TRANSACTIONS.toString()).isEqualTo("frontier: true / eip1559: false"); + } + + @Test + public void testTransitionalToString() { + assertThat(FEE_MARKET_TRANSITIONAL_TRANSACTIONS.toString()) + .isEqualTo("frontier: true / eip1559: true"); + } + + @Test + public void testEIP1559OnlyToString() { + assertThat(FEE_MARKET_TRANSACTIONS.toString()).isEqualTo("frontier: false / eip1559: true"); + } +} diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/fees/EIP1559Test.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/fees/EIP1559Test.java index c2bae3e6a12..45bb3558b8a 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/fees/EIP1559Test.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/fees/EIP1559Test.java @@ -15,9 +15,15 @@ package org.hyperledger.besu.ethereum.core.fees; import static org.assertj.core.api.Assertions.assertThat; +import static org.hyperledger.besu.ethereum.core.AcceptedTransactionTypes.FEE_MARKET_TRANSACTIONS; +import static org.hyperledger.besu.ethereum.core.AcceptedTransactionTypes.FEE_MARKET_TRANSITIONAL_TRANSACTIONS; +import static org.hyperledger.besu.ethereum.core.AcceptedTransactionTypes.FRONTIER_TRANSACTIONS; import org.hyperledger.besu.config.experimental.ExperimentalEIPs; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.rlp.RLP; +import org.apache.tuweni.bytes.Bytes; import org.junit.Before; import org.junit.Test; @@ -119,4 +125,52 @@ public void givenNotForkBlock_whenIsForkBlock_thenReturnsFalse() { public void getForkBlock() { assertThat(eip1559.getForkBlock()).isEqualTo(FORK_BLOCK); } + + @Test + public void givenValidLegacyTransaction_whenBeforeForkBlock_thenReturnsTrue() { + assertThat(eip1559.isValidFormat(TransactionFixture.LEGACY, FRONTIER_TRANSACTIONS)).isTrue(); + } + + @Test + public void givenValidLegacyTransaction_whenEIP1559Phase1_thenReturnsTrue() { + assertThat( + eip1559.isValidFormat(TransactionFixture.LEGACY, FEE_MARKET_TRANSITIONAL_TRANSACTIONS)) + .isTrue(); + } + + @Test + public void givenValidLegacyTransaction_whenEIP1559Finalized_thenReturnsFalse() { + assertThat(eip1559.isValidFormat(TransactionFixture.LEGACY, FEE_MARKET_TRANSACTIONS)).isFalse(); + } + + @Test + public void givenValidEIP1559Transaction_whenAfterForkBlock_thenReturnsTrue() { + assertThat( + eip1559.isValidFormat(TransactionFixture.EIP1559, FEE_MARKET_TRANSITIONAL_TRANSACTIONS)) + .isTrue(); + } + + @Test + public void givenValidEIP1559Transaction_whenEIP1559Finalized_thenReturnsTrue() { + assertThat(eip1559.isValidFormat(TransactionFixture.EIP1559, FEE_MARKET_TRANSACTIONS)).isTrue(); + } + + @Test + public void givenValidEIP1559Transaction_whenBeforeFork_thenReturnsFalse() { + assertThat(eip1559.isValidFormat(TransactionFixture.EIP1559, FRONTIER_TRANSACTIONS)).isFalse(); + } + + private static class TransactionFixture { + private static final Transaction LEGACY = + Transaction.readFrom( + RLP.input( + Bytes.fromHexString( + "0xf901fc8032830138808080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b561ca0c5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0a01221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884"))); + + private static final Transaction EIP1559 = + Transaction.readFrom( + RLP.input( + Bytes.fromHexString( + "0xf902028032830138808080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b5682020f8201711ca0c5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0a01221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884"))); + } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidatorTest.java index 78968152144..9461e04ade4 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidatorTest.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.config.experimental.ExperimentalEIPs; import org.hyperledger.besu.crypto.SECP256K1.KeyPair; +import org.hyperledger.besu.ethereum.core.AcceptedTransactionTypes; import org.hyperledger.besu.ethereum.core.Account; import org.hyperledger.besu.ethereum.core.Address; import org.hyperledger.besu.ethereum.core.Gas; @@ -31,6 +32,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.vm.GasCalculator; import java.math.BigInteger; @@ -48,6 +50,7 @@ public class MainnetTransactionValidatorTest { private static final KeyPair senderKeys = KeyPair.generate(); @Mock private GasCalculator gasCalculator; + final FeeMarket feeMarket = FeeMarket.eip1559(); private final Transaction basicTransaction = new TransactionTestFixture() @@ -235,10 +238,14 @@ public void shouldRejectTransactionIfGasLimitExceedsPerTransactionGasLimit() { ExperimentalEIPs.eip1559Enabled = true; final MainnetTransactionValidator validator = new MainnetTransactionValidator( - gasCalculator, false, Optional.empty(), Optional.of(eip1559)); + gasCalculator, + false, + Optional.empty(), + Optional.of(eip1559), + AcceptedTransactionTypes.FEE_MARKET_TRANSITIONAL_TRANSACTIONS); final Transaction transaction = new TransactionTestFixture() - .gasLimit(eip1559.getFeeMarket().getPerTxGaslimit() + 1) + .gasLimit(feeMarket.getPerTxGaslimit() + 1) .chainId(Optional.empty()) .createTransaction(senderKeys); assertThat(validator.validate(transaction)) @@ -248,6 +255,30 @@ public void shouldRejectTransactionIfGasLimitExceedsPerTransactionGasLimit() { ExperimentalEIPs.eip1559Enabled = false; } + @Test + public void shouldRejectTransactionIfLegacyAfterEIP1559Finalized() { + final long forkBlock = 845L; + final EIP1559 eip1559 = new EIP1559(forkBlock); + ExperimentalEIPs.eip1559Enabled = true; + final MainnetTransactionValidator validator = + new MainnetTransactionValidator( + gasCalculator, + false, + Optional.empty(), + Optional.of(eip1559), + AcceptedTransactionTypes.FEE_MARKET_TRANSACTIONS); + final Transaction transaction = + new TransactionTestFixture() + .gasLimit(feeMarket.getPerTxGaslimit() + 1) + .chainId(Optional.empty()) + .createTransaction(senderKeys); + assertThat(validator.validate(transaction)) + .isEqualTo( + ValidationResult.invalid( + TransactionValidator.TransactionInvalidReason.INVALID_TRANSACTION_FORMAT)); + ExperimentalEIPs.eip1559Enabled = false; + } + private Account accountWithNonce(final long nonce) { return account(basicTransaction.getUpfrontCost(), nonce); }