From fa19459bb2c26259de29e29487c9d534ba5e922b Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Thu, 13 Feb 2025 11:24:25 +1000 Subject: [PATCH] Use dynamic gas calculator to calculate currentBlobGasLimit (#8257) Signed-off-by: Simon Dudley --- .../CancunTargetingGasLimitCalculator.java | 16 +++--- .../mainnet/MainnetProtocolSpecs.java | 15 ++++-- .../mainnet/MainnetTransactionProcessor.java | 1 + .../OsakaTargetingGasLimitCalculator.java | 14 ++++-- .../PragueTargetingGasLimitCalculator.java | 14 ++++-- ...CancunTargetingGasLimitCalculatorTest.java | 49 ++++++++++++++++++- ...PragueTargetingGasLimitCalculatorTest.java | 19 ++++++- 7 files changed, 109 insertions(+), 19 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculator.java index 707abda32a6..fe2119d9d84 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculator.java @@ -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 CancunTargetingGasLimitCalculator( * 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 diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java index 686bed1dd84..9f23cec74ce 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java @@ -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) -> @@ -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) -> @@ -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) -> diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java index faec6fd9ba7..a1111dee555 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java @@ -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: {}", diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/OsakaTargetingGasLimitCalculator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/OsakaTargetingGasLimitCalculator.java index 903cce27dff..c8db9acdf84 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/OsakaTargetingGasLimitCalculator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/OsakaTargetingGasLimitCalculator.java @@ -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 OsakaTargetingGasLimitCalculator( * 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); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculator.java index b7574c3f3db..68fe075febf 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculator.java @@ -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 PragueTargetingGasLimitCalculator( * 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); } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculatorTest.java index c732aeafb75..6c5f394bb7b 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculatorTest.java @@ -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; @@ -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; + } + } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculatorTest.java index e85b89bdfec..64934f9659b 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculatorTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculatorTest.java @@ -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; @@ -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); + } }