Skip to content
This repository was archived by the owner on Jul 1, 2025. It is now read-only.

Commit 59fb31a

Browse files
garyschultesiladu
andcommitted
prague fee market for blob gas (#8064)
* prague fee market for blob gas Signed-off-by: garyschulte <[email protected]> * Fix wiring and unit test Signed-off-by: Simon Dudley <[email protected]> --------- Signed-off-by: garyschulte <[email protected]> Signed-off-by: Simon Dudley <[email protected]> Co-authored-by: Simon Dudley <[email protected]>
1 parent c9dea04 commit 59fb31a

File tree

6 files changed

+146
-5
lines changed

6 files changed

+146
-5
lines changed

ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;
1616

1717
import static org.assertj.core.api.Assertions.assertThat;
18-
import static org.mockito.ArgumentMatchers.any;
1918
import static org.mockito.Mockito.mock;
2019
import static org.mockito.Mockito.spy;
2120
import static org.mockito.Mockito.when;
@@ -323,8 +322,7 @@ private void mockBlockWithBlobTransaction(final Hash blockHash, final long block
323322
}
324323

325324
private void mockProtocolSpec(final BlockHeader blockHeader) {
326-
FeeMarket feeMarket = mock(CancunFeeMarket.class);
327-
when(feeMarket.blobGasPricePerGas(any())).thenCallRealMethod();
325+
FeeMarket feeMarket = new CancunFeeMarket(0, Optional.empty());
328326
ProtocolSpec spec = mock(ProtocolSpec.class);
329327
when(spec.getFeeMarket()).thenReturn(feeMarket);
330328
when(spec.getGasCalculator()).thenReturn(new CancunGasCalculator());

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,18 @@ static ProtocolSpecBuilder pragueDefinition(
815815
final java.util.function.Supplier<GasCalculator> pragueGasCalcSupplier =
816816
() -> new PragueGasCalculator(pragueBlobSchedule.getTarget());
817817

818+
final BaseFeeMarket pragueFeeMarket;
819+
if (genesisConfigOptions.isZeroBaseFee()) {
820+
pragueFeeMarket = FeeMarket.zeroBaseFee(londonForkBlockNumber);
821+
} else if (genesisConfigOptions.isFixedBaseFee()) {
822+
pragueFeeMarket =
823+
FeeMarket.fixedBaseFee(
824+
londonForkBlockNumber, miningConfiguration.getMinTransactionGasPrice());
825+
} else {
826+
pragueFeeMarket =
827+
FeeMarket.prague(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas());
828+
}
829+
818830
return cancunDefinition(
819831
chainId,
820832
enableRevertReason,
@@ -823,6 +835,7 @@ static ProtocolSpecBuilder pragueDefinition(
823835
miningConfiguration,
824836
isParallelTxProcessingEnabled,
825837
metricsSystem)
838+
.feeMarket(pragueFeeMarket)
826839
.gasCalculator(pragueGasCalcSupplier)
827840
// EIP-7840 Blob schedule | EIP-7691 6/9 blob increase
828841
.gasLimitCalculatorBuilder(

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/CancunFeeMarket.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
public class CancunFeeMarket extends LondonFeeMarket {
2727
private static final Logger LOG = LoggerFactory.getLogger(CancunFeeMarket.class);
28-
private static final BigInteger BLOB_GAS_PRICE = BigInteger.ONE;
28+
protected static final BigInteger BLOB_GAS_PRICE = BigInteger.ONE;
2929
private static final BigInteger BLOB_GAS_PRICE_UPDATE_FRACTION = BigInteger.valueOf(3338477);
3030

3131
public CancunFeeMarket(
@@ -53,7 +53,7 @@ public Wei blobGasPricePerGas(final BlobGas excessBlobGas) {
5353
return blobGasPrice;
5454
}
5555

56-
private BigInteger fakeExponential(
56+
protected BigInteger fakeExponential(
5757
final BigInteger factor, final BigInteger numerator, final BigInteger denominator) {
5858
int i = 1;
5959
BigInteger output = BigInteger.ZERO;

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/FeeMarket.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ static BaseFeeMarket cancun(
4949
return new CancunFeeMarket(londonForkBlockNumber, baseFeePerGasOverride);
5050
}
5151

52+
static BaseFeeMarket prague(
53+
final long londonForkBlockNumber, final Optional<Wei> baseFeePerGasOverride) {
54+
return new PragueFeeMarket(londonForkBlockNumber, baseFeePerGasOverride);
55+
}
56+
5257
static BaseFeeMarket zeroBaseFee(final long londonForkBlockNumber) {
5358
return new ZeroBaseFeeMarket(londonForkBlockNumber);
5459
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright contributors to Besu.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5+
* the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
* specific language governing permissions and limitations under the License.
12+
*
13+
* SPDX-License-Identifier: Apache-2.0
14+
*/
15+
package org.hyperledger.besu.ethereum.mainnet.feemarket;
16+
17+
import org.hyperledger.besu.datatypes.BlobGas;
18+
import org.hyperledger.besu.datatypes.Wei;
19+
20+
import java.math.BigInteger;
21+
import java.util.Optional;
22+
23+
import org.slf4j.Logger;
24+
import org.slf4j.LoggerFactory;
25+
26+
public class PragueFeeMarket extends CancunFeeMarket {
27+
private static final BigInteger BLOB_BASE_FEE_UPDATE_FRACTION_ELECTRA =
28+
BigInteger.valueOf(5007716);
29+
private static final Logger LOG = LoggerFactory.getLogger(PragueFeeMarket.class);
30+
31+
public PragueFeeMarket(
32+
final long londonForkBlockNumber, final Optional<Wei> baseFeePerGasOverride) {
33+
super(londonForkBlockNumber, baseFeePerGasOverride);
34+
}
35+
36+
@Override
37+
public Wei blobGasPricePerGas(final BlobGas excessBlobGas) {
38+
final var blobGasPrice =
39+
Wei.of(
40+
fakeExponential(
41+
BLOB_GAS_PRICE,
42+
excessBlobGas.toBigInteger(),
43+
BLOB_BASE_FEE_UPDATE_FRACTION_ELECTRA));
44+
LOG.atTrace()
45+
.setMessage("parentExcessBlobGas: {} blobGasPrice: {}")
46+
.addArgument(excessBlobGas::toShortHexString)
47+
.addArgument(blobGasPrice::toHexString)
48+
.log();
49+
50+
return blobGasPrice;
51+
}
52+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright contributors to Hyperledger Besu.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5+
* the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
* specific language governing permissions and limitations under the License.
12+
*
13+
* SPDX-License-Identifier: Apache-2.0
14+
*/
15+
package org.hyperledger.besu.ethereum.mainnet.feemarket;
16+
17+
import static org.junit.jupiter.api.Assertions.assertEquals;
18+
19+
import org.hyperledger.besu.datatypes.BlobGas;
20+
21+
import java.util.ArrayList;
22+
import java.util.List;
23+
import java.util.Optional;
24+
25+
import org.junit.jupiter.api.Test;
26+
27+
class PragueFeeMarketTest {
28+
29+
private static final int BLOB_GAS_PER_BLOB = 131072;
30+
31+
/**
32+
* from: https://eips.ethereum.org/EIPS/eip-7691 The BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE value in
33+
* this EIP is chosen as the mid-point between keeping the responsiveness to full blobs and no
34+
* blobs constant:
35+
*
36+
* <p>full blobs: basefee increases by ~8.2% no blobs: basefee decreases by ~14.5%
37+
*/
38+
@Test
39+
void dataPricePerGas() {
40+
PragueFeeMarket pragueFeeMarket = new PragueFeeMarket(0, Optional.empty());
41+
// when no excess blob gas, data price per gas is 1
42+
assertEquals(1, pragueFeeMarket.blobGasPricePerGas(BlobGas.ZERO).getAsBigInteger().intValue());
43+
44+
record BlobGasPricing(long excess, long price) {}
45+
List<BlobGasPricing> testVector = new ArrayList<>();
46+
47+
int numBlobs = 1;
48+
long price = 1;
49+
while (price <= 1000) {
50+
price = blobGasPrice(BlobGas.of(numBlobs * BLOB_GAS_PER_BLOB));
51+
var testCase = new BlobGasPricing(numBlobs * BLOB_GAS_PER_BLOB, price);
52+
testVector.add(testCase);
53+
numBlobs++;
54+
}
55+
56+
testVector.stream()
57+
.forEach(
58+
blobGasPricing -> {
59+
assertEquals(
60+
blobGasPricing.price,
61+
pragueFeeMarket
62+
.blobGasPricePerGas(BlobGas.of(blobGasPricing.excess))
63+
.getAsBigInteger()
64+
.intValue());
65+
});
66+
}
67+
68+
private long blobGasPrice(final BlobGas excess) {
69+
double dgufDenominator = 5007716;
70+
double fakeExpo = excess.getValue().longValue() / dgufDenominator;
71+
return (long) (1 * Math.exp(fakeExpo));
72+
}
73+
}

0 commit comments

Comments
 (0)