From 35062a4a35e251fb5f4cc782805078dc37150fb6 Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Tue, 17 Dec 2024 21:52:17 +1000 Subject: [PATCH] EIP-7840 prototype Signed-off-by: Simon Dudley --- .../src/test/resources/dev/dev_prague.json | 14 +++ .../besu/config/BlobScheduleOptions.java | 110 ++++++++++++++++++ .../besu/config/GenesisConfigOptions.java | 7 ++ .../besu/config/JsonGenesisConfigOptions.java | 9 ++ .../besu/config/StubGenesisConfigOptions.java | 5 + .../besu/config/BlobScheduleOptionsTest.java | 36 ++++++ .../resources/mainnet_with_blob_schedule.json | 37 ++++++ .../besu/ethereum/GasLimitCalculator.java | 7 +- .../CancunTargetingGasLimitCalculator.java | 23 +++- .../mainnet/MainnetProtocolSpecs.java | 41 +++++-- .../PragueTargetingGasLimitCalculator.java | 36 ++++++ .../feemarket/ExcessBlobGasCalculator.java | 3 +- .../BlobGasValidationRule.java | 3 +- ...CancunTargetingGasLimitCalculatorTest.java | 33 ++++++ ...PragueTargetingGasLimitCalculatorTest.java | 33 ++++++ .../gascalculator/CancunGasCalculator.java | 58 ++++++++- .../besu/evm/gascalculator/GasCalculator.java | 50 ++++---- .../evm/gascalculator/OsakaGasCalculator.java | 28 +++-- .../gascalculator/PragueGasCalculator.java | 22 +++- .../CancunGasCalculatorTest.java | 7 +- .../gascalculator/OsakaGasCalculatorTest.java | 43 ++++++- .../PragueGasCalculatorTest.java | 35 ++---- 22 files changed, 552 insertions(+), 88 deletions(-) create mode 100644 config/src/main/java/org/hyperledger/besu/config/BlobScheduleOptions.java create mode 100644 config/src/test/java/org/hyperledger/besu/config/BlobScheduleOptionsTest.java create mode 100644 config/src/test/resources/mainnet_with_blob_schedule.json create mode 100644 ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculator.java create mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculatorTest.java create mode 100644 ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculatorTest.java diff --git a/acceptance-tests/tests/src/test/resources/dev/dev_prague.json b/acceptance-tests/tests/src/test/resources/dev/dev_prague.json index 942edc4e70a..7a7b56d9508 100644 --- a/acceptance-tests/tests/src/test/resources/dev/dev_prague.json +++ b/acceptance-tests/tests/src/test/resources/dev/dev_prague.json @@ -15,6 +15,20 @@ "terminalTotalDifficulty":0, "cancunTime":0, "pragueTime":0, + "blobSchedule": { + "cancun": { + "target": 3, + "max": 6 + }, + "prague": { + "target": 6, + "max": 9 + }, + "osaka": { + "target": 9, + "max": 12 + } + }, "clique": { "period": 5, "epoch": 30000 diff --git a/config/src/main/java/org/hyperledger/besu/config/BlobScheduleOptions.java b/config/src/main/java/org/hyperledger/besu/config/BlobScheduleOptions.java new file mode 100644 index 00000000000..f2f8727707a --- /dev/null +++ b/config/src/main/java/org/hyperledger/besu/config/BlobScheduleOptions.java @@ -0,0 +1,110 @@ +/* + * 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.config; + +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** The Checkpoint config options. */ +public class BlobScheduleOptions { + + /** The constant DEFAULT. */ + public static final BlobScheduleOptions DEFAULT = + new BlobScheduleOptions(JsonUtil.createEmptyObjectNode()); + + private final ObjectNode blobScheduleOptionsConfigRoot; + + private static final String CANCUN_KEY = "cancun"; + private static final String PRAGUE_KEY = "prague"; + private static final String OSAKA_KEY = "osaka"; + + /** + * Instantiates a new Blob Schedule config options. + * + * @param blobScheduleConfigRoot the blob schedule config root + */ + public BlobScheduleOptions(final ObjectNode blobScheduleConfigRoot) { + this.blobScheduleOptionsConfigRoot = blobScheduleConfigRoot; + } + + /** + * Gets cancun blob schedule. + * + * @return the cancun blob schedule + */ + public BlobSchedule getCancun() { + return JsonUtil.getObjectNode(blobScheduleOptionsConfigRoot, CANCUN_KEY) + .map(BlobSchedule::new) + .orElse(BlobSchedule.DEFAULT); + } + + /** + * Gets prague blob schedule. + * + * @return the prague blob schedule + */ + public BlobSchedule getPrague() { + return JsonUtil.getObjectNode(blobScheduleOptionsConfigRoot, PRAGUE_KEY) + .map(BlobSchedule::new) + .orElse(BlobSchedule.DEFAULT); + } + + /** + * Gets osaka blob schedule. + * + * @return the osaka blob schedule + */ + public BlobSchedule getOsaka() { + return JsonUtil.getObjectNode(blobScheduleOptionsConfigRoot, OSAKA_KEY) + .map(BlobSchedule::new) + .orElse(BlobSchedule.DEFAULT); + } + + /** The Blob schedule for a particular fork. */ + public static class BlobSchedule { + private final ObjectNode blobScheduleConfigRoot; + + /** The constant DEFAULT. */ + public static final BlobSchedule DEFAULT = new BlobSchedule(JsonUtil.createEmptyObjectNode()); + + /** + * Instantiates a new Blob schedule. + * + * @param blobScheduleItemConfigRoot the blob schedule item config root + */ + public BlobSchedule(final ObjectNode blobScheduleItemConfigRoot) { + this.blobScheduleConfigRoot = blobScheduleItemConfigRoot; + } + + /** + * Gets target. + * + * @return the target + */ + public int getTarget() { + // TODO SLD EIP-7840 - reasonable default? + return JsonUtil.getInt(blobScheduleConfigRoot, "target").orElse(3); + } + + /** + * Gets max. + * + * @return the max + */ + public int getMax() { + // TODO SLD EIP-7840 - reasonable default? + return JsonUtil.getInt(blobScheduleConfigRoot, "max").orElse(6); + } + } +} diff --git a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java index e2458c93247..32e436bf861 100644 --- a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java @@ -546,4 +546,11 @@ default boolean isConsensusMigration() { * @return the consolidation request contract address */ Optional
getConsolidationRequestContractAddress(); + + /** + * The blob schedule is a list of hardfork names and their associated target and max blob values. + * + * @return the blob schedule + */ + BlobScheduleOptions getBlobScheduleOptions(); } diff --git a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java index 51f85f0ec82..66ea8f3e929 100644 --- a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java @@ -47,6 +47,7 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { private static final String TRANSITIONS_CONFIG_KEY = "transitions"; private static final String DISCOVERY_CONFIG_KEY = "discovery"; private static final String CHECKPOINT_CONFIG_KEY = "checkpoint"; + private static final String BLOB_SCHEDULE_CONFIG_KEY = "blobschedule"; private static final String ZERO_BASE_FEE_KEY = "zerobasefee"; private static final String FIXED_BASE_FEE_KEY = "fixedbasefee"; private static final String WITHDRAWAL_REQUEST_CONTRACT_ADDRESS_KEY = @@ -199,6 +200,13 @@ public EthashConfigOptions getEthashConfigOptions() { .orElse(EthashConfigOptions.DEFAULT); } + @Override + public BlobScheduleOptions getBlobScheduleOptions() { + return JsonUtil.getObjectNode(configRoot, BLOB_SCHEDULE_CONFIG_KEY) + .map(BlobScheduleOptions::new) + .orElse(BlobScheduleOptions.DEFAULT); + } + @Override public TransitionsConfigOptions getTransitions() { return transitions; @@ -462,6 +470,7 @@ public Optional
getConsolidationRequestContractAddress() { return inputAddress.map(Address::fromHexString); } + // TODO SLD - EIP-7840 @Override public Map asMap() { final ImmutableMap.Builder builder = ImmutableMap.builder(); diff --git a/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java index c9c8dad7954..4d04abbd384 100644 --- a/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java @@ -472,6 +472,11 @@ public Optional
getConsolidationRequestContractAddress() { return Optional.empty(); } + @Override + public BlobScheduleOptions getBlobScheduleOptions() { + return BlobScheduleOptions.DEFAULT; + } + /** * Homestead block stub genesis config options. * diff --git a/config/src/test/java/org/hyperledger/besu/config/BlobScheduleOptionsTest.java b/config/src/test/java/org/hyperledger/besu/config/BlobScheduleOptionsTest.java new file mode 100644 index 00000000000..f3565bf670b --- /dev/null +++ b/config/src/test/java/org/hyperledger/besu/config/BlobScheduleOptionsTest.java @@ -0,0 +1,36 @@ +/* + * 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.config; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +public class BlobScheduleOptionsTest { + + @Test + public void blobScheduleIsParsed() { + final GenesisConfigFile genesisConfigFile = + GenesisConfigFile.fromResource("/mainnet_with_blob_schedule.json"); + final GenesisConfigOptions configOptions = genesisConfigFile.getConfigOptions(); + + assertThat(configOptions.getBlobScheduleOptions().getCancun().getTarget()).isEqualTo(3); + assertThat(configOptions.getBlobScheduleOptions().getCancun().getMax()).isEqualTo(6); + assertThat(configOptions.getBlobScheduleOptions().getPrague().getTarget()).isEqualTo(6); + assertThat(configOptions.getBlobScheduleOptions().getPrague().getMax()).isEqualTo(9); + assertThat(configOptions.getBlobScheduleOptions().getOsaka().getTarget()).isEqualTo(9); + assertThat(configOptions.getBlobScheduleOptions().getOsaka().getMax()).isEqualTo(12); + } +} diff --git a/config/src/test/resources/mainnet_with_blob_schedule.json b/config/src/test/resources/mainnet_with_blob_schedule.json new file mode 100644 index 00000000000..7476d812c96 --- /dev/null +++ b/config/src/test/resources/mainnet_with_blob_schedule.json @@ -0,0 +1,37 @@ +{ + "config": { + "chainId": 3151908, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "preMergeForkBlock": 0, + "terminalTotalDifficulty": 0, + "ethash": {}, + "shanghaiTime": 0, + "cancunTime": 0, + "blobSchedule": { + "cancun": { + "target": 3, + "max": 6 + }, + "prague": { + "target": 6, + "max": 9 + }, + "osaka": { + "target": 9, + "max": 12 + } + }, + "depositContractAddress": "0x4242424242424242424242424242424242424242", + "pragueTime": 1734106711, + "osakaTime": 1734107095 + } +} \ No newline at end of file diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/GasLimitCalculator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/GasLimitCalculator.java index 7c15d6229c0..0d1a09511a5 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/GasLimitCalculator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/GasLimitCalculator.java @@ -17,8 +17,11 @@ /** The GasLimitCalculator interface defines methods for calculating the gas limit. */ public interface GasLimitCalculator { - /** The constant BLOB_GAS_LIMIT represents the gas limit for blob data. */ - long BLOB_GAS_LIMIT = 786432; + /** + * The constant BLOB_GAS_LIMIT represents the gas limit for blob data. Defaults to the Cancun + * value where it was first introduced as part of EIP-4844 + */ + long BLOB_GAS_LIMIT = 0xC0000; /** * Calculates the next gas limit based on the current gas limit, target gas limit, and new block 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 7dd1be481f6..2edaf3d39b6 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,17 +15,36 @@ package org.hyperledger.besu.ethereum.mainnet; import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; +import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator; public class CancunTargetingGasLimitCalculator extends LondonTargetingGasLimitCalculator { - private static final long MAX_BLOB_GAS_PER_BLOCK = 786432L; + + /** + * The constant MAX_BLOB_GAS_PER_BLOCK represents the maximum gas limit for blob data. = + * CancunGasCalculator.BLOB_GAS_PER_BLOB * 6 blobs = 131072 * 6 = 786432 = 0xC0000 + */ + private static final int DEFAULT_MAX_BLOBS_PER_BLOCK = 6; + + /** + * The maximum gas limit for blob data per block. getBlobGasPerBlob() * 6 blobs = 131072 * 6 = + * 786432 = 0xC0000 + */ + private final long maxBlobGasPerBlock; public CancunTargetingGasLimitCalculator( final long londonForkBlock, final BaseFeeMarket feeMarket) { + this(londonForkBlock, feeMarket, DEFAULT_MAX_BLOBS_PER_BLOCK); + } + + public CancunTargetingGasLimitCalculator( + final long londonForkBlock, final BaseFeeMarket feeMarket, final int maxBlobsPerBlock) { super(londonForkBlock, feeMarket); + final CancunGasCalculator cancunGasCalculator = new CancunGasCalculator(); + this.maxBlobGasPerBlock = cancunGasCalculator.getBlobGasPerBlob() * maxBlobsPerBlock; } @Override public long currentBlobGasLimit() { - return MAX_BLOB_GAS_PER_BLOCK; + return maxBlobGasPerBlock; } } 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 26c9e69c8f5..a6dcb6a636f 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 @@ -683,6 +683,10 @@ static ProtocolSpecBuilder cancunDefinition( FeeMarket.cancun(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas()); } + final int targetBlobsPerBlock = + genesisConfigOptions.getBlobScheduleOptions().getCancun().getTarget(); + final int maxBlobsPerBlock = genesisConfigOptions.getBlobScheduleOptions().getCancun().getMax(); + return shanghaiDefinition( chainId, enableRevertReason, @@ -693,12 +697,12 @@ static ProtocolSpecBuilder cancunDefinition( metricsSystem) .feeMarket(cancunFeeMarket) // gas calculator for EIP-4844 blob gas - .gasCalculator(CancunGasCalculator::new) + .gasCalculator(() -> new CancunGasCalculator(targetBlobsPerBlock)) // gas limit with EIP-4844 max blob gas per block .gasLimitCalculatorBuilder( feeMarket -> new CancunTargetingGasLimitCalculator( - londonForkBlockNumber, (BaseFeeMarket) feeMarket)) + londonForkBlockNumber, (BaseFeeMarket) feeMarket, maxBlobsPerBlock)) // EVM changes to support EIP-1153: TSTORE and EIP-5656: MCOPY .evmBuilder( (gasCalculator, jdCacheConfig) -> @@ -753,6 +757,9 @@ static ProtocolSpecBuilder cancunEOFDefinition( final boolean isParallelTxProcessingEnabled, final MetricsSystem metricsSystem) { + final int targetBlobsPerBlock = + genesisConfigOptions.getBlobScheduleOptions().getCancun().getTarget(); + ProtocolSpecBuilder protocolSpecBuilder = cancunDefinition( chainId, @@ -762,7 +769,8 @@ static ProtocolSpecBuilder cancunEOFDefinition( miningConfiguration, isParallelTxProcessingEnabled, metricsSystem); - return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("CancunEOF"); + return addEOF(chainId, evmConfiguration, protocolSpecBuilder, targetBlobsPerBlock) + .name("CancunEOF"); } static ProtocolSpecBuilder pragueDefinition( @@ -777,6 +785,11 @@ static ProtocolSpecBuilder pragueDefinition( RequestContractAddresses requestContractAddresses = RequestContractAddresses.fromGenesis(genesisConfigOptions); + final long londonForkBlockNumber = genesisConfigOptions.getLondonBlockNumber().orElse(0L); + final int targetBlobsPerBlock = + genesisConfigOptions.getBlobScheduleOptions().getPrague().getTarget(); + final int maxBlobsPerBlock = genesisConfigOptions.getBlobScheduleOptions().getPrague().getMax(); + return cancunDefinition( chainId, enableRevertReason, @@ -785,8 +798,13 @@ static ProtocolSpecBuilder pragueDefinition( miningConfiguration, isParallelTxProcessingEnabled, metricsSystem) - // EIP-3074 AUTH and AUTCALL gas - .gasCalculator(PragueGasCalculator::new) + // EIP-3074 AUTH and AUTCALL gas | EIP-7840 Blob schedule + .gasCalculator(() -> new PragueGasCalculator(targetBlobsPerBlock)) + // EIP-7840 Blob schedule + .gasLimitCalculatorBuilder( + feeMarket -> + new PragueTargetingGasLimitCalculator( + londonForkBlockNumber, (BaseFeeMarket) feeMarket, maxBlobsPerBlock)) // EIP-3074 AUTH and AUTHCALL .evmBuilder( (gasCalculator, jdCacheConfig) -> @@ -832,6 +850,9 @@ static ProtocolSpecBuilder osakaDefinition( final boolean isParallelTxProcessingEnabled, final MetricsSystem metricsSystem) { + final int targetBlobsPerBlock = + genesisConfigOptions.getBlobScheduleOptions().getCancun().getTarget(); + ProtocolSpecBuilder protocolSpecBuilder = pragueDefinition( chainId, @@ -841,16 +862,20 @@ static ProtocolSpecBuilder osakaDefinition( miningConfiguration, isParallelTxProcessingEnabled, metricsSystem); - return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("Osaka"); + return addEOF(chainId, evmConfiguration, protocolSpecBuilder, targetBlobsPerBlock) + .name("Osaka"); } private static ProtocolSpecBuilder addEOF( final Optional chainId, final EvmConfiguration evmConfiguration, - final ProtocolSpecBuilder protocolSpecBuilder) { + final ProtocolSpecBuilder protocolSpecBuilder, + final int targetBlobsPerBlock) { + + // TODO SLD EIP-7840 Add OsakaTargetingGasLimitCalculator with maxBlobsPerBlock return protocolSpecBuilder // EIP-7692 EOF v1 Gas calculator - .gasCalculator(OsakaGasCalculator::new) + .gasCalculator(() -> new OsakaGasCalculator(targetBlobsPerBlock)) // EIP-7692 EOF v1 EVM and opcodes .evmBuilder( (gasCalculator, jdCacheConfig) -> 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 new file mode 100644 index 00000000000..1e64cf5a5b7 --- /dev/null +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculator.java @@ -0,0 +1,36 @@ +/* + * 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; + +import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; + +public class PragueTargetingGasLimitCalculator extends CancunTargetingGasLimitCalculator { + + /** + * The constant MAX_BLOB_GAS_PER_BLOCK represents the maximum gas limit for blob data. = + * CancunGasCalculator.BLOB_GAS_PER_BLOB * 9 blobs = 131072 * 9 = 1179648 = 0x120000 + */ + 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); + } + + public PragueTargetingGasLimitCalculator( + final long londonForkBlock, final BaseFeeMarket feeMarket, final int maxBlobsPerBlock) { + super(londonForkBlock, feeMarket, maxBlobsPerBlock); + } +} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/ExcessBlobGasCalculator.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/ExcessBlobGasCalculator.java index b483e4292ca..f6372097b7f 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/ExcessBlobGasCalculator.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/ExcessBlobGasCalculator.java @@ -36,8 +36,7 @@ public static BlobGas calculateExcessBlobGasForParent( .getGasCalculator() .computeExcessBlobGas( parentHeader.getExcessBlobGas().map(BlobGas::toLong).orElse(0L), - parentHeader.getBlobGasUsed().orElse(0L), - parentHeader.getTargetBlobsPerBlock()); + parentHeader.getBlobGasUsed().orElse(0L)); return BlobGas.of(headerExcess); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/BlobGasValidationRule.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/BlobGasValidationRule.java index 2f24d618326..c986ec08588 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/BlobGasValidationRule.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/BlobGasValidationRule.java @@ -44,8 +44,7 @@ public boolean validate(final BlockHeader header, final BlockHeader parent) { long parentBlobGasUsed = parent.getBlobGasUsed().orElse(0L); long calculatedExcessBlobGas = - gasCalculator.computeExcessBlobGas( - parentExcessBlobGas, parentBlobGasUsed, parent.getTargetBlobsPerBlock()); + gasCalculator.computeExcessBlobGas(parentExcessBlobGas, parentBlobGasUsed); if (headerExcessBlobGas != calculatedExcessBlobGas) { LOG.info( 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 new file mode 100644 index 00000000000..c732aeafb75 --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/CancunTargetingGasLimitCalculatorTest.java @@ -0,0 +1,33 @@ +/* + * 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; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; + +import java.util.Optional; + +import org.junit.jupiter.api.Test; + +class CancunTargetingGasLimitCalculatorTest { + + @Test + void currentBlobGasLimitIs6Blobs() { + var cancunTargetingGasLimitCalculator = + new CancunTargetingGasLimitCalculator(0L, FeeMarket.cancun(0L, Optional.empty())); + assertThat(cancunTargetingGasLimitCalculator.currentBlobGasLimit()).isEqualTo(0xC0000); + } +} 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 new file mode 100644 index 00000000000..e85b89bdfec --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/PragueTargetingGasLimitCalculatorTest.java @@ -0,0 +1,33 @@ +/* + * 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; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; + +import java.util.Optional; + +import org.junit.jupiter.api.Test; + +class PragueTargetingGasLimitCalculatorTest { + + @Test + void currentBlobGasLimitIs9BlobsByDefault() { + var pragueTargetingGasLimitCalculator = + new PragueTargetingGasLimitCalculator(0L, FeeMarket.cancun(0L, Optional.empty())); + assertThat(pragueTargetingGasLimitCalculator.currentBlobGasLimit()).isEqualTo(0x120000); + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculator.java index 2d6168322ec..3ec442c9c47 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculator.java @@ -26,18 +26,35 @@ */ public class CancunGasCalculator extends ShanghaiGasCalculator { + /** The default mainnet target blobs per block for Cancun */ + private static final int DEFAULT_TARGET_BLOBS_PER_BLOCK_CANCUN = 3; + + /** this.getBlobGasPerBlob() * 3 blobs = 131072 * 6 = 393216 = 0x60000 */ + private final long targetBlobGasPerBlock; + /** Instantiates a new Cancun Gas Calculator. */ public CancunGasCalculator() { - this(KZG_POINT_EVAL.toArrayUnsafe()[19]); + this(KZG_POINT_EVAL.toArrayUnsafe()[19], DEFAULT_TARGET_BLOBS_PER_BLOCK_CANCUN); + } + + /** + * Instantiates a new Cancun Gas Calculator + * + * @param targetBlobsPerBlock the target blobs per block + */ + public CancunGasCalculator(final int targetBlobsPerBlock) { + this(KZG_POINT_EVAL.toArrayUnsafe()[19], targetBlobsPerBlock); } /** * Instantiates a new Cancun Gas Calculator * * @param maxPrecompile the max precompile + * @param targetBlobsPerBlock the target blobs per block */ - protected CancunGasCalculator(final int maxPrecompile) { + protected CancunGasCalculator(final int maxPrecompile, final int targetBlobsPerBlock) { super(maxPrecompile); + this.targetBlobGasPerBlock = getBlobGasPerBlob() * targetBlobsPerBlock; } private static final long TLOAD_GAS = WARM_STORAGE_READ_COST; @@ -49,9 +66,6 @@ protected CancunGasCalculator(final int maxPrecompile) { */ private static final long BLOB_GAS_PER_BLOB = 1 << 17; - /** The target blob gas per block. */ - static final long TARGET_BLOB_GAS_PER_BLOCK = 0x60000; - // EIP-1153 @Override public long getTransientLoadOperationGasCost() { @@ -79,6 +93,38 @@ public long getBlobGasPerBlob() { * @return The target blob gas per block. */ public long getTargetBlobGasPerBlock() { - return TARGET_BLOB_GAS_PER_BLOCK; + return targetBlobGasPerBlock; + } + + // /** + // * Computes the excess blob gas for a given block based on the parent's excess blob gas and + // blob + // * gas used. If the sum of parent's excess blob gas and parent's blob gas used is less than + // the + // * target blob gas per block, the excess blob gas is calculated as 0. Otherwise, it is + // computed as + // * the difference between the sum and the target blob gas per block. + // * + // * @param parentExcessBlobGas The excess blob gas of the parent block. + // * @param newBlobs blob gas incurred by current block + // * @return The excess blob gas for the current block. + // */ + // @Override + // public long computeExcessBlobGas(final long parentExcessBlobGas, final int newBlobs) { + // final long consumedBlobGas = blobGasCost(newBlobs); + // final long currentExcessBlobGas = parentExcessBlobGas + consumedBlobGas; + // if (currentExcessBlobGas < TARGET_BLOB_GAS_PER_BLOCK) { + // return 0L; + // } + // return currentExcessBlobGas - TARGET_BLOB_GAS_PER_BLOCK; + // } + + @Override + public long computeExcessBlobGas(final long parentExcessBlobGas, final long parentBlobGasUsed) { + final long currentExcessBlobGas = parentExcessBlobGas + parentBlobGasUsed; + if (currentExcessBlobGas < targetBlobGasPerBlock) { + return 0L; + } + return currentExcessBlobGas - targetBlobGasPerBlock; } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java index 049b197d031..0107cc7def6 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java @@ -40,12 +40,10 @@ import org.hyperledger.besu.evm.processor.AbstractMessageProcessor; import java.util.List; -import java.util.Optional; import java.util.function.Supplier; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; -import org.apache.tuweni.units.bigints.UInt64; /** * Provides various gas cost lookups and calculations used during block processing. @@ -635,31 +633,37 @@ default long blobGasCost(final long blobCount) { return 0L; } - /** - * Compute the new value for the excess blob gas, given the parent value, the parent blob gas used - * and the parent target blobs per block, if present. Used from Cancun onwards. Presence of - * parentTargetBlobsPerBlock implies EIP-7442/Prague enabled. Default to Cancun constant target - * gas value if parentTargetBlobsPerBlock is not present. + // /** + // * Compute the new value for the excess blob gas, given the parent value, the parent blob gas + // used + // * and the parent target blobs per block, if present. Used from Cancun onwards. Presence of + // * parentTargetBlobsPerBlock implies EIP-7442/Prague enabled. Default to Cancun constant + // target + // * gas value if parentTargetBlobsPerBlock is not present. + // * + // * @param parentExcessBlobGas excess blob gas from the parent + // * @param parentBlobGasUsed blob gas used from the parent + // * @return the new excess blob gas value + // */ + // default long computeExcessBlobGas( + // final long parentExcessBlobGas, + // final long parentBlobGasUsed) { + // final long currentExcessBlobGas = parentExcessBlobGas + parentBlobGasUsed; + // + // if (currentExcessBlobGas < parentTargetBlobGas) { + // return 0L; + // } + // return currentExcessBlobGas - parentTargetBlobGas; + // } + /** + * Compute the new value for the excess blob gas, given the parent value and the blob gas used * * @param parentExcessBlobGas excess blob gas from the parent - * @param parentBlobGasUsed blob gas used from the parent - * @param parentTargetBlobsPerBlock the optional target blobs per block from the parent + * @param blobGasUsed blob gas used * @return the new excess blob gas value */ - default long computeExcessBlobGas( - final long parentExcessBlobGas, - final long parentBlobGasUsed, - final Optional parentTargetBlobsPerBlock) { - final long parentTargetBlobGas = - parentTargetBlobsPerBlock - .map(blobCount -> blobGasCost(blobCount.toLong())) - .orElse(CancunGasCalculator.TARGET_BLOB_GAS_PER_BLOCK); - final long currentExcessBlobGas = parentExcessBlobGas + parentBlobGasUsed; - - if (currentExcessBlobGas < parentTargetBlobGas) { - return 0L; - } - return currentExcessBlobGas - parentTargetBlobGas; + default long computeExcessBlobGas(final long parentExcessBlobGas, final long blobGasUsed) { + return 0L; } /** diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculator.java index b4155dac52a..de56430f00f 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculator.java @@ -17,10 +17,9 @@ import static org.hyperledger.besu.datatypes.Address.BLS12_MAP_FP2_TO_G2; /** - * Gas Calculator for Prague + * Gas Calculator for Osaka * - *

Placeholder for new gas schedule items. If Prague finalzies without changes this can be - * removed + *

Placeholder for new gas schedule items. If Osaka finalzies without changes this can be removed * *

    *
  • TBD @@ -28,21 +27,34 @@ */ public class OsakaGasCalculator extends PragueGasCalculator { + /** The default mainnet target blobs per block for Osaka */ + private static final int DEFAULT_TARGET_BLOBS_PER_BLOCK_OSAKA = 9; + static final long MIN_RETAINED_GAS = 5_000; static final long MIN_CALLEE_GAS = 2300; - /** Instantiates a new Prague Gas Calculator. */ + /** Instantiates a new Osaka Gas Calculator. */ public OsakaGasCalculator() { - this(BLS12_MAP_FP2_TO_G2.toArrayUnsafe()[19]); + this(BLS12_MAP_FP2_TO_G2.toArrayUnsafe()[19], DEFAULT_TARGET_BLOBS_PER_BLOCK_OSAKA); + } + + /** + * Instantiates a new Osaka Gas Calculator + * + * @param targetBlobsPerBlock the target blobs per block + */ + public OsakaGasCalculator(final int targetBlobsPerBlock) { + this(BLS12_MAP_FP2_TO_G2.toArrayUnsafe()[19], targetBlobsPerBlock); } /** - * Instantiates a new Prague Gas Calculator + * Instantiates a new Osaka Gas Calculator * * @param maxPrecompile the max precompile + * @param targetBlobsPerBlock the target blobs per block */ - protected OsakaGasCalculator(final int maxPrecompile) { - super(maxPrecompile); + protected OsakaGasCalculator(final int maxPrecompile, final int targetBlobsPerBlock) { + super(maxPrecompile, targetBlobsPerBlock); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java index 666292e9e10..268a58061c7 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java @@ -28,18 +28,34 @@ public class PragueGasCalculator extends CancunGasCalculator { final long existingAccountGasRefund; + /** + * The default mainnet target blobs per block for Prague getBlobGasPerBlob() * 6 blobs = 131072 * + * 6 = 786432 = 0xC0000 + */ + private static final int DEFAULT_TARGET_BLOBS_PER_BLOCK_PRAGUE = 6; + /** Instantiates a new Prague Gas Calculator. */ public PragueGasCalculator() { - this(BLS12_MAP_FP2_TO_G2.toArrayUnsafe()[19]); + this(BLS12_MAP_FP2_TO_G2.toArrayUnsafe()[19], DEFAULT_TARGET_BLOBS_PER_BLOCK_PRAGUE); + } + + /** + * Instantiates a new Prague Gas Calculator + * + * @param targetBlobsPerBlock the target blobs per block + */ + public PragueGasCalculator(final int targetBlobsPerBlock) { + this(BLS12_MAP_FP2_TO_G2.toArrayUnsafe()[19], targetBlobsPerBlock); } /** * Instantiates a new Prague Gas Calculator * * @param maxPrecompile the max precompile + * @param targetBlobsPerBlock the target blobs per block */ - protected PragueGasCalculator(final int maxPrecompile) { - super(maxPrecompile); + protected PragueGasCalculator(final int maxPrecompile, final int targetBlobsPerBlock) { + super(maxPrecompile, targetBlobsPerBlock); this.existingAccountGasRefund = newAccountGasCost() - CodeDelegation.PER_AUTH_BASE_COST; } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculatorTest.java b/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculatorTest.java index b7a11395a9e..02cb9fd1754 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculatorTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/CancunGasCalculatorTest.java @@ -17,7 +17,6 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.List; -import java.util.Optional; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; @@ -28,6 +27,7 @@ @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class CancunGasCalculatorTest { + private static final long TARGET_BLOB_GAS_PER_BLOCK_CANCUN = 0x60000; private final CancunGasCalculator cancunGasCalculator = new CancunGasCalculator(); @ParameterizedTest(name = "{index} - parent gas {0}, used gas {1}, new excess {2}") @@ -35,13 +35,12 @@ public class CancunGasCalculatorTest { public void shouldCalculateExcessBlobGasCorrectly( final long parentExcess, final long used, final long expected) { final long usedBlobGas = cancunGasCalculator.blobGasCost(used); - assertThat( - cancunGasCalculator.computeExcessBlobGas(parentExcess, usedBlobGas, Optional.empty())) + assertThat(cancunGasCalculator.computeExcessBlobGas(parentExcess, usedBlobGas)) .isEqualTo(expected); } Iterable blobGasses() { - long targetGasPerBlock = CancunGasCalculator.TARGET_BLOB_GAS_PER_BLOCK; + long targetGasPerBlock = TARGET_BLOB_GAS_PER_BLOCK_CANCUN; return List.of( Arguments.of(0L, 0L, 0L), Arguments.of(targetGasPerBlock, 0L, 0L), diff --git a/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculatorTest.java b/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculatorTest.java index 3236c13e833..28ead82f8aa 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculatorTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/OsakaGasCalculatorTest.java @@ -18,10 +18,20 @@ import org.hyperledger.besu.datatypes.Address; +import java.util.List; + import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) class OsakaGasCalculatorTest { + private static final long TARGET_BLOB_GAS_PER_BLOCK_OSAKA = 0x120000; + private final OsakaGasCalculator osakaGasCalculator = new OsakaGasCalculator(); + @Test void testPrecompileSize() { OsakaGasCalculator subject = new OsakaGasCalculator(); @@ -32,10 +42,35 @@ void testPrecompileSize() { @Test void testNewConstants() { CancunGasCalculator cancunGas = new CancunGasCalculator(); - OsakaGasCalculator praugeGasCalculator = new OsakaGasCalculator(); + assertThat(osakaGasCalculator.getMinCalleeGas()).isGreaterThan(cancunGas.getMinCalleeGas()); + assertThat(osakaGasCalculator.getMinRetainedGas()).isGreaterThan(cancunGas.getMinRetainedGas()); + } + + @ParameterizedTest( + name = "{index} - parent gas {0}, used gas {1}, blob target {2} new excess {3}") + @MethodSource("blobGasses") + public void shouldCalculateExcessBlobGasCorrectly( + final long parentExcess, final long used, final long expected) { + final long usedBlobGas = osakaGasCalculator.blobGasCost(used); + assertThat(osakaGasCalculator.computeExcessBlobGas(parentExcess, usedBlobGas)) + .isEqualTo(expected); + } + + Iterable blobGasses() { + long nineBlobTargetGas = TARGET_BLOB_GAS_PER_BLOCK_OSAKA; + long newTargetCount = 9; - assertThat(praugeGasCalculator.getMinCalleeGas()).isGreaterThan(cancunGas.getMinCalleeGas()); - assertThat(praugeGasCalculator.getMinRetainedGas()) - .isGreaterThan(cancunGas.getMinRetainedGas()); + return List.of( + // New target count + Arguments.of(0L, 0L, 0L), + Arguments.of(nineBlobTargetGas, 0L, 0L), + Arguments.of(newTargetCount, 0L, 0L), + Arguments.of(0L, newTargetCount, 0L), + Arguments.of(1L, newTargetCount, 1L), + Arguments.of( + osakaGasCalculator.blobGasCost(newTargetCount), + 1L, + osakaGasCalculator.getBlobGasPerBlob()), + Arguments.of(nineBlobTargetGas, newTargetCount, nineBlobTargetGas)); } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculatorTest.java b/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculatorTest.java index 0b9d0f2372a..fdacad0e84e 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculatorTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculatorTest.java @@ -19,9 +19,7 @@ import org.hyperledger.besu.datatypes.Address; import java.util.List; -import java.util.Optional; -import org.apache.tuweni.units.bigints.UInt64; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.params.ParameterizedTest; @@ -31,6 +29,7 @@ @TestInstance(TestInstance.Lifecycle.PER_CLASS) class PragueGasCalculatorTest { + private static final long TARGET_BLOB_GAS_PER_BLOCK_PRAGUE = 0xC0000; private final PragueGasCalculator pragueGasCalculator = new PragueGasCalculator(); @Test @@ -44,39 +43,27 @@ void testPrecompileSize() { name = "{index} - parent gas {0}, used gas {1}, blob target {2} new excess {3}") @MethodSource("blobGasses") public void shouldCalculateExcessBlobGasCorrectly( - final long parentExcess, final long used, final long target, final long expected) { + final long parentExcess, final long used, final long expected) { final long usedBlobGas = pragueGasCalculator.blobGasCost(used); - assertThat( - pragueGasCalculator.computeExcessBlobGas( - parentExcess, usedBlobGas, Optional.of(UInt64.valueOf(target)))) + assertThat(pragueGasCalculator.computeExcessBlobGas(parentExcess, usedBlobGas)) .isEqualTo(expected); } Iterable blobGasses() { - long threeBlobTargetGas = CancunGasCalculator.TARGET_BLOB_GAS_PER_BLOCK; - long cancunTargetCount = 3; - long newTargetCount = 4; + long sixBlobTargetGas = TARGET_BLOB_GAS_PER_BLOCK_PRAGUE; + long newTargetCount = 6; return List.of( - // If blob target count remains at 3 - Arguments.of(0L, 0L, cancunTargetCount, 0L), - Arguments.of(threeBlobTargetGas, 0L, cancunTargetCount, 0L), - Arguments.of(0L, cancunTargetCount, cancunTargetCount, 0L), - Arguments.of(1L, cancunTargetCount, cancunTargetCount, 1L), - Arguments.of( - threeBlobTargetGas, 1L, cancunTargetCount, pragueGasCalculator.getBlobGasPerBlob()), - Arguments.of(threeBlobTargetGas, 3L, cancunTargetCount, threeBlobTargetGas), // New target count - Arguments.of(0L, 0L, newTargetCount, 0L), - Arguments.of(threeBlobTargetGas, 0L, newTargetCount, 0L), - Arguments.of(newTargetCount, 0L, newTargetCount, 0L), - Arguments.of(0L, newTargetCount, newTargetCount, 0L), - Arguments.of(1L, newTargetCount, newTargetCount, 1L), + Arguments.of(0L, 0L, 0L), + Arguments.of(sixBlobTargetGas, 0L, 0L), + Arguments.of(newTargetCount, 0L, 0L), + Arguments.of(0L, newTargetCount, 0L), + Arguments.of(1L, newTargetCount, 1L), Arguments.of( pragueGasCalculator.blobGasCost(newTargetCount), 1L, - newTargetCount, pragueGasCalculator.getBlobGasPerBlob()), - Arguments.of(threeBlobTargetGas, newTargetCount, newTargetCount, threeBlobTargetGas)); + Arguments.of(sixBlobTargetGas, newTargetCount, sixBlobTargetGas)); } }