Use dynamic gas calculator to calculate currentBlobGasLimit (#8257)

Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
This commit is contained in:
Simon Dudley
2025-02-13 11:24:25 +10:00
committed by GitHub
parent 9d33e95471
commit fa19459bb2
7 changed files with 109 additions and 19 deletions

View File

@@ -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 {
@@ -25,8 +25,10 @@ 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);
}
/**
@@ -34,10 +36,12 @@ public class CancunTargetingGasLimitCalculator extends LondonTargetingGasLimitCa
* 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

View File

@@ -717,7 +717,10 @@ public abstract class MainnetProtocolSpecs {
.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) ->
@@ -854,7 +857,10 @@ public abstract class MainnetProtocolSpecs {
.gasLimitCalculatorBuilder(
feeMarket ->
new PragueTargetingGasLimitCalculator(
londonForkBlockNumber, (BaseFeeMarket) feeMarket, pragueBlobSchedule.getMax()))
londonForkBlockNumber,
(BaseFeeMarket) feeMarket,
pragueGasCalcSupplier.get(),
pragueBlobSchedule.getMax()))
// EIP-3074 AUTH and AUTHCALL
.evmBuilder(
(gasCalculator, jdCacheConfig) ->
@@ -950,7 +956,10 @@ public abstract class MainnetProtocolSpecs {
.gasLimitCalculatorBuilder(
feeMarket ->
new OsakaTargetingGasLimitCalculator(
londonForkBlockNumber, (BaseFeeMarket) feeMarket, maxBlobsPerBlock))
londonForkBlockNumber,
(BaseFeeMarket) feeMarket,
osakaGasCalcSupplier.get(),
maxBlobsPerBlock))
// EIP-7692 EOF v1 EVM and opcodes
.evmBuilder(
(gasCalculator, jdCacheConfig) ->

View File

@@ -481,6 +481,7 @@ public class MainnetTransactionProcessor {
}
}
// TODO SLD are the log correct following EIP-7623?
if (LOG.isTraceEnabled()) {
LOG.trace(
"Gas used by transaction: {}, by message call/contract creation: {}",

View File

@@ -15,6 +15,7 @@
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 {
@@ -22,8 +23,10 @@ public class OsakaTargetingGasLimitCalculator extends PragueTargetingGasLimitCal
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);
}
/**
@@ -31,7 +34,10 @@ public class OsakaTargetingGasLimitCalculator extends PragueTargetingGasLimitCal
* 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);
}
}

View File

@@ -15,6 +15,7 @@
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 {
@@ -22,8 +23,10 @@ public class PragueTargetingGasLimitCalculator extends CancunTargetingGasLimitCa
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);
}
/**
@@ -31,7 +34,10 @@ public class PragueTargetingGasLimitCalculator extends CancunTargetingGasLimitCa
* 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);
}
}

View File

@@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.mainnet;
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;
@@ -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;
}
}
}

View File

@@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.mainnet;
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;
@@ -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);
}
}