Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion internal/ethapi/simulate.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package ethapi

import (
"context"
"encoding/binary"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -359,7 +360,17 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
reqHash := types.CalcRequestsHash(requests)
header.RequestsHash = &reqHash
}
blockBody := &types.Body{Transactions: txes, Withdrawals: *block.BlockOverrides.Withdrawals}

// For OP Stack Jovian blocks, inject a synthetic deposit transaction at the beginning of the block.
// This is required because CalcDAFootprint (called by FinalizeAndAssemble for Jovian blocks)
// expects the first transaction to be a deposit transaction containing L1 attributes data.
finalTxes := txes
if sim.chainConfig.IsJovian(header.Time) {
depositTx := createSimulatedJovianDepositTx()
finalTxes = append([]*types.Transaction{depositTx}, txes...)
}

blockBody := &types.Body{Transactions: finalTxes, Withdrawals: *block.BlockOverrides.Withdrawals}
chainHeadReader := &simChainHeadReader{ctx, sim.b}
b, err := sim.b.Engine().FinalizeAndAssemble(chainHeadReader, header, sim.state, blockBody, receipts)
if err != nil {
Expand All @@ -380,6 +391,30 @@ func repairLogs(calls []simCallResult, hash common.Hash) {
}
}

// createSimulatedJovianDepositTx creates a synthetic L1 attributes deposit transaction for
// Jovian simulations. This is required because CalcDAFootprint expects the first transaction in a
// Jovian block to be a deposit transaction containing L1 attributes data with the Jovian selector
// and DA footprint gas scalar.
func createSimulatedJovianDepositTx() *types.Transaction {
// Jovian format: 178 bytes with JovianL1AttributesSelector and daFootprintGasScalar in last 2 bytes
data := make([]byte, types.JovianL1AttributesLen)
copy(data[0:4], types.JovianL1AttributesSelector)
// Set a reasonable default DA footprint gas scalar (e.g., 1 wei)
// This scalar is used to calculate DA footprint: EstimatedDASize * daFootprintGasScalar
binary.BigEndian.PutUint16(data[types.JovianL1AttributesLen-2:types.JovianL1AttributesLen], 1)

return types.NewTx(&types.DepositTx{
SourceHash: common.Hash{}, // Zero hash for simulated deposit
From: common.Address{}, // Zero address (system)
To: &types.L1BlockAddr,
Mint: nil,
Value: big.NewInt(0),
Gas: 0,
IsSystemTransaction: true,
Data: data,
})
}

func (sim *simulator) sanitizeCall(call *TransactionArgs, state vm.StateDB, header *types.Header, blockContext vm.BlockContext, gasUsed *uint64) error {
if call.Nonce == nil {
nonce := state.GetNonce(call.from())
Expand Down