mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
sync l1datafee change for curie (#888)
* update rollup/rcfg/config.go * update consensus/misc/curie.go * update rollup/fees/rollup_fee_test.go * update rollup/fees/rollup_fee.go * update rollup/tracing/tracing.go * update tests/state_test_util.go * update light/txpool.go * fix some * update eth/tracers/internal/tracetest/prestate_test.go * update eth/tracers/api.go * update core/chain_makers.go * update core/state_processor.go * update cmd/evm/internal/t8ntool/execution.go * update txpool * update ethclient/ethclient_test.go * update ethclient/gethclient/gethclient_test.go * update core/blockchain_test.go * update miner/worker.go * update txpool 2
This commit is contained in:
parent
5e255cf5b1
commit
f777318776
31 changed files with 367 additions and 103 deletions
|
|
@ -715,7 +715,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(), header.Number, header.Time)
|
signer := types.MakeSigner(b.blockchain.Config(), header.Number, header.Time)
|
||||||
l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, b.blockchain.Config().ChainID, signer, stateDB)
|
l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, b.blockchain.Config(), signer, stateDB, header.Number)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -186,6 +186,10 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
chainConfig.DAOForkBlock.Cmp(new(big.Int).SetUint64(pre.Env.Number)) == 0 {
|
chainConfig.DAOForkBlock.Cmp(new(big.Int).SetUint64(pre.Env.Number)) == 0 {
|
||||||
misc.ApplyDAOHardFork(statedb)
|
misc.ApplyDAOHardFork(statedb)
|
||||||
}
|
}
|
||||||
|
// Apply Curie hard fork
|
||||||
|
if chainConfig.CurieBlock != nil && chainConfig.CurieBlock.Cmp(new(big.Int).SetUint64(pre.Env.Number)) == 0 {
|
||||||
|
misc.ApplyCurieHardFork(statedb)
|
||||||
|
}
|
||||||
if beaconRoot := pre.Env.ParentBeaconBlockRoot; beaconRoot != nil {
|
if beaconRoot := pre.Env.ParentBeaconBlockRoot; beaconRoot != nil {
|
||||||
evm := vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vmConfig)
|
evm := vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vmConfig)
|
||||||
core.ProcessBeaconBlockRoot(*beaconRoot, evm, statedb)
|
core.ProcessBeaconBlockRoot(*beaconRoot, evm, statedb)
|
||||||
|
|
@ -221,7 +225,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
)
|
)
|
||||||
evm := vm.NewEVM(vmContext, txContext, statedb, chainConfig, vmConfig)
|
evm := vm.NewEVM(vmContext, txContext, statedb, chainConfig, vmConfig)
|
||||||
|
|
||||||
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, chainConfig, new(big.Int).SetUint64(pre.Env.Number))
|
||||||
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()})
|
||||||
|
|
|
||||||
23
consensus/misc/curie.go
Normal file
23
consensus/misc/curie.go
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
package misc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/rollup/rcfg"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ApplyCurieHardFork modifies the state database according to the Curie hard-fork rules,
|
||||||
|
// updating the bytecode and storage of the L1GasPriceOracle contract.
|
||||||
|
func ApplyCurieHardFork(statedb *state.StateDB) {
|
||||||
|
log.Info("Applying Curie hard fork")
|
||||||
|
|
||||||
|
// update contract byte code
|
||||||
|
statedb.SetCode(rcfg.L1GasPriceOracleAddress, rcfg.CurieL1GasPriceOracleBytecode)
|
||||||
|
|
||||||
|
// initialize new storage slots
|
||||||
|
statedb.SetState(rcfg.L1GasPriceOracleAddress, rcfg.IsCurieSlot, common.BytesToHash([]byte{1}))
|
||||||
|
statedb.SetState(rcfg.L1GasPriceOracleAddress, rcfg.L1BlobBaseFeeSlot, common.BytesToHash([]byte{1}))
|
||||||
|
statedb.SetState(rcfg.L1GasPriceOracleAddress, rcfg.CommitScalarSlot, common.BigToHash(rcfg.InitialCommitScalar))
|
||||||
|
statedb.SetState(rcfg.L1GasPriceOracleAddress, rcfg.BlobScalarSlot, common.BigToHash(rcfg.InitialBlobScalar))
|
||||||
|
}
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
@ -39,7 +40,9 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/rollup/rcfg"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
// So we can deterministically seed different blockchains
|
// So we can deterministically seed different blockchains
|
||||||
|
|
@ -4716,3 +4719,78 @@ func TestEIP3651(t *testing.T) {
|
||||||
t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
|
t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCurieTransition(t *testing.T) {
|
||||||
|
// Set fork blocks in config
|
||||||
|
// (we make a deep copy to avoid interference with other tests)
|
||||||
|
var config *params.ChainConfig
|
||||||
|
b, _ := json.Marshal(params.AllEthashProtocolChanges)
|
||||||
|
json.Unmarshal(b, &config)
|
||||||
|
config.CurieBlock = big.NewInt(2)
|
||||||
|
config.DescartesBlock = nil
|
||||||
|
|
||||||
|
var (
|
||||||
|
db = rawdb.NewMemoryDatabase()
|
||||||
|
gspec = &Genesis{Config: config}
|
||||||
|
genesis = gspec.MustCommit(db, trie.NewDatabase(db, trie.HashDefaults))
|
||||||
|
)
|
||||||
|
|
||||||
|
blockchain, _ := NewBlockChain(db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
|
||||||
|
defer blockchain.Stop()
|
||||||
|
blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, nil)
|
||||||
|
|
||||||
|
if _, err := blockchain.InsertChain(blocks); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
latestBlock := uint64(4)
|
||||||
|
assert.Equal(t, latestBlock, blockchain.CurrentHeader().Number.Uint64())
|
||||||
|
|
||||||
|
for ii := uint64(0); ii <= latestBlock; ii++ {
|
||||||
|
block := blockchain.GetBlockByNumber(ii)
|
||||||
|
|
||||||
|
number := block.Number().Uint64()
|
||||||
|
baseFee := block.BaseFee()
|
||||||
|
|
||||||
|
statedb, _ := state.New(block.Root(), state.NewDatabase(db), nil)
|
||||||
|
|
||||||
|
code := statedb.GetCode(rcfg.L1GasPriceOracleAddress)
|
||||||
|
codeSize := statedb.GetCodeSize(rcfg.L1GasPriceOracleAddress)
|
||||||
|
keccakCodeHash := statedb.GetKeccakCodeHash(rcfg.L1GasPriceOracleAddress)
|
||||||
|
poseidonCodeHash := statedb.GetPoseidonCodeHash(rcfg.L1GasPriceOracleAddress)
|
||||||
|
|
||||||
|
l1BlobBaseFee := statedb.GetState(rcfg.L1GasPriceOracleAddress, rcfg.L1BlobBaseFeeSlot)
|
||||||
|
commitScalar := statedb.GetState(rcfg.L1GasPriceOracleAddress, rcfg.CommitScalarSlot)
|
||||||
|
blobScalar := statedb.GetState(rcfg.L1GasPriceOracleAddress, rcfg.BlobScalarSlot)
|
||||||
|
isCurie := statedb.GetState(rcfg.L1GasPriceOracleAddress, rcfg.IsCurieSlot)
|
||||||
|
|
||||||
|
if number < config.CurieBlock.Uint64() {
|
||||||
|
assert.Nil(t, baseFee, "Expected zero base fee before Curie")
|
||||||
|
|
||||||
|
// we don't have predeploys configured in this test,
|
||||||
|
// so there is no gas oracle deployed before Curie
|
||||||
|
assert.Nil(t, code)
|
||||||
|
assert.Equal(t, uint64(0), codeSize)
|
||||||
|
assert.Equal(t, common.Hash{}, keccakCodeHash)
|
||||||
|
assert.Equal(t, common.Hash{}, poseidonCodeHash)
|
||||||
|
|
||||||
|
assert.Equal(t, common.Hash{}, l1BlobBaseFee)
|
||||||
|
assert.Equal(t, common.Hash{}, commitScalar)
|
||||||
|
assert.Equal(t, common.Hash{}, blobScalar)
|
||||||
|
assert.Equal(t, common.Hash{}, isCurie)
|
||||||
|
} else {
|
||||||
|
assert.NotNil(t, baseFee, "Expected nonzero base fee after Curie")
|
||||||
|
|
||||||
|
// all gas oracle entries updated
|
||||||
|
assert.NotNil(t, code)
|
||||||
|
assert.NotEqual(t, uint64(0), codeSize)
|
||||||
|
assert.NotEqual(t, common.Hash{}, keccakCodeHash)
|
||||||
|
assert.NotEqual(t, common.Hash{}, poseidonCodeHash)
|
||||||
|
|
||||||
|
assert.NotEqual(t, common.Hash{}, l1BlobBaseFee)
|
||||||
|
assert.NotEqual(t, common.Hash{}, commitScalar)
|
||||||
|
assert.NotEqual(t, common.Hash{}, blobScalar)
|
||||||
|
assert.NotEqual(t, common.Hash{}, isCurie)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -328,6 +328,9 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
||||||
if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(b.header.Number) == 0 {
|
if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(b.header.Number) == 0 {
|
||||||
misc.ApplyDAOHardFork(statedb)
|
misc.ApplyDAOHardFork(statedb)
|
||||||
}
|
}
|
||||||
|
if config.CurieBlock != nil && config.CurieBlock.Cmp(b.header.Number) == 0 {
|
||||||
|
misc.ApplyCurieHardFork(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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, p.config, block.Number())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,10 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
||||||
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
|
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
|
||||||
misc.ApplyDAOHardFork(statedb)
|
misc.ApplyDAOHardFork(statedb)
|
||||||
}
|
}
|
||||||
|
// Apply Curie hard fork
|
||||||
|
if p.config.CurieBlock != nil && p.config.CurieBlock.Cmp(block.Number()) == 0 {
|
||||||
|
misc.ApplyCurieHardFork(statedb)
|
||||||
|
}
|
||||||
var (
|
var (
|
||||||
context = NewEVMBlockContext(header, p.bc, p.config, nil)
|
context = NewEVMBlockContext(header, p.bc, p.config, nil)
|
||||||
vmenv = vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg)
|
vmenv = vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg)
|
||||||
|
|
@ -110,7 +114,7 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta
|
||||||
txContext := NewEVMTxContext(msg)
|
txContext := NewEVMTxContext(msg)
|
||||||
evm.Reset(txContext, statedb)
|
evm.Reset(txContext, statedb)
|
||||||
|
|
||||||
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, config, blockNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1080,7 +1080,7 @@ func (p *BlobPool) validateTx(tx *types.Transaction) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if err := txpool.ValidateTransactionWithState(tx, p.signer, stateOpts); err != nil {
|
if err := txpool.ValidateTransactionWithState(tx, p.signer, stateOpts, p.chain.Config(), p.head.Number); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// If the transaction replaces an existing one, ensure that price bumps are
|
// If the transaction replaces an existing one, ensure that price bumps are
|
||||||
|
|
|
||||||
|
|
@ -638,7 +638,7 @@ func (pool *LegacyPool) validateTx(tx *types.Transaction, local bool) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if err := txpool.ValidateTransactionWithState(tx, pool.signer, opts); err != nil {
|
if err := txpool.ValidateTransactionWithState(tx, pool.signer, opts, pool.chainconfig, pool.currentHead.Load().Number); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -759,7 +759,7 @@ func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, e
|
||||||
// Try to replace an existing transaction in the pending pool
|
// Try to replace an existing transaction in the pending pool
|
||||||
if list := pool.pending[from]; list != nil && list.Contains(tx.Nonce()) {
|
if list := pool.pending[from]; list != nil && list.Contains(tx.Nonce()) {
|
||||||
// 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.config.PriceBump)
|
inserted, old := list.Add(tx, pool.currentState, pool.config.PriceBump, pool.chainconfig, pool.currentHead.Load().Number)
|
||||||
if !inserted {
|
if !inserted {
|
||||||
pendingDiscardMeter.Mark(1)
|
pendingDiscardMeter.Mark(1)
|
||||||
return false, txpool.ErrReplaceUnderpriced
|
return false, txpool.ErrReplaceUnderpriced
|
||||||
|
|
@ -833,7 +833,7 @@ func (pool *LegacyPool) enqueueTx(hash common.Hash, tx *types.Transaction, local
|
||||||
if pool.queue[from] == nil {
|
if pool.queue[from] == nil {
|
||||||
pool.queue[from] = newList(false)
|
pool.queue[from] = newList(false)
|
||||||
}
|
}
|
||||||
inserted, old := pool.queue[from].Add(tx, pool.config.PriceBump)
|
inserted, old := pool.queue[from].Add(tx, pool.currentState, pool.config.PriceBump, pool.chainconfig, pool.currentHead.Load().Number)
|
||||||
if !inserted {
|
if !inserted {
|
||||||
// An older transaction was better, discard this
|
// An older transaction was better, discard this
|
||||||
queuedDiscardMeter.Mark(1)
|
queuedDiscardMeter.Mark(1)
|
||||||
|
|
@ -887,7 +887,7 @@ func (pool *LegacyPool) promoteTx(addr common.Address, hash common.Hash, tx *typ
|
||||||
}
|
}
|
||||||
list := pool.pending[addr]
|
list := pool.pending[addr]
|
||||||
|
|
||||||
inserted, old := list.Add(tx, pool.config.PriceBump)
|
inserted, old := list.Add(tx, pool.currentState, pool.config.PriceBump, pool.chainconfig, pool.currentHead.Load().Number)
|
||||||
if !inserted {
|
if !inserted {
|
||||||
// An older transaction was better, discard this
|
// An older transaction was better, discard this
|
||||||
pool.all.Remove(hash)
|
pool.all.Remove(hash)
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,11 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/rollup/fees"
|
||||||
)
|
)
|
||||||
|
|
||||||
// nonceHeap is a heap.Interface implementation over 64bit unsigned integers for
|
// nonceHeap is a heap.Interface implementation over 64bit unsigned integers for
|
||||||
|
|
@ -298,7 +302,7 @@ func (l *list) Contains(nonce uint64) 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 *list) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Transaction) {
|
func (l *list) Add(tx *types.Transaction, state *state.StateDB, priceBump uint64, chainconfig *params.ChainConfig, blockNumber *big.Int) (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 {
|
||||||
|
|
@ -322,13 +326,24 @@ func (l *list) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Transa
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
// Old is being replaced, subtract old cost
|
// Old is being replaced, subtract old cost
|
||||||
|
// TODO: fix for L1DataFee
|
||||||
l.subTotalCost([]*types.Transaction{old})
|
l.subTotalCost([]*types.Transaction{old})
|
||||||
}
|
}
|
||||||
|
l1DataFee := big.NewInt(0)
|
||||||
|
if state != nil && chainconfig != nil {
|
||||||
|
var err error
|
||||||
|
l1DataFee, err = fees.CalculateL1DataFee(tx, state, chainconfig, blockNumber)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Failed to calculate L1 data fee", "err", err, "tx", tx)
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
// Add new tx cost to totalcost
|
// Add new tx cost to totalcost
|
||||||
|
// TODO: fix totalcost for L1DataFee for both sub and add
|
||||||
l.totalcost.Add(l.totalcost, tx.Cost())
|
l.totalcost.Add(l.totalcost, tx.Cost())
|
||||||
// Otherwise overwrite the old transaction with the current one
|
// Otherwise overwrite the old transaction with the current one
|
||||||
l.txs.Put(tx)
|
l.txs.Put(tx)
|
||||||
if cost := tx.Cost(); l.costcap.Cmp(cost) < 0 {
|
if cost := new(big.Int).Add(tx.Cost(), l1DataFee); l.costcap.Cmp(cost) < 0 {
|
||||||
l.costcap = cost
|
l.costcap = cost
|
||||||
}
|
}
|
||||||
if gas := tx.Gas(); l.gascap < gas {
|
if gas := tx.Gas(); l.gascap < gas {
|
||||||
|
|
@ -454,6 +469,7 @@ func (l *list) LastElement() *types.Transaction {
|
||||||
|
|
||||||
// subTotalCost subtracts the cost of the given transactions from the
|
// subTotalCost subtracts the cost of the given transactions from the
|
||||||
// total cost of all transactions.
|
// total cost of all transactions.
|
||||||
|
// TODO: fix for L1DataFee
|
||||||
func (l *list) subTotalCost(txs []*types.Transaction) {
|
func (l *list) subTotalCost(txs []*types.Transaction) {
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
l.totalcost.Sub(l.totalcost, tx.Cost())
|
l.totalcost.Sub(l.totalcost, tx.Cost())
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,19 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Tests that transactions can be added to strict lists and list contents and
|
// Tests that transactions can be added to strict lists and list contents and
|
||||||
// nonce boundaries are correctly maintained.
|
// nonce boundaries are correctly maintained.
|
||||||
func TestStrictListAdd(t *testing.T) {
|
func TestStrictListAdd(t *testing.T) {
|
||||||
|
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
||||||
|
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
// Generate a list of transactions to insert
|
// Generate a list of transactions to insert
|
||||||
key, _ := crypto.GenerateKey()
|
key, _ := crypto.GenerateKey()
|
||||||
|
|
||||||
|
|
@ -38,7 +44,7 @@ func TestStrictListAdd(t *testing.T) {
|
||||||
// Insert the transactions in a random order
|
// Insert the transactions in a random order
|
||||||
list := newList(true)
|
list := newList(true)
|
||||||
for _, v := range rand.Perm(len(txs)) {
|
for _, v := range rand.Perm(len(txs)) {
|
||||||
list.Add(txs[v], DefaultConfig.PriceBump)
|
list.Add(txs[v], statedb, DefaultConfig.PriceBump, blockchain.Config(), blockchain.CurrentBlock().Number)
|
||||||
}
|
}
|
||||||
// Verify internal state
|
// Verify internal state
|
||||||
if len(list.txs.items) != len(txs) {
|
if len(list.txs.items) != len(txs) {
|
||||||
|
|
@ -52,6 +58,9 @@ func TestStrictListAdd(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkListAdd(b *testing.B) {
|
func BenchmarkListAdd(b *testing.B) {
|
||||||
|
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
||||||
|
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
// Generate a list of transactions to insert
|
// Generate a list of transactions to insert
|
||||||
key, _ := crypto.GenerateKey()
|
key, _ := crypto.GenerateKey()
|
||||||
|
|
||||||
|
|
@ -65,7 +74,7 @@ func BenchmarkListAdd(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
list := newList(true)
|
list := newList(true)
|
||||||
for _, v := range rand.Perm(len(txs)) {
|
for _, v := range rand.Perm(len(txs)) {
|
||||||
list.Add(txs[v], DefaultConfig.PriceBump)
|
list.Add(txs[v], statedb, DefaultConfig.PriceBump, blockchain.Config(), blockchain.CurrentBlock().Number)
|
||||||
list.Filter(priceLimit, DefaultConfig.PriceBump)
|
list.Filter(priceLimit, DefaultConfig.PriceBump)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@ type ValidationOptionsWithState struct {
|
||||||
//
|
//
|
||||||
// This check is public to allow different transaction pools to check the stateful
|
// This check is public to allow different transaction pools to check the stateful
|
||||||
// rules without duplicating code and running the risk of missed updates.
|
// rules without duplicating code and running the risk of missed updates.
|
||||||
func ValidateTransactionWithState(tx *types.Transaction, signer types.Signer, opts *ValidationOptionsWithState) error {
|
func ValidateTransactionWithState(tx *types.Transaction, signer types.Signer, opts *ValidationOptionsWithState, chainConfig *params.ChainConfig, headNumber *big.Int) error {
|
||||||
// Ensure the transaction adheres to nonce ordering
|
// Ensure the transaction adheres to nonce ordering
|
||||||
from, err := signer.Sender(tx) // already validated (and cached), but cleaner to check
|
from, err := signer.Sender(tx) // already validated (and cached), but cleaner to check
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -227,7 +227,7 @@ func ValidateTransactionWithState(tx *types.Transaction, signer types.Signer, op
|
||||||
// 2. Perform an additional check for L1 data fees.
|
// 2. Perform an additional check for L1 data fees.
|
||||||
// Always perform the check, because it's not easy to check FeeVault here
|
// Always perform the check, because it's not easy to check FeeVault here
|
||||||
// Get L1 data fee in current state
|
// Get L1 data fee in current state
|
||||||
l1DataFee, err := fees.CalculateL1DataFee(tx, opts.State)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, opts.State, chainConfig, headNumber)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -249,7 +249,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
|
||||||
// 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)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, eth.blockchain.Config(), block.Number())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, vm.BlockContext{}, nil, nil, err
|
return nil, vm.BlockContext{}, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -280,7 +280,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
||||||
TxIndex: i,
|
TxIndex: i,
|
||||||
TxHash: tx.Hash(),
|
TxHash: tx.Hash(),
|
||||||
}
|
}
|
||||||
l1DataFee, err := fees.CalculateL1DataFee(tx, task.statedb)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, task.statedb, api.backend.ChainConfig(), task.block.Number())
|
||||||
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{TxHash: tx.Hash(), Error: err.Error()}
|
task.results[i] = &txTraceResult{TxHash: tx.Hash(), Error: err.Error()}
|
||||||
|
|
@ -546,7 +546,7 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
|
||||||
vmenv = vm.NewEVM(vmctx, txContext, statedb, chainConfig, vm.Config{})
|
vmenv = vm.NewEVM(vmctx, txContext, statedb, chainConfig, vm.Config{})
|
||||||
)
|
)
|
||||||
statedb.SetTxContext(tx.Hash(), i)
|
statedb.SetTxContext(tx.Hash(), i)
|
||||||
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, chainConfig, block.Number())
|
||||||
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
|
||||||
|
|
@ -627,7 +627,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
|
||||||
TxIndex: i,
|
TxIndex: i,
|
||||||
TxHash: tx.Hash(),
|
TxHash: tx.Hash(),
|
||||||
}
|
}
|
||||||
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, api.backend.ChainConfig(), block.Number())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -674,7 +674,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat
|
||||||
TxIndex: task.index,
|
TxIndex: task.index,
|
||||||
TxHash: txs[task.index].Hash(),
|
TxHash: txs[task.index].Hash(),
|
||||||
}
|
}
|
||||||
l1DataFee, err := fees.CalculateL1DataFee(txs[task.index], task.statedb)
|
l1DataFee, err := fees.CalculateL1DataFee(txs[task.index], task.statedb, api.backend.ChainConfig(), block.Number())
|
||||||
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{TxHash: txs[task.index].Hash(), Error: err.Error()}
|
results[task.index] = &txTraceResult{TxHash: txs[task.index].Hash(), Error: err.Error()}
|
||||||
|
|
@ -707,7 +707,7 @@ txloop:
|
||||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
msg, _ := core.TransactionToMessage(tx, 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)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, api.backend.ChainConfig(), block.Number())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
failed = err
|
failed = err
|
||||||
break txloop
|
break txloop
|
||||||
|
|
@ -819,7 +819,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)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, chainConfig, block.Number())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
_, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit), l1DataFee)
|
_, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit), l1DataFee)
|
||||||
}
|
}
|
||||||
|
|
@ -891,7 +891,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)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, api.backend.ChainConfig(), block.Number())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -955,7 +955,7 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
|
||||||
traceConfig = &config.TraceConfig
|
traceConfig = &config.TraceConfig
|
||||||
}
|
}
|
||||||
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().ChainID, signer, statedb)
|
l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, block.BaseFee(), api.backend.ChainConfig(), signer, statedb, block.Number())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block
|
||||||
return msg, context, statedb, release, nil
|
return msg, context, statedb, release, 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)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, b.chainConfig, block.Number())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x CalculateL1DataFee failed: %v", tx.Hash(), err)
|
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x CalculateL1DataFee failed: %v", tx.Hash(), err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,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)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, test.Genesis.Config, context.BlockNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to calculate l1DataFee: %v", err)
|
t.Fatalf("failed to calculate l1DataFee: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -256,7 +256,7 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
|
||||||
}
|
}
|
||||||
evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Tracer: tracer})
|
evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Tracer: tracer})
|
||||||
snap := statedb.Snapshot()
|
snap := statedb.Snapshot()
|
||||||
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, test.Genesis.Config, context.BlockNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("failed to calculate l1DataFee: %v", err)
|
b.Fatalf("failed to calculate l1DataFee: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -398,7 +398,7 @@ func TestInternals(t *testing.T) {
|
||||||
SkipAccountChecks: false,
|
SkipAccountChecks: false,
|
||||||
}
|
}
|
||||||
signer := types.MakeSigner(params.MainnetChainConfig, context.BlockNumber, context.Time)
|
signer := types.MakeSigner(params.MainnetChainConfig, context.BlockNumber, context.Time)
|
||||||
l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, nil, params.MainnetChainConfig.ChainID, signer, statedb)
|
l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, nil, params.MainnetChainConfig, signer, statedb, context.BlockNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("test %v: failed to estimate L1DataFee: %v", tc.name, err)
|
t.Fatalf("test %v: failed to estimate L1DataFee: %v", tc.name, err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to prepare transaction for tracing: %v", err)
|
return fmt.Errorf("failed to prepare transaction for tracing: %v", err)
|
||||||
}
|
}
|
||||||
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, test.Genesis.Config, context.BlockNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to calculate L1DataFee: %v", err)
|
return fmt.Errorf("failed to calculate L1DataFee: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ func testPrestateDiffTracer(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)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, test.Genesis.Config, context.BlockNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to calculate L1DataFee: %v", err)
|
t.Fatalf("failed to calculate L1DataFee: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,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)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, params.AllEthashProtocolChanges, context.BlockNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
||||||
"github.com/ethereum/go-ethereum/node"
|
"github.com/ethereum/go-ethereum/node"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/rollup/rcfg"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -186,8 +187,22 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
var genesis = &core.Genesis{
|
var genesis = &core.Genesis{
|
||||||
Config: params.AllEthashProtocolChanges,
|
Config: params.AllEthashProtocolChanges,
|
||||||
Alloc: core.GenesisAlloc{testAddr: {Balance: testBalance}},
|
Alloc: core.GenesisAlloc{
|
||||||
|
testAddr: {Balance: testBalance},
|
||||||
|
rcfg.L1GasPriceOracleAddress: {
|
||||||
|
Balance: big.NewInt(0),
|
||||||
|
Storage: map[common.Hash]common.Hash{
|
||||||
|
rcfg.L1BaseFeeSlot: common.BigToHash(big.NewInt(10000)),
|
||||||
|
rcfg.OverheadSlot: common.BigToHash(big.NewInt(10000)),
|
||||||
|
rcfg.ScalarSlot: common.BigToHash(big.NewInt(10000)),
|
||||||
|
rcfg.L1BlobBaseFeeSlot: common.BigToHash(big.NewInt(10000)),
|
||||||
|
rcfg.CommitScalarSlot: common.BigToHash(big.NewInt(10000)),
|
||||||
|
rcfg.BlobScalarSlot: common.BigToHash(big.NewInt(10000)),
|
||||||
|
rcfg.IsCurieSlot: common.BytesToHash([]byte{1}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
ExtraData: []byte("test genesis"),
|
ExtraData: []byte("test genesis"),
|
||||||
Timestamp: 9000,
|
Timestamp: 9000,
|
||||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
"github.com/ethereum/go-ethereum/ethclient"
|
||||||
"github.com/ethereum/go-ethereum/node"
|
"github.com/ethereum/go-ethereum/node"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/rollup/rcfg"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -80,8 +81,22 @@ func newTestBackend(t *testing.T) (*node.Node, []*types.Block) {
|
||||||
func generateTestChain() (*core.Genesis, []*types.Block) {
|
func generateTestChain() (*core.Genesis, []*types.Block) {
|
||||||
genesis := &core.Genesis{
|
genesis := &core.Genesis{
|
||||||
Config: params.AllEthashProtocolChanges,
|
Config: params.AllEthashProtocolChanges,
|
||||||
Alloc: core.GenesisAlloc{testAddr: {Balance: testBalance, Storage: map[common.Hash]common.Hash{testSlot: testValue}},
|
Alloc: core.GenesisAlloc{
|
||||||
testContract: {Nonce: 1, Code: []byte{0x13, 0x37}}},
|
testAddr: {Balance: testBalance, Storage: map[common.Hash]common.Hash{testSlot: testValue}},
|
||||||
|
testContract: {Nonce: 1, Code: []byte{0x13, 0x37}},
|
||||||
|
rcfg.L1GasPriceOracleAddress: {
|
||||||
|
Balance: big.NewInt(0),
|
||||||
|
Storage: map[common.Hash]common.Hash{
|
||||||
|
rcfg.L1BaseFeeSlot: common.BigToHash(big.NewInt(10000)),
|
||||||
|
rcfg.OverheadSlot: common.BigToHash(big.NewInt(10000)),
|
||||||
|
rcfg.ScalarSlot: common.BigToHash(big.NewInt(10000)),
|
||||||
|
rcfg.L1BlobBaseFeeSlot: common.BigToHash(big.NewInt(10000)),
|
||||||
|
rcfg.CommitScalarSlot: common.BigToHash(big.NewInt(10000)),
|
||||||
|
rcfg.BlobScalarSlot: common.BigToHash(big.NewInt(10000)),
|
||||||
|
rcfg.IsCurieSlot: common.BytesToHash([]byte{1}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
ExtraData: []byte("test genesis"),
|
ExtraData: []byte("test genesis"),
|
||||||
Timestamp: 9000,
|
Timestamp: 9000,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1234,7 +1234,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.ChainID, signer, evm.StateDB)
|
return fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config, signer, evm.StateDB, header.Number)
|
||||||
}
|
}
|
||||||
|
|
||||||
// executeEstimate is a helper that executes the transaction under a given gas limit and returns
|
// executeEstimate is a helper that executes the transaction under a given gas limit and returns
|
||||||
|
|
@ -1729,7 +1729,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH
|
||||||
config := vm.Config{Tracer: tracer, NoBaseFee: true}
|
config := vm.Config{Tracer: tracer, NoBaseFee: true}
|
||||||
vmenv, _ := b.GetEVM(ctx, msg, statedb, header, &config, nil)
|
vmenv, _ := b.GetEVM(ctx, msg, statedb, header, &config, nil)
|
||||||
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().ChainID, signer, statedb)
|
l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, b.ChainConfig(), signer, statedb, header.Number)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,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)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, leth.blockchain.Config(), block.Number())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,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.ChainID, signer, st)
|
l1DataFee, _ := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config, signer, st, header.Number)
|
||||||
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 {
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,8 @@ type TxPool struct {
|
||||||
istanbul bool // Fork indicator whether we are in the istanbul stage.
|
istanbul bool // Fork indicator whether we are in the istanbul stage.
|
||||||
eip2718 bool // Fork indicator whether we are in the eip2718 stage.
|
eip2718 bool // Fork indicator whether we are in the eip2718 stage.
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
// TxRelayBackend provides an interface to the mechanism that forwards transactions to the
|
// TxRelayBackend provides an interface to the mechanism that forwards transactions to the
|
||||||
|
|
@ -320,6 +322,8 @@ func (pool *TxPool) setNewHead(head *types.Header) {
|
||||||
pool.istanbul = pool.config.IsIstanbul(next)
|
pool.istanbul = pool.config.IsIstanbul(next)
|
||||||
pool.eip2718 = pool.config.IsBerlin(next)
|
pool.eip2718 = pool.config.IsBerlin(next)
|
||||||
pool.shanghai = pool.config.IsShanghai(next, uint64(time.Now().Unix()))
|
pool.shanghai = pool.config.IsShanghai(next, uint64(time.Now().Unix()))
|
||||||
|
|
||||||
|
pool.currentHead = next
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop stops the light transaction pool
|
// Stop stops the light transaction pool
|
||||||
|
|
@ -389,7 +393,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)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, currentState, pool.config, pool.currentHead)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus/misc"
|
||||||
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
||||||
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
|
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
|
@ -1384,6 +1385,9 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
|
||||||
log.Error("Failed to create sealing context", "err", err)
|
log.Error("Failed to create sealing context", "err", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if w.chainConfig.CurieBlock != nil && w.chainConfig.CurieBlock.Cmp(header.Number) == 0 {
|
||||||
|
misc.ApplyCurieHardFork(env.state)
|
||||||
|
}
|
||||||
if header.ParentBeaconRoot != nil {
|
if header.ParentBeaconRoot != nil {
|
||||||
context := core.NewEVMBlockContext(header, w.chain, w.chainConfig, nil)
|
context := core.NewEVMBlockContext(header, w.chain, w.chainConfig, nil)
|
||||||
vmenv := vm.NewEVM(context, vm.TxContext{}, env.state, w.chainConfig, vm.Config{})
|
vmenv := vm.NewEVM(context, vm.TxContext{}, env.state, w.chainConfig, vm.Config{})
|
||||||
|
|
@ -1571,35 +1575,45 @@ func (w *worker) commitWork(interrupt *atomic.Int32, timestamp int64) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Fill pending transactions from the txpool into the block.
|
|
||||||
err = w.fillTransactions(interrupt, work)
|
|
||||||
switch {
|
|
||||||
case err == nil:
|
|
||||||
// The entire block is filled, decrease resubmit interval in case
|
|
||||||
// of current interval is larger than the user-specified one.
|
|
||||||
w.resubmitAdjustCh <- &intervalAdjust{inc: false}
|
|
||||||
|
|
||||||
case errors.Is(err, errBlockInterruptedByRecommit):
|
noTxs := false
|
||||||
// Notify resubmit loop to increase resubmitting interval if the
|
// zkEVM requirement: Curie transition block has 0 transactions
|
||||||
// interruption is due to frequent commits.
|
if w.chainConfig.CurieBlock != nil && w.chainConfig.CurieBlock.Cmp(work.header.Number) == 0 {
|
||||||
gaslimit := work.header.GasLimit
|
noTxs = true
|
||||||
ratio := float64(gaslimit-work.gasPool.Gas()) / float64(gaslimit)
|
|
||||||
if ratio < 0.1 {
|
|
||||||
ratio = 0.1
|
|
||||||
}
|
|
||||||
w.resubmitAdjustCh <- &intervalAdjust{
|
|
||||||
ratio: ratio,
|
|
||||||
inc: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
case errors.Is(err, errBlockInterruptedByNewHead):
|
|
||||||
// If the block building is interrupted by newhead event, discard it
|
|
||||||
// totally. Committing the interrupted block introduces unnecessary
|
|
||||||
// delay, and possibly causes miner to mine on the previous head,
|
|
||||||
// which could result in higher uncle rate.
|
|
||||||
work.discard()
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !noTxs {
|
||||||
|
// Fill pending transactions from the txpool into the block.
|
||||||
|
err = w.fillTransactions(interrupt, work)
|
||||||
|
switch {
|
||||||
|
case err == nil:
|
||||||
|
// The entire block is filled, decrease resubmit interval in case
|
||||||
|
// of current interval is larger than the user-specified one.
|
||||||
|
w.resubmitAdjustCh <- &intervalAdjust{inc: false}
|
||||||
|
|
||||||
|
case errors.Is(err, errBlockInterruptedByRecommit):
|
||||||
|
// Notify resubmit loop to increase resubmitting interval if the
|
||||||
|
// interruption is due to frequent commits.
|
||||||
|
gaslimit := work.header.GasLimit
|
||||||
|
ratio := float64(gaslimit-work.gasPool.Gas()) / float64(gaslimit)
|
||||||
|
if ratio < 0.1 {
|
||||||
|
ratio = 0.1
|
||||||
|
}
|
||||||
|
w.resubmitAdjustCh <- &intervalAdjust{
|
||||||
|
ratio: ratio,
|
||||||
|
inc: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
case errors.Is(err, errBlockInterruptedByNewHead):
|
||||||
|
// If the block building is interrupted by newhead event, discard it
|
||||||
|
// totally. Committing the interrupted block introduces unnecessary
|
||||||
|
// delay, and possibly causes miner to mine on the previous head,
|
||||||
|
// which could result in higher uncle rate.
|
||||||
|
work.discard()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Submit the generated block for consensus sealing.
|
// Submit the generated block for consensus sealing.
|
||||||
w.commit(work.copy(), w.fullTaskHook, true, start)
|
w.commit(work.copy(), w.fullTaskHook, true, start)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package fees
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
@ -43,25 +44,42 @@ type StateDB interface {
|
||||||
GetBalance(addr common.Address) *big.Int
|
GetBalance(addr common.Address) *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
func EstimateL1DataFeeForMessage(msg Message, baseFee, chainID *big.Int, signer types.Signer, state StateDB) (*big.Int, error) {
|
type gpoState struct {
|
||||||
|
l1BaseFee *big.Int
|
||||||
|
overhead *big.Int
|
||||||
|
scalar *big.Int
|
||||||
|
l1BlobBaseFee *big.Int
|
||||||
|
commitScalar *big.Int
|
||||||
|
blobScalar *big.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
func EstimateL1DataFeeForMessage(msg Message, baseFee *big.Int, config *params.ChainConfig, signer types.Signer, state StateDB, blockNumber *big.Int) (*big.Int, error) {
|
||||||
if msg.GetIsL1MessageTx() {
|
if msg.GetIsL1MessageTx() {
|
||||||
return big.NewInt(0), nil
|
return big.NewInt(0), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned := asUnsignedTx(msg, baseFee, chainID)
|
unsigned := asUnsignedTx(msg, baseFee, config.ChainID)
|
||||||
// with v=1
|
// with v=1
|
||||||
tx, err := unsigned.WithSignature(signer, append(bytes.Repeat([]byte{0xff}, crypto.SignatureLength-1), 0x01))
|
tx, err := unsigned.WithSignature(signer, append(bytes.Repeat([]byte{0xff}, crypto.SignatureLength-1), 0x01))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
raw, err := rlpEncode(tx)
|
raw, err := tx.MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
l1BaseFee, overhead, scalar := readGPOStorageSlots(rcfg.L1GasPriceOracleAddress, state)
|
gpoState := readGPOStorageSlots(rcfg.L1GasPriceOracleAddress, state)
|
||||||
l1DataFee := calculateEncodedL1DataFee(raw, overhead, l1BaseFee, scalar)
|
|
||||||
|
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
|
return l1DataFee, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,35 +134,46 @@ func asUnsignedDynamicTx(msg Message, chainID *big.Int) *types.Transaction {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// rlpEncode RLP encodes the transaction into bytes
|
func readGPOStorageSlots(addr common.Address, state StateDB) gpoState {
|
||||||
func rlpEncode(tx *types.Transaction) ([]byte, error) {
|
var gpoState gpoState
|
||||||
raw := new(bytes.Buffer)
|
gpoState.l1BaseFee = state.GetState(addr, rcfg.L1BaseFeeSlot).Big()
|
||||||
if err := tx.EncodeRLP(raw); err != nil {
|
gpoState.overhead = state.GetState(addr, rcfg.OverheadSlot).Big()
|
||||||
return nil, err
|
gpoState.scalar = state.GetState(addr, rcfg.ScalarSlot).Big()
|
||||||
}
|
gpoState.l1BlobBaseFee = state.GetState(addr, rcfg.L1BlobBaseFeeSlot).Big()
|
||||||
|
gpoState.commitScalar = state.GetState(addr, rcfg.CommitScalarSlot).Big()
|
||||||
return raw.Bytes(), nil
|
gpoState.blobScalar = state.GetState(addr, rcfg.BlobScalarSlot).Big()
|
||||||
}
|
return gpoState
|
||||||
|
|
||||||
func readGPOStorageSlots(addr common.Address, state StateDB) (*big.Int, *big.Int, *big.Int) {
|
|
||||||
l1BaseFee := state.GetState(addr, rcfg.L1BaseFeeSlot)
|
|
||||||
overhead := state.GetState(addr, rcfg.OverheadSlot)
|
|
||||||
scalar := state.GetState(addr, rcfg.ScalarSlot)
|
|
||||||
return l1BaseFee.Big(), overhead.Big(), scalar.Big()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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, l1GasPrice *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)
|
||||||
l1DataFee := new(big.Int).Mul(l1GasUsed, l1GasPrice)
|
l1DataFee := new(big.Int).Mul(l1GasUsed, l1BaseFee)
|
||||||
return mulAndScale(l1DataFee, scalar, rcfg.Precision)
|
return mulAndScale(l1DataFee, scalar, rcfg.Precision)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CalculateL1GasUsed computes the L1 gas used based on the calldata and
|
// calculateEncodedL1DataFeeCurie computes the L1 fee for an RLP-encoded tx, post Curie
|
||||||
|
func calculateEncodedL1DataFeeCurie(data []byte, l1BaseFee *big.Int, l1BlobBaseFee *big.Int, commitScalar *big.Int, blobScalar *big.Int) *big.Int {
|
||||||
|
// calldata component of commit fees (calldata gas + execution)
|
||||||
|
calldataGas := new(big.Int).Mul(commitScalar, l1BaseFee)
|
||||||
|
|
||||||
|
// blob component of commit fees
|
||||||
|
blobGas := big.NewInt(int64(len(data)))
|
||||||
|
blobGas = new(big.Int).Mul(blobGas, l1BlobBaseFee)
|
||||||
|
blobGas = new(big.Int).Mul(blobGas, blobScalar)
|
||||||
|
|
||||||
|
// combined
|
||||||
|
l1DataFee := new(big.Int).Add(calldataGas, blobGas)
|
||||||
|
l1DataFee = new(big.Int).Quo(l1DataFee, rcfg.Precision)
|
||||||
|
|
||||||
|
return l1DataFee
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
// under standard network conditions.
|
// under standard network conditions.
|
||||||
func CalculateL1GasUsed(data []byte, overhead *big.Int) *big.Int {
|
func calculateL1GasUsed(data []byte, overhead *big.Int) *big.Int {
|
||||||
zeroes, ones := zeroesAndOnes(data)
|
zeroes, ones := zeroesAndOnes(data)
|
||||||
zeroesGas := zeroes * params.TxDataZeroGas
|
zeroesGas := zeroes * params.TxDataZeroGas
|
||||||
onesGas := (ones + txExtraDataBytes) * params.TxDataNonZeroGasEIP2028
|
onesGas := (ones + txExtraDataBytes) * params.TxDataNonZeroGasEIP2028
|
||||||
|
|
@ -173,18 +202,32 @@ 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) (*big.Int, error) {
|
func CalculateL1DataFee(tx *types.Transaction, state StateDB, config *params.ChainConfig, blockNumber *big.Int) (*big.Int, error) {
|
||||||
if tx.IsL1MessageTx() {
|
if tx.IsL1MessageTx() {
|
||||||
return big.NewInt(0), nil
|
return big.NewInt(0), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
raw, err := rlpEncode(tx)
|
raw, err := tx.MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
l1BaseFee, overhead, scalar := readGPOStorageSlots(rcfg.L1GasPriceOracleAddress, state)
|
gpoState := readGPOStorageSlots(rcfg.L1GasPriceOracleAddress, state)
|
||||||
l1DataFee := calculateEncodedL1DataFee(raw, overhead, l1BaseFee, scalar)
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure l1DataFee fits into uint64 for circuit compatibility
|
||||||
|
// (note: in practice this value should never be this big)
|
||||||
|
if !l1DataFee.IsUint64() {
|
||||||
|
l1DataFee.SetUint64(math.MaxUint64)
|
||||||
|
}
|
||||||
|
|
||||||
return l1DataFee, nil
|
return l1DataFee, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,27 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCalculateEncodedL1DataFee(t *testing.T) {
|
func TestL1DataFeeBeforeCurie(t *testing.T) {
|
||||||
l1BaseFee := new(big.Int).SetUint64(15000000)
|
l1BaseFee := new(big.Int).SetUint64(15000000)
|
||||||
|
|
||||||
data := []byte{0, 10, 1, 0}
|
|
||||||
overhead := new(big.Int).SetUint64(100)
|
overhead := new(big.Int).SetUint64(100)
|
||||||
scalar := new(big.Int).SetUint64(10)
|
scalar := new(big.Int).SetUint64(10)
|
||||||
|
|
||||||
expected := new(big.Int).SetUint64(184) // 184.2
|
data := []byte{0, 10, 1, 0}
|
||||||
|
|
||||||
|
expected := new(big.Int).SetUint64(30) // 30.6
|
||||||
actual := calculateEncodedL1DataFee(data, overhead, l1BaseFee, scalar)
|
actual := calculateEncodedL1DataFee(data, overhead, l1BaseFee, scalar)
|
||||||
assert.Equal(t, expected, actual)
|
assert.Equal(t, expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestL1DataFeeAfterCurie(t *testing.T) {
|
||||||
|
l1BaseFee := new(big.Int).SetUint64(1500000000)
|
||||||
|
l1BlobBaseFee := new(big.Int).SetUint64(150000000)
|
||||||
|
commitScalar := new(big.Int).SetUint64(10)
|
||||||
|
blobScalar := new(big.Int).SetUint64(10)
|
||||||
|
|
||||||
|
data := []byte{0, 10, 1, 0}
|
||||||
|
|
||||||
|
expected := new(big.Int).SetUint64(21)
|
||||||
|
actual := calculateEncodedL1DataFeeCurie(data, l1BaseFee, l1BlobBaseFee, commitScalar, blobScalar)
|
||||||
|
assert.Equal(t, expected, actual)
|
||||||
|
}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -220,7 +220,7 @@ func (env *TraceEnv) GetBlockTrace(block *types.Block) (*types.BlockTrace, error
|
||||||
msg, _ := core.TransactionToMessage(tx, env.signer, block.BaseFee())
|
msg, _ := core.TransactionToMessage(tx, 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)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, env.state, env.chainConfig, block.Number())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
failed = err
|
failed = err
|
||||||
break
|
break
|
||||||
|
|
@ -330,7 +330,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)
|
l1DataFee, err := fees.CalculateL1DataFee(tx, state, env.chainConfig, block.Number())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -515,6 +515,10 @@ func (env *TraceEnv) fillBlockTrace(block *types.Block) (*types.BlockTrace, erro
|
||||||
rcfg.L1BaseFeeSlot,
|
rcfg.L1BaseFeeSlot,
|
||||||
rcfg.OverheadSlot,
|
rcfg.OverheadSlot,
|
||||||
rcfg.ScalarSlot,
|
rcfg.ScalarSlot,
|
||||||
|
rcfg.L1BlobBaseFeeSlot,
|
||||||
|
rcfg.CommitScalarSlot,
|
||||||
|
rcfg.BlobScalarSlot,
|
||||||
|
rcfg.IsCurieSlot,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
|
||||||
snapshot := statedb.Snapshot()
|
snapshot := statedb.Snapshot()
|
||||||
gaspool := new(core.GasPool)
|
gaspool := new(core.GasPool)
|
||||||
gaspool.AddGas(block.GasLimit())
|
gaspool.AddGas(block.GasLimit())
|
||||||
l1DataFee, err := fees.CalculateL1DataFee(&ttx, statedb)
|
l1DataFee, err := fees.CalculateL1DataFee(&ttx, statedb, config, block.Number())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, common.Hash{}, err
|
return nil, nil, nil, common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue