Skip to content

Commit

Permalink
[EIP-1559] Step 7 - Check transaction format for send raw transaction (
Browse files Browse the repository at this point in the history
…hyperledger#694)

* Added changelog entries for PR:
- hyperledger#430
- hyperledger#440

Signed-off-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>

* Check transaction format for send raw transaction

Signed-off-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>

* Address PR comments

Signed-off-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>

* Address PR comments

Signed-off-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>

* remove EthSendRawTransactionTest.blokchainQueries field

Signed-off-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>
  • Loading branch information
AbdelStark authored Apr 10, 2020
1 parent 5655084 commit 5a5f4eb
Show file tree
Hide file tree
Showing 12 changed files with 313 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ public class EthSendRawTransactionTest {
private static final String VALID_TRANSACTION =
"0xf86d0485174876e800830222e0945aae326516b4f8fe08074b7e972e40a713048d62880de0b6b3a7640000801ba05d4e7998757264daab67df2ce6f7e7a0ae36910778a406ca73898c9899a32b9ea0674700d5c3d1d27f2e6b4469957dfd1a1c49bf92383d80717afc84eb05695d5b";
@Mock private TransactionPool transactionPool;

private EthSendRawTransaction method;

@Before
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -276,11 +276,10 @@ private boolean validatePerTransactionGasLimit(final Block block) {
final BlockBody body = block.getBody();
final List<Transaction> 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;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -345,7 +346,11 @@ static ProtocolSpecBuilder<Void> 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<Void> blockHeaderValidatorBuilder =
eip1559ProtocolSpecBuilder.getBlockHeaderValidatorBuilder();
Expand All @@ -355,6 +360,30 @@ static ProtocolSpecBuilder<Void> eip1559Definition(
return eip1559ProtocolSpecBuilder;
}

// TODO EIP-1559 change for the actual fork name when known
static ProtocolSpecBuilder<Void> eip1559FinalizedDefinition(
final Optional<BigInteger> 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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -43,23 +44,31 @@ public class MainnetTransactionValidator implements TransactionValidator {

private Optional<TransactionFilter> transactionFilter = Optional.empty();
private final Optional<EIP1559> maybeEip1559;
private final AcceptedTransactionTypes acceptedTransactionTypes;

public MainnetTransactionValidator(
final GasCalculator gasCalculator,
final boolean checkSignatureMalleability,
final Optional<BigInteger> 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<BigInteger> chainId,
final Optional<EIP1559> maybeEip1559) {
final Optional<EIP1559> maybeEip1559,
final AcceptedTransactionTypes acceptedTransactionTypes) {
this.gasCalculator = gasCalculator;
this.disallowSignatureMalleability = checkSignatureMalleability;
this.chainId = chainId;
this.maybeEip1559 = maybeEip1559;
this.acceptedTransactionTypes = acceptedTransactionTypes;
}

@Override
Expand All @@ -70,14 +79,22 @@ public ValidationResult<TransactionInvalidReason> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -35,6 +36,7 @@ public class ProtocolScheduleBuilder<C> {
private final Optional<BigInteger> defaultChainId;
private final PrivacyParameters privacyParameters;
private final boolean isRevertReasonEnabled;
private final FeeMarket feeMarket = FeeMarket.eip1559();

public ProtocolScheduleBuilder(
final GenesisConfigOptions config,
Expand Down Expand Up @@ -171,6 +173,20 @@ public ProtocolSchedule<C> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading

0 comments on commit 5a5f4eb

Please sign in to comment.