Skip to content

Commit

Permalink
Use dynamic gas calculator to calculate currentBlobGasLimit (hyperled…
Browse files Browse the repository at this point in the history
…ger#8257)

Signed-off-by: Simon Dudley <[email protected]>
  • Loading branch information
siladu authored Feb 13, 2025
1 parent 9d33e95 commit fa19459
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package org.hyperledger.besu.ethereum.mainnet;

import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;

public class CancunTargetingGasLimitCalculator extends LondonTargetingGasLimitCalculator {

Expand All @@ -25,19 +25,23 @@ public class CancunTargetingGasLimitCalculator extends LondonTargetingGasLimitCa
private final long maxBlobGasPerBlock;

public CancunTargetingGasLimitCalculator(
final long londonForkBlock, final BaseFeeMarket feeMarket) {
this(londonForkBlock, feeMarket, DEFAULT_MAX_BLOBS_PER_BLOCK_CANCUN);
final long londonForkBlock,
final BaseFeeMarket feeMarket,
final GasCalculator gasCalculator) {
this(londonForkBlock, feeMarket, gasCalculator, DEFAULT_MAX_BLOBS_PER_BLOCK_CANCUN);
}

/**
* Using Cancun mainnet default of 6 blobs for maxBlobsPerBlock: getBlobGasPerBlob() * 6 blobs =
* 131072 * 6 = 786432 = 0xC0000
*/
public CancunTargetingGasLimitCalculator(
final long londonForkBlock, final BaseFeeMarket feeMarket, final int maxBlobsPerBlock) {
final long londonForkBlock,
final BaseFeeMarket feeMarket,
final GasCalculator gasCalculator,
final int maxBlobsPerBlock) {
super(londonForkBlock, feeMarket);
final CancunGasCalculator cancunGasCalculator = new CancunGasCalculator();
this.maxBlobGasPerBlock = cancunGasCalculator.getBlobGasPerBlob() * maxBlobsPerBlock;
this.maxBlobGasPerBlock = gasCalculator.getBlobGasPerBlob() * maxBlobsPerBlock;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,10 @@ static ProtocolSpecBuilder cancunDefinition(
.gasLimitCalculatorBuilder(
feeMarket ->
new CancunTargetingGasLimitCalculator(
londonForkBlockNumber, (BaseFeeMarket) feeMarket, cancunBlobSchedule.getMax()))
londonForkBlockNumber,
(BaseFeeMarket) feeMarket,
cancunGasCalcSupplier.get(),
cancunBlobSchedule.getMax()))
// EVM changes to support EIP-1153: TSTORE and EIP-5656: MCOPY
.evmBuilder(
(gasCalculator, jdCacheConfig) ->
Expand Down Expand Up @@ -854,7 +857,10 @@ static ProtocolSpecBuilder pragueDefinition(
.gasLimitCalculatorBuilder(
feeMarket ->
new PragueTargetingGasLimitCalculator(
londonForkBlockNumber, (BaseFeeMarket) feeMarket, pragueBlobSchedule.getMax()))
londonForkBlockNumber,
(BaseFeeMarket) feeMarket,
pragueGasCalcSupplier.get(),
pragueBlobSchedule.getMax()))
// EIP-3074 AUTH and AUTHCALL
.evmBuilder(
(gasCalculator, jdCacheConfig) ->
Expand Down Expand Up @@ -950,7 +956,10 @@ private static ProtocolSpecBuilder addEOF(
.gasLimitCalculatorBuilder(
feeMarket ->
new OsakaTargetingGasLimitCalculator(
londonForkBlockNumber, (BaseFeeMarket) feeMarket, maxBlobsPerBlock))
londonForkBlockNumber,
(BaseFeeMarket) feeMarket,
osakaGasCalcSupplier.get(),
maxBlobsPerBlock))
// EIP-7692 EOF v1 EVM and opcodes
.evmBuilder(
(gasCalculator, jdCacheConfig) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ public TransactionProcessingResult processTransaction(
}
}

// TODO SLD are the log correct following EIP-7623?
if (LOG.isTraceEnabled()) {
LOG.trace(
"Gas used by transaction: {}, by message call/contract creation: {}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,29 @@
package org.hyperledger.besu.ethereum.mainnet;

import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;

public class OsakaTargetingGasLimitCalculator extends PragueTargetingGasLimitCalculator {

/** The mainnet default maximum number of blobs per block for Osaka */
private static final int DEFAULT_MAX_BLOBS_PER_BLOCK_OSAKA = 12;

public OsakaTargetingGasLimitCalculator(
final long londonForkBlock, final BaseFeeMarket feeMarket) {
super(londonForkBlock, feeMarket, DEFAULT_MAX_BLOBS_PER_BLOCK_OSAKA);
final long londonForkBlock,
final BaseFeeMarket feeMarket,
final GasCalculator gasCalculator) {
super(londonForkBlock, feeMarket, gasCalculator, DEFAULT_MAX_BLOBS_PER_BLOCK_OSAKA);
}

/**
* Using Osaka mainnet default of 12 blobs for maxBlobsPerBlock:
* CancunGasCalculator.BLOB_GAS_PER_BLOB * 12 blobs = 131072 * 12 = 1572864 = 0x180000
*/
public OsakaTargetingGasLimitCalculator(
final long londonForkBlock, final BaseFeeMarket feeMarket, final int maxBlobsPerBlock) {
super(londonForkBlock, feeMarket, maxBlobsPerBlock);
final long londonForkBlock,
final BaseFeeMarket feeMarket,
final GasCalculator gasCalculator,
final int maxBlobsPerBlock) {
super(londonForkBlock, feeMarket, gasCalculator, maxBlobsPerBlock);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,29 @@
package org.hyperledger.besu.ethereum.mainnet;

import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;

public class PragueTargetingGasLimitCalculator extends CancunTargetingGasLimitCalculator {

/** The mainnet default maximum number of blobs per block for Prague */
private static final int DEFAULT_MAX_BLOBS_PER_BLOCK_PRAGUE = 9;

public PragueTargetingGasLimitCalculator(
final long londonForkBlock, final BaseFeeMarket feeMarket) {
super(londonForkBlock, feeMarket, DEFAULT_MAX_BLOBS_PER_BLOCK_PRAGUE);
final long londonForkBlock,
final BaseFeeMarket feeMarket,
final GasCalculator gasCalculator) {
super(londonForkBlock, feeMarket, gasCalculator, DEFAULT_MAX_BLOBS_PER_BLOCK_PRAGUE);
}

/**
* Using Prague mainnet default of 9 blobs for maxBlobsPerBlock:
* CancunGasCalculator.BLOB_GAS_PER_BLOB * 9 blobs = 131072 * 9 = 1179648 = 0x120000
*/
public PragueTargetingGasLimitCalculator(
final long londonForkBlock, final BaseFeeMarket feeMarket, final int maxBlobsPerBlock) {
super(londonForkBlock, feeMarket, maxBlobsPerBlock);
final long londonForkBlock,
final BaseFeeMarket feeMarket,
final GasCalculator gasCalculator,
final int maxBlobsPerBlock) {
super(londonForkBlock, feeMarket, gasCalculator, maxBlobsPerBlock);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator;

import java.util.Optional;

Expand All @@ -27,7 +28,53 @@ class CancunTargetingGasLimitCalculatorTest {
@Test
void currentBlobGasLimitIs6Blobs() {
var cancunTargetingGasLimitCalculator =
new CancunTargetingGasLimitCalculator(0L, FeeMarket.cancun(0L, Optional.empty()));
new org.hyperledger.besu.ethereum.mainnet.CancunTargetingGasLimitCalculator(
0L, FeeMarket.cancun(0L, Optional.empty()), new CancunGasCalculator());
assertThat(cancunTargetingGasLimitCalculator.currentBlobGasLimit()).isEqualTo(0xC0000);
}

@Test
void shouldUseCancunCalculatorBlobGasPerBlob() {
// should use CancunGasCalculator's blob gas per blob to calculate the gas limit
final long blobGasPerBlob = new CancunGasCalculator().getBlobGasPerBlob();
assertThat(blobGasPerBlob).isEqualTo(131072);
int maxBlobs = 10;
var cancunTargetingGasLimitCalculator =
new CancunTargetingGasLimitCalculator(
0L, FeeMarket.cancun(0L, Optional.empty()), new CancunGasCalculator(), maxBlobs);
// if maxBlobs = 10, then the gas limit would be 131072 * 10 = 1310720
assertThat(cancunTargetingGasLimitCalculator.currentBlobGasLimit())
.isEqualTo(blobGasPerBlob * maxBlobs);
assertThat(cancunTargetingGasLimitCalculator.currentBlobGasLimit()).isEqualTo(1310720);
}

@Test
void shouldUseFutureForkCalculatorBlobGasPerBlob() {
// if a future fork changes the blob gas per blob
// even if we still use the CancunTargetingGasLimitCalculator
// it should use TestFutureForkCalculator's blob gas per blob to calculate the blob gas limit
final long blobGasPerBlob = new TestFutureGasCalculator().getBlobGasPerBlob();
assertThat(blobGasPerBlob).isEqualTo(262144);
int maxBlobs = 10;
var cancunTargetingGasLimitCalculator =
new CancunTargetingGasLimitCalculator(
0L, FeeMarket.cancun(0L, Optional.empty()), new TestFutureGasCalculator(), maxBlobs);
// if maxBlobs = 10, then the gas limit would be 262144 * 10 = 2621440
assertThat(cancunTargetingGasLimitCalculator.currentBlobGasLimit())
.isEqualTo(blobGasPerBlob * maxBlobs);
assertThat(cancunTargetingGasLimitCalculator.currentBlobGasLimit()).isEqualTo(2621440);
}

private static class TestFutureGasCalculator extends CancunGasCalculator {
private static final long TEST_BLOB_GAS_PER_BLOB_FUTURE = 262144;

public TestFutureGasCalculator() {
super(0, 7);
}

@Override
public long getBlobGasPerBlob() {
return TEST_BLOB_GAS_PER_BLOB_FUTURE;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator;

import java.util.Optional;

Expand All @@ -27,7 +28,23 @@ class PragueTargetingGasLimitCalculatorTest {
@Test
void currentBlobGasLimitIs9BlobsByDefault() {
var pragueTargetingGasLimitCalculator =
new PragueTargetingGasLimitCalculator(0L, FeeMarket.cancun(0L, Optional.empty()));
new PragueTargetingGasLimitCalculator(
0L, FeeMarket.cancun(0L, Optional.empty()), new PragueGasCalculator());
assertThat(pragueTargetingGasLimitCalculator.currentBlobGasLimit()).isEqualTo(0x120000);
}

@Test
void shouldUsePragueCalculatorBlobGasPerBlob() {
// should use PragueGasCalculator's blob gas per blob to calculate the gas limit
final long blobGasPerBlob = new PragueGasCalculator().getBlobGasPerBlob();
assertThat(blobGasPerBlob).isEqualTo(131072); // same as Cancun
int maxBlobs = 10;
var pragueTargetingGasLimitCalculator =
new PragueTargetingGasLimitCalculator(
0L, FeeMarket.cancun(0L, Optional.empty()), new PragueGasCalculator(), maxBlobs);
// if maxBlobs = 10, then the gas limit would be 131072 * 10 = 1310720
assertThat(pragueTargetingGasLimitCalculator.currentBlobGasLimit())
.isEqualTo(blobGasPerBlob * maxBlobs);
assertThat(pragueTargetingGasLimitCalculator.currentBlobGasLimit()).isEqualTo(1310720);
}
}

0 comments on commit fa19459

Please sign in to comment.