Repository: hyperledger/besu (2025-07-08T09:38:12Z)

Issue:
EIP-7594: Remove maxBlobsPerTx from from BPO and hard a constant limit of 6 blobs/txn
<!-- Have you done the following? -->
<!--   * read the Code of Conduct? By filing an Issue, you are expected to -->  
<!--     comply with it, including treating everyone with respect: -->
<!--     https://github.com/hyperledger/besu/blob/main/CODE_OF_CONDUCT.md -->
<!--   * Duplicate Issue check:  https://github.com/search?q=+is%3Aissue+repo%3Ahyperledger/Besu -->

### Description
As an [Actor], I want [feature] so that [why].

### Acceptance Criteria
* [Criteria 1]
* [Criteria 2]
* [Criteria 3...]

### Logs (if a change in behavior)
Please post relevant logs from Besu (and the consensus client, if running proof of stake) illustrating behavior to be altered

### Versions (Add all that apply)
* Software version: [`besu --version`]
* Java version: [`java -version`]
* OS Name & Version: [`cat /etc/*release`]
* Kernel Version: [`uname -a`]
* Virtual Machine software & version: [`vmware -v`]
* Docker Version: [`docker version`]
* Cloud VM, type, size: [Amazon Web Services I3-large]
* Consensus Client & Version if using Proof of Stake: [e.g. Teku, Lighthouse, Prysm, Nimbus, Lodestar]

### Smart contract information (If you're reporting an issue arising from deploying or calling a smart contract, please supply related information)
* Solidity version [`solc --version`]
* Repo with minimal set of deployable/reproducible contract code - please provide a link
* Please include specifics on how you are deploying/calling the contract
* Have you reproduced the issue on other eth clients

### Additional Information (Add any of the following or anything else that may be relevant)
* Besu setup info - genesis file, config options
* System info - memory, CPU



Discussion:
https://github.com/hyperledger/besu/pull/8929



Patch:
diff --git a/config/src/main/java/org/hyperledger/besu/config/BlobSchedule.java b/config/src/main/java/org/hyperledger/besu/config/BlobSchedule.java
index 5b0ddb5b68e..b2bd1b46101 100644
--- a/config/src/main/java/org/hyperledger/besu/config/BlobSchedule.java
+++ b/config/src/main/java/org/hyperledger/besu/config/BlobSchedule.java
@@ -21,24 +21,18 @@
 /** The Blob schedule for a particular fork. */
 public class BlobSchedule {
   /** The constant CANCUN_DEFAULT. */
-  public static final BlobSchedule CANCUN_DEFAULT = BlobSchedule.create(3, 6, 6, 3338477);
+  public static final BlobSchedule CANCUN_DEFAULT = BlobSchedule.create(3, 6, 3338477);
 
   /** The constant PRAGUE_DEFAULT. */
-  public static final BlobSchedule PRAGUE_DEFAULT = BlobSchedule.create(6, 9, 9, 5007716);
+  public static final BlobSchedule PRAGUE_DEFAULT = BlobSchedule.create(6, 9, 5007716);
 
   private final int target;
   private final int max;
-  private final int maxPerTransaction;
   private final int baseFeeUpdateFraction;
 
-  private BlobSchedule(
-      final int target,
-      final int max,
-      final int maxPerTransaction,
-      final int baseFeeUpdateFraction) {
+  private BlobSchedule(final int target, final int max, final int baseFeeUpdateFraction) {
     this.target = target;
     this.max = max;
-    this.maxPerTransaction = maxPerTransaction;
     this.baseFeeUpdateFraction = baseFeeUpdateFraction;
   }
 
@@ -51,18 +45,14 @@ private BlobSchedule(
   public static BlobSchedule create(final ObjectNode blobScheduleConfigRoot) {
     int target = JsonUtil.getInt(blobScheduleConfigRoot, "target").orElseThrow();
     int max = JsonUtil.getInt(blobScheduleConfigRoot, "max").orElseThrow();
-    int maxPerTransaction = JsonUtil.getInt(blobScheduleConfigRoot, "maxblobspertx").orElse(max);
     int baseFeeUpdateFraction =
         JsonUtil.getInt(blobScheduleConfigRoot, "basefeeupdatefraction").orElseThrow();
-    return create(target, max, maxPerTransaction, baseFeeUpdateFraction);
+    return create(target, max, baseFeeUpdateFraction);
   }
 
   private static BlobSchedule create(
-      final int target,
-      final int max,
-      final int maxPerTransaction,
-      final int baseFeeUpdateFraction) {
-    return new BlobSchedule(target, max, maxPerTransaction, baseFeeUpdateFraction);
+      final int target, final int max, final int baseFeeUpdateFraction) {
+    return new BlobSchedule(target, max, baseFeeUpdateFraction);
   }
 
   /**
@@ -83,15 +73,6 @@ public int getMax() {
     return max;
   }
 
-  /**
-   * Gets max per transaction.
-   *
-   * @return the max per transaction
-   */
-  public int getMaxPerTransaction() {
-    return maxPerTransaction;
-  }
-
   /**
    * Gets base fee update fraction.
    *
@@ -126,7 +107,7 @@ public String toString() {
   public static class NoBlobSchedule extends BlobSchedule {
     /** Constructs a NoBlobSchedule */
     public NoBlobSchedule() {
-      super(0, 0, 0, 0);
+      super(0, 0, 0);
     }
 
     @Override
@@ -144,11 +125,6 @@ public int getBaseFeeUpdateFraction() {
       throw new UnsupportedOperationException("NoBlobSchedule does not support this operation.");
     }
 
-    @Override
-    public int getMaxPerTransaction() {
-      throw new UnsupportedOperationException("NoBlobSchedule does not support this operation.");
-    }
-
     @Override
     public Map<String, Object> asMap() {
       throw new UnsupportedOperationException("NoBlobSchedule does not support this operation.");
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 14c60daeb3d..fec7ce858ab 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
@@ -14,43 +14,16 @@
  */
 package org.hyperledger.besu.ethereum.mainnet;
 
-import static com.google.common.base.Preconditions.checkArgument;
-
 import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
 import org.hyperledger.besu.evm.gascalculator.GasCalculator;
 
 public class CancunTargetingGasLimitCalculator extends LondonTargetingGasLimitCalculator {
-
-  /** The mainnet default maximum number of blobs per block for Cancun */
-  private static final int DEFAULT_MAX_BLOBS_PER_BLOCK_CANCUN = 6;
-
-  /** The default target number of blobs per transaction for Cancun */
-  private static final int DEFAULT_MAX_BLOBS_PER_TRANSACTION_CANCUN = 6;
-
-  /** The default mainnet target blobs per block for Cancun */
-  private static final int DEFAULT_TARGET_BLOBS_PER_BLOCK_CANCUN = 3;
-
   private final long maxBlobGasPerBlock;
-
   private final long targetBlobGasPerBlock;
-
   private final long blobGasPerBlob;
+
   protected final int maxBlobsPerBlock;
   protected final int targetBlobsPerBlock;
-  private final long transactionBlobGasLimitCap;
-
-  public CancunTargetingGasLimitCalculator(
-      final long londonForkBlock,
-      final BaseFeeMarket feeMarket,
-      final GasCalculator gasCalculator) {
-    this(
-        londonForkBlock,
-        feeMarket,
-        gasCalculator,
-        DEFAULT_MAX_BLOBS_PER_BLOCK_CANCUN,
-        DEFAULT_TARGET_BLOBS_PER_BLOCK_CANCUN,
-        DEFAULT_MAX_BLOBS_PER_TRANSACTION_CANCUN);
-  }
 
   /**
    * Using Cancun mainnet default of 6 blobs for maxBlobsPerBlock: getBlobGasPerBlob() * 6 blobs =
@@ -61,20 +34,13 @@ public CancunTargetingGasLimitCalculator(
       final BaseFeeMarket feeMarket,
       final GasCalculator gasCalculator,
       final int maxBlobsPerBlock,
-      final int targetBlobsPerBlock,
-      final int maxBlobsPerTransaction) {
+      final int targetBlobsPerBlock) {
     super(londonForkBlock, feeMarket);
     this.blobGasPerBlob = gasCalculator.getBlobGasPerBlob();
     this.targetBlobGasPerBlock = blobGasPerBlob * targetBlobsPerBlock;
     this.maxBlobGasPerBlock = blobGasPerBlob * maxBlobsPerBlock;
     this.maxBlobsPerBlock = maxBlobsPerBlock;
     this.targetBlobsPerBlock = targetBlobsPerBlock;
-    this.transactionBlobGasLimitCap = gasCalculator.getBlobGasPerBlob() * maxBlobsPerTransaction;
-    checkArgument(
-        maxBlobsPerBlock >= maxBlobsPerTransaction,
-        "maxBlobsPerTransaction (%s) must not be greater than maxBlobsPerBlock (%s)",
-        maxBlobsPerTransaction,
-        maxBlobsPerBlock);
   }
 
   @Override
@@ -114,6 +80,6 @@ public long getMaxBlobGasPerBlock() {
 
   @Override
   public long transactionBlobGasLimitCap() {
-    return transactionBlobGasLimitCap;
+    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 507bd315153..cf067f3b6e0 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
@@ -692,8 +692,7 @@ static ProtocolSpecBuilder cancunDefinition(
                     (BaseFeeMarket) feeMarket,
                     gasCalculator,
                     blobSchedule.getMax(),
-                    blobSchedule.getTarget(),
-                    blobSchedule.getMaxPerTransaction()))
+                    blobSchedule.getTarget()))
         // EVM changes to support EIP-1153: TSTORE and EIP-5656: MCOPY
         .evmBuilder(
             (gasCalculator, jdCacheConfig) ->
@@ -783,7 +782,6 @@ static ProtocolSpecBuilder pragueDefinition(
                     .flatMap(BlobScheduleOptions::getPrague)
                     .orElse(BlobSchedule.PRAGUE_DEFAULT))
             .gasCalculator(PragueGasCalculator::new)
-            // EIP-3074 AUTH and AUTHCALL
             .evmBuilder(
                 (gasCalculator, jdCacheConfig) ->
                     MainnetEVMs.prague(
@@ -879,8 +877,7 @@ static ProtocolSpecBuilder osakaDefinition(
                     (BaseFeeMarket) feeMarket,
                     gasCalculator,
                     blobSchedule.getMax(),
-                    blobSchedule.getTarget(),
-                    blobSchedule.getMaxPerTransaction()))
+                    blobSchedule.getTarget()))
         .evmBuilder(
             (gasCalculator, __) ->
                 MainnetEVMs.osaka(gasCalculator, chainId.orElse(BigInteger.ZERO), evmConfiguration))
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 597f98178e2..1019345462c 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
@@ -14,12 +14,17 @@
  */
 package org.hyperledger.besu.ethereum.mainnet;
 
+import static com.google.common.base.Preconditions.checkArgument;
+
 import org.hyperledger.besu.datatypes.BlobGas;
 import org.hyperledger.besu.datatypes.Wei;
 import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
 import org.hyperledger.besu.evm.gascalculator.GasCalculator;
 
 public class OsakaTargetingGasLimitCalculator extends CancunTargetingGasLimitCalculator {
+  /** The constant max number of blobs per transaction defined for Osaka */
+  private static final int DEFAULT_MAX_BLOBS_PER_TRANSACTION = 6;
+
   /** The blob base cost constant for Osaka */
   private static final long BLOB_BASE_COST = 1 << 13; // 2^13
 
@@ -27,21 +32,21 @@ public class OsakaTargetingGasLimitCalculator extends CancunTargetingGasLimitCal
   private static final long DEFAULT_TRANSACTION_GAS_LIMIT_CAP_OSAKA = 30_000_000L;
 
   private final long transactionGasLimitCap;
+  private final long transactionBlobGasLimitCap;
 
   public OsakaTargetingGasLimitCalculator(
       final long londonForkBlock,
       final BaseFeeMarket feeMarket,
       final GasCalculator gasCalculator,
       final int maxBlobsPerBlock,
-      final int targetBlobsPerBlock,
-      final int maxBlobsPerTransaction) {
+      final int targetBlobsPerBlock) {
     this(
         londonForkBlock,
         feeMarket,
         gasCalculator,
         maxBlobsPerBlock,
         targetBlobsPerBlock,
-        maxBlobsPerTransaction,
+        DEFAULT_MAX_BLOBS_PER_TRANSACTION,
         DEFAULT_TRANSACTION_GAS_LIMIT_CAP_OSAKA);
   }
 
@@ -53,14 +58,14 @@ public OsakaTargetingGasLimitCalculator(
       final int targetBlobsPerBlock,
       final int maxBlobsPerTransaction,
       final long transactionGasLimitCap) {
-    super(
-        londonForkBlock,
-        feeMarket,
-        gasCalculator,
-        maxBlobsPerBlock,
-        targetBlobsPerBlock,
-        maxBlobsPerTransaction);
+    super(londonForkBlock, feeMarket, gasCalculator, maxBlobsPerBlock, targetBlobsPerBlock);
     this.transactionGasLimitCap = transactionGasLimitCap;
+    this.transactionBlobGasLimitCap = gasCalculator.getBlobGasPerBlob() * maxBlobsPerTransaction;
+    checkArgument(
+        maxBlobsPerBlock >= maxBlobsPerTransaction,
+        "maxBlobsPerTransaction (%s) must not be greater than maxBlobsPerBlock (%s)",
+        maxBlobsPerTransaction,
+        maxBlobsPerBlock);
   }
 
   @Override
@@ -91,4 +96,9 @@ public long computeExcessBlobGas(
       return currentExcessBlobGas - getTargetBlobGasPerBlock();
     }
   }
+
+  @Override
+  public long transactionBlobGasLimitCap() {
+    return transactionBlobGasLimitCap;
+  }
 }


Test patch:
diff --git a/config/src/test/java/org/hyperledger/besu/config/BlobScheduleOptionsTest.java b/config/src/test/java/org/hyperledger/besu/config/BlobScheduleOptionsTest.java
index d14c96376ee..e7e6879cb0e 100644
--- a/config/src/test/java/org/hyperledger/besu/config/BlobScheduleOptionsTest.java
+++ b/config/src/test/java/org/hyperledger/besu/config/BlobScheduleOptionsTest.java
@@ -49,30 +49,11 @@ public void blobScheduleIsParsed() {
   @Test
   public void blobScheduleDefaults() {
     assertThat(BlobSchedule.CANCUN_DEFAULT.getTarget()).isEqualTo(3);
-    assertThat(BlobSchedule.CANCUN_DEFAULT.getMaxPerTransaction()).isEqualTo(6);
     assertThat(BlobSchedule.CANCUN_DEFAULT.getMax()).isEqualTo(6);
     assertThat(BlobSchedule.PRAGUE_DEFAULT.getTarget()).isEqualTo(6);
-    assertThat(BlobSchedule.PRAGUE_DEFAULT.getMaxPerTransaction()).isEqualTo(9);
     assertThat(BlobSchedule.PRAGUE_DEFAULT.getMax()).isEqualTo(9);
   }
 
-  @Test
-  public void blobScheduleMaxPerTransactionDefaultsToMax() {
-    Optional<BlobSchedule> cancun = options.getCancun();
-    assertThat(cancun).isNotEmpty();
-    BlobSchedule schedule = cancun.get();
-    assertThat(schedule.getMaxPerTransaction()).isEqualTo(schedule.getMax());
-  }
-
-  @Test
-  public void blobScheduleMaxPerTransactionIsSpecified() {
-    Optional<BlobSchedule> bpo1 = options.getBpo1();
-    assertThat(bpo1).isNotEmpty();
-    BlobSchedule schedule = bpo1.get();
-    assertThat(schedule.getMax()).isEqualTo(12);
-    assertThat(schedule.getMaxPerTransaction()).isEqualTo(13);
-  }
-
   private void assertParsed(
       final Supplier<Optional<BlobSchedule>> scheduleSupplier,
       final int expectedTarget,
diff --git a/config/src/test/resources/mainnet_with_blob_schedule.json b/config/src/test/resources/mainnet_with_blob_schedule.json
index 9719d40084d..4dfe4aa68b6 100644
--- a/config/src/test/resources/mainnet_with_blob_schedule.json
+++ b/config/src/test/resources/mainnet_with_blob_schedule.json
@@ -30,31 +30,26 @@
       "bpo1": {
         "target": 11,
         "max": 12,
-        "maxBlobsPerTx": 13,
         "baseFeeUpdateFraction": 5007716
       },
       "bpo2": {
         "target": 21,
         "max": 22,
-        "maxBlobsPerTx": 23,
         "baseFeeUpdateFraction": 5007716
       },
       "bpo3": {
         "target": 31,
         "max": 32,
-        "maxBlobsPerTx": 33,
         "baseFeeUpdateFraction": 5007716
       },
       "bpo4": {
         "target": 41,
         "max": 42,
-        "maxBlobsPerTx": 43,
         "baseFeeUpdateFraction": 5007716
       },
       "bpo5": {
         "target": 51,
         "max": 52,
-        "maxBlobsPerTx": 53,
         "baseFeeUpdateFraction": 5007716
       },
       "future_eips": {
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthBlobBaseFeeTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthBlobBaseFeeTest.java
index d5df79a1922..8fa0b73024b 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthBlobBaseFeeTest.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthBlobBaseFeeTest.java
@@ -41,6 +41,8 @@
 import org.junit.jupiter.api.Test;
 
 public class EthBlobBaseFeeTest {
+  private static final int MAX_BLOBS_PER_BLOCK = 6;
+  private static final int TARGET_BLOBS_PER_BLOCK = 3;
   private final BlockDataGenerator blockDataGenerator = new BlockDataGenerator();
   private MutableBlockchain blockchain;
   private EthBlobBaseFee method;
@@ -62,7 +64,11 @@ public void setUp() {
   public void shouldReturnBlobBaseFee() {
     final CancunTargetingGasLimitCalculator gasLimitCalculator =
         new CancunTargetingGasLimitCalculator(
-            0L, FeeMarket.cancunDefault(0L, Optional.empty()), new CancunGasCalculator());
+            0L,
+            FeeMarket.cancunDefault(0L, Optional.empty()),
+            new CancunGasCalculator(),
+            MAX_BLOBS_PER_BLOCK,
+            TARGET_BLOBS_PER_BLOCK);
     configureProtocolSpec(
         FeeMarket.cancunDefault(5, Optional.empty()),
         new CancunGasCalculator(),
@@ -75,7 +81,11 @@ public void shouldReturnBlobBaseFee() {
   public void shouldReturnZeroForNonBlobForks() {
     final CancunTargetingGasLimitCalculator gasLimitCalculator =
         new CancunTargetingGasLimitCalculator(
-            0L, FeeMarket.cancunDefault(0L, Optional.empty()), new ShanghaiGasCalculator());
+            0L,
+            FeeMarket.cancunDefault(0L, Optional.empty()),
+            new ShanghaiGasCalculator(),
+            MAX_BLOBS_PER_BLOCK,
+            TARGET_BLOBS_PER_BLOCK);
     configureProtocolSpec(
         FeeMarket.london(5, Optional.empty()), new ShanghaiGasCalculator(), gasLimitCalculator);
     assertThat(requestBlobBaseFee().getResult()).isEqualTo("0x0");
diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java
index a0cca61c016..d4fd1c8cbf0 100644
--- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java
+++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java
@@ -64,6 +64,8 @@
 import org.junit.jupiter.api.Test;
 
 public class EthGetTransactionReceiptTest {
+  private static final int MAX_BLOBS_PER_BLOCK = 6;
+  private static final int TARGET_BLOBS_PER_BLOCK = 3;
   private final TransactionReceipt statusReceipt =
       new TransactionReceipt(1, 12, Collections.emptyList(), Optional.empty());
   private final Hash stateRoot =
@@ -329,7 +331,11 @@ private void mockProtocolSpec(final BlockHeader blockHeader) {
     when(spec.getGasLimitCalculator())
         .thenReturn(
             new CancunTargetingGasLimitCalculator(
-                0L, FeeMarket.cancunDefault(0L, Optional.empty()), new CancunGasCalculator()));
+                0L,
+                FeeMarket.cancunDefault(0L, Optional.empty()),
+                new CancunGasCalculator(),
+                MAX_BLOBS_PER_BLOCK,
+                TARGET_BLOBS_PER_BLOCK));
     when(protocolSchedule.getByBlockHeader(blockHeader)).thenReturn(spec);
   }
 
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 79aae79922b..07d2fd7a795 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
@@ -35,10 +35,16 @@
 
 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
 class CancunTargetingGasLimitCalculatorTest {
+  private static final int MAX_BLOBS_PER_BLOCK = 6;
+  private static final int TARGET_BLOBS_PER_BLOCK = 3;
   private static final long TARGET_BLOB_GAS_PER_BLOCK_CANCUN = 0x60000;
   private final CancunTargetingGasLimitCalculator cancunTargetingGasLimitCalculator =
       new CancunTargetingGasLimitCalculator(
-          0L, FeeMarket.cancunDefault(0L, Optional.empty()), new CancunGasCalculator());
+          0L,
+          FeeMarket.cancunDefault(0L, Optional.empty()),
+          new CancunGasCalculator(),
+          MAX_BLOBS_PER_BLOCK,
+          TARGET_BLOBS_PER_BLOCK);
 
   @ParameterizedTest(name = "{index} - parent gas {0}, used gas {1}, new excess {2}")
   @MethodSource("cancunBlobGasses")
@@ -61,35 +67,6 @@ Iterable<Arguments> cancunBlobGasses() {
         Arguments.of(targetGasPerBlock, 3, targetGasPerBlock));
   }
 
-  @Test
-  void currentBlobGasLimitIs6Blobs() {
-    var cancunTargetingGasLimitCalculator =
-        new org.hyperledger.besu.ethereum.mainnet.CancunTargetingGasLimitCalculator(
-            0L, FeeMarket.cancunDefault(0L, Optional.empty()), new CancunGasCalculator());
-    assertThat(cancunTargetingGasLimitCalculator.currentBlobGasLimit()).isEqualTo(0xC0000);
-  }
-
-  @Test
-  void maxBlobPerTransactionMustNotExceedMaxBlobsPerBlock() {
-    int maxBlobsPerBlock = 10;
-    int targetBlobsPerBlock = 9;
-    int maxBlobsPerTransaction = 11;
-    Assertions.assertThatThrownBy(
-            () ->
-                new CancunTargetingGasLimitCalculator(
-                    0L,
-                    FeeMarket.cancunDefault(0L, Optional.empty()),
-                    pragueGasCalculator,
-                    maxBlobsPerBlock,
-                    targetBlobsPerBlock,
-                    maxBlobsPerTransaction))
-        .isInstanceOf(IllegalArgumentException.class)
-        .hasMessageContaining(
-            String.format(
-                "maxBlobsPerTransaction (%d) must not be greater than maxBlobsPerBlock (%d)",
-                maxBlobsPerTransaction, maxBlobsPerBlock));
-  }
-
   @Test
   void shouldUseCancunCalculatorBlobGasPerBlob() {
     // should use CancunGasCalculator's blob gas per blob to calculate the gas limit
@@ -103,8 +80,7 @@ void shouldUseCancunCalculatorBlobGasPerBlob() {
             FeeMarket.cancunDefault(0L, Optional.empty()),
             new CancunGasCalculator(),
             maxBlobs,
-            targetBlobs,
-            maxBlobs);
+            targetBlobs);
     // if maxBlobs = 10, then the gas limit would be 131072 * 10 = 1310720
     assertThat(cancunTargetingGasLimitCalculator.currentBlobGasLimit())
         .isEqualTo(blobGasPerBlob * maxBlobs);
@@ -119,8 +95,7 @@ void shouldUseCancunCalculatorBlobGasPerBlob() {
           FeeMarket.cancunDefault(0L, Optional.empty()),
           pragueGasCalculator,
           BlobSchedule.PRAGUE_DEFAULT.getMax(),
-          BlobSchedule.PRAGUE_DEFAULT.getTarget(),
-          BlobSchedule.PRAGUE_DEFAULT.getMaxPerTransaction());
+          BlobSchedule.PRAGUE_DEFAULT.getTarget());
 
   private static final long TARGET_BLOB_GAS_PER_BLOCK_PRAGUE = 0xC0000;
 
@@ -164,8 +139,7 @@ void shouldCalculateCorrectlyPragueBlobGasPerBlob() {
             FeeMarket.cancun(0L, Optional.empty(), BlobSchedule.PRAGUE_DEFAULT),
             new PragueGasCalculator(),
             maxBlobs,
-            targetBlobs,
-            maxBlobs);
+            targetBlobs);
     // if maxBlobs = 10, then the gas limit would be 131072 * 10 = 1310720
     assertThat(pragueTargetingGasLimitCalculator.currentBlobGasLimit())
         .isEqualTo(blobGasPerBlob * maxBlobs);
@@ -182,8 +156,7 @@ void shouldCalculateCorrectlyPragueBlobGasPerBlob() {
           FeeMarket.cancunDefault(0L, Optional.empty()),
           osakaGasCalculator,
           BlobSchedule.PRAGUE_DEFAULT.getMax(),
-          newTargetCount,
-          BlobSchedule.PRAGUE_DEFAULT.getMaxPerTransaction());
+          newTargetCount);
 
   private static final long TARGET_BLOB_GAS_PER_BLOCK_OSAKA = 0x120000;
 
@@ -220,8 +193,7 @@ void cancunDefaultGasLimit() {
             FeeMarket.cancunDefault(0L, Optional.empty()),
             new CancunGasCalculator(),
             BlobSchedule.CANCUN_DEFAULT.getMax(),
-            BlobSchedule.CANCUN_DEFAULT.getTarget(),
-            BlobSchedule.CANCUN_DEFAULT.getMaxPerTransaction());
+            BlobSchedule.CANCUN_DEFAULT.getTarget());
     assertThat(gasLimitCalculator.currentBlobGasLimit()).isEqualTo(0xC0000); // 6 * 131072
     assertThat(gasLimitCalculator.transactionBlobGasLimitCap()).isEqualTo(0xC0000); // 6 * 131072
   }
@@ -234,8 +206,7 @@ void pragueDefaultGasLimit() {
             FeeMarket.cancunDefault(0L, Optional.empty()),
             new CancunGasCalculator(),
             BlobSchedule.PRAGUE_DEFAULT.getMax(),
-            BlobSchedule.PRAGUE_DEFAULT.getTarget(),
-            BlobSchedule.PRAGUE_DEFAULT.getMaxPerTransaction());
+            BlobSchedule.PRAGUE_DEFAULT.getTarget());
     assertThat(gasLimitCalculator.currentBlobGasLimit()).isEqualTo(0x120000); // 9 * 131072
     assertThat(gasLimitCalculator.transactionBlobGasLimitCap()).isEqualTo(0x120000); // 9 * 131072
   }
diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/OsakaTargetingGasLimitCalculatorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/OsakaTargetingGasLimitCalculatorTest.java
index 3ed9a1ae5cc..432852e4aa0 100644
--- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/OsakaTargetingGasLimitCalculatorTest.java
+++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/OsakaTargetingGasLimitCalculatorTest.java
@@ -33,7 +33,7 @@
 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
 class OsakaTargetingGasLimitCalculatorTest {
   private static final long TARGET_BLOB_GAS_PER_BLOCK_OSAKA = 0x120000;
-
+  private static final long TRANSACTION_GAS_LIMIT_CAP = 30_000_000L;
   private final OsakaGasCalculator osakaGasCalculator = new OsakaGasCalculator();
   private final BaseFeeMarket feeMarket = FeeMarket.cancunDefault(0L, Optional.empty());
 
@@ -49,7 +49,7 @@ public void shouldCalculateOsakaExcessBlobGasCorrectly(
     int targetBlobs = 9;
     final OsakaTargetingGasLimitCalculator osakaTargetingGasLimitCalculator =
         new OsakaTargetingGasLimitCalculator(
-            0L, feeMarket, osakaGasCalculator, maxBlobs, targetBlobs, maxBlobs);
+            0L, feeMarket, osakaGasCalculator, maxBlobs, targetBlobs);
 
     final long usedBlobGas = osakaGasCalculator.blobGasCost(used);
     assertThat(
@@ -87,7 +87,7 @@ void shouldUseCorrectBlobGasPerBlob() {
     int targetBlobs = 9;
     var osakaTargetingGasLimitCalculator =
         new OsakaTargetingGasLimitCalculator(
-            0L, feeMarket, osakaGasCalculator, maxBlobs, targetBlobs, maxBlobs);
+            0L, feeMarket, osakaGasCalculator, maxBlobs, targetBlobs);
 
     // if maxBlobs = 10, then the gas limit would be 131072 * 10 = 1310720
     assertThat(osakaTargetingGasLimitCalculator.currentBlobGasLimit())
@@ -104,7 +104,7 @@ void testComputeExcessBlobGasWithDifferentConditions() {
     int targetBlobs = 9;
     var calculator =
         new OsakaTargetingGasLimitCalculator(
-            0L, feeMarket, osakaGasCalculator, maxBlobs, targetBlobs, maxBlobs);
+            0L, feeMarket, osakaGasCalculator, maxBlobs, targetBlobs);
     assertThat(calculator.maxBlobsPerBlock).isEqualTo(maxBlobs);
     assertThat(calculator.targetBlobsPerBlock).isEqualTo(targetBlobs);
 
@@ -126,6 +126,38 @@ void testComputeExcessBlobGasWithDifferentConditions() {
     assertThat(result2).isEqualTo(10878976L);
   }
 
+  @Test
+  void maxBlobPerTransactionMustNotExceedMaxBlobsPerBlock() {
+    int maxBlobsPerBlock = 10;
+    int targetBlobsPerBlock = 9;
+    int maxBlobsPerTransaction = 11;
+    Assertions.assertThatThrownBy(
+            () ->
+                new OsakaTargetingGasLimitCalculator(
+                    0L,
+                    feeMarket,
+                    osakaGasCalculator,
+                    maxBlobsPerBlock,
+                    targetBlobsPerBlock,
+                    maxBlobsPerTransaction,
+                    TRANSACTION_GAS_LIMIT_CAP))
+        .isInstanceOf(IllegalArgumentException.class)
+        .hasMessageContaining(
+            String.format(
+                "maxBlobsPerTransaction (%d) must not be greater than maxBlobsPerBlock (%d)",
+                maxBlobsPerTransaction, maxBlobsPerBlock));
+  }
+
+  @Test
+  void osakaBlobGasLimitPerTransaction() {
+    int maxBlobs = 10;
+    int targetBlobs = 9;
+    var calculator =
+        new OsakaTargetingGasLimitCalculator(
+            0L, feeMarket, osakaGasCalculator, maxBlobs, targetBlobs);
+    assertThat(calculator.transactionBlobGasLimitCap()).isEqualTo(0xC0000); // 6 * 131072
+  }
+
   @Test
   void dryRunDetector() {
     Assertions.assertThat(true)
diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/BlobGasValidationRuleTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/BlobGasValidationRuleTest.java
index c946082f4ca..8fb054bd929 100644
--- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/BlobGasValidationRuleTest.java
+++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/headervalidationrules/BlobGasValidationRuleTest.java
@@ -31,7 +31,8 @@
 
 /** Tests for the {@link BlobGasValidationRule} class. */
 public class BlobGasValidationRuleTest {
-
+  private static final int MAX_BLOBS_PER_BLOCK = 6;
+  private static final int TARGET_BLOBS_PER_BLOCK = 3;
   private CancunGasCalculator cancunGasCalculator;
   private BlobGasValidationRule cancunBlobGasValidationRule;
   private CancunTargetingGasLimitCalculator cancunTargetingGasLimitCalculator;
@@ -45,14 +46,22 @@ public void setUp() {
     cancunGasCalculator = new CancunGasCalculator();
     cancunTargetingGasLimitCalculator =
         new CancunTargetingGasLimitCalculator(
-            0L, FeeMarket.cancunDefault(0L, Optional.empty()), cancunGasCalculator);
+            0L,
+            FeeMarket.cancunDefault(0L, Optional.empty()),
+            cancunGasCalculator,
+            MAX_BLOBS_PER_BLOCK,
+            TARGET_BLOBS_PER_BLOCK);
     cancunBlobGasValidationRule =
         new BlobGasValidationRule(cancunGasCalculator, cancunTargetingGasLimitCalculator);
 
     pragueGasCalculator = new PragueGasCalculator();
     pragueGasLimitCalculator =
         new CancunTargetingGasLimitCalculator(
-            0L, FeeMarket.cancunDefault(0L, Optional.empty()), pragueGasCalculator);
+            0L,
+            FeeMarket.cancunDefault(0L, Optional.empty()),
+            pragueGasCalculator,
+            MAX_BLOBS_PER_BLOCK,
+            TARGET_BLOBS_PER_BLOCK);
     pragueBlobGasValidationRule =
         new BlobGasValidationRule(pragueGasCalculator, pragueGasLimitCalculator);
   }