Use gasLimit for EIP1559 (#2244)

Signed-off-by: Karim TAAM <karim.t2am@gmail.com>
pull/2290/head
matkt 4 years ago committed by GitHub
parent adb5c3a300
commit 09a49cfd2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/BlockHeaderValidationRulesetFactory.java
  2. 3
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java
  3. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/fees/EIP1559.java
  4. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractGasLimitSpecification.java
  5. 8
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockHeaderValidator.java
  6. 20
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasLimitRangeAndDeltaValidationRule.java
  7. 19
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasUsageValidationRule.java
  8. 103
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/GasLimitElasticityValidationRuleTest.java

@ -37,6 +37,8 @@ import java.util.Optional;
public class BlockHeaderValidationRulesetFactory { public class BlockHeaderValidationRulesetFactory {
private static final int MIN_GAS_LIMIT = 5000;
/** /**
* Creates a set of rules which when executed will determine if a given block header is valid with * Creates a set of rules which when executed will determine if a given block header is valid with
* respect to its parent (or chain). * respect to its parent (or chain).
@ -56,9 +58,11 @@ public class BlockHeaderValidationRulesetFactory {
final BlockHeaderValidator.Builder builder = final BlockHeaderValidator.Builder builder =
new BlockHeaderValidator.Builder() new BlockHeaderValidator.Builder()
.addRule(new AncestryValidationRule()) .addRule(new AncestryValidationRule())
.addRule(new GasLimitRangeAndDeltaValidationRule(5000, 0x7fffffffffffffffL))
.addRule(new TimestampBoundedByFutureParameter(10)) .addRule(new TimestampBoundedByFutureParameter(10))
.addRule(new TimestampMoreRecentThanParent(secondsBetweenBlocks)) .addRule(new TimestampMoreRecentThanParent(secondsBetweenBlocks))
.addRule(
new GasLimitRangeAndDeltaValidationRule(
MIN_GAS_LIMIT, 0x7fffffffffffffffL, eip1559))
.addRule( .addRule(
new ConstantFieldValidationRule<>("MixHash", BlockHeader::getMixHash, Hash.ZERO)) new ConstantFieldValidationRule<>("MixHash", BlockHeader::getMixHash, Hash.ZERO))
.addRule( .addRule(
@ -72,7 +76,8 @@ public class BlockHeaderValidationRulesetFactory {
if (ExperimentalEIPs.eip1559Enabled && eip1559.isPresent()) { if (ExperimentalEIPs.eip1559Enabled && eip1559.isPresent()) {
builder builder
.addRule((new EIP1559BlockHeaderGasPriceValidationRule(eip1559.get()))) .addRule((new EIP1559BlockHeaderGasPriceValidationRule(eip1559.get())))
.addRule(new GasUsageValidationRule(eip1559)); .addRule(new GasUsageValidationRule());
} else { } else {
builder.addRule(new GasUsageValidationRule()); builder.addRule(new GasUsageValidationRule());
} }

@ -260,7 +260,7 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
private ProcessableBlockHeader createPendingBlockHeader(final long timestamp) { private ProcessableBlockHeader createPendingBlockHeader(final long timestamp) {
final long newBlockNumber = parentHeader.getNumber() + 1; final long newBlockNumber = parentHeader.getNumber() + 1;
final long gasLimit = gasLimitCalculator.nextGasLimit(parentHeader.getGasLimit()); long gasLimit = gasLimitCalculator.nextGasLimit(parentHeader.getGasLimit());
final DifficultyCalculator difficultyCalculator = protocolSpec.getDifficultyCalculator(); final DifficultyCalculator difficultyCalculator = protocolSpec.getDifficultyCalculator();
final BigInteger difficulty = final BigInteger difficulty =
difficultyCalculator.nextDifficulty(timestamp, parentHeader, protocolContext); difficultyCalculator.nextDifficulty(timestamp, parentHeader, protocolContext);
@ -269,6 +269,7 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
if (ExperimentalEIPs.eip1559Enabled && protocolSpec.isEip1559()) { if (ExperimentalEIPs.eip1559Enabled && protocolSpec.isEip1559()) {
final EIP1559 eip1559 = protocolSpec.getEip1559().orElseThrow(); final EIP1559 eip1559 = protocolSpec.getEip1559().orElseThrow();
if (eip1559.isForkBlock(newBlockNumber)) { if (eip1559.isForkBlock(newBlockNumber)) {
gasLimit = gasLimit * eip1559.getFeeMarket().getSlackCoefficient();
baseFee = eip1559.getFeeMarket().getInitialBasefee(); baseFee = eip1559.getFeeMarket().getInitialBasefee();
} else { } else {
baseFee = baseFee =

@ -100,7 +100,7 @@ public class EIP1559 {
public long targetGasUsed(final BlockHeader header) { public long targetGasUsed(final BlockHeader header) {
guardActivation(); guardActivation();
return header.getGasLimit(); return header.getGasLimit() / getFeeMarket().getSlackCoefficient();
} }
public FeeMarket getFeeMarket() { public FeeMarket getFeeMarket() {

@ -33,7 +33,7 @@ public abstract class AbstractGasLimitSpecification {
this.maxGasLimit = maxGasLimit; this.maxGasLimit = maxGasLimit;
} }
protected static long deltaBound(final long currentGasLimit) { public static long deltaBound(final long currentGasLimit) {
return Long.divideUnsigned(currentGasLimit, GAS_LIMIT_BOUND_DIVISOR); return Long.divideUnsigned(currentGasLimit, GAS_LIMIT_BOUND_DIVISOR);
} }
} }

@ -27,6 +27,8 @@ import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.ProofOfWorkVa
import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.TimestampBoundedByFutureParameter; import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.TimestampBoundedByFutureParameter;
import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.TimestampMoreRecentThanParent; import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.TimestampMoreRecentThanParent;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
public final class MainnetBlockHeaderValidator { public final class MainnetBlockHeaderValidator {
@ -122,6 +124,9 @@ public final class MainnetBlockHeaderValidator {
.addRule(CalculatedDifficultyValidationRule::new) .addRule(CalculatedDifficultyValidationRule::new)
.addRule(new AncestryValidationRule()) .addRule(new AncestryValidationRule())
.addRule(new GasUsageValidationRule()) .addRule(new GasUsageValidationRule())
.addRule(
new GasLimitRangeAndDeltaValidationRule(
MIN_GAS_LIMIT, Long.MAX_VALUE, Optional.of(eip1559)))
.addRule(new TimestampMoreRecentThanParent(MINIMUM_SECONDS_SINCE_PARENT)) .addRule(new TimestampMoreRecentThanParent(MINIMUM_SECONDS_SINCE_PARENT))
.addRule(new TimestampBoundedByFutureParameter(TIMESTAMP_TOLERANCE_S)) .addRule(new TimestampBoundedByFutureParameter(TIMESTAMP_TOLERANCE_S))
.addRule(new ExtraDataMaxLengthValidationRule(BlockHeader.MAX_EXTRA_DATA_BYTES)) .addRule(new ExtraDataMaxLengthValidationRule(BlockHeader.MAX_EXTRA_DATA_BYTES))
@ -136,6 +141,9 @@ public final class MainnetBlockHeaderValidator {
.addRule(CalculatedDifficultyValidationRule::new) .addRule(CalculatedDifficultyValidationRule::new)
.addRule(new AncestryValidationRule()) .addRule(new AncestryValidationRule())
.addRule(new GasUsageValidationRule()) .addRule(new GasUsageValidationRule())
.addRule(
new GasLimitRangeAndDeltaValidationRule(
MIN_GAS_LIMIT, Long.MAX_VALUE, Optional.of(eip1559)))
.addRule(new TimestampMoreRecentThanParent(MINIMUM_SECONDS_SINCE_PARENT)) .addRule(new TimestampMoreRecentThanParent(MINIMUM_SECONDS_SINCE_PARENT))
.addRule(new ExtraDataMaxLengthValidationRule(BlockHeader.MAX_EXTRA_DATA_BYTES)) .addRule(new ExtraDataMaxLengthValidationRule(BlockHeader.MAX_EXTRA_DATA_BYTES))
.addRule( .addRule(

@ -15,9 +15,12 @@
package org.hyperledger.besu.ethereum.mainnet.headervalidationrules; package org.hyperledger.besu.ethereum.mainnet.headervalidationrules;
import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.fees.EIP1559;
import org.hyperledger.besu.ethereum.mainnet.AbstractGasLimitSpecification; import org.hyperledger.besu.ethereum.mainnet.AbstractGasLimitSpecification;
import org.hyperledger.besu.ethereum.mainnet.DetachedBlockHeaderValidationRule; import org.hyperledger.besu.ethereum.mainnet.DetachedBlockHeaderValidationRule;
import java.util.Optional;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -31,8 +34,16 @@ public class GasLimitRangeAndDeltaValidationRule extends AbstractGasLimitSpecifi
private static final Logger LOG = LogManager.getLogger(GasLimitRangeAndDeltaValidationRule.class); private static final Logger LOG = LogManager.getLogger(GasLimitRangeAndDeltaValidationRule.class);
public GasLimitRangeAndDeltaValidationRule(final long minGasLimit, final long maxGasLimit) { private final Optional<EIP1559> eip1559;
public GasLimitRangeAndDeltaValidationRule(
final long minGasLimit, final long maxGasLimit, final Optional<EIP1559> eip1559) {
super(minGasLimit, maxGasLimit); super(minGasLimit, maxGasLimit);
this.eip1559 = eip1559;
}
public GasLimitRangeAndDeltaValidationRule(final long minGasLimit, final long maxGasLimit) {
this(minGasLimit, maxGasLimit, Optional.empty());
} }
@Override @Override
@ -48,7 +59,12 @@ public class GasLimitRangeAndDeltaValidationRule extends AbstractGasLimitSpecifi
return false; return false;
} }
final long parentGasLimit = parent.getGasLimit(); long parentGasLimit = parent.getGasLimit();
if (eip1559.isPresent() && eip1559.get().isForkBlock(header.getNumber())) {
parentGasLimit = parent.getGasLimit() * eip1559.get().getFeeMarket().getSlackCoefficient();
}
final long difference = Math.abs(parentGasLimit - gasLimit); final long difference = Math.abs(parentGasLimit - gasLimit);
final long bounds = deltaBound(parentGasLimit); final long bounds = deltaBound(parentGasLimit);
if (Long.compareUnsigned(difference, bounds) >= 0) { if (Long.compareUnsigned(difference, bounds) >= 0) {

@ -15,11 +15,8 @@
package org.hyperledger.besu.ethereum.mainnet.headervalidationrules; package org.hyperledger.besu.ethereum.mainnet.headervalidationrules;
import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.fees.EIP1559;
import org.hyperledger.besu.ethereum.mainnet.DetachedBlockHeaderValidationRule; import org.hyperledger.besu.ethereum.mainnet.DetachedBlockHeaderValidationRule;
import java.util.Optional;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -31,23 +28,11 @@ public class GasUsageValidationRule implements DetachedBlockHeaderValidationRule
private static final Logger LOG = LogManager.getLogger(); private static final Logger LOG = LogManager.getLogger();
private final Optional<EIP1559> eip1559; public GasUsageValidationRule() {}
public GasUsageValidationRule() {
this.eip1559 = Optional.empty();
}
public GasUsageValidationRule(final Optional<EIP1559> eip1559) {
this.eip1559 = eip1559;
}
@Override @Override
public boolean validate(final BlockHeader header, final BlockHeader parent) { public boolean validate(final BlockHeader header, final BlockHeader parent) {
long slackCoefficient = 1; if (header.getGasUsed() > header.getGasLimit()) {
if (eip1559.isPresent() && eip1559.get().isEIP1559(header.getNumber())) {
slackCoefficient = eip1559.get().getFeeMarket().getSlackCoefficient();
}
if (header.getGasUsed() > (header.getGasLimit() * slackCoefficient)) {
LOG.info( LOG.info(
"Invalid block header: gas used {} exceeds gas limit {}", "Invalid block header: gas used {} exceeds gas limit {}",
header.getGasUsed(), header.getGasUsed(),

@ -0,0 +1,103 @@
/*
* 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 java.lang.Long.MAX_VALUE;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.config.experimental.ExperimentalEIPs;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.fees.EIP1559;
import java.util.Arrays;
import java.util.Collection;
import java.util.Optional;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class GasLimitElasticityValidationRuleTest {
private static final Optional<EIP1559> EIP1559 = Optional.of(new EIP1559(10));
@Parameter public long headerGasLimit;
@Parameter(1)
public long parentGasLimit;
@Parameterized.Parameter(2)
public long headerNumber;
@Parameter(3)
public boolean expectedResult;
public GasLimitRangeAndDeltaValidationRule uut =
new GasLimitRangeAndDeltaValidationRule(5000, MAX_VALUE, EIP1559);
@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(
new Object[][] {
{20000000, 10000000, 10, true},
{20019530, 10000000, 10, true},
{20019531, 10000000, 10, false},
{19980470, 10000000, 10, true},
{19980469, 10000000, 10, false},
{20000000, 20000000, 11, true},
{20019530, 20000000, 11, true},
{20019531, 20000000, 11, false},
{19980470, 20000000, 11, true},
{19980469, 20000000, 11, false},
{40039061, 40000000, 11, true},
{40039062, 40000000, 11, false},
{39960939, 40000000, 11, true},
{39960938, 40000000, 11, false},
{4999, 40000000, 11, false}
});
}
@BeforeClass
public static void initialize() {
ExperimentalEIPs.eip1559Enabled = true;
}
@AfterClass
public static void reset() {
ExperimentalEIPs.eip1559Enabled = ExperimentalEIPs.EIP1559_ENABLED_DEFAULT_VALUE;
}
@Test
public void test() {
final BlockHeaderTestFixture blockHeaderBuilder = new BlockHeaderTestFixture();
blockHeaderBuilder.number(headerNumber);
blockHeaderBuilder.gasLimit(headerGasLimit);
final BlockHeader header = blockHeaderBuilder.buildHeader();
blockHeaderBuilder.number(headerNumber - 1);
blockHeaderBuilder.gasLimit(parentGasLimit);
final BlockHeader parent = blockHeaderBuilder.buildHeader();
assertThat(uut.validate(header, parent)).isEqualTo(expectedResult);
}
}
Loading…
Cancel
Save