mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
feat: check basefee in Curie (#770)
* add consensus/misc/eip1559/eip1559_scroll.go * update core/chain_makers.go * add `fees.GetL1BaseFee` * update eth/gasprice/feehistory.go * fix internal/ethapi/api.go & eth/filters/api.go * update graphql/graphql.go * update miner/worker.go * update txpool * fix api_backend * fix Curie * update core/state_transition.go * update internal/ethapi/transaction_args.go * fix cmd/evm/internal/t8ntool/transition.go * update core/state_processor_test.go * update core/txpool/blobpool/blobpool_test.go * fix internal/ethapi/api_test.go * update eth/gasprice/gasprice_test.go * update internal/ethapi/transaction_args_test.go * update accounts/abi/bind/backends/simulated.go * update accounts/abi/bind/base.go
This commit is contained in:
parent
34bf14978e
commit
e5171495e1
31 changed files with 301 additions and 81 deletions
|
|
@ -646,7 +646,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
|
|||
if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) {
|
||||
return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
||||
}
|
||||
if !b.blockchain.Config().IsLondon(header.Number) {
|
||||
if !b.blockchain.Config().IsCurie(header.Number) {
|
||||
// If there's no basefee, then it must be a non-1559 execution
|
||||
if call.GasPrice == nil {
|
||||
call.GasPrice = new(big.Int)
|
||||
|
|
@ -668,7 +668,11 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
|
|||
// Backfill the legacy gasPrice for EVM execution, unless we're all zeroes
|
||||
call.GasPrice = new(big.Int)
|
||||
if call.GasFeeCap.BitLen() > 0 || call.GasTipCap.BitLen() > 0 {
|
||||
call.GasPrice = math.BigMin(new(big.Int).Add(call.GasTipCap, header.BaseFee), call.GasFeeCap)
|
||||
if header.BaseFee != nil {
|
||||
call.GasPrice = math.BigMin(new(big.Int).Add(call.GasTipCap, header.BaseFee), call.GasFeeCap)
|
||||
} else {
|
||||
call.GasPrice = math.BigMin(call.GasTipCap, call.GasFeeCap)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -980,3 +984,7 @@ func nullSubscription() event.Subscription {
|
|||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (fb *filterBackend) StateAt(root common.Hash) (*state.StateDB, error) {
|
||||
return fb.bc.StateAt(root)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -277,10 +277,14 @@ func (c *BoundContract) createDynamicTx(opts *TransactOpts, contract *common.Add
|
|||
// Estimate FeeCap
|
||||
gasFeeCap := opts.GasFeeCap
|
||||
if gasFeeCap == nil {
|
||||
gasFeeCap = new(big.Int).Add(
|
||||
gasTipCap,
|
||||
new(big.Int).Mul(head.BaseFee, big.NewInt(basefeeWiggleMultiplier)),
|
||||
)
|
||||
if head.BaseFee != nil {
|
||||
gasFeeCap = new(big.Int).Add(
|
||||
gasTipCap,
|
||||
new(big.Int).Mul(head.BaseFee, big.NewInt(basefeeWiggleMultiplier)),
|
||||
)
|
||||
} else {
|
||||
gasFeeCap = new(big.Int).Set(gasTipCap)
|
||||
}
|
||||
}
|
||||
if gasFeeCap.Cmp(gasTipCap) < 0 {
|
||||
return nil, fmt.Errorf("maxFeePerGas (%v) < maxPriorityFeePerGas (%v)", gasFeeCap, gasTipCap)
|
||||
|
|
@ -313,7 +317,7 @@ func (c *BoundContract) createDynamicTx(opts *TransactOpts, contract *common.Add
|
|||
|
||||
func (c *BoundContract) createLegacyTx(opts *TransactOpts, contract *common.Address, input []byte) (*types.Transaction, error) {
|
||||
if opts.GasFeeCap != nil || opts.GasTipCap != nil {
|
||||
return nil, errors.New("maxFeePerGas or maxPriorityFeePerGas specified but london is not active yet")
|
||||
return nil, errors.New("maxFeePerGas or maxPriorityFeePerGas specified but curie is not active yet")
|
||||
}
|
||||
// Normalize value
|
||||
value := opts.Value
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ type input struct {
|
|||
Env *stEnv `json:"env,omitempty"`
|
||||
Txs []*txWithKey `json:"txs,omitempty"`
|
||||
TxRlp string `json:"txsRlp,omitempty"`
|
||||
|
||||
ParentL1BaseFee *big.Int `json:"parentL1BaseFee,omitempty"`
|
||||
}
|
||||
|
||||
func Transition(ctx *cli.Context) error {
|
||||
|
|
@ -195,7 +197,7 @@ func Transition(ctx *cli.Context) error {
|
|||
if txs, err = loadTransactions(txStr, inputData, prestate.Env, chainConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := applyLondonChecks(&prestate.Env, chainConfig); err != nil {
|
||||
if err := applyCurieChecks(&prestate.Env, chainConfig, inputData.ParentL1BaseFee); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := applyShanghaiChecks(&prestate.Env, chainConfig); err != nil {
|
||||
|
|
@ -338,8 +340,8 @@ func loadTransactions(txStr string, inputData *input, env stEnv, chainConfig *pa
|
|||
return signUnsignedTransactions(txsWithKeys, signer)
|
||||
}
|
||||
|
||||
func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error {
|
||||
if !chainConfig.IsLondon(big.NewInt(int64(env.Number))) {
|
||||
func applyCurieChecks(env *stEnv, chainConfig *params.ChainConfig, parentL1BaseFee *big.Int) error {
|
||||
if !chainConfig.IsCurie(big.NewInt(int64(env.Number))) {
|
||||
return nil
|
||||
}
|
||||
// Sanity check, to not `panic` in state_transition
|
||||
|
|
@ -350,12 +352,15 @@ func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error {
|
|||
if env.ParentBaseFee == nil || env.Number == 0 {
|
||||
return NewError(ErrorConfig, errors.New("EIP-1559 config but missing 'currentBaseFee' in env section"))
|
||||
}
|
||||
if parentL1BaseFee == nil {
|
||||
return errors.New("EIP-1559 config but missing 'parentL1BaseFee' for calculating basefee")
|
||||
}
|
||||
env.BaseFee = eip1559.CalcBaseFee(chainConfig, &types.Header{
|
||||
Number: new(big.Int).SetUint64(env.Number - 1),
|
||||
BaseFee: env.ParentBaseFee,
|
||||
GasUsed: env.ParentGasUsed,
|
||||
GasLimit: env.ParentGasLimit,
|
||||
})
|
||||
}, parentL1BaseFee)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -336,7 +336,7 @@ func (c *Clique) verifyCascadingFields(chain consensus.ChainHeaderReader, header
|
|||
if header.GasUsed > header.GasLimit {
|
||||
return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
|
||||
}
|
||||
if !chain.Config().IsLondon(header.Number) {
|
||||
if !chain.Config().IsCurie(header.Number) {
|
||||
// Verify BaseFee not present before EIP-1559 fork.
|
||||
if header.BaseFee != nil {
|
||||
return fmt.Errorf("invalid baseFee before fork: have %d, want <nil>", header.BaseFee)
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, pa
|
|||
return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
|
||||
}
|
||||
// Verify the block's gas usage and (if applicable) verify the base fee.
|
||||
if !chain.Config().IsLondon(header.Number) {
|
||||
if !chain.Config().IsCurie(header.Number) {
|
||||
// Verify BaseFee not present before EIP-1559 fork.
|
||||
if header.BaseFee != nil {
|
||||
return fmt.Errorf("invalid baseFee before fork: have %d, expected 'nil'", header.BaseFee)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package eip1559
|
||||
|
||||
/*
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
|
@ -93,3 +95,5 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
|
|||
return math.BigMax(baseFee, common.Big0)
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
|
|
|||
73
consensus/misc/eip1559/eip1559_scroll.go
Normal file
73
consensus/misc/eip1559/eip1559_scroll.go
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright 2021 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package eip1559
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/consensus/misc"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
// Protocol-enforced maximum L2 base fee.
|
||||
// We would only go above this if L1 base fee hits 700 Gwei.
|
||||
const MaximumL2BaseFee = 10000000000
|
||||
|
||||
// VerifyEIP1559Header verifies some header attributes which were changed in EIP-1559,
|
||||
// - gas limit check
|
||||
// - basefee check
|
||||
func VerifyEIP1559Header(config *params.ChainConfig, parent, header *types.Header) error {
|
||||
// Verify that the gas limit remains within allowed bounds
|
||||
if err := misc.VerifyGaslimit(parent.GasLimit, header.GasLimit); err != nil {
|
||||
return err
|
||||
}
|
||||
// Verify the header is not malformed
|
||||
if header.BaseFee == nil {
|
||||
return fmt.Errorf("header is missing baseFee")
|
||||
}
|
||||
// note: we do not verify L2 base fee, the sequencer has the
|
||||
// right to set any base fee below the maximum. L2 base fee
|
||||
// is not subject to L2 consensus or zk verification.
|
||||
if header.BaseFee.Cmp(big.NewInt(MaximumL2BaseFee)) > 0 {
|
||||
return fmt.Errorf("invalid baseFee: have %s, maximum %d", header.BaseFee, MaximumL2BaseFee)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CalcBaseFee calculates the basefee of the header.
|
||||
func CalcBaseFee(config *params.ChainConfig, parent *types.Header, parentL1BaseFee *big.Int) *big.Int {
|
||||
l2SequencerFee := big.NewInt(10000000) // 0.01 Gwei
|
||||
provingFee := big.NewInt(140000000) // 0.14 Gwei
|
||||
|
||||
// L1_base_fee * 0.014
|
||||
verificationFee := parentL1BaseFee
|
||||
verificationFee = new(big.Int).Mul(verificationFee, big.NewInt(14))
|
||||
verificationFee = new(big.Int).Div(verificationFee, big.NewInt(1000))
|
||||
|
||||
baseFee := big.NewInt(0)
|
||||
baseFee.Add(baseFee, l2SequencerFee)
|
||||
baseFee.Add(baseFee, provingFee)
|
||||
baseFee.Add(baseFee, verificationFee)
|
||||
|
||||
if baseFee.Cmp(big.NewInt(MaximumL2BaseFee)) > 0 {
|
||||
baseFee = big.NewInt(MaximumL2BaseFee)
|
||||
}
|
||||
|
||||
return baseFee
|
||||
}
|
||||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package eip1559
|
||||
|
||||
/*
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
|
@ -129,3 +131,5 @@ func TestCalcBaseFee(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rollup/fees"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
)
|
||||
|
||||
|
|
@ -179,7 +180,11 @@ func (b *BlockGen) Timestamp() uint64 {
|
|||
|
||||
// BaseFee returns the EIP-1559 base fee of the block being generated.
|
||||
func (b *BlockGen) BaseFee() *big.Int {
|
||||
return new(big.Int).Set(b.header.BaseFee)
|
||||
if b.header.BaseFee != nil {
|
||||
return new(big.Int).Set(b.header.BaseFee)
|
||||
} else {
|
||||
return big.NewInt(0)
|
||||
}
|
||||
}
|
||||
|
||||
// AddUncheckedReceipt forcefully adds a receipts to the block without a
|
||||
|
|
@ -217,12 +222,9 @@ func (b *BlockGen) AddUncle(h *types.Header) {
|
|||
|
||||
// The gas limit and price should be derived from the parent
|
||||
h.GasLimit = parent.GasLimit
|
||||
if b.config.IsLondon(h.Number) {
|
||||
h.BaseFee = eip1559.CalcBaseFee(b.config, parent)
|
||||
if !b.config.IsLondon(parent.Number) {
|
||||
parentGasLimit := parent.GasLimit * b.config.ElasticityMultiplier()
|
||||
h.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
|
||||
}
|
||||
if b.config.IsCurie(h.Number) {
|
||||
parentL1BaseFee := fees.GetL1BaseFee(b.statedb)
|
||||
h.BaseFee = eip1559.CalcBaseFee(b.config, parent, parentL1BaseFee)
|
||||
}
|
||||
b.uncles = append(b.uncles, h)
|
||||
}
|
||||
|
|
@ -409,12 +411,9 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S
|
|||
Number: new(big.Int).Add(parent.Number(), common.Big1),
|
||||
Time: time,
|
||||
}
|
||||
if chain.Config().IsLondon(header.Number) {
|
||||
header.BaseFee = eip1559.CalcBaseFee(chain.Config(), parent.Header())
|
||||
if !chain.Config().IsLondon(parent.Number()) {
|
||||
parentGasLimit := parent.GasLimit() * chain.Config().ElasticityMultiplier()
|
||||
header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
|
||||
}
|
||||
if chain.Config().IsCurie(header.Number) {
|
||||
parentL1BaseFee := fees.GetL1BaseFee(state)
|
||||
header.BaseFee = eip1559.CalcBaseFee(chain.Config(), parent.Header(), parentL1BaseFee)
|
||||
}
|
||||
if chain.Config().IsCancun(header.Number, header.Time) {
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
|
@ -450,14 +451,13 @@ func (g *Genesis) ToBlock() *types.Block {
|
|||
if g.Difficulty == nil && g.Mixhash == (common.Hash{}) {
|
||||
head.Difficulty = params.GenesisDifficulty
|
||||
}
|
||||
// TODO: fix basefee
|
||||
// if g.Config != nil && g.Config.IsLondon(common.Big0) {
|
||||
// if g.BaseFee != nil {
|
||||
// head.BaseFee = g.BaseFee
|
||||
// } else {
|
||||
// head.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee)
|
||||
// }
|
||||
// }
|
||||
if g.Config != nil && g.Config.IsCurie(common.Big0) {
|
||||
if g.BaseFee != nil {
|
||||
head.BaseFee = g.BaseFee
|
||||
} else {
|
||||
head.BaseFee = eip1559.CalcBaseFee(g.Config, nil, big.NewInt(0))
|
||||
}
|
||||
}
|
||||
var withdrawals []*types.Withdrawal
|
||||
// if conf := g.Config; conf != nil {
|
||||
// num := big.NewInt(int64(g.Number))
|
||||
|
|
|
|||
|
|
@ -376,8 +376,9 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
|
|||
Time: parent.Time() + 10,
|
||||
UncleHash: types.EmptyUncleHash,
|
||||
}
|
||||
if config.IsLondon(header.Number) {
|
||||
header.BaseFee = eip1559.CalcBaseFee(config, parent.Header())
|
||||
if config.IsCurie(header.Number) {
|
||||
parentL1BaseFee := big.NewInt(1000000000) // 1 gwei
|
||||
header.BaseFee = eip1559.CalcBaseFee(config, parent.Header(), parentL1BaseFee)
|
||||
}
|
||||
if config.IsShanghai(header.Number, header.Time) {
|
||||
header.WithdrawalsHash = &types.EmptyWithdrawalsHash
|
||||
|
|
|
|||
|
|
@ -335,6 +335,7 @@ func (st *StateTransition) preCheck() error {
|
|||
}
|
||||
|
||||
// Make sure that transaction gasFeeCap is greater than the baseFee (post london)
|
||||
// Note: Logically, this should be `IsCurie`, but we keep `IsLondon` to ensure backward compatibility.
|
||||
if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
|
||||
// Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call)
|
||||
if !st.evm.Config.NoBaseFee || msg.GasFeeCap.BitLen() > 0 || msg.GasTipCap.BitLen() > 0 {
|
||||
|
|
@ -352,7 +353,11 @@ func (st *StateTransition) preCheck() error {
|
|||
}
|
||||
// This will panic if baseFee is nil, but basefee presence is verified
|
||||
// as part of header validation.
|
||||
if msg.GasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 {
|
||||
if st.evm.Context.BaseFee != nil && msg.GasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 {
|
||||
return fmt.Errorf("%w: address %v, maxFeePerGas: %s baseFee: %s", ErrFeeCapTooLow,
|
||||
msg.From.Hex(), msg.GasFeeCap, st.evm.Context.BaseFee)
|
||||
}
|
||||
if st.evm.Context.BaseFee == nil && msg.GasFeeCap.Cmp(big.NewInt(0)) < 0 {
|
||||
return fmt.Errorf("%w: address %v, maxFeePerGas: %s baseFee: %s", ErrFeeCapTooLow,
|
||||
msg.From.Hex(), msg.GasFeeCap, st.evm.Context.BaseFee)
|
||||
}
|
||||
|
|
@ -479,7 +484,9 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||
st.refundGas(params.RefundQuotientEIP3529)
|
||||
}
|
||||
effectiveTip := msg.GasPrice
|
||||
if rules.IsLondon {
|
||||
|
||||
// only burn the base fee if the fee vault is not enabled
|
||||
if rules.IsCurie && !st.evm.ChainConfig().Scroll.FeeVaultEnabled() {
|
||||
effectiveTip = cmath.BigMin(msg.GasTipCap, new(big.Int).Sub(msg.GasFeeCap, st.evm.Context.BaseFee))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/rollup/fees"
|
||||
"github.com/holiman/billy"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
|
@ -399,7 +400,7 @@ func (p *BlobPool) Init(gasTip *big.Int, head *types.Header, reserve txpool.Addr
|
|||
p.recheck(addr, nil)
|
||||
}
|
||||
var (
|
||||
basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), p.head))
|
||||
basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), p.head, fees.GetL1BaseFee(p.state)))
|
||||
blobfee = uint256.MustFromBig(big.NewInt(params.BlobTxMinBlobGasprice))
|
||||
)
|
||||
if p.head.ExcessBlobGas != nil {
|
||||
|
|
@ -782,7 +783,7 @@ func (p *BlobPool) Reset(oldHead, newHead *types.Header) {
|
|||
}
|
||||
// Reset the price heap for the new set of basefee/blobfee pairs
|
||||
var (
|
||||
basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), newHead))
|
||||
basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), newHead, fees.GetL1BaseFee(p.state)))
|
||||
blobfee = uint256.MustFromBig(big.NewInt(params.BlobTxMinBlobGasprice))
|
||||
)
|
||||
if newHead.ExcessBlobGas != nil {
|
||||
|
|
|
|||
|
|
@ -109,12 +109,13 @@ func (bc *testBlockChain) CurrentBlock() *types.Header {
|
|||
mid := new(big.Int).Add(lo, hi)
|
||||
mid.Div(mid, big.NewInt(2))
|
||||
|
||||
parentL1BaseFee := big.NewInt(1000000000) // 1 gwei
|
||||
if eip1559.CalcBaseFee(bc.config, &types.Header{
|
||||
Number: blockNumber,
|
||||
GasLimit: gasLimit,
|
||||
GasUsed: 0,
|
||||
BaseFee: mid,
|
||||
}).Cmp(bc.basefee.ToBig()) > 0 {
|
||||
}, parentL1BaseFee).Cmp(bc.basefee.ToBig()) > 0 {
|
||||
hi = mid
|
||||
} else {
|
||||
lo = mid
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rollup/fees"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -1287,8 +1288,9 @@ func (pool *LegacyPool) runReorg(done chan struct{}, reset *txpoolResetRequest,
|
|||
if reset != nil {
|
||||
pool.demoteUnexecutables()
|
||||
if reset.newHead != nil {
|
||||
if pool.chainconfig.IsLondon(new(big.Int).Add(reset.newHead.Number, big.NewInt(1))) {
|
||||
pendingBaseFee := eip1559.CalcBaseFee(pool.chainconfig, reset.newHead)
|
||||
if pool.chainconfig.IsCurie(new(big.Int).Add(reset.newHead.Number, big.NewInt(1))) {
|
||||
l1BaseFee := fees.GetL1BaseFee(pool.currentState)
|
||||
pendingBaseFee := eip1559.CalcBaseFee(pool.chainconfig, reset.newHead, l1BaseFee)
|
||||
pool.priced.SetBaseFee(pendingBaseFee)
|
||||
} else {
|
||||
pool.priced.Reheap()
|
||||
|
|
|
|||
|
|
@ -58,10 +58,10 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
|
|||
return fmt.Errorf("%w: transaction size %v, limit %v", ErrOversizedData, tx.Size(), opts.MaxSize)
|
||||
}
|
||||
// Ensure only transactions that have been enabled are accepted
|
||||
if !opts.Config.IsBerlin(head.Number) && tx.Type() != types.LegacyTxType {
|
||||
if !opts.Config.IsCurie(head.Number) && tx.Type() != types.LegacyTxType {
|
||||
return fmt.Errorf("%w: type %d rejected, pool not yet in Berlin", core.ErrTxTypeNotSupported, tx.Type())
|
||||
}
|
||||
if !opts.Config.IsLondon(head.Number) && tx.Type() == types.DynamicFeeTxType {
|
||||
if !opts.Config.IsCurie(head.Number) && tx.Type() == types.DynamicFeeTxType {
|
||||
return fmt.Errorf("%w: type %d rejected, pool not yet in London", core.ErrTxTypeNotSupported, tx.Type())
|
||||
}
|
||||
if !opts.Config.IsCancun(head.Number, head.Time) && tx.Type() == types.BlobTxType {
|
||||
|
|
|
|||
|
|
@ -432,3 +432,7 @@ func (b *EthAPIBackend) StateAtBlock(ctx context.Context, block *types.Block, re
|
|||
func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
|
||||
return b.eth.stateAtTransaction(ctx, block, txIndex, reexec)
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) StateAt(root common.Hash) (*state.StateDB, error) {
|
||||
return b.eth.BlockChain().StateAt(root)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/rollup/fees"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
||||
|
|
@ -164,9 +166,17 @@ func (api *FilterAPI) NewPendingTransactions(ctx context.Context, fullTx *bool)
|
|||
// To keep the original behaviour, send a single tx hash in one notification.
|
||||
// TODO(rjl493456442) Send a batch of tx hashes in one notification
|
||||
latest := api.sys.backend.CurrentHeader()
|
||||
|
||||
state, err := api.sys.backend.StateAt(latest.Root)
|
||||
if err != nil || state == nil {
|
||||
log.Error("State not found", "number", latest.Number, "hash", latest.Hash().Hex(), "state", state, "err", err)
|
||||
continue
|
||||
}
|
||||
l1BaseFee := fees.GetL1BaseFee(state)
|
||||
|
||||
for _, tx := range txs {
|
||||
if fullTx != nil && *fullTx {
|
||||
rpcTx := ethapi.NewRPCPendingTransaction(tx, latest, chainConfig)
|
||||
rpcTx := ethapi.NewRPCPendingTransaction(tx, latest, chainConfig, l1BaseFee)
|
||||
notifier.Notify(rpcSub.ID, rpcTx)
|
||||
} else {
|
||||
notifier.Notify(rpcSub.ID, tx.Hash())
|
||||
|
|
@ -438,9 +448,16 @@ func (api *FilterAPI) GetFilterChanges(id rpc.ID) (interface{}, error) {
|
|||
return returnHashes(hashes), nil
|
||||
case PendingTransactionsSubscription:
|
||||
if f.fullTx {
|
||||
state, err := api.sys.backend.StateAt(latest.Root)
|
||||
if err != nil || state == nil {
|
||||
log.Error("State not found", "number", latest.Number, "hash", latest.Hash().Hex(), "state", state, "err", err)
|
||||
return nil, errors.New("state not found")
|
||||
}
|
||||
l1BaseFee := fees.GetL1BaseFee(state)
|
||||
|
||||
txs := make([]*ethapi.RPCTransaction, 0, len(f.txs))
|
||||
for _, tx := range f.txs {
|
||||
txs = append(txs, ethapi.NewRPCPendingTransaction(tx, latest, chainConfig))
|
||||
txs = append(txs, ethapi.NewRPCPendingTransaction(tx, latest, chainConfig, l1BaseFee))
|
||||
}
|
||||
f.txs = nil
|
||||
return txs, nil
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/bloombits"
|
||||
"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/ethdb"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
|
|
@ -65,6 +66,8 @@ type Backend interface {
|
|||
GetLogs(ctx context.Context, blockHash common.Hash, number uint64) ([][]*types.Log, error)
|
||||
PendingBlockAndReceipts() (*types.Block, types.Receipts)
|
||||
|
||||
StateAt(root common.Hash) (*state.StateDB, error)
|
||||
|
||||
CurrentHeader() *types.Header
|
||||
ChainConfig() *params.ChainConfig
|
||||
SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/rollup/fees"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
|
@ -82,8 +83,14 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
|
|||
if bf.results.baseFee = bf.header.BaseFee; bf.results.baseFee == nil {
|
||||
bf.results.baseFee = new(big.Int)
|
||||
}
|
||||
if chainconfig.IsLondon(big.NewInt(int64(bf.blockNumber + 1))) {
|
||||
bf.results.nextBaseFee = eip1559.CalcBaseFee(chainconfig, bf.header)
|
||||
if chainconfig.IsCurie(big.NewInt(int64(bf.blockNumber + 1))) {
|
||||
state, err := oracle.backend.StateAt(bf.header.Root)
|
||||
if err != nil || state == nil {
|
||||
log.Error("State not found", "number", bf.header.Number, "hash", bf.header.Hash().Hex(), "state", state, "err", err)
|
||||
return
|
||||
}
|
||||
l1BaseFee := fees.GetL1BaseFee(state)
|
||||
bf.results.nextBaseFee = eip1559.CalcBaseFee(chainconfig, bf.header, l1BaseFee)
|
||||
} else {
|
||||
bf.results.nextBaseFee = new(big.Int)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/lru"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
|
|
@ -57,6 +58,7 @@ type OracleBackend interface {
|
|||
PendingBlockAndReceipts() (*types.Block, types.Receipts)
|
||||
ChainConfig() *params.ChainConfig
|
||||
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
|
||||
StateAt(root common.Hash) (*state.StateDB, error)
|
||||
}
|
||||
|
||||
// Oracle recommends gas prices based on the content of recent
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"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/vm"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
|
|
@ -117,6 +118,10 @@ func (b *testBackend) teardown() {
|
|||
b.chain.Stop()
|
||||
}
|
||||
|
||||
func (b *testBackend) StateAt(root common.Hash) (*state.StateDB, error) {
|
||||
return b.chain.StateAt(root)
|
||||
}
|
||||
|
||||
// newTestBackend creates a test backend. OBS: don't forget to invoke tearDown
|
||||
// after use, otherwise the blockchain instance will mem-leak via goroutines.
|
||||
func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBackend {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,9 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/eth/filters"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/rollup/fees"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
||||
|
|
@ -769,11 +771,19 @@ func (b *Block) NextBaseFeePerGas(ctx context.Context) (*hexutil.Big, error) {
|
|||
chaincfg := b.r.backend.ChainConfig()
|
||||
if header.BaseFee == nil {
|
||||
// Make sure next block doesn't enable EIP-1559
|
||||
if !chaincfg.IsLondon(new(big.Int).Add(header.Number, common.Big1)) {
|
||||
if !chaincfg.IsCurie(new(big.Int).Add(header.Number, common.Big1)) {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
nextBaseFee := eip1559.CalcBaseFee(chaincfg, header)
|
||||
|
||||
state, err := b.r.backend.StateAt(header.Root)
|
||||
if err != nil {
|
||||
log.Error("Failed to get state", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
l1BaseFee := fees.GetL1BaseFee(state)
|
||||
|
||||
nextBaseFee := eip1559.CalcBaseFee(chaincfg, header, l1BaseFee)
|
||||
return (*hexutil.Big)(nextBaseFee), nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -169,11 +169,20 @@ func (s *TxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction {
|
|||
}
|
||||
pending, queue := s.b.TxPoolContent()
|
||||
curHeader := s.b.CurrentHeader()
|
||||
|
||||
// get latest L1 base fee
|
||||
state, err := s.b.StateAt(curHeader.Root)
|
||||
if err != nil || state == nil {
|
||||
log.Error("State not found", "number", curHeader.Number, "hash", curHeader.Hash().Hex(), "state", state, "err", err)
|
||||
return nil
|
||||
}
|
||||
l1BaseFee := fees.GetL1BaseFee(state)
|
||||
|
||||
// Flatten the pending transactions
|
||||
for account, txs := range pending {
|
||||
dump := make(map[string]*RPCTransaction)
|
||||
for _, tx := range txs {
|
||||
dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, s.b.ChainConfig())
|
||||
dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, s.b.ChainConfig(), l1BaseFee)
|
||||
}
|
||||
content["pending"][account.Hex()] = dump
|
||||
}
|
||||
|
|
@ -181,7 +190,7 @@ func (s *TxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction {
|
|||
for account, txs := range queue {
|
||||
dump := make(map[string]*RPCTransaction)
|
||||
for _, tx := range txs {
|
||||
dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, s.b.ChainConfig())
|
||||
dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, s.b.ChainConfig(), l1BaseFee)
|
||||
}
|
||||
content["queued"][account.Hex()] = dump
|
||||
}
|
||||
|
|
@ -194,17 +203,25 @@ func (s *TxPoolAPI) ContentFrom(addr common.Address) map[string]map[string]*RPCT
|
|||
pending, queue := s.b.TxPoolContentFrom(addr)
|
||||
curHeader := s.b.CurrentHeader()
|
||||
|
||||
// get latest L1 base fee
|
||||
state, err := s.b.StateAt(curHeader.Root)
|
||||
if err != nil || state == nil {
|
||||
log.Error("State not found", "number", curHeader.Number, "hash", curHeader.Hash().Hex(), "state", state, "err", err)
|
||||
return nil
|
||||
}
|
||||
l1BaseFee := fees.GetL1BaseFee(state)
|
||||
|
||||
// Build the pending transactions
|
||||
dump := make(map[string]*RPCTransaction, len(pending))
|
||||
for _, tx := range pending {
|
||||
dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, s.b.ChainConfig())
|
||||
dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, s.b.ChainConfig(), l1BaseFee)
|
||||
}
|
||||
content["pending"] = dump
|
||||
|
||||
// Build the queued transactions
|
||||
dump = make(map[string]*RPCTransaction, len(queue))
|
||||
for _, tx := range queue {
|
||||
dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, s.b.ChainConfig())
|
||||
dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, s.b.ChainConfig(), l1BaseFee)
|
||||
}
|
||||
content["queued"] = dump
|
||||
|
||||
|
|
@ -1599,14 +1616,14 @@ func effectiveGasPrice(tx *types.Transaction, baseFee *big.Int) *big.Int {
|
|||
}
|
||||
|
||||
// NewRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation
|
||||
func NewRPCPendingTransaction(tx *types.Transaction, current *types.Header, config *params.ChainConfig) *RPCTransaction {
|
||||
func NewRPCPendingTransaction(tx *types.Transaction, current *types.Header, config *params.ChainConfig, l1BaseFee *big.Int) *RPCTransaction {
|
||||
var (
|
||||
baseFee *big.Int
|
||||
blockNumber = uint64(0)
|
||||
blockTime = uint64(0)
|
||||
)
|
||||
if current != nil {
|
||||
baseFee = eip1559.CalcBaseFee(config, current)
|
||||
baseFee = eip1559.CalcBaseFee(config, current, l1BaseFee)
|
||||
blockNumber = current.Number.Uint64()
|
||||
blockTime = current.Time
|
||||
}
|
||||
|
|
@ -1827,7 +1844,17 @@ func (s *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common.H
|
|||
}
|
||||
// No finalized transaction, try to retrieve it from the pool
|
||||
if tx := s.b.GetPoolTransaction(hash); tx != nil {
|
||||
return NewRPCPendingTransaction(tx, s.b.CurrentHeader(), s.b.ChainConfig()), nil
|
||||
curHeader := s.b.CurrentHeader()
|
||||
|
||||
// get latest L1 base fee
|
||||
state, err := s.b.StateAt(curHeader.Root)
|
||||
if err != nil || state == nil {
|
||||
log.Error("State not found", "number", curHeader.Number, "hash", curHeader.Hash().Hex(), "state", state, "err", err)
|
||||
return nil, fmt.Errorf("cannot get L1 base fee, state not found")
|
||||
}
|
||||
l1BaseFee := fees.GetL1BaseFee(state)
|
||||
|
||||
return NewRPCPendingTransaction(tx, s.b.CurrentHeader(), s.b.ChainConfig(), l1BaseFee), nil
|
||||
}
|
||||
|
||||
// Transaction unknown, return as such
|
||||
|
|
@ -2101,10 +2128,19 @@ func (s *TransactionAPI) PendingTransactions() ([]*RPCTransaction, error) {
|
|||
}
|
||||
curHeader := s.b.CurrentHeader()
|
||||
transactions := make([]*RPCTransaction, 0, len(pending))
|
||||
|
||||
// get latest L1 base fee
|
||||
state, err := s.b.StateAt(curHeader.Root)
|
||||
if err != nil || state == nil {
|
||||
log.Error("State not found", "number", curHeader.Number, "hash", curHeader.Hash().Hex(), "state", state, "err", err)
|
||||
return nil, fmt.Errorf("cannot get L1 base fee, state not found")
|
||||
}
|
||||
l1BaseFee := fees.GetL1BaseFee(state)
|
||||
|
||||
for _, tx := range pending {
|
||||
from, _ := types.Sender(s.signer, tx)
|
||||
if _, exists := accounts[from]; exists {
|
||||
transactions = append(transactions, NewRPCPendingTransaction(tx, curHeader, s.b.ChainConfig()))
|
||||
transactions = append(transactions, NewRPCPendingTransaction(tx, curHeader, s.b.ChainConfig(), l1BaseFee))
|
||||
}
|
||||
}
|
||||
return transactions, nil
|
||||
|
|
|
|||
|
|
@ -604,6 +604,9 @@ func (b testBackend) BloomStatus() (uint64, uint64) { panic("implement me") }
|
|||
func (b testBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) {
|
||||
panic("implement me")
|
||||
}
|
||||
func (b testBackend) StateAt(root common.Hash) (*state.StateDB, error) {
|
||||
return b.chain.StateAt(root)
|
||||
}
|
||||
|
||||
func TestEstimateGas(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ type Backend interface {
|
|||
BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error)
|
||||
StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error)
|
||||
StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error)
|
||||
StateAt(root common.Hash) (*state.StateDB, error)
|
||||
PendingBlockAndReceipts() (*types.Block, types.Receipts)
|
||||
GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error)
|
||||
GetTd(ctx context.Context, hash common.Hash) *big.Int
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ func (args *TransactionArgs) setFeeDefaults(ctx context.Context, b Backend) erro
|
|||
return errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
||||
}
|
||||
// If the tx has completely specified a fee mechanism, no default is needed. This allows users
|
||||
// who are not yet synced past London to get defaults for other tx values. See
|
||||
// who are not yet synced past Curie to get defaults for other tx values. See
|
||||
// https://github.com/ethereum/go-ethereum/pull/23274 for more information.
|
||||
eip1559ParamsSet := args.MaxFeePerGas != nil && args.MaxPriorityFeePerGas != nil
|
||||
if (args.GasPrice != nil && !eip1559ParamsSet) || (args.GasPrice == nil && eip1559ParamsSet) {
|
||||
|
|
@ -148,18 +148,18 @@ func (args *TransactionArgs) setFeeDefaults(ctx context.Context, b Backend) erro
|
|||
}
|
||||
return nil
|
||||
}
|
||||
// Now attempt to fill in default value depending on whether London is active or not.
|
||||
// Now attempt to fill in default value depending on whether Curie is active or not.
|
||||
head := b.CurrentHeader()
|
||||
if b.ChainConfig().IsLondon(head.Number) {
|
||||
// London is active, set maxPriorityFeePerGas and maxFeePerGas.
|
||||
if err := args.setLondonFeeDefaults(ctx, head, b); err != nil {
|
||||
if b.ChainConfig().IsCurie(head.Number) {
|
||||
// Curie is active, set maxPriorityFeePerGas and maxFeePerGas.
|
||||
if err := args.setCurieFeeDefaults(ctx, head, b); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil {
|
||||
return errors.New("maxFeePerGas and maxPriorityFeePerGas are not valid before London is active")
|
||||
return errors.New("maxFeePerGas and maxPriorityFeePerGas are not valid before Curie is active")
|
||||
}
|
||||
// London not active, set gas price.
|
||||
// Curie not active, set gas price.
|
||||
price, err := b.SuggestGasTipCap(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -169,8 +169,8 @@ func (args *TransactionArgs) setFeeDefaults(ctx context.Context, b Backend) erro
|
|||
return nil
|
||||
}
|
||||
|
||||
// setLondonFeeDefaults fills in reasonable default fee values for unspecified fields.
|
||||
func (args *TransactionArgs) setLondonFeeDefaults(ctx context.Context, head *types.Header, b Backend) error {
|
||||
// setCurieFeeDefaults fills in reasonable default fee values for unspecified fields.
|
||||
func (args *TransactionArgs) setCurieFeeDefaults(ctx context.Context, head *types.Header, b Backend) error {
|
||||
// Set maxPriorityFeePerGas if it is missing.
|
||||
if args.MaxPriorityFeePerGas == nil {
|
||||
tip, err := b.SuggestGasTipCap(ctx)
|
||||
|
|
@ -181,13 +181,19 @@ func (args *TransactionArgs) setLondonFeeDefaults(ctx context.Context, head *typ
|
|||
}
|
||||
// Set maxFeePerGas if it is missing.
|
||||
if args.MaxFeePerGas == nil {
|
||||
// Set the max fee to be 2 times larger than the previous block's base fee.
|
||||
// The additional slack allows the tx to not become invalidated if the base
|
||||
// fee is rising.
|
||||
val := new(big.Int).Add(
|
||||
args.MaxPriorityFeePerGas.ToInt(),
|
||||
new(big.Int).Mul(head.BaseFee, big.NewInt(2)),
|
||||
)
|
||||
var val *big.Int
|
||||
if head.BaseFee != nil {
|
||||
// Set the max fee to be 2 times larger than the previous block's base fee.
|
||||
// The additional slack allows the tx to not become invalidated if the base
|
||||
// fee is rising.
|
||||
val = new(big.Int).Add(
|
||||
args.MaxPriorityFeePerGas.ToInt(),
|
||||
new(big.Int).Mul(head.BaseFee, big.NewInt(2)),
|
||||
)
|
||||
} else {
|
||||
val = new(big.Int).Set(
|
||||
(*big.Int)(args.MaxPriorityFeePerGas))
|
||||
}
|
||||
args.MaxFeePerGas = (*hexutil.Big)(val)
|
||||
}
|
||||
// Both EIP-1559 fee parameters are now set; sanity check them.
|
||||
|
|
|
|||
|
|
@ -343,3 +343,7 @@ func (b *backendMock) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent)
|
|||
}
|
||||
|
||||
func (b *backendMock) Engine() consensus.Engine { return nil }
|
||||
|
||||
func (b *backendMock) StateAt(root common.Hash) (*state.StateDB, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package les
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
|
|
@ -336,3 +337,7 @@ func (b *LesApiBackend) StateAtBlock(ctx context.Context, block *types.Block, re
|
|||
func (b *LesApiBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
|
||||
return b.eth.stateAtTransaction(ctx, block, txIndex, reexec)
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) StateAt(root common.Hash) (*state.StateDB, error) {
|
||||
return nil, fmt.Errorf("StateAt is not supported in LES protocol")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rollup/circuitcapacitychecker"
|
||||
"github.com/ethereum/go-ethereum/rollup/fees"
|
||||
"github.com/ethereum/go-ethereum/rollup/tracing"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
)
|
||||
|
|
@ -1346,13 +1347,16 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
|
|||
if genParams.random != (common.Hash{}) {
|
||||
header.MixDigest = genParams.random
|
||||
}
|
||||
// Set baseFee and GasLimit if we are on an EIP-1559 chain
|
||||
if w.chainConfig.IsLondon(header.Number) {
|
||||
header.BaseFee = eip1559.CalcBaseFee(w.chainConfig, parent)
|
||||
if !w.chainConfig.IsLondon(parent.Number) {
|
||||
parentGasLimit := parent.GasLimit * w.chainConfig.ElasticityMultiplier()
|
||||
header.GasLimit = core.CalcGasLimit(parentGasLimit, w.config.GasCeil)
|
||||
// Set baseFee if we are on an EIP-1559 chain
|
||||
if w.chainConfig.IsCurie(header.Number) {
|
||||
state, err := w.chain.StateAt(parent.Root)
|
||||
if err != nil {
|
||||
log.Error("Failed to create mining context", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
parentL1BaseFee := fees.GetL1BaseFee(state)
|
||||
header.BaseFee = eip1559.CalcBaseFee(w.chainConfig, parent, parentL1BaseFee)
|
||||
|
||||
}
|
||||
// Apply EIP-4844, EIP-4788.
|
||||
if w.chainConfig.IsCancun(header.Number, header.Time) {
|
||||
|
|
|
|||
|
|
@ -187,3 +187,7 @@ func CalculateL1DataFee(tx *types.Transaction, state StateDB) (*big.Int, error)
|
|||
l1DataFee := calculateEncodedL1DataFee(raw, overhead, l1BaseFee, scalar)
|
||||
return l1DataFee, nil
|
||||
}
|
||||
|
||||
func GetL1BaseFee(state StateDB) *big.Int {
|
||||
return state.GetState(rcfg.L1GasPriceOracleAddress, rcfg.L1BaseFeeSlot).Big()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue