Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

prague fee market for blob gas #8064

Merged
merged 2 commits into from
Dec 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
Expand Down Expand Up @@ -323,8 +322,7 @@ private void mockBlockWithBlobTransaction(final Hash blockHash, final long block
}

private void mockProtocolSpec(final BlockHeader blockHeader) {
FeeMarket feeMarket = mock(CancunFeeMarket.class);
when(feeMarket.blobGasPricePerGas(any())).thenCallRealMethod();
FeeMarket feeMarket = new CancunFeeMarket(0, Optional.empty());
ProtocolSpec spec = mock(ProtocolSpec.class);
when(spec.getFeeMarket()).thenReturn(feeMarket);
when(spec.getGasCalculator()).thenReturn(new CancunGasCalculator());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,18 @@ static ProtocolSpecBuilder pragueDefinition(
final java.util.function.Supplier<GasCalculator> pragueGasCalcSupplier =
() -> new PragueGasCalculator(pragueBlobSchedule.getTarget());

final BaseFeeMarket pragueFeeMarket;
if (genesisConfigOptions.isZeroBaseFee()) {
pragueFeeMarket = FeeMarket.zeroBaseFee(londonForkBlockNumber);
} else if (genesisConfigOptions.isFixedBaseFee()) {
pragueFeeMarket =
FeeMarket.fixedBaseFee(
londonForkBlockNumber, miningConfiguration.getMinTransactionGasPrice());
} else {
pragueFeeMarket =
FeeMarket.prague(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas());
}

return cancunDefinition(
chainId,
enableRevertReason,
Expand All @@ -823,6 +835,7 @@ static ProtocolSpecBuilder pragueDefinition(
miningConfiguration,
isParallelTxProcessingEnabled,
metricsSystem)
.feeMarket(pragueFeeMarket)
.gasCalculator(pragueGasCalcSupplier)
// EIP-7840 Blob schedule | EIP-7691 6/9 blob increase
.gasLimitCalculatorBuilder(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

public class CancunFeeMarket extends LondonFeeMarket {
private static final Logger LOG = LoggerFactory.getLogger(CancunFeeMarket.class);
private static final BigInteger BLOB_GAS_PRICE = BigInteger.ONE;
protected static final BigInteger BLOB_GAS_PRICE = BigInteger.ONE;
private static final BigInteger BLOB_GAS_PRICE_UPDATE_FRACTION = BigInteger.valueOf(3338477);

public CancunFeeMarket(
Expand Down Expand Up @@ -53,7 +53,7 @@ public Wei blobGasPricePerGas(final BlobGas excessBlobGas) {
return blobGasPrice;
}

private BigInteger fakeExponential(
protected BigInteger fakeExponential(
final BigInteger factor, final BigInteger numerator, final BigInteger denominator) {
int i = 1;
BigInteger output = BigInteger.ZERO;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ static BaseFeeMarket cancun(
return new CancunFeeMarket(londonForkBlockNumber, baseFeePerGasOverride);
}

static BaseFeeMarket prague(
final long londonForkBlockNumber, final Optional<Wei> baseFeePerGasOverride) {
return new PragueFeeMarket(londonForkBlockNumber, baseFeePerGasOverride);
}

static BaseFeeMarket zeroBaseFee(final long londonForkBlockNumber) {
return new ZeroBaseFeeMarket(londonForkBlockNumber);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright contributors to Besu.
*
* 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.feemarket;

import org.hyperledger.besu.datatypes.BlobGas;
import org.hyperledger.besu.datatypes.Wei;

import java.math.BigInteger;
import java.util.Optional;

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

public class PragueFeeMarket extends CancunFeeMarket {
private static final BigInteger BLOB_BASE_FEE_UPDATE_FRACTION_ELECTRA =
BigInteger.valueOf(5007716);
private static final Logger LOG = LoggerFactory.getLogger(PragueFeeMarket.class);

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

@Override
public Wei blobGasPricePerGas(final BlobGas excessBlobGas) {
final var blobGasPrice =
Wei.of(
fakeExponential(
BLOB_GAS_PRICE,
excessBlobGas.toBigInteger(),
BLOB_BASE_FEE_UPDATE_FRACTION_ELECTRA));
LOG.atTrace()
.setMessage("parentExcessBlobGas: {} blobGasPrice: {}")
.addArgument(excessBlobGas::toShortHexString)
.addArgument(blobGasPrice::toHexString)
.log();

return blobGasPrice;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright contributors to Hyperledger Besu.
*
* 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.feemarket;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.hyperledger.besu.datatypes.BlobGas;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.junit.jupiter.api.Test;

class PragueFeeMarketTest {

private static final int BLOB_GAS_PER_BLOB = 131072;

/**
* from: https://eips.ethereum.org/EIPS/eip-7691 The BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE value in
* this EIP is chosen as the mid-point between keeping the responsiveness to full blobs and no
* blobs constant:
*
* <p>full blobs: basefee increases by ~8.2% no blobs: basefee decreases by ~14.5%
*/
@Test
void dataPricePerGas() {
PragueFeeMarket pragueFeeMarket = new PragueFeeMarket(0, Optional.empty());
// when no excess blob gas, data price per gas is 1
assertEquals(1, pragueFeeMarket.blobGasPricePerGas(BlobGas.ZERO).getAsBigInteger().intValue());

record BlobGasPricing(long excess, long price) {}
List<BlobGasPricing> testVector = new ArrayList<>();

int numBlobs = 1;
long price = 1;
while (price <= 1000) {
price = blobGasPrice(BlobGas.of(numBlobs * BLOB_GAS_PER_BLOB));
var testCase = new BlobGasPricing(numBlobs * BLOB_GAS_PER_BLOB, price);
testVector.add(testCase);
numBlobs++;
}

testVector.stream()
.forEach(
blobGasPricing -> {
assertEquals(
blobGasPricing.price,
pragueFeeMarket
.blobGasPricePerGas(BlobGas.of(blobGasPricing.excess))
.getAsBigInteger()
.intValue());
});
}

private long blobGasPrice(final BlobGas excess) {
double dgufDenominator = 5007716;
double fakeExpo = excess.getValue().longValue() / dgufDenominator;
return (long) (1 * Math.exp(fakeExpo));
}
}
Loading