Skip to content

Commit

Permalink
fix: baseFee calculate
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkAfCod committed Jan 5, 2024
1 parent f146253 commit 60735b6
Show file tree
Hide file tree
Showing 15 changed files with 87 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public class OptimismConfigOptions {
* @return the EIP1559 elasticity
*/
public OptionalLong getEIP1559Elasticity() {
return JsonUtil.getLong(optimismConfigRoot, "eip1559Elasticity");
return JsonUtil.getLong(optimismConfigRoot, "eip1559elasticity");
}

/**
Expand All @@ -54,7 +54,7 @@ public OptionalLong getEIP1559Elasticity() {
* @return the EIP1559 denominator
*/
public OptionalLong getEIP1559Denominator() {
return JsonUtil.getLong(optimismConfigRoot, "eip1559Denominator");
return JsonUtil.getLong(optimismConfigRoot, "eip1559denominator");
}

/**
Expand All @@ -63,7 +63,7 @@ public OptionalLong getEIP1559Denominator() {
* @return the EIP1559 denominatorCanyon
*/
public OptionalLong getEIP1559DenominatorCanyon() {
return JsonUtil.getLong(optimismConfigRoot, "eip1559DenominatorCanyon");
return JsonUtil.getLong(optimismConfigRoot, "eip1559denominatorcanyon");
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.stream.LongStream;
import java.util.stream.Stream;

Expand Down Expand Up @@ -138,7 +139,8 @@ public JsonRpcResponse response(final JsonRpcRequestContext request) {
explicitlyRequestedBaseFees.get(
explicitlyRequestedBaseFees.size() - 1),
lastBlockHeader.getGasUsed(),
feeMarket.targetGasUsed(lastBlockHeader));
feeMarket.targetGasUsed(lastBlockHeader),
OptionalLong.of(chainHeadHeader.getTimestamp()));
})
.orElse(Wei.ZERO));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.concurrent.CancellationException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
Expand Down Expand Up @@ -445,7 +446,8 @@ private ProcessableBlockHeader createPendingBlockHeader(
newBlockNumber,
parentHeader.getBaseFee().orElse(Wei.ZERO),
parentHeader.getGasUsed(),
feeMarket.targetGasUsed(parentHeader)))
feeMarket.targetGasUsed(parentHeader),
OptionalLong.of(timestamp)))
.orElse(null);

final Bytes32 prevRandao = maybePrevRandao.orElse(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,8 @@ public Wei getEffectivePriorityFeePerGas(final Optional<Wei> maybeBaseFee) {
.map(
baseFee -> {
if (getType().supports1559FeeMarket()) {
if (baseFee.greaterOrEqualThan(getMaxFeePerGas().get())) {
if (getType().equals(TransactionType.OPTIMISM_DEPOSIT)
|| baseFee.greaterOrEqualThan(getMaxFeePerGas().get())) {
return Wei.ZERO;
}
return UInt256s.min(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;

import java.util.OptionalLong;

public class BaseFee {
private final Wei value;
private final Wei delta;
Expand All @@ -25,7 +27,7 @@ public class BaseFee {

public BaseFee(final BaseFeeMarket feeMarket, final Wei value) {
this.value = value;
this.delta = value.divide(feeMarket.getBasefeeMaxChangeDenominator());
this.delta = value.divide(feeMarket.getBasefeeMaxChangeDenominator(OptionalLong.empty()));
this.minNextValue = value.subtract(delta);
this.maxNextValue = value.add(delta);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/
package org.hyperledger.besu.ethereum.mainnet;

import org.hyperledger.besu.datatypes.TransactionType;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.core.Block;
Expand Down Expand Up @@ -59,6 +60,9 @@ boolean validateTransactionGasPrice(final Block block) {
.getTransactionPriceCalculator();

for (final Transaction transaction : transactions) {
if (transaction.getType().equals(TransactionType.OPTIMISM_DEPOSIT)) {
continue;
}
final Optional<Wei> baseFee = block.getHeader().getBaseFee();
final Wei price = transactionPriceCalculator.price(transaction, baseFee);
if (price.compareTo(baseFee.orElseThrow()) < 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,10 @@ static ProtocolSpecBuilder londonDefinition(
final BaseFeeMarket londonFeeMarket =
genesisConfigOptions.isZeroBaseFee()
? FeeMarket.zeroBaseFee(londonForkBlockNumber)
: FeeMarket.london(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas());
: FeeMarket.london(
londonForkBlockNumber,
genesisConfigOptions.getBaseFeePerGas(),
Optional.of(genesisConfigOptions));
return berlinDefinition(
chainId,
configContractSizeLimit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.BlockHeader;

import java.util.OptionalLong;

public interface BaseFeeMarket extends FeeMarket {

enum ValidationMode {
Expand All @@ -30,7 +32,7 @@ default boolean implementsBaseFee() {
return true;
}

long getBasefeeMaxChangeDenominator();
long getBasefeeMaxChangeDenominator(OptionalLong time);

Wei getInitialBasefee();

Expand All @@ -51,7 +53,8 @@ Wei computeBaseFee(
final long blockNumber,
final Wei parentBaseFee,
final long parentBlockGasUsed,
final long targetGasUsed);
final long targetGasUsed,
final OptionalLong time);

ValidationMode baseFeeValidationMode(final long blockNumber);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class CancunFeeMarket extends LondonFeeMarket {

public CancunFeeMarket(
final long londonForkBlockNumber, final Optional<Wei> baseFeePerGasOverride) {
super(londonForkBlockNumber, baseFeePerGasOverride);
super(londonForkBlockNumber, baseFeePerGasOverride, Optional.empty());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/
package org.hyperledger.besu.ethereum.mainnet.feemarket;

import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.datatypes.BlobGas;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.Transaction;
Expand All @@ -36,12 +37,14 @@ default boolean implementsDataFee() {
boolean satisfiesFloorTxFee(Transaction txn);

static BaseFeeMarket london(final long londonForkBlockNumber) {
return london(londonForkBlockNumber, Optional.empty());
return london(londonForkBlockNumber, Optional.empty(), Optional.empty());
}

static BaseFeeMarket london(
final long londonForkBlockNumber, final Optional<Wei> baseFeePerGasOverride) {
return new LondonFeeMarket(londonForkBlockNumber, baseFeePerGasOverride);
final long londonForkBlockNumber,
final Optional<Wei> baseFeePerGasOverride,
final Optional<GenesisConfigOptions> chainOptions) {
return new LondonFeeMarket(londonForkBlockNumber, baseFeePerGasOverride, chainOptions);
}

static BaseFeeMarket cancun(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
package org.hyperledger.besu.ethereum.mainnet.feemarket;

import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.feemarket.TransactionPriceCalculator;

import java.util.Optional;
import java.util.OptionalLong;

import org.apache.tuweni.units.bigints.UInt256s;
import org.slf4j.Logger;
Expand All @@ -39,28 +41,48 @@ public class LondonFeeMarket implements BaseFeeMarket {
private final long londonForkBlockNumber;
private final TransactionPriceCalculator txPriceCalculator;
private final Wei baseFeeFloor;
private final Optional<GenesisConfigOptions> chainOptions;

public LondonFeeMarket(final long londonForkBlockNumber) {
this(londonForkBlockNumber, Optional.empty());
this(londonForkBlockNumber, Optional.empty(), Optional.empty());
}

public LondonFeeMarket(
final long londonForkBlockNumber, final Optional<Wei> baseFeePerGasOverride) {
this(TransactionPriceCalculator.eip1559(), londonForkBlockNumber, baseFeePerGasOverride);
final long londonForkBlockNumber,
final Optional<Wei> baseFeePerGasOverride,
final Optional<GenesisConfigOptions> chainOptions) {
this(
TransactionPriceCalculator.eip1559(),
londonForkBlockNumber,
baseFeePerGasOverride,
chainOptions);
}

protected LondonFeeMarket(
final TransactionPriceCalculator txPriceCalculator,
final long londonForkBlockNumber,
final Optional<Wei> baseFeePerGasOverride) {
final Optional<Wei> baseFeePerGasOverride,
final Optional<GenesisConfigOptions> chainOptions) {
this.txPriceCalculator = txPriceCalculator;
this.londonForkBlockNumber = londonForkBlockNumber;
this.baseFeeInitialValue = baseFeePerGasOverride.orElse(DEFAULT_BASEFEE_INITIAL_VALUE);
this.baseFeeFloor = baseFeeInitialValue.isZero() ? Wei.ZERO : DEFAULT_BASEFEE_FLOOR;
this.chainOptions = chainOptions;
}

@Override
public long getBasefeeMaxChangeDenominator() {
public long getBasefeeMaxChangeDenominator(final OptionalLong time) {
if (time.isPresent() && this.chainOptions.isPresent()) {
if (this.chainOptions.get().isCanyon(time.getAsLong())) {
return chainOptions
.get()
.getOptimismConfigOptions()
.getEIP1559DenominatorCanyon()
.orElseThrow();
} else {
return chainOptions.get().getOptimismConfigOptions().getEIP1559Denominator().orElseThrow();
}
}
return DEFAULT_BASEFEE_MAX_CHANGE_DENOMINATOR;
}

Expand All @@ -71,6 +93,9 @@ public Wei getInitialBasefee() {

@Override
public long getSlackCoefficient() {
if (chainOptions.isPresent() && chainOptions.get().isOptimism()) {
return chainOptions.get().getOptimismConfigOptions().getEIP1559Elasticity().orElseThrow();
}
return DEFAULT_SLACK_COEFFICIENT;
}

Expand All @@ -94,7 +119,8 @@ public Wei computeBaseFee(
final long blockNumber,
final Wei parentBaseFee,
final long parentBlockGasUsed,
final long targetGasUsed) {
final long targetGasUsed,
final OptionalLong time) {
if (londonForkBlockNumber == blockNumber) {
return getInitialBasefee();
}
Expand All @@ -105,16 +131,16 @@ public Wei computeBaseFee(
return parentBaseFee;
} else if (parentBlockGasUsed > targetGasUsed) {
gasDelta = parentBlockGasUsed - targetGasUsed;
final long denominator = getBasefeeMaxChangeDenominator();
final long denominator = getBasefeeMaxChangeDenominator(time);
feeDelta =
UInt256s.max(
parentBaseFee.multiply(gasDelta).divide(targetGasUsed).divide(denominator), Wei.ONE);
baseFee = parentBaseFee.add(feeDelta);
} else {
gasDelta = targetGasUsed - parentBlockGasUsed;
final long denominator = getBasefeeMaxChangeDenominator();
final long denominator = getBasefeeMaxChangeDenominator(time);
feeDelta = parentBaseFee.multiply(gasDelta).divide(targetGasUsed).divide(denominator);
baseFee = parentBaseFee.subtract(feeDelta);
baseFee = UInt256s.max(parentBaseFee.subtract(feeDelta), Wei.ZERO);
}
LOG.trace(
"block #{} parentBaseFee: {} parentGasUsed: {} parentGasTarget: {} baseFee: {}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,21 @@
import org.hyperledger.besu.datatypes.Wei;

import java.util.Optional;
import java.util.OptionalLong;

public class ZeroBaseFeeMarket extends LondonFeeMarket {

public ZeroBaseFeeMarket(final long londonForkBlockNumber) {
super(londonForkBlockNumber, Optional.of(Wei.ZERO));
super(londonForkBlockNumber, Optional.of(Wei.ZERO), Optional.empty());
}

@Override
public Wei computeBaseFee(
final long blockNumber,
final Wei parentBaseFee,
final long parentBlockGasUsed,
final long targetGasUsed) {
final long targetGasUsed,
final OptionalLong time) {

return Wei.ZERO;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import org.hyperledger.besu.ethereum.mainnet.DetachedBlockHeaderValidationRule;
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;

import java.util.OptionalLong;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -59,7 +61,11 @@ public boolean validate(final BlockHeader header, final BlockHeader parent) {
final long targetGasUsed = baseFeeMarket.targetGasUsed(parent);
final Wei expectedBaseFee =
baseFeeMarket.computeBaseFee(
header.getNumber(), parentBaseFee, parent.getGasUsed(), targetGasUsed);
header.getNumber(),
parentBaseFee,
parent.getGasUsed(),
targetGasUsed,
OptionalLong.of(header.getTimestamp()));
if (!expectedBaseFee.equals(currentBaseFee)) {
LOG.info(
"Invalid block header: basefee {} does not equal expected basefee {}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.hyperledger.besu.ethereum.core.TransactionTestFixture;

import java.util.Optional;
import java.util.OptionalLong;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand All @@ -43,7 +44,7 @@ public void setUp() throws Exception {

@Test
public void getBasefeeMaxChangeDenominatorShouldUseLondonDefault() {
assertThat(zeroBaseFeeMarket.getBasefeeMaxChangeDenominator())
assertThat(zeroBaseFeeMarket.getBasefeeMaxChangeDenominator(OptionalLong.empty()))
.isEqualTo(LondonFeeMarket.DEFAULT_BASEFEE_MAX_CHANGE_DENOMINATOR);
}

Expand Down Expand Up @@ -100,7 +101,8 @@ public void satisfiesFloorTxCostWhenGasFeeIsZero() {

@Test
public void computeBaseFeeReturnsZero() {
assertThat(zeroBaseFeeMarket.computeBaseFee(1L, Wei.of(8), 1L, 2L)).isEqualTo(Wei.ZERO);
assertThat(zeroBaseFeeMarket.computeBaseFee(1L, Wei.of(8), 1L, 2L, OptionalLong.empty()))
.isEqualTo(Wei.ZERO);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import java.util.Comparator;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.function.BiFunction;
import java.util.function.Supplier;

Expand Down Expand Up @@ -137,7 +138,8 @@ private Wei calculateNextBlockBaseFee(final FeeMarket feeMarket, final BlockHead
blockHeader.getNumber() + 1,
blockHeader.getBaseFee().orElse(Wei.ZERO),
blockHeader.getGasUsed(),
baseFeeMarket.targetGasUsed(blockHeader));
baseFeeMarket.targetGasUsed(blockHeader),
OptionalLong.of(blockHeader.getTimestamp()));
}
return Wei.ZERO;
}
Expand Down

0 comments on commit 60735b6

Please sign in to comment.