Skip to content
This repository was archived by the owner on Apr 1, 2026. It is now read-only.

Commit 1f74e90

Browse files
committed
Fix DAFootprint calculation in block header
1 parent 816896a commit 1f74e90

5 files changed

Lines changed: 49 additions & 49 deletions

File tree

consensus/merge/merge.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"errors"
66
"fmt"
7+
"github.com/erigontech/erigon-lib/opstack"
78
"math/big"
89

910
"github.com/holiman/uint256"
@@ -189,6 +190,17 @@ func (s *Merge) Finalize(config *chain.Config, header *types.Header, state *stat
189190
}
190191
}
191192

193+
// Store DA footprint in BlobGasUsed header field if it hasn't already been set yet.
194+
// Builder code may already calculate it during block building to avoid recalculating it here.
195+
if config.IsJovian(header.Time) && (header.BlobGasUsed == nil || *header.BlobGasUsed == 0) {
196+
daFootprint, err := CalcDAFootprint(txs)
197+
if err != nil {
198+
return nil, nil, nil, fmt.Errorf("error calculating DA footprint: %w", err)
199+
}
200+
log.Info("DA Footprint: ", "val", daFootprint)
201+
header.BlobGasUsed = &daFootprint
202+
}
203+
192204
return txs, receipts, rs, nil
193205
}
194206

@@ -373,3 +385,37 @@ func IsTTDReached(chain consensus.ChainHeaderReader, parentHash libcommon.Hash,
373385
}
374386
return td.Cmp(chain.Config().TerminalTotalDifficulty) >= 0, nil
375387
}
388+
389+
// CalcDAFootprint calculates the total DA footprint of a block for an OP Stack chain.
390+
// Jovian introduces a DA footprint block limit which is stored in the BlobGasUsed header field and that is taken
391+
// into account during base fee updates.
392+
// CalcDAFootprint must not be called for pre-Jovian blocks.
393+
func CalcDAFootprint(txs types.Transactions) (uint64, error) {
394+
if txs.Len() == 0 || txs[0].Type() != types.DepositTxType {
395+
return 0, fmt.Errorf("missing deposit transaction")
396+
}
397+
398+
// First Jovian block doesn't set the DA footprint gas scalar yet and
399+
// it must not have user transactions.
400+
data := txs[0].GetData()
401+
if len(data) == opstack.IsthmusL1AttributesLen {
402+
if txs[len(txs)-1].Type() != types.DepositTxType {
403+
// sufficient to check last transaction because deposits precede non-deposit txs
404+
return 0, fmt.Errorf("unexpected non-deposit transactions in Jovian activation block")
405+
}
406+
return 0, nil
407+
} // ExtractDAFootprintGasScalar catches all invalid lengths
408+
409+
daFootprintGasScalar, err := opstack.ExtractDAFootprintGasScalar(data)
410+
if err != nil {
411+
return 0, err
412+
}
413+
var daFootprint uint64
414+
for _, tx := range txs {
415+
if tx.Type() == types.DepositTxType {
416+
continue
417+
}
418+
daFootprint += tx.RollupCostData().EstimatedDASize().Uint64() * uint64(daFootprintGasScalar)
419+
}
420+
return daFootprint, nil
421+
}

core/blockchain.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ func ExecuteBlockEphemerally(
153153
return nil, fmt.Errorf("gas used by execution: %d, in header: %d", *usedGas, header.GasUsed)
154154
}
155155

156-
if header.BlobGasUsed != nil && *usedBlobGas != *header.BlobGasUsed {
156+
if !chainConfig.IsOptimism() && header.BlobGasUsed != nil && *usedBlobGas != *header.BlobGasUsed {
157157
return nil, fmt.Errorf("blob gas used by execution: %d, in header: %d", *usedBlobGas, *header.BlobGasUsed)
158158
}
159159

eth/stagedsync/stage_mining_exec.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ LOOP:
509509
var txDAFootprint uint64
510510
// Note that commitTransaction is only called after deposit transactions have already been committed,
511511
// so we don't need to resolve the transaction here and exclude deposits.
512-
if isJovian {
512+
if isJovian && txn.Type() != types.DepositTxType {
513513
txDAFootprint = txn.RollupCostData().EstimatedDASize().Uint64() * uint64(current.daFootprintGasScalar)
514514
if daFootprintLeft < txDAFootprint {
515515
log.Debug("Not enough DA space left for transaction", "hash", txn.Hash(), "left", daFootprintLeft, "needed", txDAFootprint)

eth/stagedsync/stage_mining_finish.go

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"github.com/erigontech/erigon-lib/chain"
77
"github.com/erigontech/erigon-lib/kv"
88
"github.com/erigontech/erigon-lib/log/v3"
9-
"github.com/erigontech/erigon-lib/opstack"
109
"github.com/erigontech/erigon/consensus"
1110
"github.com/erigontech/erigon/core/types"
1211
"github.com/erigontech/erigon/turbo/builder"
@@ -52,17 +51,6 @@ func SpawnMiningFinishStage(s *StageState, tx kv.RwTx, cfg MiningFinishCfg, quit
5251
// continue
5352
//}
5453

55-
// Store DA footprint in BlobGasUsed header field if it hasn't already been set yet.
56-
// Builder code may already calculate it during block building to avoid recalculating it here.
57-
header := current.Header
58-
if cfg.chainConfig.IsJovian(header.Time) && (header.BlobGasUsed == nil || *header.BlobGasUsed == 0) {
59-
daFootprint, err := CalcDAFootprint(current.Txs)
60-
if err != nil {
61-
return fmt.Errorf("error calculating DA footprint: %w", err)
62-
}
63-
header.BlobGasUsed = &daFootprint
64-
}
65-
6654
block := types.NewBlockForAsembling(current.Header, current.Txs, current.Uncles, current.Receipts, current.Withdrawals, cfg.chainConfig.IsOptimismIsthmus(current.Header.Time))
6755
blockWithReceipts := &types.BlockWithReceipts{Block: block, Receipts: current.Receipts, Requests: current.Requests}
6856
*current = MiningBlock{} // hack to clean global data
@@ -109,37 +97,3 @@ func SpawnMiningFinishStage(s *StageState, tx kv.RwTx, cfg MiningFinishCfg, quit
10997

11098
return nil
11199
}
112-
113-
// CalcDAFootprint calculates the total DA footprint of a block for an OP Stack chain.
114-
// Jovian introduces a DA footprint block limit which is stored in the BlobGasUsed header field and that is taken
115-
// into account during base fee updates.
116-
// CalcDAFootprint must not be called for pre-Jovian blocks.
117-
func CalcDAFootprint(txs types.Transactions) (uint64, error) {
118-
if txs.Len() == 0 || txs[0].Type() != types.DepositTxType {
119-
return 0, fmt.Errorf("missing deposit transaction")
120-
}
121-
122-
// First Jovian block doesn't set the DA footprint gas scalar yet and
123-
// it must not have user transactions.
124-
data := txs[0].GetData()
125-
if len(data) == opstack.IsthmusL1AttributesLen {
126-
if txs[len(txs)-1].Type() != types.DepositTxType {
127-
// sufficient to check last transaction because deposits precede non-deposit txs
128-
return 0, fmt.Errorf("unexpected non-deposit transactions in Jovian activation block")
129-
}
130-
return 0, nil
131-
} // ExtractDAFootprintGasScalar catches all invalid lengths
132-
133-
daFootprintGasScalar, err := opstack.ExtractDAFootprintGasScalar(data)
134-
if err != nil {
135-
return 0, err
136-
}
137-
var daFootprint uint64
138-
for _, tx := range txs {
139-
if tx.Type() == types.DepositTxType {
140-
continue
141-
}
142-
daFootprint += tx.RollupCostData().EstimatedDASize().Uint64() * uint64(daFootprintGasScalar)
143-
}
144-
return daFootprint, nil
145-
}

turbo/engineapi/engine_server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ func (s *EngineServer) newPayload(ctx context.Context, req *engine_types.Executi
140140
) (*engine_types.PayloadStatus, error) {
141141
var bloom types.Bloom
142142
copy(bloom[:], req.LogsBloom)
143-
143+
log.Info("HEader", "blobGasUsed", req.BlobGasUsed)
144144
txs := [][]byte{}
145145
for _, transaction := range req.Transactions {
146146
txs = append(txs, transaction)

0 commit comments

Comments
 (0)