1559 blockchain reftests (#2374)

* allow transaction pool to accept transactions with maxFeePerGas less than base fee
* make 1559 fields return short hex format instead of 8 bytes zero padded
* update reference tests to latest

Signed-off-by: garyschulte <garyschulte@gmail.com>
pull/2379/head
garyschulte 4 years ago committed by GitHub
parent 75c7e204d0
commit e90cef0f6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 4
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionCompleteResult.java
  3. 22
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionCompleteResultTest.java
  4. 2
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/graphql/eth_getBalance_invalidAccountBlockNumber.json
  5. 2
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/graphql/eth_getBalance_invalidAccountLatest.json
  6. 5
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Difficulty.java
  7. 5
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Wei.java
  8. 1
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasLimitRangeAndDeltaValidationRule.java
  9. 2
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockDataGenerator.java
  10. 9
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/BlockHeaderTestFixture.java
  11. 31
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidatorTest.java
  12. 4
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasLimitRangeAndDeltaValidationRuleTest.java
  13. 2
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java
  14. 2
      ethereum/referencetests/build.gradle
  15. 2
      ethereum/referencetests/src/test/resources
  16. 2
      plugin-api/build.gradle
  17. 7
      plugin-api/src/main/java/org/hyperledger/besu/plugin/data/Quantity.java

@ -3,6 +3,7 @@
## 21.7.0-RC1
### Additions and Improvements
- eip-1559 changes: accept transactions which have maxFeePerGas below current baseFee [\#2374](https://github.com/hyperledger/besu/pull/2374)
### Bug Fixes

@ -99,9 +99,9 @@ public class TransactionCompleteResult implements TransactionResult {
this.from = transaction.getSender().toString();
this.gas = Quantity.create(transaction.getGasLimit());
this.maxPriorityFeePerGas =
tx.getTransaction().getMaxPriorityFeePerGas().map(q -> q.toHexString()).orElse(null);
tx.getTransaction().getMaxPriorityFeePerGas().map(q -> q.toShortHexString()).orElse(null);
this.maxFeePerGas =
tx.getTransaction().getMaxFeePerGas().map(q -> q.toHexString()).orElse(null);
tx.getTransaction().getMaxFeePerGas().map(q -> q.toShortHexString()).orElse(null);
this.gasPrice = Quantity.create(transaction.getGasPrice());
this.hash = transaction.getHash().toString();
this.input = transaction.getPayload().toString();

@ -20,14 +20,36 @@ import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata;
import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
import org.hyperledger.besu.ethereum.core.Hash;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionTestFixture;
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.plugin.data.TransactionType;
import java.util.Optional;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
public class TransactionCompleteResultTest {
@Test
public void eip1559TransactionWithShortWeiVals() {
final BlockDataGenerator gen = new BlockDataGenerator();
TransactionCompleteResult zeroPriorityFeeTx =
new TransactionCompleteResult(
new TransactionWithMetadata(
new TransactionTestFixture()
.maxFeePerGas(Optional.of(Wei.ONE))
.maxPriorityFeePerGas(Optional.of(Wei.ZERO))
.createTransaction(gen.generateKeyPair()),
0L,
Hash.ZERO,
0));
assertThat(zeroPriorityFeeTx.getMaxFeePerGas()).isEqualTo("0x1");
assertThat(zeroPriorityFeeTx.getMaxPriorityFeePerGas()).isEqualTo("0x0");
}
@Test
public void eip1559TransactionFields() {
final BlockDataGenerator gen = new BlockDataGenerator();

@ -3,7 +3,7 @@
"response": {
"data" : {
"account" : {
"balance" : "0x"
"balance" : "0x0"
}
}
},

@ -82,6 +82,11 @@ public final class Difficulty extends BaseUInt256Value<Difficulty> implements Qu
return super.toHexString();
}
@Override
public String toShortHexString() {
return super.isZero() ? "0x0" : super.toShortHexString();
}
@Override
public Difficulty copy() {
return super.copy();

@ -87,4 +87,9 @@ public final class Wei extends BaseUInt256Value<Wei> implements Quantity {
public String toHexString() {
return super.toHexString();
}
@Override
public String toShortHexString() {
return super.isZero() ? "0x0" : super.toShortHexString();
}
}

@ -67,6 +67,7 @@ public class GasLimitRangeAndDeltaValidationRule extends AbstractGasLimitSpecifi
final long difference = Math.abs(parentGasLimit - gasLimit);
final long bounds = deltaBound(parentGasLimit);
// this is an exclusive bound, so the difference should be strictly less:
if (Long.compareUnsigned(difference, bounds) >= 0) {
LOG.info(
"Invalid block header: gas limit delta {} is out of bounds of {}", difference, bounds);

@ -582,7 +582,7 @@ public class BlockDataGenerator {
return bytes;
}
private KeyPair generateKeyPair() {
public KeyPair generateKeyPair() {
final java.security.KeyPair rawKeyPair = keyPairGenerator.generateKeyPair();
final BCECPrivateKey privateKey = (BCECPrivateKey) rawKeyPair.getPrivate();
final BCECPublicKey publicKey = (BCECPublicKey) rawKeyPair.getPublic();

@ -16,6 +16,8 @@ package org.hyperledger.besu.ethereum.core;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
public class BlockHeaderTestFixture {
@ -33,6 +35,7 @@ public class BlockHeaderTestFixture {
private long number = 0;
private long gasLimit = 0;
private Optional<Long> baseFee = Optional.empty();
private long gasUsed = 0;
private long timestamp = 0;
private Bytes extraData = Bytes.EMPTY;
@ -54,6 +57,7 @@ public class BlockHeaderTestFixture {
builder.number(number);
builder.gasLimit(gasLimit);
builder.gasUsed(gasUsed);
baseFee.ifPresent(builder::baseFee);
builder.timestamp(timestamp);
builder.extraData(extraData);
builder.mixHash(mixHash);
@ -118,6 +122,11 @@ public class BlockHeaderTestFixture {
return this;
}
public BlockHeaderTestFixture baseFee(final long baseFee) {
this.baseFee = Optional.of(baseFee);
return this;
}
public BlockHeaderTestFixture timestamp(final long timestamp) {
this.timestamp = timestamp;
return this;

@ -387,14 +387,15 @@ public class MainnetTransactionValidatorTest {
gasCalculator,
Optional.of(transactionPriceCalculator),
false,
Optional.empty(),
Optional.of(BigInteger.ONE),
Set.of(TransactionType.FRONTIER, TransactionType.EIP1559),
defaultGoQuorumCompatibilityMode);
final Transaction transaction =
new TransactionTestFixture()
.maxPriorityFeePerGas(Optional.of(Wei.of(1)))
.maxFeePerGas(Optional.of(Wei.of(1)))
.chainId(Optional.empty())
.type(TransactionType.EIP1559)
.chainId(Optional.of(BigInteger.ONE))
.createTransaction(senderKeys);
final Optional<Long> basefee = Optional.of(150000L);
when(gasCalculator.transactionIntrinsicGasCostAndAccessedState(transaction))
@ -404,6 +405,32 @@ public class MainnetTransactionValidatorTest {
assertThat(validator.validate(transaction, basefee)).isEqualTo(ValidationResult.valid());
}
@Test
public void shouldValidate1559TransactionWithPriceLowerThanBaseFee() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
Optional.of(TransactionPriceCalculator.eip1559()),
false,
Optional.of(BigInteger.ONE),
Set.of(TransactionType.FRONTIER, TransactionType.EIP1559),
defaultGoQuorumCompatibilityMode);
final Transaction transaction =
new TransactionTestFixture()
.maxPriorityFeePerGas(Optional.of(Wei.of(1)))
.maxFeePerGas(Optional.of(Wei.of(1)))
.type(TransactionType.EIP1559)
.chainId(Optional.of(BigInteger.ONE))
.createTransaction(senderKeys);
when(gasCalculator.transactionIntrinsicGasCostAndAccessedState(transaction))
.thenReturn(new GasAndAccessedState(Gas.of(50)));
// validate without basefee is an adding to transaction pool case
// rather than a transaction processing case
assertThat(validator.validate(transaction, Optional.empty()))
.isEqualTo(ValidationResult.valid());
}
@Test
public void goQuorumCompatibilityModeRejectNonZeroGasPrice() {
final MainnetTransactionValidator validator =

@ -55,9 +55,9 @@ public class GasLimitRangeAndDeltaValidationRuleTest {
{4093, 4096, new GasLimitRangeAndDeltaValidationRule(4000, 4200), true},
// In Range, ,1/1024 change = valid,
{4092, 4096, new GasLimitRangeAndDeltaValidationRule(4000, 4200), false},
// In Range, >1/1024 change = invalid,
// In Range, == 1/1024 change = invalid,
{4100, 4096, new GasLimitRangeAndDeltaValidationRule(4000, 4200), false}
// In Range, >1/1024 change = invalid,
// In Range, == 1/1024 change = invalid,
});
}

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

@ -41,7 +41,7 @@ task ('validateReferenceTestSubmodule') {
description = "Checks that the reference tests submodule is not accidentally changed"
doLast {
def result = new ByteArrayOutputStream()
def expectedHash = '4d539de6788147a0376b70f2bc71a8f818872164'
def expectedHash = '4662cd89590d75e5af012cd57f1ca4271ab53e0d'
def submodulePath = java.nio.file.Path.of("${rootProject.projectDir}", "ethereum/referencetests/src/test/resources").toAbsolutePath()
try {
exec {

@ -1 +1 @@
Subproject commit 4d539de6788147a0376b70f2bc71a8f818872164
Subproject commit 4662cd89590d75e5af012cd57f1ca4271ab53e0d

@ -64,7 +64,7 @@ Calculated : ${currentHash}
tasks.register('checkAPIChanges', FileStateChecker) {
description = "Checks that the API for the Plugin-API project does not change without deliberate thought"
files = sourceSets.main.allJava.files
knownHash = 'hS/pEDa9mV5gqekY7f00rDxan6OC99cr/pMSx1rCQvI='
knownHash = 'IFz5V3JG2AEZo9wCv6hEh5HugU5Afd0JfPe50cygvqo='
}
check.dependsOn('checkAPIChanges')

@ -43,4 +43,11 @@ public interface Quantity {
* @return This value represented as hexadecimal, starting with "0x".
*/
String toHexString();
/**
* The value as a hexadecimal string with leading zeros truncated.
*
* @return This value represented as hexadecimal, starting with "0x".
*/
String toShortHexString();
}

Loading…
Cancel
Save