Merge branch 'develop' into fix-requests-hash-in-sdk

This commit is contained in:
colin 2025-06-26 18:10:20 +08:00 committed by GitHub
commit 47bc86cd96
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 461 additions and 118 deletions

View file

@ -640,7 +640,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
vmEnv := vm.NewEVM(evmContext, txContext, stateDB, b.config, vm.Config{NoBaseFee: true}) vmEnv := vm.NewEVM(evmContext, txContext, stateDB, b.config, vm.Config{NoBaseFee: true})
gasPool := new(core.GasPool).AddGas(math.MaxUint64) gasPool := new(core.GasPool).AddGas(math.MaxUint64)
signer := types.MakeSigner(b.blockchain.Config(), head.Number, head.Time) signer := types.MakeSigner(b.blockchain.Config(), head.Number, head.Time)
l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, head.BaseFee, b.blockchain.Config(), signer, stateDB, head.Number) l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, head.BaseFee, b.blockchain.Config(), signer, stateDB, head.Number, head.Time)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -152,6 +152,10 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
if chainConfig.CurieBlock != nil && chainConfig.CurieBlock.Cmp(new(big.Int).SetUint64(pre.Env.Number)) == 0 { if chainConfig.CurieBlock != nil && chainConfig.CurieBlock.Cmp(new(big.Int).SetUint64(pre.Env.Number)) == 0 {
misc.ApplyCurieHardFork(statedb) misc.ApplyCurieHardFork(statedb)
} }
// Apply Feynman hard fork
if chainConfig.IsFeynmanTransitionBlock(pre.Env.Timestamp, pre.Env.ParentTimestamp) {
misc.ApplyFeynmanHardFork(statedb)
}
// Apply EIP-2935 // Apply EIP-2935
if pre.Env.BlockHashes != nil && chainConfig.IsFeynman(pre.Env.Timestamp) { if pre.Env.BlockHashes != nil && chainConfig.IsFeynman(pre.Env.Timestamp) {
var ( var (
@ -180,7 +184,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
snapshot := statedb.Snapshot() snapshot := statedb.Snapshot()
evm := vm.NewEVM(vmContext, txContext, statedb, chainConfig, vmConfig) evm := vm.NewEVM(vmContext, txContext, statedb, chainConfig, vmConfig)
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, chainConfig, new(big.Int).SetUint64(pre.Env.Number)) l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, chainConfig, new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp)
if err != nil { if err != nil {
log.Info("rejected tx due to fees.CalculateL1DataFee", "index", i, "hash", tx.Hash(), "from", msg.From(), "error", err) log.Info("rejected tx due to fees.CalculateL1DataFee", "index", i, "hash", tx.Hash(), "from", msg.From(), "error", err)
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()}) rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})

View file

@ -176,6 +176,8 @@ var (
utils.CircuitCapacityCheckWorkersFlag, utils.CircuitCapacityCheckWorkersFlag,
utils.RollupVerifyEnabledFlag, utils.RollupVerifyEnabledFlag,
utils.ShadowforkPeersFlag, utils.ShadowforkPeersFlag,
utils.TxGossipBroadcastDisabledFlag,
utils.TxGossipReceivingDisabledFlag,
utils.DASyncEnabledFlag, utils.DASyncEnabledFlag,
utils.DABlockNativeAPIEndpointFlag, utils.DABlockNativeAPIEndpointFlag,
utils.DABlobScanAPIEndpointFlag, utils.DABlobScanAPIEndpointFlag,

View file

@ -248,6 +248,8 @@ var AppHelpFlagGroups = []flags.FlagGroup{
utils.DARecoveryProduceBlocksFlag, utils.DARecoveryProduceBlocksFlag,
utils.CircuitCapacityCheckEnabledFlag, utils.CircuitCapacityCheckEnabledFlag,
utils.CircuitCapacityCheckWorkersFlag, utils.CircuitCapacityCheckWorkersFlag,
utils.TxGossipBroadcastDisabledFlag,
utils.TxGossipReceivingDisabledFlag,
}, },
}, },
{ {

View file

@ -893,6 +893,16 @@ var (
Usage: "peer ids of shadow fork peers", Usage: "peer ids of shadow fork peers",
} }
// Tx gossip settings
TxGossipBroadcastDisabledFlag = cli.BoolFlag{
Name: "txgossip.disablebroadcast",
Usage: "Disable gossip broadcast transactions to other peers",
}
TxGossipReceivingDisabledFlag = cli.BoolFlag{
Name: "txgossip.disablereceiving",
Usage: "Disable gossip receiving transactions from other peers",
}
// DA syncing settings // DA syncing settings
DASyncEnabledFlag = cli.BoolFlag{ DASyncEnabledFlag = cli.BoolFlag{
Name: "da.sync", Name: "da.sync",
@ -1790,6 +1800,14 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
cfg.ShadowForkPeerIDs = ctx.GlobalStringSlice(ShadowforkPeersFlag.Name) cfg.ShadowForkPeerIDs = ctx.GlobalStringSlice(ShadowforkPeersFlag.Name)
log.Info("Shadow fork peers", "ids", cfg.ShadowForkPeerIDs) log.Info("Shadow fork peers", "ids", cfg.ShadowForkPeerIDs)
} }
if ctx.GlobalIsSet(TxGossipBroadcastDisabledFlag.Name) {
cfg.TxGossipBroadcastDisabled = ctx.GlobalBool(TxGossipBroadcastDisabledFlag.Name)
log.Info("Transaction gossip broadcast disabled", "disabled", cfg.TxGossipBroadcastDisabled)
}
if ctx.GlobalIsSet(TxGossipReceivingDisabledFlag.Name) {
cfg.TxGossipReceivingDisabled = ctx.GlobalBool(TxGossipReceivingDisabledFlag.Name)
log.Info("Transaction gossip receiving disabled", "disabled", cfg.TxGossipReceivingDisabled)
}
// Cap the cache allowance and tune the garbage collector // Cap the cache allowance and tune the garbage collector
mem, err := gopsutil.VirtualMemory() mem, err := gopsutil.VirtualMemory()

22
consensus/misc/feynman.go Normal file
View file

@ -0,0 +1,22 @@
package misc
import (
"github.com/scroll-tech/go-ethereum/common"
"github.com/scroll-tech/go-ethereum/core/state"
"github.com/scroll-tech/go-ethereum/log"
"github.com/scroll-tech/go-ethereum/rollup/rcfg"
)
// ApplyFeynmanHardFork modifies the state database according to the Feynman hard-fork rules,
// updating the bytecode and storage of the L1GasPriceOracle contract.
func ApplyFeynmanHardFork(statedb *state.StateDB) {
log.Info("Applying Feynman hard fork")
// update contract byte code
statedb.SetCode(rcfg.L1GasPriceOracleAddress, rcfg.FeynmanL1GasPriceOracleBytecode)
// initialize new storage slots
statedb.SetState(rcfg.L1GasPriceOracleAddress, rcfg.IsFeynmanSlot, common.BytesToHash([]byte{1}))
statedb.SetState(rcfg.L1GasPriceOracleAddress, rcfg.PenaltyThresholdSlot, common.BigToHash(rcfg.InitialPenaltyThreshold))
statedb.SetState(rcfg.L1GasPriceOracleAddress, rcfg.PenaltyFactorSlot, common.BigToHash(rcfg.InitialPenaltyFactor))
}

View file

@ -249,6 +249,9 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
if config.CurieBlock != nil && config.CurieBlock.Cmp(b.header.Number) == 0 { if config.CurieBlock != nil && config.CurieBlock.Cmp(b.header.Number) == 0 {
misc.ApplyCurieHardFork(statedb) misc.ApplyCurieHardFork(statedb)
} }
if config.IsFeynmanTransitionBlock(b.Time(), parent.Time()) {
misc.ApplyFeynmanHardFork(statedb)
}
// Execute any user modifications to the block // Execute any user modifications to the block
if gen != nil { if gen != nil {
gen(i, b) gen(i, b)

View file

@ -71,7 +71,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
} }
statedb.SetTxContext(tx.Hash(), i) statedb.SetTxContext(tx.Hash(), i)
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, p.config, block.Number()) l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, p.config, block.Number(), block.Time())
if err != nil { if err != nil {
return return
} }

View file

@ -80,6 +80,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
header = block.Header() header = block.Header()
blockHash = block.Hash() blockHash = block.Hash()
blockNumber = block.Number() blockNumber = block.Number()
blockTime = block.Time()
allLogs []*types.Log allLogs []*types.Log
gp = new(GasPool).AddGas(block.GasLimit()) gp = new(GasPool).AddGas(block.GasLimit())
) )
@ -91,6 +92,11 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
if p.config.CurieBlock != nil && p.config.CurieBlock.Cmp(block.Number()) == 0 { if p.config.CurieBlock != nil && p.config.CurieBlock.Cmp(block.Number()) == 0 {
misc.ApplyCurieHardFork(statedb) misc.ApplyCurieHardFork(statedb)
} }
// Apply Feynman hard fork
parent := p.bc.GetHeaderByHash(block.ParentHash())
if p.config.IsFeynmanTransitionBlock(block.Time(), parent.Time) {
misc.ApplyFeynmanHardFork(statedb)
}
blockContext := NewEVMBlockContext(header, p.bc, p.config, nil) blockContext := NewEVMBlockContext(header, p.bc, p.config, nil)
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg)
processorBlockTransactionGauge.Update(int64(block.Transactions().Len())) processorBlockTransactionGauge.Update(int64(block.Transactions().Len()))
@ -105,7 +111,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
} }
statedb.SetTxContext(tx.Hash(), i) statedb.SetTxContext(tx.Hash(), i)
receipt, err := applyTransaction(msg, p.config, p.bc, nil, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv) receipt, err := applyTransaction(msg, p.config, p.bc, nil, gp, statedb, blockNumber, blockTime, blockHash, tx, usedGas, vmenv)
if err != nil { if err != nil {
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
} }
@ -120,7 +126,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
return receipts, allLogs, *usedGas, nil return receipts, allLogs, *usedGas, nil
} }
func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) { func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockTime uint64, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) {
defer func(t0 time.Time) { defer func(t0 time.Time) {
applyTransactionTimer.Update(time.Since(t0)) applyTransactionTimer.Update(time.Since(t0))
}(time.Now()) }(time.Now())
@ -129,7 +135,7 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainCon
txContext := NewEVMTxContext(msg) txContext := NewEVMTxContext(msg)
evm.Reset(txContext, statedb) evm.Reset(txContext, statedb)
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, config, blockNumber) l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, config, blockNumber, blockTime)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -201,7 +207,7 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
// Create a new context to be used in the EVM environment // Create a new context to be used in the EVM environment
blockContext := NewEVMBlockContext(header, bc, config, author) blockContext := NewEVMBlockContext(header, bc, config, author)
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg) vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg)
return applyTransaction(msg, config, bc, author, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv) return applyTransaction(msg, config, bc, author, gp, statedb, header.Number, header.Time, header.Hash(), tx, usedGas, vmenv)
} }
// ProcessParentBlockHash stores the parent block hash in the history storage contract // ProcessParentBlockHash stores the parent block hash in the history storage contract

View file

@ -282,7 +282,7 @@ func (l *txList) Overlaps(tx *types.Transaction) bool {
// //
// If the new transaction is accepted into the list, the lists' cost and gas // If the new transaction is accepted into the list, the lists' cost and gas
// thresholds are also potentially updated. // thresholds are also potentially updated.
func (l *txList) Add(tx *types.Transaction, state *state.StateDB, priceBump uint64, chainconfig *params.ChainConfig, blockNumber *big.Int) (bool, *types.Transaction) { func (l *txList) Add(tx *types.Transaction, state *state.StateDB, priceBump uint64, chainconfig *params.ChainConfig, blockNumber *big.Int, blockTime uint64) (bool, *types.Transaction) {
// If there's an older better transaction, abort // If there's an older better transaction, abort
old := l.txs.Get(tx.Nonce()) old := l.txs.Get(tx.Nonce())
if old != nil { if old != nil {
@ -310,7 +310,7 @@ func (l *txList) Add(tx *types.Transaction, state *state.StateDB, priceBump uint
l1DataFee := big.NewInt(0) l1DataFee := big.NewInt(0)
if state != nil && chainconfig != nil { if state != nil && chainconfig != nil {
var err error var err error
l1DataFee, err = fees.CalculateL1DataFee(tx, state, chainconfig, blockNumber) l1DataFee, err = fees.CalculateL1DataFee(tx, state, chainconfig, blockNumber, blockTime)
if err != nil { if err != nil {
log.Error("Failed to calculate L1 data fee", "err", err, "tx", tx) log.Error("Failed to calculate L1 data fee", "err", err, "tx", tx)
return false, nil return false, nil

View file

@ -38,7 +38,7 @@ func TestStrictTxListAdd(t *testing.T) {
// Insert the transactions in a random order // Insert the transactions in a random order
list := newTxList(true) list := newTxList(true)
for _, v := range rand.Perm(len(txs)) { for _, v := range rand.Perm(len(txs)) {
list.Add(txs[v], nil, DefaultTxPoolConfig.PriceBump, nil, nil) list.Add(txs[v], nil, DefaultTxPoolConfig.PriceBump, nil, nil, 0)
} }
// Verify internal state // Verify internal state
if len(list.txs.items) != len(txs) { if len(list.txs.items) != len(txs) {
@ -65,7 +65,7 @@ func BenchmarkTxListAdd(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
list := newTxList(true) list := newTxList(true)
for _, v := range rand.Perm(len(txs)) { for _, v := range rand.Perm(len(txs)) {
list.Add(txs[v], nil, DefaultTxPoolConfig.PriceBump, nil, nil) list.Add(txs[v], nil, DefaultTxPoolConfig.PriceBump, nil, nil, 0)
list.Filter(priceLimit, DefaultTxPoolConfig.PriceBump) list.Filter(priceLimit, DefaultTxPoolConfig.PriceBump)
} }
} }

View file

@ -301,6 +301,7 @@ type TxPool struct {
currentState *state.StateDB // Current state in the blockchain head currentState *state.StateDB // Current state in the blockchain head
currentHead *big.Int // Current blockchain head currentHead *big.Int // Current blockchain head
currentTime uint64 // Current blockchain head time
pendingNonces *txNoncer // Pending state tracking virtual nonces pendingNonces *txNoncer // Pending state tracking virtual nonces
currentMaxGas uint64 // Current gas limit for transaction caps currentMaxGas uint64 // Current gas limit for transaction caps
@ -838,7 +839,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
// 2. If FeeVault is enabled, perform an additional check for L1 data fees. // 2. If FeeVault is enabled, perform an additional check for L1 data fees.
if pool.chainconfig.Scroll.FeeVaultEnabled() { if pool.chainconfig.Scroll.FeeVaultEnabled() {
// Get L1 data fee in current state // Get L1 data fee in current state
l1DataFee, err := fees.CalculateL1DataFee(tx, pool.currentState, pool.chainconfig, pool.currentHead) l1DataFee, err := fees.CalculateL1DataFee(tx, pool.currentState, pool.chainconfig, pool.currentHead, pool.currentTime)
if err != nil { if err != nil {
return fmt.Errorf("failed to calculate L1 data fee, err: %w", err) return fmt.Errorf("failed to calculate L1 data fee, err: %w", err)
} }
@ -947,7 +948,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
from, _ := types.Sender(pool.signer, tx) // already validated from, _ := types.Sender(pool.signer, tx) // already validated
if list := pool.pending[from]; list != nil && list.Overlaps(tx) { if list := pool.pending[from]; list != nil && list.Overlaps(tx) {
// Nonce already pending, check if required price bump is met // Nonce already pending, check if required price bump is met
inserted, old := list.Add(tx, pool.currentState, pool.config.PriceBump, pool.chainconfig, pool.currentHead) inserted, old := list.Add(tx, pool.currentState, pool.config.PriceBump, pool.chainconfig, pool.currentHead, pool.currentTime)
if !inserted { if !inserted {
log.Debug("Discarding underpriced pending transaction", "hash", hash.Hex(), "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap()) log.Debug("Discarding underpriced pending transaction", "hash", hash.Hex(), "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap())
pendingDiscardMeter.Mark(1) pendingDiscardMeter.Mark(1)
@ -1001,7 +1002,7 @@ func (pool *TxPool) enqueueTx(hash common.Hash, tx *types.Transaction, local boo
pool.queue[from] = newTxList(false) pool.queue[from] = newTxList(false)
} }
inserted, old := pool.queue[from].Add(tx, pool.currentState, pool.config.PriceBump, pool.chainconfig, pool.currentHead) inserted, old := pool.queue[from].Add(tx, pool.currentState, pool.config.PriceBump, pool.chainconfig, pool.currentHead, pool.currentTime)
if !inserted { if !inserted {
// An older transaction was better, discard this // An older transaction was better, discard this
log.Debug("Discarding underpriced queued transaction", "hash", hash.Hex(), "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap()) log.Debug("Discarding underpriced queued transaction", "hash", hash.Hex(), "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap())
@ -1068,7 +1069,7 @@ func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.T
return false return false
} }
inserted, old := list.Add(tx, pool.currentState, pool.config.PriceBump, pool.chainconfig, pool.currentHead) inserted, old := list.Add(tx, pool.currentState, pool.config.PriceBump, pool.chainconfig, pool.currentHead, pool.currentTime)
if !inserted { if !inserted {
// An older transaction was better, discard this // An older transaction was better, discard this
log.Debug("Discarding underpriced pending transaction", "hash", hash.Hex(), "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap()) log.Debug("Discarding underpriced pending transaction", "hash", hash.Hex(), "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap())
@ -1603,6 +1604,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) {
// Update current head // Update current head
pool.currentHead = next pool.currentHead = next
pool.currentTime = newHead.Time
} }
// promoteExecutables moves transactions that have become processable from the // promoteExecutables moves transactions that have become processable from the
@ -1690,7 +1692,7 @@ func (pool *TxPool) executableTxFilter(costLimit *big.Int) func(tx *types.Transa
if pool.chainconfig.Scroll.FeeVaultEnabled() { if pool.chainconfig.Scroll.FeeVaultEnabled() {
// recheck L1 data fee, as the oracle price may have changed // recheck L1 data fee, as the oracle price may have changed
l1DataFee, err := fees.CalculateL1DataFee(tx, pool.currentState, pool.chainconfig, pool.currentHead) l1DataFee, err := fees.CalculateL1DataFee(tx, pool.currentState, pool.chainconfig, pool.currentHead, pool.currentTime)
if err != nil { if err != nil {
log.Error("Failed to calculate L1 data fee", "err", err, "tx", tx) log.Error("Failed to calculate L1 data fee", "err", err, "tx", tx)
return false return false

View file

@ -362,6 +362,11 @@ func generateWitness(blockchain *core.BlockChain, block *types.Block) (*stateles
// Collect storage locations that prover needs but sequencer might not touch necessarily // Collect storage locations that prover needs but sequencer might not touch necessarily
statedb.GetState(rcfg.L2MessageQueueAddress, rcfg.WithdrawTrieRootSlot) statedb.GetState(rcfg.L2MessageQueueAddress, rcfg.WithdrawTrieRootSlot)
// Note: scroll-revm detects the Feynman transition block using this storage slot,
// since it does not have access to the parent block timestamp. We need to make
// sure that this is always present in the execution witness.
statedb.GetState(rcfg.L1GasPriceOracleAddress, rcfg.IsFeynmanSlot)
receipts, _, usedGas, err := blockchain.Processor().Process(block, statedb, *blockchain.GetVMConfig()) receipts, _, usedGas, err := blockchain.Processor().Process(block, statedb, *blockchain.GetVMConfig())
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to process block %d: %w", block.Number(), err) return nil, fmt.Errorf("failed to process block %d: %w", block.Number(), err)

View file

@ -273,16 +273,18 @@ func New(stack *node.Node, config *ethconfig.Config, l1Client l1.Client) (*Ether
checkpoint = params.TrustedCheckpoints[genesisHash] checkpoint = params.TrustedCheckpoints[genesisHash]
} }
if eth.handler, err = newHandler(&handlerConfig{ if eth.handler, err = newHandler(&handlerConfig{
Database: chainDb, Database: chainDb,
Chain: eth.blockchain, Chain: eth.blockchain,
TxPool: eth.txPool, TxPool: eth.txPool,
Network: config.NetworkId, Network: config.NetworkId,
Sync: config.SyncMode, Sync: config.SyncMode,
BloomCache: uint64(cacheLimit), BloomCache: uint64(cacheLimit),
EventMux: eth.eventMux, EventMux: eth.eventMux,
Checkpoint: checkpoint, Checkpoint: checkpoint,
Whitelist: config.Whitelist, Whitelist: config.Whitelist,
ShadowForkPeerIDs: config.ShadowForkPeerIDs, ShadowForkPeerIDs: config.ShadowForkPeerIDs,
DisableTxBroadcast: config.TxGossipBroadcastDisabled,
DisableTxReceiving: config.TxGossipReceivingDisabled,
}); err != nil { }); err != nil {
return nil, err return nil, err
} }

View file

@ -230,6 +230,9 @@ type Config struct {
// DA syncer options // DA syncer options
DA da_syncer.Config DA da_syncer.Config
TxGossipBroadcastDisabled bool
TxGossipReceivingDisabled bool
} }
// CreateConsensusEngine creates a consensus engine for the given chain configuration. // CreateConsensusEngine creates a consensus engine for the given chain configuration.

View file

@ -93,6 +93,9 @@ type handlerConfig struct {
Checkpoint *params.TrustedCheckpoint // Hard coded checkpoint for sync challenges Checkpoint *params.TrustedCheckpoint // Hard coded checkpoint for sync challenges
Whitelist map[uint64]common.Hash // Hard coded whitelist for sync challenged Whitelist map[uint64]common.Hash // Hard coded whitelist for sync challenged
ShadowForkPeerIDs []string // List of peer ids that take part in the shadow-fork ShadowForkPeerIDs []string // List of peer ids that take part in the shadow-fork
DisableTxBroadcast bool
DisableTxReceiving bool
} }
type handler struct { type handler struct {
@ -131,7 +134,9 @@ type handler struct {
wg sync.WaitGroup wg sync.WaitGroup
peerWG sync.WaitGroup peerWG sync.WaitGroup
shadowForkPeerIDs []string shadowForkPeerIDs []string
disableTxBroadcast bool
disableTxReceiving bool
} }
// newHandler returns a handler for all Ethereum chain management protocol. // newHandler returns a handler for all Ethereum chain management protocol.
@ -141,16 +146,18 @@ func newHandler(config *handlerConfig) (*handler, error) {
config.EventMux = new(event.TypeMux) // Nicety initialization for tests config.EventMux = new(event.TypeMux) // Nicety initialization for tests
} }
h := &handler{ h := &handler{
networkID: config.Network, networkID: config.Network,
forkFilter: forkid.NewFilter(config.Chain), forkFilter: forkid.NewFilter(config.Chain),
eventMux: config.EventMux, eventMux: config.EventMux,
database: config.Database, database: config.Database,
txpool: config.TxPool, txpool: config.TxPool,
chain: config.Chain, chain: config.Chain,
peers: newPeerSet(), peers: newPeerSet(),
whitelist: config.Whitelist, whitelist: config.Whitelist,
quitSync: make(chan struct{}), quitSync: make(chan struct{}),
shadowForkPeerIDs: config.ShadowForkPeerIDs, shadowForkPeerIDs: config.ShadowForkPeerIDs,
disableTxBroadcast: config.DisableTxBroadcast,
disableTxReceiving: config.DisableTxReceiving,
} }
if config.Sync == downloader.FullSync { if config.Sync == downloader.FullSync {
// The database seems empty as the current block is the genesis. Yet the fast // The database seems empty as the current block is the genesis. Yet the fast
@ -415,10 +422,12 @@ func (h *handler) Start(maxPeers int) {
h.maxPeers = maxPeers h.maxPeers = maxPeers
// broadcast transactions // broadcast transactions
h.wg.Add(1) if !h.disableTxBroadcast {
h.txsCh = make(chan core.NewTxsEvent, txChanSize) h.wg.Add(1)
h.txsSub = h.txpool.SubscribeNewTxsEvent(h.txsCh) h.txsCh = make(chan core.NewTxsEvent, txChanSize)
go h.txBroadcastLoop() h.txsSub = h.txpool.SubscribeNewTxsEvent(h.txsCh)
go h.txBroadcastLoop()
}
// broadcast mined blocks // broadcast mined blocks
h.wg.Add(1) h.wg.Add(1)

View file

@ -56,6 +56,9 @@ func (h *ethHandler) PeerInfo(id enode.ID) interface{} {
// AcceptTxs retrieves whether transaction processing is enabled on the node // AcceptTxs retrieves whether transaction processing is enabled on the node
// or if inbound transactions should simply be dropped. // or if inbound transactions should simply be dropped.
func (h *ethHandler) AcceptTxs() bool { func (h *ethHandler) AcceptTxs() bool {
if h.disableTxReceiving {
return false
}
return atomic.LoadUint32(&h.acceptTxs) == 1 return atomic.LoadUint32(&h.acceptTxs) == 1
} }

View file

@ -198,7 +198,7 @@ func (eth *Ethereum) stateAtTransaction(block *types.Block, txIndex int, reexec
// Not yet the searched for transaction, execute on top of the current state // Not yet the searched for transaction, execute on top of the current state
vmenv := vm.NewEVM(context, txContext, statedb, eth.blockchain.Config(), vm.Config{}) vmenv := vm.NewEVM(context, txContext, statedb, eth.blockchain.Config(), vm.Config{})
statedb.SetTxContext(tx.Hash(), idx) statedb.SetTxContext(tx.Hash(), idx)
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, eth.blockchain.Config(), block.Number()) l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, eth.blockchain.Config(), block.Number(), block.Time())
if err != nil { if err != nil {
return nil, vm.BlockContext{}, nil, err return nil, vm.BlockContext{}, nil, err
} }

View file

@ -292,7 +292,7 @@ func (api *API) traceChain(ctx context.Context, start, end *types.Block, config
TxHash: tx.Hash(), TxHash: tx.Hash(),
} }
l1DataFee, err := fees.CalculateL1DataFee(tx, task.statedb, api.backend.ChainConfig(), task.block.Number()) l1DataFee, err := fees.CalculateL1DataFee(tx, task.statedb, api.backend.ChainConfig(), task.block.Number(), task.block.Time())
if err != nil { if err != nil {
// though it's not a "tracing error", we still need to put it here // though it's not a "tracing error", we still need to put it here
task.results[i] = &txTraceResult{Error: err.Error()} task.results[i] = &txTraceResult{Error: err.Error()}
@ -557,7 +557,7 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
) )
statedb.SetTxContext(tx.Hash(), i) statedb.SetTxContext(tx.Hash(), i)
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, api.backend.ChainConfig(), block.Number()) l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, api.backend.ChainConfig(), block.Number(), block.Time())
if err != nil { if err != nil {
log.Warn("Tracing intermediate roots did not complete due to fees.CalculateL1DataFee", "txindex", i, "txhash", tx.Hash(), "err", err) log.Warn("Tracing intermediate roots did not complete due to fees.CalculateL1DataFee", "txindex", i, "txhash", tx.Hash(), "err", err)
return nil, err return nil, err
@ -645,7 +645,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
TxHash: txs[task.index].Hash(), TxHash: txs[task.index].Hash(),
} }
l1DataFee, err := fees.CalculateL1DataFee(txs[task.index], task.statedb, api.backend.ChainConfig(), block.Number()) l1DataFee, err := fees.CalculateL1DataFee(txs[task.index], task.statedb, api.backend.ChainConfig(), block.Number(), block.Time())
if err != nil { if err != nil {
// though it's not a "tracing error", we still need to put it here // though it's not a "tracing error", we still need to put it here
results[task.index] = &txTraceResult{ results[task.index] = &txTraceResult{
@ -679,7 +679,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
msg, _ := tx.AsMessage(signer, block.BaseFee()) msg, _ := tx.AsMessage(signer, block.BaseFee())
statedb.SetTxContext(tx.Hash(), i) statedb.SetTxContext(tx.Hash(), i)
vmenv := vm.NewEVM(blockCtx, core.NewEVMTxContext(msg), statedb, api.backend.ChainConfig(), vm.Config{}) vmenv := vm.NewEVM(blockCtx, core.NewEVMTxContext(msg), statedb, api.backend.ChainConfig(), vm.Config{})
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, api.backend.ChainConfig(), block.Number()) l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, api.backend.ChainConfig(), block.Number(), block.Time())
if err != nil { if err != nil {
failed = err failed = err
break break
@ -804,7 +804,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
// Execute the transaction and flush any traces to disk // Execute the transaction and flush any traces to disk
vmenv := vm.NewEVM(vmctx, txContext, statedb, chainConfig, vmConf) vmenv := vm.NewEVM(vmctx, txContext, statedb, chainConfig, vmConf)
statedb.SetTxContext(tx.Hash(), i) statedb.SetTxContext(tx.Hash(), i)
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, api.backend.ChainConfig(), block.Number()) l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, api.backend.ChainConfig(), block.Number(), block.Time())
if err == nil { if err == nil {
_, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), l1DataFee) _, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), l1DataFee)
} }
@ -869,7 +869,7 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *
TxIndex: int(index), TxIndex: int(index),
TxHash: hash, TxHash: hash,
} }
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, api.backend.ChainConfig(), block.Number()) l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, api.backend.ChainConfig(), block.Number(), block.Time())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -929,7 +929,7 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
} }
signer := types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()) signer := types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, block.BaseFee(), api.backend.ChainConfig(), signer, statedb, block.Number()) l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, block.BaseFee(), api.backend.ChainConfig(), signer, statedb, block.Number(), block.Time())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -173,7 +173,7 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block
return msg, context, statedb, nil return msg, context, statedb, nil
} }
vmenv := vm.NewEVM(context, txContext, statedb, b.chainConfig, vm.Config{}) vmenv := vm.NewEVM(context, txContext, statedb, b.chainConfig, vm.Config{})
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, b.chainConfig, block.Number()) l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, b.chainConfig, block.Number(), block.Time())
if err != nil { if err != nil {
return nil, vm.BlockContext{}, nil, err return nil, vm.BlockContext{}, nil, err
} }

View file

@ -193,7 +193,7 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("failed to prepare transaction for tracing: %v", err) t.Fatalf("failed to prepare transaction for tracing: %v", err)
} }
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, test.Genesis.Config, context.BlockNumber) l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, test.Genesis.Config, context.BlockNumber, context.Time.Uint64())
if err != nil { if err != nil {
t.Fatalf("failed to calculate l1DataFee: %v", err) t.Fatalf("failed to calculate l1DataFee: %v", err)
} }
@ -308,7 +308,7 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
} }
evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer}) evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer})
snap := statedb.Snapshot() snap := statedb.Snapshot()
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, test.Genesis.Config, context.BlockNumber) l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, test.Genesis.Config, context.BlockNumber, context.Time.Uint64())
if err != nil { if err != nil {
b.Fatalf("failed to calculate l1DataFee: %v", err) b.Fatalf("failed to calculate l1DataFee: %v", err)
} }
@ -381,7 +381,7 @@ func TestZeroValueToNotExitCall(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("failed to prepare transaction for tracing: %v", err) t.Fatalf("failed to prepare transaction for tracing: %v", err)
} }
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, params.MainnetChainConfig, context.BlockNumber) l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, params.MainnetChainConfig, context.BlockNumber, context.Time.Uint64())
if err != nil { if err != nil {
t.Fatalf("failed to calculate l1DataFee: %v", err) t.Fatalf("failed to calculate l1DataFee: %v", err)
} }

View file

@ -112,7 +112,7 @@ func BenchmarkTransactionTrace(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
snap := statedb.Snapshot() snap := statedb.Snapshot()
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, params.AllEthashProtocolChanges, context.BlockNumber) l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, params.AllEthashProtocolChanges, context.BlockNumber, context.Time.Uint64())
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }

2
go.mod
View file

@ -51,7 +51,7 @@ require (
github.com/prometheus/tsdb v0.7.1 github.com/prometheus/tsdb v0.7.1
github.com/rjeczalik/notify v0.9.1 github.com/rjeczalik/notify v0.9.1
github.com/rs/cors v1.7.0 github.com/rs/cors v1.7.0
github.com/scroll-tech/da-codec v0.1.3-0.20250313120912-344f2d5e33e1 github.com/scroll-tech/da-codec v0.1.3-0.20250626091118-58b899494da6
github.com/scroll-tech/zktrie v0.8.4 github.com/scroll-tech/zktrie v0.8.4
github.com/shirou/gopsutil v3.21.11+incompatible github.com/shirou/gopsutil v3.21.11+incompatible
github.com/sourcegraph/conc v0.3.0 github.com/sourcegraph/conc v0.3.0

4
go.sum
View file

@ -396,8 +396,8 @@ github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncj
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/scroll-tech/da-codec v0.1.3-0.20250313120912-344f2d5e33e1 h1:Dhd58LE1D+dnoxpgLVeQBMF9uweL/fhQfZHWtWSiOlE= github.com/scroll-tech/da-codec v0.1.3-0.20250626091118-58b899494da6 h1:vb2XLvQwCf+F/ifP6P/lfeiQrHY6+Yb/E3R4KHXLqSE=
github.com/scroll-tech/da-codec v0.1.3-0.20250313120912-344f2d5e33e1/go.mod h1:yhTS9OVC0xQGhg7DN5iV5KZJvnSIlFWAxDdp+6jxQtY= github.com/scroll-tech/da-codec v0.1.3-0.20250626091118-58b899494da6/go.mod h1:Z6kN5u2khPhiqHyk172kGB7o38bH/nj7Ilrb/46wZGg=
github.com/scroll-tech/zktrie v0.8.4 h1:UagmnZ4Z3ITCk+aUq9NQZJNAwnWl4gSxsLb2Nl7IgRE= github.com/scroll-tech/zktrie v0.8.4 h1:UagmnZ4Z3ITCk+aUq9NQZJNAwnWl4gSxsLb2Nl7IgRE=
github.com/scroll-tech/zktrie v0.8.4/go.mod h1:XvNo7vAk8yxNyTjBDj5WIiFzYW4bx/gJ78+NK6Zn6Uk= github.com/scroll-tech/zktrie v0.8.4/go.mod h1:XvNo7vAk8yxNyTjBDj5WIiFzYW4bx/gJ78+NK6Zn6Uk=
github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=

View file

@ -999,7 +999,7 @@ func EstimateL1MsgFee(ctx context.Context, b Backend, args TransactionArgs, bloc
}() }()
signer := types.MakeSigner(config, header.Number, header.Time) signer := types.MakeSigner(config, header.Number, header.Time)
return fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config, signer, evm.StateDB, header.Number) return fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config, signer, evm.StateDB, header.Number, header.Time)
} }
func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) { func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) {
@ -1595,7 +1595,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH
return nil, 0, nil, err return nil, 0, nil, err
} }
signer := types.MakeSigner(b.ChainConfig(), header.Number, header.Time) signer := types.MakeSigner(b.ChainConfig(), header.Number, header.Time)
l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, b.ChainConfig(), signer, statedb, header.Number) l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, b.ChainConfig(), signer, statedb, header.Number, header.Time)
if err != nil { if err != nil {
return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.toTransaction().Hash(), err) return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.toTransaction().Hash(), err)
} }

View file

@ -145,7 +145,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
//vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{}) //vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
gp := new(core.GasPool).AddGas(math.MaxUint64) gp := new(core.GasPool).AddGas(math.MaxUint64)
signer := types.MakeSigner(config, header.Number, header.Time) signer := types.MakeSigner(config, header.Number, header.Time)
l1DataFee, _ := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config, signer, statedb, header.Number) l1DataFee, _ := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config, signer, statedb, header.Number, header.Time)
result, _ := core.ApplyMessage(vmenv, msg, gp, l1DataFee) result, _ := core.ApplyMessage(vmenv, msg, gp, l1DataFee)
res = append(res, result.Return()...) res = append(res, result.Return()...)
} }
@ -159,7 +159,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
vmenv := vm.NewEVM(context, txContext, state, config, vm.Config{NoBaseFee: true}) vmenv := vm.NewEVM(context, txContext, state, config, vm.Config{NoBaseFee: true})
gp := new(core.GasPool).AddGas(math.MaxUint64) gp := new(core.GasPool).AddGas(math.MaxUint64)
signer := types.MakeSigner(config, header.Number, header.Time) signer := types.MakeSigner(config, header.Number, header.Time)
l1DataFee, _ := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config, signer, state, header.Number) l1DataFee, _ := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config, signer, state, header.Number, header.Time)
result, _ := core.ApplyMessage(vmenv, msg, gp, l1DataFee) result, _ := core.ApplyMessage(vmenv, msg, gp, l1DataFee)
if state.Error() == nil { if state.Error() == nil {
res = append(res, result.Return()...) res = append(res, result.Return()...)

View file

@ -65,7 +65,7 @@ func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types.
} }
// Not yet the searched for transaction, execute on top of the current state // Not yet the searched for transaction, execute on top of the current state
vmenv := vm.NewEVM(context, txContext, statedb, leth.blockchain.Config(), vm.Config{}) vmenv := vm.NewEVM(context, txContext, statedb, leth.blockchain.Config(), vm.Config{})
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, leth.blockchain.Config(), block.Number()) l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, leth.blockchain.Config(), block.Number(), block.Time())
if err != nil { if err != nil {
return nil, vm.BlockContext{}, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err) return nil, vm.BlockContext{}, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
} }

View file

@ -201,7 +201,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
vmenv := vm.NewEVM(context, txContext, st, config, vm.Config{NoBaseFee: true}) vmenv := vm.NewEVM(context, txContext, st, config, vm.Config{NoBaseFee: true})
gp := new(core.GasPool).AddGas(math.MaxUint64) gp := new(core.GasPool).AddGas(math.MaxUint64)
signer := types.MakeSigner(config, header.Number, header.Time) signer := types.MakeSigner(config, header.Number, header.Time)
l1DataFee, _ := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config, signer, st, header.Number) l1DataFee, _ := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config, signer, st, header.Number, header.Time)
result, _ := core.ApplyMessage(vmenv, msg, gp, l1DataFee) result, _ := core.ApplyMessage(vmenv, msg, gp, l1DataFee)
res = append(res, result.Return()...) res = append(res, result.Return()...)
if st.Error() != nil { if st.Error() != nil {

View file

@ -74,6 +74,7 @@ type TxPool struct {
shanghai bool // Fork indicator whether we are in the shanghai stage. shanghai bool // Fork indicator whether we are in the shanghai stage.
currentHead *big.Int // Current blockchain head currentHead *big.Int // Current blockchain head
currentTime uint64 // Current blockchain head time
} }
// TxRelayBackend provides an interface to the mechanism that forwards transacions // TxRelayBackend provides an interface to the mechanism that forwards transacions
@ -326,6 +327,7 @@ func (pool *TxPool) setNewHead(head *types.Header) {
pool.shanghai = pool.config.IsShanghai(next) pool.shanghai = pool.config.IsShanghai(next)
pool.currentHead = next pool.currentHead = next
pool.currentTime = head.Time
} }
// Stop stops the light transaction pool // Stop stops the light transaction pool
@ -408,7 +410,7 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error
// 2. If FeeVault is enabled, perform an additional check for L1 data fees. // 2. If FeeVault is enabled, perform an additional check for L1 data fees.
if pool.config.Scroll.FeeVaultEnabled() { if pool.config.Scroll.FeeVaultEnabled() {
// Get L1 data fee in current state // Get L1 data fee in current state
l1DataFee, err := fees.CalculateL1DataFee(tx, currentState, pool.config, pool.currentHead) l1DataFee, err := fees.CalculateL1DataFee(tx, currentState, pool.config, pool.currentHead, pool.currentTime)
if err != nil { if err != nil {
return fmt.Errorf("failed to calculate L1 data fee, err: %w", err) return fmt.Errorf("failed to calculate L1 data fee, err: %w", err)
} }

View file

@ -464,8 +464,7 @@ func (w *worker) collectPendingL1Messages(startIndex uint64) []types.L1MessageTx
} }
// newWork // newWork
func (w *worker) newWork(now time.Time, parentHash common.Hash, reorging bool, reorgReason error) error { func (w *worker) newWork(now time.Time, parent *types.Block, reorging bool, reorgReason error) error {
parent := w.chain.GetBlockByHash(parentHash)
header := &types.Header{ header := &types.Header{
ParentHash: parent.Hash(), ParentHash: parent.Hash(),
Number: new(big.Int).Add(parent.Number(), common.Big1), Number: new(big.Int).Add(parent.Number(), common.Big1),
@ -586,13 +585,14 @@ func (w *worker) newWork(now time.Time, parentHash common.Hash, reorging bool, r
} }
// tryCommitNewWork // tryCommitNewWork
func (w *worker) tryCommitNewWork(now time.Time, parent common.Hash, reorging bool, reorgReason error) (common.Hash, error) { func (w *worker) tryCommitNewWork(now time.Time, parentHash common.Hash, reorging bool, reorgReason error) (common.Hash, error) {
parent := w.chain.GetBlockByHash(parentHash)
err := w.newWork(now, parent, reorging, reorgReason) err := w.newWork(now, parent, reorging, reorgReason)
if err != nil { if err != nil {
return common.Hash{}, fmt.Errorf("failed creating new work: %w", err) return common.Hash{}, fmt.Errorf("failed creating new work: %w", err)
} }
shouldCommit, err := w.handleForks() shouldCommit, err := w.handleForks(parent)
if err != nil { if err != nil {
return common.Hash{}, fmt.Errorf("failed handling forks: %w", err) return common.Hash{}, fmt.Errorf("failed handling forks: %w", err)
} }
@ -626,17 +626,16 @@ func (w *worker) tryCommitNewWork(now time.Time, parent common.Hash, reorging bo
} }
// handleForks // handleForks
func (w *worker) handleForks() (bool, error) { func (w *worker) handleForks(parent *types.Block) (bool, error) {
// Apply Curie predeployed contract update // Apply Curie predeployed contract update
if w.chainConfig.CurieBlock != nil && w.chainConfig.CurieBlock.Cmp(w.current.header.Number) == 0 { if w.chainConfig.CurieBlock != nil && w.chainConfig.CurieBlock.Cmp(w.current.header.Number) == 0 {
misc.ApplyCurieHardFork(w.current.state) misc.ApplyCurieHardFork(w.current.state)
return true, nil return true, nil
} }
// Stop/start miner at Euclid fork boundary on zktrie/mpt nodes // Apply Feynman hard fork
if w.chainConfig.IsEuclid(w.current.header.Time) { if w.chainConfig.IsFeynmanTransitionBlock(w.current.header.Time, parent.Time()) {
parent := w.chain.GetBlockByHash(w.current.header.ParentHash) misc.ApplyFeynmanHardFork(w.current.state)
return parent != nil && !w.chainConfig.IsEuclid(parent.Time()), nil
} }
// Apply EIP-2935 // Apply EIP-2935
@ -646,6 +645,12 @@ func (w *worker) handleForks() (bool, error) {
core.ProcessParentBlockHash(w.current.header.ParentHash, vmenv, w.current.state) core.ProcessParentBlockHash(w.current.header.ParentHash, vmenv, w.current.state)
} }
// Stop/start miner at Euclid fork boundary on zktrie/mpt nodes
if w.chainConfig.IsEuclid(w.current.header.Time) {
parent := w.chain.GetBlockByHash(w.current.header.ParentHash)
return parent != nil && !w.chainConfig.IsEuclid(parent.Time()), nil
}
return false, nil return false, nil
} }

View file

@ -1002,6 +1002,11 @@ func (c *ChainConfig) IsFeynman(now uint64) bool {
return isForkedTime(now, c.FeynmanTime) return isForkedTime(now, c.FeynmanTime)
} }
// IsFeynmanTransitionBlock returns whether the given block timestamp corresponds to the first Feynman block.
func (c *ChainConfig) IsFeynmanTransitionBlock(blockTimestamp uint64, parentTimestamp uint64) bool {
return isForkedTime(blockTimestamp, c.FeynmanTime) && !isForkedTime(parentTimestamp, c.FeynmanTime)
}
// IsTerminalPoWBlock returns whether the given block is the last block of PoW stage. // IsTerminalPoWBlock returns whether the given block is the last block of PoW stage.
func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *big.Int) bool { func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *big.Int) bool {
if c.TerminalTotalDifficulty == nil { if c.TerminalTotalDifficulty == nil {

View file

@ -24,7 +24,7 @@ import (
const ( const (
VersionMajor = 5 // Major version component of the current release VersionMajor = 5 // Major version component of the current release
VersionMinor = 8 // Minor version component of the current release VersionMinor = 8 // Minor version component of the current release
VersionPatch = 56 // Patch version component of the current release VersionPatch = 59 // Patch version component of the current release
VersionMeta = "mainnet" // Version metadata to append to the version string VersionMeta = "mainnet" // Version metadata to append to the version string
) )

View file

@ -2,14 +2,17 @@ package fees
import ( import (
"bytes" "bytes"
"fmt"
"math" "math"
"math/big" "math/big"
"github.com/holiman/uint256" "github.com/holiman/uint256"
"github.com/scroll-tech/da-codec/encoding"
"github.com/scroll-tech/go-ethereum/common" "github.com/scroll-tech/go-ethereum/common"
"github.com/scroll-tech/go-ethereum/core/types" "github.com/scroll-tech/go-ethereum/core/types"
"github.com/scroll-tech/go-ethereum/crypto" "github.com/scroll-tech/go-ethereum/crypto"
"github.com/scroll-tech/go-ethereum/log"
"github.com/scroll-tech/go-ethereum/params" "github.com/scroll-tech/go-ethereum/params"
"github.com/scroll-tech/go-ethereum/rollup/rcfg" "github.com/scroll-tech/go-ethereum/rollup/rcfg"
) )
@ -54,15 +57,17 @@ type StateDB interface {
} }
type gpoState struct { type gpoState struct {
l1BaseFee *big.Int l1BaseFee *big.Int
overhead *big.Int overhead *big.Int
scalar *big.Int scalar *big.Int
l1BlobBaseFee *big.Int l1BlobBaseFee *big.Int
commitScalar *big.Int commitScalar *big.Int
blobScalar *big.Int blobScalar *big.Int
penaltyThreshold *big.Int
penaltyFactor *big.Int
} }
func EstimateL1DataFeeForMessage(msg Message, baseFee *big.Int, config *params.ChainConfig, signer types.Signer, state StateDB, blockNumber *big.Int) (*big.Int, error) { func EstimateL1DataFeeForMessage(msg Message, baseFee *big.Int, config *params.ChainConfig, signer types.Signer, state StateDB, blockNumber *big.Int, blockTime uint64) (*big.Int, error) {
if msg.IsL1MessageTx() { if msg.IsL1MessageTx() {
return big.NewInt(0), nil return big.NewInt(0), nil
} }
@ -74,22 +79,7 @@ func EstimateL1DataFeeForMessage(msg Message, baseFee *big.Int, config *params.C
return nil, err return nil, err
} }
raw, err := tx.MarshalBinary() return CalculateL1DataFee(tx, state, config, blockNumber, blockTime)
if err != nil {
return nil, err
}
gpoState := readGPOStorageSlots(rcfg.L1GasPriceOracleAddress, state)
var l1DataFee *big.Int
if !config.IsCurie(blockNumber) {
l1DataFee = calculateEncodedL1DataFee(raw, gpoState.overhead, gpoState.l1BaseFee, gpoState.scalar)
} else {
l1DataFee = calculateEncodedL1DataFeeCurie(raw, gpoState.l1BaseFee, gpoState.l1BlobBaseFee, gpoState.commitScalar, gpoState.blobScalar)
}
return l1DataFee, nil
} }
// asUnsignedTx turns a Message into a types.Transaction // asUnsignedTx turns a Message into a types.Transaction
@ -173,9 +163,58 @@ func readGPOStorageSlots(addr common.Address, state StateDB) gpoState {
gpoState.l1BlobBaseFee = state.GetState(addr, rcfg.L1BlobBaseFeeSlot).Big() gpoState.l1BlobBaseFee = state.GetState(addr, rcfg.L1BlobBaseFeeSlot).Big()
gpoState.commitScalar = state.GetState(addr, rcfg.CommitScalarSlot).Big() gpoState.commitScalar = state.GetState(addr, rcfg.CommitScalarSlot).Big()
gpoState.blobScalar = state.GetState(addr, rcfg.BlobScalarSlot).Big() gpoState.blobScalar = state.GetState(addr, rcfg.BlobScalarSlot).Big()
gpoState.penaltyThreshold = state.GetState(addr, rcfg.PenaltyThresholdSlot).Big()
gpoState.penaltyFactor = state.GetState(addr, rcfg.PenaltyFactorSlot).Big()
return gpoState return gpoState
} }
// estimateTxCompressionRatio estimates the compression ratio for transaction data using da-codec
// compression_ratio(tx) = size(tx) * PRECISION / size(zstd(tx))
func estimateTxCompressionRatio(data []byte, blockNumber uint64, blockTime uint64, config *params.ChainConfig) (*big.Int, error) {
if len(data) == 0 {
return nil, fmt.Errorf("raw data is empty")
}
// Compress data using da-codec
compressed, err := encoding.CompressScrollBatchBytes(data, blockNumber, blockTime, config)
if err != nil {
log.Error("Batch compression failed, using 1.0 compression ratio", "error", err, "data size", len(data), "data", common.Bytes2Hex(data))
return nil, fmt.Errorf("batch compression failed: %w", err)
}
if len(compressed) == 0 {
log.Error("Compressed data is empty, using 1.0 compression ratio", "data size", len(data), "data", common.Bytes2Hex(data))
return nil, fmt.Errorf("compressed data is empty")
}
// compression_ratio = size(tx) * PRECISION / size(zstd(tx))
originalSize := new(big.Int).SetUint64(uint64(len(data)))
compressedSize := new(big.Int).SetUint64(uint64(len(compressed)))
// Make sure compression ratio >= 1 by checking if compressed data is bigger or equal to original data
// This behavior is consistent with DA Batch compression in codecv7 and later versions
if len(compressed) >= len(data) {
log.Debug("Compressed data is bigger or equal to the original data, using 1.0 compression ratio", "original size", len(data), "compressed size", len(compressed))
return rcfg.Precision, nil
}
ratio := new(big.Int).Mul(originalSize, rcfg.Precision)
ratio.Div(ratio, compressedSize)
return ratio, nil
}
// calculatePenalty computes the penalty multiplier based on compression ratio
// penalty(tx) = compression_ratio(tx) >= penalty_threshold ? 1 * PRECISION : penalty_factor
func calculatePenalty(compressionRatio, penaltyThreshold, penaltyFactor *big.Int) *big.Int {
if compressionRatio.Cmp(penaltyThreshold) >= 0 {
// No penalty
return rcfg.Precision
}
// Apply penalty
return penaltyFactor
}
// calculateEncodedL1DataFee computes the L1 fee for an RLP-encoded tx // calculateEncodedL1DataFee computes the L1 fee for an RLP-encoded tx
func calculateEncodedL1DataFee(data []byte, overhead, l1BaseFee *big.Int, scalar *big.Int) *big.Int { func calculateEncodedL1DataFee(data []byte, overhead, l1BaseFee *big.Int, scalar *big.Int) *big.Int {
l1GasUsed := calculateL1GasUsed(data, overhead) l1GasUsed := calculateL1GasUsed(data, overhead)
@ -200,6 +239,51 @@ func calculateEncodedL1DataFeeCurie(data []byte, l1BaseFee *big.Int, l1BlobBaseF
return l1DataFee return l1DataFee
} }
// calculateEncodedL1DataFeeFeynman computes the L1 fee for an RLP-encoded tx, post Feynman
//
// Post Feynman formula:
// rollup_fee(tx) = (execScalar * l1BaseFee + blobScalar * l1BlobBaseFee) * size(tx) * penalty(tx) / PRECISION / PRECISION
//
// Where:
// penalty(tx) = compression_ratio(tx) >= penalty_threshold ? 1 * PRECISION : penalty_factor
//
// compression_ratio(tx) = size(tx) * PRECISION / size(zstd(tx))
// exec_scalar = compression_scalar * (commit_scalar + verification_scalar)
// blob_scalar = compression_scalar * blob_scalar
func calculateEncodedL1DataFeeFeynman(
data []byte,
l1BaseFee *big.Int,
l1BlobBaseFee *big.Int,
execScalar *big.Int,
blobScalar *big.Int,
penaltyThreshold *big.Int,
penaltyFactor *big.Int,
compressionRatio *big.Int,
) *big.Int {
// Calculate penalty multiplier
penalty := calculatePenalty(compressionRatio, penaltyThreshold, penaltyFactor)
// Transaction size (RLP-encoded)
txSize := big.NewInt(int64(len(data)))
// Compute gas components
execGas := new(big.Int).Mul(execScalar, l1BaseFee)
blobGas := new(big.Int).Mul(blobScalar, l1BlobBaseFee)
// fee per byte = execGas + blobGas
feePerByte := new(big.Int).Add(execGas, blobGas)
// l1DataFee = feePerByte * txSize * penalty
l1DataFee := new(big.Int).Mul(feePerByte, txSize)
l1DataFee.Mul(l1DataFee, penalty)
// Divide by rcfg.Precision (once for scalars, once for penalty)
l1DataFee.Div(l1DataFee, rcfg.Precision) // account for scalars
l1DataFee.Div(l1DataFee, rcfg.Precision) // accounts for penalty
return l1DataFee
}
// calculateL1GasUsed computes the L1 gas used based on the calldata and // calculateL1GasUsed computes the L1 gas used based on the calldata and
// constant sized overhead. The overhead can be decreased as the cost of the // constant sized overhead. The overhead can be decreased as the cost of the
// batch submission goes down via contract optimizations. This will not overflow // batch submission goes down via contract optimizations. This will not overflow
@ -233,7 +317,7 @@ func mulAndScale(x *big.Int, y *big.Int, precision *big.Int) *big.Int {
return new(big.Int).Quo(z, precision) return new(big.Int).Quo(z, precision)
} }
func CalculateL1DataFee(tx *types.Transaction, state StateDB, config *params.ChainConfig, blockNumber *big.Int) (*big.Int, error) { func CalculateL1DataFee(tx *types.Transaction, state StateDB, config *params.ChainConfig, blockNumber *big.Int, blockTime uint64) (*big.Int, error) {
if tx.IsL1MessageTx() { if tx.IsL1MessageTx() {
return big.NewInt(0), nil return big.NewInt(0), nil
} }
@ -249,8 +333,26 @@ func CalculateL1DataFee(tx *types.Transaction, state StateDB, config *params.Cha
if !config.IsCurie(blockNumber) { if !config.IsCurie(blockNumber) {
l1DataFee = calculateEncodedL1DataFee(raw, gpoState.overhead, gpoState.l1BaseFee, gpoState.scalar) l1DataFee = calculateEncodedL1DataFee(raw, gpoState.overhead, gpoState.l1BaseFee, gpoState.scalar)
} else { } else if !config.IsFeynman(blockTime) {
l1DataFee = calculateEncodedL1DataFeeCurie(raw, gpoState.l1BaseFee, gpoState.l1BlobBaseFee, gpoState.commitScalar, gpoState.blobScalar) l1DataFee = calculateEncodedL1DataFeeCurie(raw, gpoState.l1BaseFee, gpoState.l1BlobBaseFee, gpoState.commitScalar, gpoState.blobScalar)
} else {
// Calculate compression ratio for Feynman
compressionRatio, err := estimateTxCompressionRatio(raw, blockNumber.Uint64(), blockTime, config)
if err != nil {
return nil, fmt.Errorf("failed to estimate compression ratio: tx hash=%s: %w", tx.Hash().Hex(), err)
}
// The contract slot for commitScalar is changed to execScalar in Feynman
l1DataFee = calculateEncodedL1DataFeeFeynman(
raw,
gpoState.l1BaseFee,
gpoState.l1BlobBaseFee,
gpoState.commitScalar, // now represents execScalar
gpoState.blobScalar,
gpoState.penaltyThreshold,
gpoState.penaltyFactor,
compressionRatio,
)
} }
// ensure l1DataFee fits into uint64 for circuit compatibility // ensure l1DataFee fits into uint64 for circuit compatibility

View file

@ -5,6 +5,8 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/scroll-tech/go-ethereum/params"
) )
func TestL1DataFeeBeforeCurie(t *testing.T) { func TestL1DataFeeBeforeCurie(t *testing.T) {
@ -31,3 +33,109 @@ func TestL1DataFeeAfterCurie(t *testing.T) {
actual := calculateEncodedL1DataFeeCurie(data, l1BaseFee, l1BlobBaseFee, commitScalar, blobScalar) actual := calculateEncodedL1DataFeeCurie(data, l1BaseFee, l1BlobBaseFee, commitScalar, blobScalar)
assert.Equal(t, expected, actual) assert.Equal(t, expected, actual)
} }
func TestL1DataFeeFeynman(t *testing.T) {
l1BaseFee := new(big.Int).SetInt64(1_000_000_000)
l1BlobBaseFee := new(big.Int).SetInt64(1_000_000_000)
execScalar := new(big.Int).SetInt64(10)
blobScalar := new(big.Int).SetInt64(20)
penaltyThreshold := new(big.Int).SetInt64(6_000_000_000) // 6 * PRECISION
penaltyFactor := new(big.Int).SetInt64(2_000_000_000) // 2 * PRECISION (200% penalty)
// Test case 1: No penalty (compression ratio >= threshold)
t.Run("no penalty case", func(t *testing.T) {
data := make([]byte, 100) // txSize = 100
compressionRatio := new(big.Int).SetInt64(6_000_000_000) // exactly at threshold
// Since compression ratio >= penaltyThreshold, penalty = 1 * PRECISION
// feePerByte = execScalar * l1BaseFee + blobScalar * l1BlobBaseFee = 10 * 1_000_000_000 + 20 * 1_000_000_000 = 30_000_000_000
// l1DataFee = feePerByte * txSize * penalty / PRECISION / PRECISION
// = 30_000_000_000 * 100 * 1_000_000_000 / 1_000_000_000 / 1_000_000_000 = 3000
expected := new(big.Int).SetInt64(3000)
actual := calculateEncodedL1DataFeeFeynman(
data,
l1BaseFee,
l1BlobBaseFee,
execScalar,
blobScalar,
penaltyThreshold,
penaltyFactor,
compressionRatio,
)
assert.Equal(t, expected, actual)
})
// Test case 2: With penalty (compression ratio < threshold)
t.Run("with penalty case", func(t *testing.T) {
data := make([]byte, 100) // txSize = 100
compressionRatio := new(big.Int).SetInt64(5_000_000_000) // below threshold
// Since compression ratio < penaltyThreshold, penalty = penaltyFactor
// feePerByte = execScalar * l1BaseFee + blobScalar * l1BlobBaseFee = 30_000_000_000
// l1DataFee = feePerByte * txSize * penaltyFactor / PRECISION / PRECISION
// = 30_000_000_000 * 100 * 2_000_000_000 / 1_000_000_000 / 1_000_000_000 = 6000
expected := new(big.Int).SetInt64(6000)
actual := calculateEncodedL1DataFeeFeynman(
data,
l1BaseFee,
l1BlobBaseFee,
execScalar,
blobScalar,
penaltyThreshold,
penaltyFactor,
compressionRatio,
)
assert.Equal(t, expected, actual)
})
}
func TestEstimateTxCompressionRatio(t *testing.T) {
// Mock config that would select a specific codec version
// Note: You'll need to adjust this based on your actual params.ChainConfig structure
t.Run("empty data", func(t *testing.T) {
data := []byte{}
// Should return 1.0 ratio (PRECISION)
ratio, err := estimateTxCompressionRatio(data, 1000000, 1700000000, params.TestChainConfig)
assert.Error(t, err, "raw data is empty")
assert.Nil(t, ratio)
// The exact value depends on rcfg.Precision, but should be the "1.0" equivalent
})
t.Run("non-empty data", func(t *testing.T) {
// Create some compressible data
data := make([]byte, 1000)
for i := range data {
data[i] = byte(i % 10) // Create patterns for better compression
}
ratio, err := estimateTxCompressionRatio(data, 1000000, 1700000000, params.TestChainConfig)
assert.NoError(t, err)
assert.NotNil(t, ratio)
// Should return a ratio > 1.0 (since compressed size < original size)
})
}
func TestCalculatePenalty(t *testing.T) {
precision := new(big.Int).SetInt64(1_000_000_000) // PRECISION
penaltyThreshold := new(big.Int).SetInt64(6_000_000_000) // 6 * PRECISION
penaltyFactor := new(big.Int).SetInt64(2_000_000_000) // 2 * PRECISION
t.Run("no penalty when ratio >= threshold", func(t *testing.T) {
compressionRatio := new(big.Int).SetInt64(6_000_000_000) // exactly at threshold
penalty := calculatePenalty(compressionRatio, penaltyThreshold, penaltyFactor)
assert.Equal(t, precision, penalty)
})
t.Run("penalty when ratio < threshold", func(t *testing.T) {
compressionRatio := new(big.Int).SetInt64(5_000_000_000) // below threshold
penalty := calculatePenalty(compressionRatio, penaltyThreshold, penaltyFactor)
assert.Equal(t, penaltyFactor, penalty)
})
}

File diff suppressed because one or more lines are too long

View file

@ -239,7 +239,7 @@ func (env *TraceEnv) GetBlockTrace(block *types.Block) (*types.BlockTrace, error
msg, _ := tx.AsMessage(env.signer, block.BaseFee()) msg, _ := tx.AsMessage(env.signer, block.BaseFee())
env.state.SetTxContext(tx.Hash(), i) env.state.SetTxContext(tx.Hash(), i)
vmenv := vm.NewEVM(env.blockCtx, core.NewEVMTxContext(msg), env.state, env.chainConfig, vm.Config{}) vmenv := vm.NewEVM(env.blockCtx, core.NewEVMTxContext(msg), env.state, env.chainConfig, vm.Config{})
l1DataFee, err := fees.CalculateL1DataFee(tx, env.state, env.chainConfig, block.Number()) l1DataFee, err := fees.CalculateL1DataFee(tx, env.state, env.chainConfig, block.Number(), block.Time())
if err != nil { if err != nil {
failed = err failed = err
break break
@ -342,7 +342,7 @@ func (env *TraceEnv) getTxResult(state *state.StateDB, index int, block *types.B
state.SetTxContext(txctx.TxHash, txctx.TxIndex) state.SetTxContext(txctx.TxHash, txctx.TxIndex)
// Computes the new state by applying the given message. // Computes the new state by applying the given message.
l1DataFee, err := fees.CalculateL1DataFee(tx, state, env.chainConfig, block.Number()) l1DataFee, err := fees.CalculateL1DataFee(tx, state, env.chainConfig, block.Number(), block.Time())
if err != nil { if err != nil {
return err return err
} }

View file

@ -251,7 +251,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
gaspool := new(core.GasPool) gaspool := new(core.GasPool)
gaspool.AddGas(block.GasLimit()) gaspool.AddGas(block.GasLimit())
l1DataFee, err := fees.CalculateL1DataFee(&ttx, statedb, config, block.Number()) l1DataFee, err := fees.CalculateL1DataFee(&ttx, statedb, config, block.Number(), block.Time())
if err != nil { if err != nil {
return nil, nil, common.Hash{}, err return nil, nil, common.Hash{}, err
} }