mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 21:26:42 +00:00
feat: re-enable EIP-1559 in Banach hard fork (#634)
* feat: re-enable EIP-1559 in Banach hard fork * enable BASEFEE opcode * do not double gas limit on Banach fork block * do not burn base fee * update base fee calculation logic * fix gas price oracle * fix ethapi backend * typo * reorder worker code * update genesis base fee * add MaximumL2BaseFee * add base fee metrics * handle nil base fee * revert state-transition change * bump version * remove TODO * update test * fix typo * fix typo * update traces * fix test * update london to banach * handle error * bump version * bump version
This commit is contained in:
parent
dab4354b62
commit
ccec84ce63
32 changed files with 274 additions and 231 deletions
|
|
@ -590,7 +590,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
|
||||||
return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
||||||
}
|
}
|
||||||
head := b.blockchain.CurrentHeader()
|
head := b.blockchain.CurrentHeader()
|
||||||
if !b.blockchain.Config().IsLondon(head.Number) {
|
if !b.blockchain.Config().IsBanach(head.Number) {
|
||||||
// If there's no basefee, then it must be a non-1559 execution
|
// If there's no basefee, then it must be a non-1559 execution
|
||||||
if call.GasPrice == nil {
|
if call.GasPrice == nil {
|
||||||
call.GasPrice = new(big.Int)
|
call.GasPrice = new(big.Int)
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,7 @@ func (c *BoundContract) createDynamicTx(opts *TransactOpts, contract *common.Add
|
||||||
|
|
||||||
func (c *BoundContract) createLegacyTx(opts *TransactOpts, contract *common.Address, input []byte) (*types.Transaction, error) {
|
func (c *BoundContract) createLegacyTx(opts *TransactOpts, contract *common.Address, input []byte) (*types.Transaction, error) {
|
||||||
if opts.GasFeeCap != nil || opts.GasTipCap != nil {
|
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 banach is not active yet")
|
||||||
}
|
}
|
||||||
// Normalize value
|
// Normalize value
|
||||||
value := opts.Value
|
value := opts.Value
|
||||||
|
|
|
||||||
|
|
@ -247,8 +247,8 @@ func Transition(ctx *cli.Context) error {
|
||||||
return NewError(ErrorJson, fmt.Errorf("failed signing transactions: %v", err))
|
return NewError(ErrorJson, fmt.Errorf("failed signing transactions: %v", err))
|
||||||
}
|
}
|
||||||
// Sanity check, to not `panic` in state_transition
|
// Sanity check, to not `panic` in state_transition
|
||||||
if chainConfig.IsLondon(big.NewInt(int64(prestate.Env.Number))) {
|
if chainConfig.IsBanach(big.NewInt(int64(prestate.Env.Number))) {
|
||||||
if prestate.Env.BaseFee == nil && chainConfig.Scroll.BaseFeeEnabled() {
|
if prestate.Env.BaseFee == nil {
|
||||||
return NewError(ErrorConfig, errors.New("EIP-1559 config but missing 'currentBaseFee' in env section"))
|
return NewError(ErrorConfig, errors.New("EIP-1559 config but missing 'currentBaseFee' in env section"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -321,8 +321,9 @@ func (t *txWithKey) UnmarshalJSON(input []byte) error {
|
||||||
// signUnsignedTransactions converts the input txs to canonical transactions.
|
// signUnsignedTransactions converts the input txs to canonical transactions.
|
||||||
//
|
//
|
||||||
// The transactions can have two forms, either
|
// The transactions can have two forms, either
|
||||||
// 1. unsigned or
|
// 1. unsigned or
|
||||||
// 2. signed
|
// 2. signed
|
||||||
|
//
|
||||||
// For (1), r, s, v, need so be zero, and the `secretKey` needs to be set.
|
// For (1), r, s, v, need so be zero, and the `secretKey` needs to be set.
|
||||||
// If so, we sign it here and now, with the given `secretKey`
|
// If so, we sign it here and now, with the given `secretKey`
|
||||||
// If the condition above is not met, then it's considered a signed transaction.
|
// If the condition above is not met, then it's considered a signed transaction.
|
||||||
|
|
|
||||||
|
|
@ -335,7 +335,7 @@ func (c *Clique) verifyCascadingFields(chain consensus.ChainHeaderReader, header
|
||||||
if header.GasUsed > header.GasLimit {
|
if header.GasUsed > header.GasLimit {
|
||||||
return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", 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().IsBanach(header.Number) {
|
||||||
// Verify BaseFee not present before EIP-1559 fork.
|
// Verify BaseFee not present before EIP-1559 fork.
|
||||||
if header.BaseFee != nil {
|
if header.BaseFee != nil {
|
||||||
return fmt.Errorf("invalid baseFee before fork: have %d, want <nil>", header.BaseFee)
|
return fmt.Errorf("invalid baseFee before fork: have %d, want <nil>", header.BaseFee)
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,7 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, pa
|
||||||
return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
|
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.
|
// Verify the block's gas usage and (if applicable) verify the base fee.
|
||||||
if !chain.Config().IsLondon(header.Number) {
|
if !chain.Config().IsBanach(header.Number) {
|
||||||
// Verify BaseFee not present before EIP-1559 fork.
|
// Verify BaseFee not present before EIP-1559 fork.
|
||||||
if header.BaseFee != nil {
|
if header.BaseFee != nil {
|
||||||
return fmt.Errorf("invalid baseFee before fork: have %d, expected 'nil'", header.BaseFee)
|
return fmt.Errorf("invalid baseFee before fork: have %d, expected 'nil'", header.BaseFee)
|
||||||
|
|
|
||||||
|
|
@ -20,90 +20,53 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/scroll-tech/go-ethereum/common"
|
|
||||||
"github.com/scroll-tech/go-ethereum/common/math"
|
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
"github.com/scroll-tech/go-ethereum/params"
|
"github.com/scroll-tech/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,
|
// VerifyEip1559Header verifies some header attributes which were changed in EIP-1559,
|
||||||
// - gas limit check
|
// - gas limit check
|
||||||
// - basefee check
|
// - basefee check
|
||||||
func VerifyEip1559Header(config *params.ChainConfig, parent, header *types.Header) error {
|
func VerifyEip1559Header(config *params.ChainConfig, parent, header *types.Header) error {
|
||||||
// Verify that the gas limit remains within allowed bounds
|
// Verify that the gas limit remains within allowed bounds
|
||||||
parentGasLimit := parent.GasLimit
|
if err := VerifyGaslimit(parent.GasLimit, header.GasLimit); err != nil {
|
||||||
if !config.IsLondon(parent.Number) {
|
|
||||||
parentGasLimit = parent.GasLimit * params.ElasticityMultiplier
|
|
||||||
}
|
|
||||||
if err := VerifyGaslimit(parentGasLimit, header.GasLimit); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Verify the header is not malformed
|
// Verify the header is not malformed
|
||||||
if header.BaseFee == nil && config.Scroll.BaseFeeEnabled() {
|
if header.BaseFee == nil {
|
||||||
return fmt.Errorf("header is missing baseFee")
|
return fmt.Errorf("header is missing baseFee")
|
||||||
}
|
}
|
||||||
// Now BaseFee can be nil, because !config.Scroll.BaseFeeEnabled()
|
// note: we do not verify L2 base fee, the sequencer has the
|
||||||
if header.BaseFee == nil {
|
// right to set any base fee below the maximum. L2 base fee
|
||||||
return nil
|
// is not subject to L2 consensus or zk verification.
|
||||||
}
|
if header.BaseFee.Cmp(big.NewInt(MaximumL2BaseFee)) > 0 {
|
||||||
// Verify the baseFee is correct based on the parent header.
|
return fmt.Errorf("invalid baseFee: have %s, maximum %d", header.BaseFee, MaximumL2BaseFee)
|
||||||
|
|
||||||
var expectedBaseFee *big.Int
|
|
||||||
|
|
||||||
// compatible check with the logic in commitNewWork
|
|
||||||
if config.Clique == nil || config.Scroll.BaseFeeEnabled() {
|
|
||||||
expectedBaseFee = CalcBaseFee(config, parent)
|
|
||||||
} else {
|
|
||||||
expectedBaseFee = big.NewInt(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
if header.BaseFee.Cmp(expectedBaseFee) != 0 {
|
|
||||||
return fmt.Errorf("invalid baseFee: have %s, want %s, parentBaseFee %s, parentGasUsed %d",
|
|
||||||
expectedBaseFee, header.BaseFee, parent.BaseFee, parent.GasUsed)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CalcBaseFee calculates the basefee of the header.
|
// CalcBaseFee calculates the basefee of the header.
|
||||||
func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
|
func CalcBaseFee(config *params.ChainConfig, parent *types.Header, parentL1BaseFee *big.Int) *big.Int {
|
||||||
// If the current block is the first EIP-1559 block, return the InitialBaseFee.
|
l2SequencerFee := big.NewInt(10000000) // 0.01 Gwei
|
||||||
if !config.IsLondon(parent.Number) {
|
provingFee := big.NewInt(140000000) // 0.14 Gwei
|
||||||
return new(big.Int).SetUint64(params.InitialBaseFee)
|
|
||||||
|
// 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
return baseFee
|
||||||
parentGasTarget = parent.GasLimit / params.ElasticityMultiplier
|
|
||||||
parentGasTargetBig = new(big.Int).SetUint64(parentGasTarget)
|
|
||||||
baseFeeChangeDenominator = new(big.Int).SetUint64(params.BaseFeeChangeDenominator)
|
|
||||||
)
|
|
||||||
if !config.Scroll.BaseFeeEnabled() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// If the parent gasUsed is the same as the target, the baseFee remains unchanged.
|
|
||||||
if parent.GasUsed == parentGasTarget {
|
|
||||||
return new(big.Int).Set(parent.BaseFee)
|
|
||||||
}
|
|
||||||
if parent.GasUsed > parentGasTarget {
|
|
||||||
// If the parent block used more gas than its target, the baseFee should increase.
|
|
||||||
gasUsedDelta := new(big.Int).SetUint64(parent.GasUsed - parentGasTarget)
|
|
||||||
x := new(big.Int).Mul(parent.BaseFee, gasUsedDelta)
|
|
||||||
y := x.Div(x, parentGasTargetBig)
|
|
||||||
baseFeeDelta := math.BigMax(
|
|
||||||
x.Div(y, baseFeeChangeDenominator),
|
|
||||||
common.Big1,
|
|
||||||
)
|
|
||||||
|
|
||||||
return x.Add(parent.BaseFee, baseFeeDelta)
|
|
||||||
} else {
|
|
||||||
// Otherwise if the parent block used less gas than its target, the baseFee should decrease.
|
|
||||||
gasUsedDelta := new(big.Int).SetUint64(parentGasTarget - parent.GasUsed)
|
|
||||||
x := new(big.Int).Mul(parent.BaseFee, gasUsedDelta)
|
|
||||||
y := x.Div(x, parentGasTargetBig)
|
|
||||||
baseFeeDelta := x.Div(y, baseFeeChangeDenominator)
|
|
||||||
|
|
||||||
return math.BigMax(
|
|
||||||
x.Sub(parent.BaseFee, baseFeeDelta),
|
|
||||||
common.Big0,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/scroll-tech/go-ethereum/common"
|
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
"github.com/scroll-tech/go-ethereum/params"
|
"github.com/scroll-tech/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
@ -52,7 +51,8 @@ func copyConfig(original *params.ChainConfig) *params.ChainConfig {
|
||||||
|
|
||||||
func config() *params.ChainConfig {
|
func config() *params.ChainConfig {
|
||||||
config := copyConfig(params.TestChainConfig)
|
config := copyConfig(params.TestChainConfig)
|
||||||
config.LondonBlock = big.NewInt(5)
|
config.LondonBlock = big.NewInt(3)
|
||||||
|
config.BanachBlock = big.NewInt(5)
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,13 +67,13 @@ func TestBlockGasLimits(t *testing.T) {
|
||||||
gasLimit uint64
|
gasLimit uint64
|
||||||
ok bool
|
ok bool
|
||||||
}{
|
}{
|
||||||
// Transitions from non-london to london
|
// Transitions from non-banach to banach
|
||||||
{10000000, 4, 20000000, true}, // No change
|
{10000000, 4, 10000000, true}, // No change
|
||||||
{10000000, 4, 20019530, true}, // Upper limit
|
{10000000, 4, 10009764, true}, // Upper limit
|
||||||
{10000000, 4, 20019531, false}, // Upper +1
|
{10000000, 4, 10009765, false}, // Upper +1
|
||||||
{10000000, 4, 19980470, true}, // Lower limit
|
{10000000, 4, 9990236, true}, // Lower limit
|
||||||
{10000000, 4, 19980469, false}, // Lower limit -1
|
{10000000, 4, 9990235, false}, // Lower limit -1
|
||||||
// London to London
|
// Banach to Banach
|
||||||
{20000000, 5, 20000000, true},
|
{20000000, 5, 20000000, true},
|
||||||
{20000000, 5, 20019530, true}, // Upper limit
|
{20000000, 5, 20019530, true}, // Upper limit
|
||||||
{20000000, 5, 20019531, false}, // Upper limit +1
|
{20000000, 5, 20019531, false}, // Upper limit +1
|
||||||
|
|
@ -109,23 +109,18 @@ func TestBlockGasLimits(t *testing.T) {
|
||||||
// TestCalcBaseFee assumes all blocks are 1559-blocks
|
// TestCalcBaseFee assumes all blocks are 1559-blocks
|
||||||
func TestCalcBaseFee(t *testing.T) {
|
func TestCalcBaseFee(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
parentBaseFee int64
|
parentL1BaseFee int64
|
||||||
parentGasLimit uint64
|
expectedL2BaseFee int64
|
||||||
parentGasUsed uint64
|
|
||||||
expectedBaseFee int64
|
|
||||||
}{
|
}{
|
||||||
{params.InitialBaseFee, 20000000, 10000000, params.InitialBaseFee}, // usage == target
|
{0, 150000000},
|
||||||
{params.InitialBaseFee, 20000000, 9000000, 987500000}, // usage below target
|
{1000000000, 164000000},
|
||||||
{params.InitialBaseFee, 20000000, 11000000, 1012500000}, // usage above target
|
{2000000000, 178000000},
|
||||||
|
{100000000000, 1550000000},
|
||||||
|
{111111111111, 1705555555},
|
||||||
|
{1000000000000, 10000000000}, // cap at max L2 base fee
|
||||||
}
|
}
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
parent := &types.Header{
|
if have, want := CalcBaseFee(config(), nil, big.NewInt(test.parentL1BaseFee)), big.NewInt(test.expectedL2BaseFee); have.Cmp(want) != 0 {
|
||||||
Number: common.Big32,
|
|
||||||
GasLimit: test.parentGasLimit,
|
|
||||||
GasUsed: test.parentGasUsed,
|
|
||||||
BaseFee: big.NewInt(test.parentBaseFee),
|
|
||||||
}
|
|
||||||
if have, want := CalcBaseFee(config(), parent), big.NewInt(test.expectedBaseFee); have.Cmp(want) != 0 {
|
|
||||||
t.Errorf("test %d: have %d want %d, ", i, have, want)
|
t.Errorf("test %d: have %d want %d, ", i, have, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,8 @@ var (
|
||||||
headHeaderGauge = metrics.NewRegisteredGauge("chain/head/header", nil)
|
headHeaderGauge = metrics.NewRegisteredGauge("chain/head/header", nil)
|
||||||
headFastBlockGauge = metrics.NewRegisteredGauge("chain/head/receipt", nil)
|
headFastBlockGauge = metrics.NewRegisteredGauge("chain/head/receipt", nil)
|
||||||
|
|
||||||
|
l2BaseFeeGauge = metrics.NewRegisteredGauge("chain/fees/l2basefee", nil)
|
||||||
|
|
||||||
accountReadTimer = metrics.NewRegisteredTimer("chain/account/reads", nil)
|
accountReadTimer = metrics.NewRegisteredTimer("chain/account/reads", nil)
|
||||||
accountHashTimer = metrics.NewRegisteredTimer("chain/account/hashes", nil)
|
accountHashTimer = metrics.NewRegisteredTimer("chain/account/hashes", nil)
|
||||||
accountUpdateTimer = metrics.NewRegisteredTimer("chain/account/updates", nil)
|
accountUpdateTimer = metrics.NewRegisteredTimer("chain/account/updates", nil)
|
||||||
|
|
@ -1246,6 +1248,13 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
||||||
return NonStatTy, errInsertionInterrupted
|
return NonStatTy, errInsertionInterrupted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note latest seen L2 base fee
|
||||||
|
if block.BaseFee() != nil {
|
||||||
|
l2BaseFeeGauge.Update(block.BaseFee().Int64())
|
||||||
|
} else {
|
||||||
|
l2BaseFeeGauge.Update(0)
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate the total difficulty of the block
|
// Calculate the total difficulty of the block
|
||||||
ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1)
|
ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1)
|
||||||
if ptd == nil {
|
if ptd == nil {
|
||||||
|
|
|
||||||
|
|
@ -607,7 +607,7 @@ func TestFastVsFullChains(t *testing.T) {
|
||||||
gendb = rawdb.NewMemoryDatabase()
|
gendb = rawdb.NewMemoryDatabase()
|
||||||
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
address = crypto.PubkeyToAddress(key.PublicKey)
|
address = crypto.PubkeyToAddress(key.PublicKey)
|
||||||
funds = big.NewInt(1000000000000000)
|
funds = big.NewInt(3000000000000000)
|
||||||
gspec = &Genesis{
|
gspec = &Genesis{
|
||||||
Config: params.TestChainConfig,
|
Config: params.TestChainConfig,
|
||||||
Alloc: GenesisAlloc{address: {Balance: funds}},
|
Alloc: GenesisAlloc{address: {Balance: funds}},
|
||||||
|
|
@ -1704,6 +1704,7 @@ func TestInsertReceiptChainRollback(t *testing.T) {
|
||||||
t.Fatalf("failed to create temp freezer db: %v", err)
|
t.Fatalf("failed to create temp freezer db: %v", err)
|
||||||
}
|
}
|
||||||
gspec := Genesis{Config: params.AllEthashProtocolChanges}
|
gspec := Genesis{Config: params.AllEthashProtocolChanges}
|
||||||
|
gspec.BaseFee = big.NewInt(params.InitialBaseFee)
|
||||||
gspec.MustCommit(ancientDb)
|
gspec.MustCommit(ancientDb)
|
||||||
ancientChain, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
ancientChain, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
||||||
defer ancientChain.Stop()
|
defer ancientChain.Stop()
|
||||||
|
|
@ -3171,7 +3172,10 @@ func TestFeeVault(t *testing.T) {
|
||||||
|
|
||||||
// Ensure that the fee vault received all tx fees
|
// Ensure that the fee vault received all tx fees
|
||||||
actual = state.GetBalance(*params.TestChainConfig.Scroll.FeeVaultAddress)
|
actual = state.GetBalance(*params.TestChainConfig.Scroll.FeeVaultAddress)
|
||||||
expected = new(big.Int).SetUint64(block.GasUsed() * block.Transactions()[0].GasTipCap().Uint64())
|
|
||||||
|
effectiveGasPrice := new(big.Int).Add(block.BaseFee(), block.Transactions()[0].GasTipCap())
|
||||||
|
gasUsed := new(big.Int).SetUint64(block.GasUsed())
|
||||||
|
expected = new(big.Int).Mul(gasUsed, effectiveGasPrice)
|
||||||
|
|
||||||
if actual.Cmp(expected) != 0 {
|
if actual.Cmp(expected) != 0 {
|
||||||
t.Fatalf("fee vault balance incorrect: expected %d, got %d", expected, actual)
|
t.Fatalf("fee vault balance incorrect: expected %d, got %d", expected, actual)
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/core/vm"
|
"github.com/scroll-tech/go-ethereum/core/vm"
|
||||||
"github.com/scroll-tech/go-ethereum/ethdb"
|
"github.com/scroll-tech/go-ethereum/ethdb"
|
||||||
"github.com/scroll-tech/go-ethereum/params"
|
"github.com/scroll-tech/go-ethereum/params"
|
||||||
|
"github.com/scroll-tech/go-ethereum/rollup/fees"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BlockGen creates blocks for testing.
|
// BlockGen creates blocks for testing.
|
||||||
|
|
@ -275,12 +276,9 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S
|
||||||
Number: new(big.Int).Add(parent.Number(), common.Big1),
|
Number: new(big.Int).Add(parent.Number(), common.Big1),
|
||||||
Time: time,
|
Time: time,
|
||||||
}
|
}
|
||||||
if chain.Config().IsLondon(header.Number) {
|
if chain.Config().IsBanach(header.Number) {
|
||||||
header.BaseFee = misc.CalcBaseFee(chain.Config(), parent.Header())
|
parentL1BaseFee := fees.GetL1BaseFee(state)
|
||||||
if !chain.Config().IsLondon(parent.Number()) {
|
header.BaseFee = misc.CalcBaseFee(chain.Config(), parent.Header(), parentL1BaseFee)
|
||||||
parentGasLimit := parent.GasLimit() * params.ElasticityMultiplier
|
|
||||||
header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return header
|
return header
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/common"
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
"github.com/scroll-tech/go-ethereum/common/hexutil"
|
"github.com/scroll-tech/go-ethereum/common/hexutil"
|
||||||
"github.com/scroll-tech/go-ethereum/common/math"
|
"github.com/scroll-tech/go-ethereum/common/math"
|
||||||
|
"github.com/scroll-tech/go-ethereum/consensus/misc"
|
||||||
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
||||||
"github.com/scroll-tech/go-ethereum/core/state"
|
"github.com/scroll-tech/go-ethereum/core/state"
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
|
|
@ -312,13 +313,11 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
|
||||||
if g.Difficulty == nil {
|
if g.Difficulty == nil {
|
||||||
head.Difficulty = params.GenesisDifficulty
|
head.Difficulty = params.GenesisDifficulty
|
||||||
}
|
}
|
||||||
if g.Config != nil && g.Config.IsLondon(common.Big0) {
|
if g.Config != nil && g.Config.IsBanach(common.Big0) {
|
||||||
if g.BaseFee != nil {
|
if g.BaseFee != nil {
|
||||||
head.BaseFee = g.BaseFee
|
head.BaseFee = g.BaseFee
|
||||||
} else if g.Config.Scroll.BaseFeeEnabled() {
|
|
||||||
head.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee)
|
|
||||||
} else {
|
} else {
|
||||||
head.BaseFee = nil
|
head.BaseFee = misc.CalcBaseFee(g.Config, nil, big.NewInt(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
statedb.Commit(false)
|
statedb.Commit(false)
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ func TestStateProcessorErrors(t *testing.T) {
|
||||||
BerlinBlock: big.NewInt(0),
|
BerlinBlock: big.NewInt(0),
|
||||||
LondonBlock: big.NewInt(0),
|
LondonBlock: big.NewInt(0),
|
||||||
ShanghaiBlock: big.NewInt(0),
|
ShanghaiBlock: big.NewInt(0),
|
||||||
|
BanachBlock: big.NewInt(0),
|
||||||
Ethash: new(params.EthashConfig),
|
Ethash: new(params.EthashConfig),
|
||||||
}
|
}
|
||||||
signer = types.LatestSigner(config)
|
signer = types.LatestSigner(config)
|
||||||
|
|
@ -332,6 +333,7 @@ func TestStateProcessorErrors(t *testing.T) {
|
||||||
ArrowGlacierBlock: big.NewInt(0),
|
ArrowGlacierBlock: big.NewInt(0),
|
||||||
ArchimedesBlock: big.NewInt(0),
|
ArchimedesBlock: big.NewInt(0),
|
||||||
ShanghaiBlock: big.NewInt(0),
|
ShanghaiBlock: big.NewInt(0),
|
||||||
|
BanachBlock: big.NewInt(0),
|
||||||
},
|
},
|
||||||
Alloc: GenesisAlloc{
|
Alloc: GenesisAlloc{
|
||||||
common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): GenesisAccount{
|
common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): GenesisAccount{
|
||||||
|
|
@ -346,21 +348,22 @@ func TestStateProcessorErrors(t *testing.T) {
|
||||||
smallInitCode = [320]byte{}
|
smallInitCode = [320]byte{}
|
||||||
)
|
)
|
||||||
defer blockchain.Stop()
|
defer blockchain.Stop()
|
||||||
|
parentL1BaseFee := big.NewInt(1000000000) // 1 gwei
|
||||||
for i, tt := range []struct {
|
for i, tt := range []struct {
|
||||||
txs []*types.Transaction
|
txs []*types.Transaction
|
||||||
want string
|
want string
|
||||||
}{
|
}{
|
||||||
{ // ErrMaxInitCodeSizeExceeded
|
{ // ErrMaxInitCodeSizeExceeded
|
||||||
txs: []*types.Transaction{
|
txs: []*types.Transaction{
|
||||||
mkDynamicCreationTx(0, 500000, common.Big0, misc.CalcBaseFee(config, genesis.Header()), tooBigInitCode[:]),
|
mkDynamicCreationTx(0, 500000, common.Big0, misc.CalcBaseFee(config, genesis.Header(), parentL1BaseFee), tooBigInitCode[:]),
|
||||||
},
|
},
|
||||||
want: "could not apply tx 0 [0x7b33776d375660694a23ef992c090265682f3687607e0099b14503fdb65d73e3]: max initcode size exceeded: code size 49153 limit 49152",
|
want: "could not apply tx 0 [0xa3d2dadf08846f3328b84b0a38240ace42f79c99ea4b9c097c8dcb345f61a84e]: max initcode size exceeded: code size 49153 limit 49152",
|
||||||
},
|
},
|
||||||
{ // ErrIntrinsicGas: Not enough gas to cover init code
|
{ // ErrIntrinsicGas: Not enough gas to cover init code
|
||||||
txs: []*types.Transaction{
|
txs: []*types.Transaction{
|
||||||
mkDynamicCreationTx(0, 54299, common.Big0, misc.CalcBaseFee(config, genesis.Header()), smallInitCode[:]),
|
mkDynamicCreationTx(0, 54299, common.Big0, misc.CalcBaseFee(config, genesis.Header(), parentL1BaseFee), smallInitCode[:]),
|
||||||
},
|
},
|
||||||
want: "could not apply tx 0 [0x98e54c5ecfa7986a66480d65ba32f2c6a2a6aedc3a67abb91b1e118b0717ed2d]: intrinsic gas too low: have 54299, want 54300",
|
want: "could not apply tx 0 [0x0880861c73bc504c01041b6d506737a119ca7c68c1fe666dc1682636b807c9db]: intrinsic gas too low: have 54299, want 54300",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
block := GenerateBadBlock(genesis, ethash.NewFaker(), tt.txs, gspec.Config)
|
block := GenerateBadBlock(genesis, ethash.NewFaker(), tt.txs, gspec.Config)
|
||||||
|
|
@ -394,8 +397,10 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
|
||||||
Time: parent.Time() + 10,
|
Time: parent.Time() + 10,
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
}
|
}
|
||||||
if config.IsLondon(header.Number) {
|
|
||||||
header.BaseFee = misc.CalcBaseFee(config, parent.Header())
|
if config.IsBanach(header.Number) {
|
||||||
|
parentL1BaseFee := big.NewInt(1000000000) // 1 gwei
|
||||||
|
header.BaseFee = misc.CalcBaseFee(config, parent.Header(), parentL1BaseFee)
|
||||||
}
|
}
|
||||||
var receipts []*types.Receipt
|
var receipts []*types.Receipt
|
||||||
// The post-state result doesn't need to be correct (this is a bad block), but we do need something there
|
// The post-state result doesn't need to be correct (this is a bad block), but we do need something there
|
||||||
|
|
|
||||||
|
|
@ -288,6 +288,7 @@ func (st *StateTransition) preCheck() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Make sure that transaction gasFeeCap is greater than the baseFee (post london)
|
// Make sure that transaction gasFeeCap is greater than the baseFee (post london)
|
||||||
|
// Note: Logically, this should be `IsBanach`, but we keep `IsLondon` to ensure backward compatibility.
|
||||||
if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
|
if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
|
||||||
// Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call)
|
// Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call)
|
||||||
if !st.evm.Config.NoBaseFee || st.gasFeeCap.BitLen() > 0 || st.gasTipCap.BitLen() > 0 {
|
if !st.evm.Config.NoBaseFee || st.gasFeeCap.BitLen() > 0 || st.gasTipCap.BitLen() > 0 {
|
||||||
|
|
@ -411,12 +412,10 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
||||||
st.refundGas(params.RefundQuotientEIP3529)
|
st.refundGas(params.RefundQuotientEIP3529)
|
||||||
}
|
}
|
||||||
effectiveTip := st.gasPrice
|
effectiveTip := st.gasPrice
|
||||||
if rules.IsLondon {
|
|
||||||
if st.evm.Context.BaseFee != nil {
|
// only burn the base fee if the fee vault is not enabled
|
||||||
effectiveTip = cmath.BigMin(st.gasTipCap, new(big.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee))
|
if rules.IsBanach && !st.evm.ChainConfig().Scroll.FeeVaultEnabled() {
|
||||||
} else {
|
effectiveTip = cmath.BigMin(st.gasTipCap, new(big.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee))
|
||||||
effectiveTip = cmath.BigMin(st.gasTipCap, st.gasFeeCap)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The L2 Fee is the same as the fee that is charged in the normal geth
|
// The L2 Fee is the same as the fee that is charged in the normal geth
|
||||||
|
|
|
||||||
|
|
@ -1231,8 +1231,9 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt
|
||||||
// because of another transaction (e.g. higher gas price).
|
// because of another transaction (e.g. higher gas price).
|
||||||
if reset != nil {
|
if reset != nil {
|
||||||
pool.demoteUnexecutables()
|
pool.demoteUnexecutables()
|
||||||
if reset.newHead != nil && pool.chainconfig.IsLondon(new(big.Int).Add(reset.newHead.Number, big.NewInt(1))) {
|
if reset.newHead != nil && pool.chainconfig.IsBanach(new(big.Int).Add(reset.newHead.Number, big.NewInt(1))) {
|
||||||
pendingBaseFee := misc.CalcBaseFee(pool.chainconfig, reset.newHead)
|
l1BaseFee := fees.GetL1BaseFee(pool.currentState)
|
||||||
|
pendingBaseFee := misc.CalcBaseFee(pool.chainconfig, reset.newHead, l1BaseFee)
|
||||||
pool.priced.SetBaseFee(pendingBaseFee)
|
pool.priced.SetBaseFee(pendingBaseFee)
|
||||||
}
|
}
|
||||||
// Update all accounts to the latest known pending nonce
|
// Update all accounts to the latest known pending nonce
|
||||||
|
|
@ -1356,8 +1357,8 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) {
|
||||||
next := new(big.Int).Add(newHead.Number, big.NewInt(1))
|
next := new(big.Int).Add(newHead.Number, big.NewInt(1))
|
||||||
pool.istanbul = pool.chainconfig.IsIstanbul(next)
|
pool.istanbul = pool.chainconfig.IsIstanbul(next)
|
||||||
|
|
||||||
pool.eip2718 = pool.chainconfig.Scroll.EnableEIP2718 && pool.chainconfig.IsBerlin(next)
|
pool.eip2718 = pool.chainconfig.IsBanach(next)
|
||||||
pool.eip1559 = pool.chainconfig.Scroll.EnableEIP1559 && pool.chainconfig.IsLondon(next)
|
pool.eip1559 = pool.chainconfig.IsBanach(next)
|
||||||
pool.shanghai = pool.chainconfig.IsShanghai(next)
|
pool.shanghai = pool.chainconfig.IsShanghai(next)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,20 +148,23 @@ type StorageWrapper struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type TransactionData struct {
|
type TransactionData struct {
|
||||||
Type uint8 `json:"type"`
|
Type uint8 `json:"type"`
|
||||||
Nonce uint64 `json:"nonce"`
|
Nonce uint64 `json:"nonce"`
|
||||||
TxHash string `json:"txHash"`
|
TxHash string `json:"txHash"`
|
||||||
Gas uint64 `json:"gas"`
|
Gas uint64 `json:"gas"`
|
||||||
GasPrice *hexutil.Big `json:"gasPrice"`
|
GasPrice *hexutil.Big `json:"gasPrice"`
|
||||||
From common.Address `json:"from"`
|
GasTipCap *hexutil.Big `json:"gasTipCap"`
|
||||||
To *common.Address `json:"to"`
|
GasFeeCap *hexutil.Big `json:"gasFeeCap"`
|
||||||
ChainId *hexutil.Big `json:"chainId"`
|
From common.Address `json:"from"`
|
||||||
Value *hexutil.Big `json:"value"`
|
To *common.Address `json:"to"`
|
||||||
Data string `json:"data"`
|
ChainId *hexutil.Big `json:"chainId"`
|
||||||
IsCreate bool `json:"isCreate"`
|
Value *hexutil.Big `json:"value"`
|
||||||
V *hexutil.Big `json:"v"`
|
Data string `json:"data"`
|
||||||
R *hexutil.Big `json:"r"`
|
IsCreate bool `json:"isCreate"`
|
||||||
S *hexutil.Big `json:"s"`
|
AccessList AccessList `json:"accessList"`
|
||||||
|
V *hexutil.Big `json:"v"`
|
||||||
|
R *hexutil.Big `json:"r"`
|
||||||
|
S *hexutil.Big `json:"s"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTransactionData returns a transaction that will serialize to the trace
|
// NewTransactionData returns a transaction that will serialize to the trace
|
||||||
|
|
@ -177,20 +180,23 @@ func NewTransactionData(tx *Transaction, blockNumber uint64, config *params.Chai
|
||||||
}
|
}
|
||||||
|
|
||||||
result := &TransactionData{
|
result := &TransactionData{
|
||||||
Type: tx.Type(),
|
Type: tx.Type(),
|
||||||
TxHash: tx.Hash().String(),
|
TxHash: tx.Hash().String(),
|
||||||
Nonce: nonce,
|
Nonce: nonce,
|
||||||
ChainId: (*hexutil.Big)(tx.ChainId()),
|
ChainId: (*hexutil.Big)(tx.ChainId()),
|
||||||
From: from,
|
From: from,
|
||||||
Gas: tx.Gas(),
|
Gas: tx.Gas(),
|
||||||
GasPrice: (*hexutil.Big)(tx.GasPrice()),
|
GasPrice: (*hexutil.Big)(tx.GasPrice()),
|
||||||
To: tx.To(),
|
GasTipCap: (*hexutil.Big)(tx.GasTipCap()),
|
||||||
Value: (*hexutil.Big)(tx.Value()),
|
GasFeeCap: (*hexutil.Big)(tx.GasFeeCap()),
|
||||||
Data: hexutil.Encode(tx.Data()),
|
To: tx.To(),
|
||||||
IsCreate: tx.To() == nil,
|
Value: (*hexutil.Big)(tx.Value()),
|
||||||
V: (*hexutil.Big)(v),
|
Data: hexutil.Encode(tx.Data()),
|
||||||
R: (*hexutil.Big)(r),
|
IsCreate: tx.To() == nil,
|
||||||
S: (*hexutil.Big)(s),
|
AccessList: tx.AccessList(),
|
||||||
|
V: (*hexutil.Big)(v),
|
||||||
|
R: (*hexutil.Big)(r),
|
||||||
|
S: (*hexutil.Big)(s),
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ type sigCache struct {
|
||||||
func MakeSigner(config *params.ChainConfig, blockNumber *big.Int) Signer {
|
func MakeSigner(config *params.ChainConfig, blockNumber *big.Int) Signer {
|
||||||
var signer Signer
|
var signer Signer
|
||||||
switch {
|
switch {
|
||||||
|
case config.IsBanach(blockNumber):
|
||||||
|
signer = NewLondonSignerWithEIP4844(config.ChainID)
|
||||||
case config.IsLondon(blockNumber):
|
case config.IsLondon(blockNumber):
|
||||||
signer = NewLondonSignerWithEIP4844(config.ChainID)
|
signer = NewLondonSignerWithEIP4844(config.ChainID)
|
||||||
case config.IsBerlin(blockNumber):
|
case config.IsBerlin(blockNumber):
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,8 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
|
||||||
if cfg.JumpTable[STOP] == nil {
|
if cfg.JumpTable[STOP] == nil {
|
||||||
var jt JumpTable
|
var jt JumpTable
|
||||||
switch {
|
switch {
|
||||||
|
case evm.chainRules.IsBanach:
|
||||||
|
jt = banachInstructionSet
|
||||||
case evm.chainRules.IsShanghai:
|
case evm.chainRules.IsShanghai:
|
||||||
jt = shanghaiInstructionSet
|
jt = shanghaiInstructionSet
|
||||||
case evm.chainRules.IsLondon:
|
case evm.chainRules.IsLondon:
|
||||||
|
|
|
||||||
|
|
@ -59,11 +59,20 @@ var (
|
||||||
berlinInstructionSet = newBerlinInstructionSet()
|
berlinInstructionSet = newBerlinInstructionSet()
|
||||||
londonInstructionSet = newLondonInstructionSet()
|
londonInstructionSet = newLondonInstructionSet()
|
||||||
shanghaiInstructionSet = newShanghaiInstructionSet()
|
shanghaiInstructionSet = newShanghaiInstructionSet()
|
||||||
|
banachInstructionSet = newBanachInstructionSet()
|
||||||
)
|
)
|
||||||
|
|
||||||
// JumpTable contains the EVM opcodes supported at a given fork.
|
// JumpTable contains the EVM opcodes supported at a given fork.
|
||||||
type JumpTable [256]*operation
|
type JumpTable [256]*operation
|
||||||
|
|
||||||
|
// newBanachInstructionSet returns the frontier, homestead, byzantium,
|
||||||
|
// contantinople, istanbul, petersburg, berlin, london, shanghai, and banach instructions.
|
||||||
|
func newBanachInstructionSet() JumpTable {
|
||||||
|
instructionSet := newShanghaiInstructionSet()
|
||||||
|
enable3198(&instructionSet) // Base fee opcode https://eips.ethereum.org/EIPS/eip-3198
|
||||||
|
return instructionSet
|
||||||
|
}
|
||||||
|
|
||||||
// newShanghaiInstructionSet returns the frontier, homestead, byzantium,
|
// newShanghaiInstructionSet returns the frontier, homestead, byzantium,
|
||||||
// contantinople, istanbul, petersburg, berlin, london and shanghai instructions.
|
// contantinople, istanbul, petersburg, berlin, london and shanghai instructions.
|
||||||
func newShanghaiInstructionSet() JumpTable {
|
func newShanghaiInstructionSet() JumpTable {
|
||||||
|
|
|
||||||
|
|
@ -380,3 +380,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, error) {
|
func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, error) {
|
||||||
return b.eth.stateAtTransaction(block, txIndex, reexec)
|
return b.eth.stateAtTransaction(block, txIndex, reexec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *EthAPIBackend) StateAt(root common.Hash) (*state.StateDB, error) {
|
||||||
|
return b.eth.BlockChain().StateAt(root)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/log"
|
"github.com/scroll-tech/go-ethereum/log"
|
||||||
"github.com/scroll-tech/go-ethereum/node"
|
"github.com/scroll-tech/go-ethereum/node"
|
||||||
chainParams "github.com/scroll-tech/go-ethereum/params"
|
chainParams "github.com/scroll-tech/go-ethereum/params"
|
||||||
|
"github.com/scroll-tech/go-ethereum/rollup/fees"
|
||||||
"github.com/scroll-tech/go-ethereum/rpc"
|
"github.com/scroll-tech/go-ethereum/rpc"
|
||||||
"github.com/scroll-tech/go-ethereum/trie"
|
"github.com/scroll-tech/go-ethereum/trie"
|
||||||
)
|
)
|
||||||
|
|
@ -141,8 +142,13 @@ func (api *consensusAPI) AssembleBlock(params assembleBlockParams) (*executableD
|
||||||
Extra: []byte{},
|
Extra: []byte{},
|
||||||
Time: params.Timestamp,
|
Time: params.Timestamp,
|
||||||
}
|
}
|
||||||
if config := api.eth.BlockChain().Config(); config.IsLondon(header.Number) {
|
if config := api.eth.BlockChain().Config(); config.IsBanach(header.Number) {
|
||||||
header.BaseFee = misc.CalcBaseFee(config, parent.Header())
|
stateDb, err := api.eth.BlockChain().StateAt(parent.Root())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
parentL1BaseFee := fees.GetL1BaseFee(stateDb)
|
||||||
|
header.BaseFee = misc.CalcBaseFee(config, parent.Header(), parentL1BaseFee)
|
||||||
}
|
}
|
||||||
err = api.eth.Engine().Prepare(bc, header)
|
err = api.eth.Engine().Prepare(bc, header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -245,7 +251,7 @@ func decodeTransactions(enc [][]byte) ([]*types.Transaction, error) {
|
||||||
return txs, nil
|
return txs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func insertBlockParamsToBlock(config *chainParams.ChainConfig, parent *types.Header, params executableData) (*types.Block, error) {
|
func insertBlockParamsToBlock(config *chainParams.ChainConfig, parent *types.Header, params executableData, parentL1BaseFee *big.Int) (*types.Block, error) {
|
||||||
txs, err := decodeTransactions(params.Transactions)
|
txs, err := decodeTransactions(params.Transactions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -267,8 +273,8 @@ func insertBlockParamsToBlock(config *chainParams.ChainConfig, parent *types.Hea
|
||||||
GasUsed: params.GasUsed,
|
GasUsed: params.GasUsed,
|
||||||
Time: params.Timestamp,
|
Time: params.Timestamp,
|
||||||
}
|
}
|
||||||
if config.IsLondon(number) {
|
if config.IsBanach(number) {
|
||||||
header.BaseFee = misc.CalcBaseFee(config, parent)
|
header.BaseFee = misc.CalcBaseFee(config, parent, parentL1BaseFee)
|
||||||
}
|
}
|
||||||
block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */)
|
block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */)
|
||||||
return block, nil
|
return block, nil
|
||||||
|
|
@ -282,7 +288,12 @@ func (api *consensusAPI) NewBlock(params executableData) (*newBlockResponse, err
|
||||||
if parent == nil {
|
if parent == nil {
|
||||||
return &newBlockResponse{false}, fmt.Errorf("could not find parent %x", params.ParentHash)
|
return &newBlockResponse{false}, fmt.Errorf("could not find parent %x", params.ParentHash)
|
||||||
}
|
}
|
||||||
block, err := insertBlockParamsToBlock(api.eth.BlockChain().Config(), parent.Header(), params)
|
stateDb, err := api.eth.BlockChain().StateAt(parent.Root())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
parentL1BaseFee := fees.GetL1BaseFee(stateDb)
|
||||||
|
block, err := insertBlockParamsToBlock(api.eth.BlockChain().Config(), parent.Header(), params, parentL1BaseFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/consensus/misc"
|
"github.com/scroll-tech/go-ethereum/consensus/misc"
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
"github.com/scroll-tech/go-ethereum/log"
|
"github.com/scroll-tech/go-ethereum/log"
|
||||||
|
"github.com/scroll-tech/go-ethereum/rollup/fees"
|
||||||
"github.com/scroll-tech/go-ethereum/rpc"
|
"github.com/scroll-tech/go-ethereum/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -88,8 +89,14 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
|
||||||
if bf.results.baseFee = bf.header.BaseFee; bf.results.baseFee == nil {
|
if bf.results.baseFee = bf.header.BaseFee; bf.results.baseFee == nil {
|
||||||
bf.results.baseFee = new(big.Int)
|
bf.results.baseFee = new(big.Int)
|
||||||
}
|
}
|
||||||
if chainconfig.IsLondon(big.NewInt(int64(bf.blockNumber + 1))) {
|
if chainconfig.IsBanach(big.NewInt(int64(bf.blockNumber + 1))) {
|
||||||
bf.results.nextBaseFee = misc.CalcBaseFee(chainconfig, bf.header)
|
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 = misc.CalcBaseFee(chainconfig, bf.header, l1BaseFee)
|
||||||
} else {
|
} else {
|
||||||
bf.results.nextBaseFee = new(big.Int)
|
bf.results.nextBaseFee = new(big.Int)
|
||||||
}
|
}
|
||||||
|
|
@ -191,10 +198,11 @@ func (oracle *Oracle) resolveBlockRange(ctx context.Context, lastBlock rpc.Block
|
||||||
// actually processed range is returned to avoid ambiguity when parts of the requested range
|
// actually processed range is returned to avoid ambiguity when parts of the requested range
|
||||||
// are not available or when the head has changed during processing this request.
|
// are not available or when the head has changed during processing this request.
|
||||||
// Three arrays are returned based on the processed blocks:
|
// Three arrays are returned based on the processed blocks:
|
||||||
// - reward: the requested percentiles of effective priority fees per gas of transactions in each
|
// - reward: the requested percentiles of effective priority fees per gas of transactions in each
|
||||||
// block, sorted in ascending order and weighted by gas used.
|
// block, sorted in ascending order and weighted by gas used.
|
||||||
// - baseFee: base fee per gas in the given block
|
// - baseFee: base fee per gas in the given block
|
||||||
// - gasUsedRatio: gasUsed/gasLimit in the given block
|
// - gasUsedRatio: gasUsed/gasLimit in the given block
|
||||||
|
//
|
||||||
// Note: baseFee includes the next block after the newest of the returned range, because this
|
// Note: baseFee includes the next block after the newest of the returned range, because this
|
||||||
// value can be derived from the newest block.
|
// value can be derived from the newest block.
|
||||||
func (oracle *Oracle) FeeHistory(ctx context.Context, blocks int, unresolvedLastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) {
|
func (oracle *Oracle) FeeHistory(ctx context.Context, blocks int, unresolvedLastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) {
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import (
|
||||||
|
|
||||||
"github.com/scroll-tech/go-ethereum/common"
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
"github.com/scroll-tech/go-ethereum/core"
|
"github.com/scroll-tech/go-ethereum/core"
|
||||||
|
"github.com/scroll-tech/go-ethereum/core/state"
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
"github.com/scroll-tech/go-ethereum/event"
|
"github.com/scroll-tech/go-ethereum/event"
|
||||||
"github.com/scroll-tech/go-ethereum/log"
|
"github.com/scroll-tech/go-ethereum/log"
|
||||||
|
|
@ -58,6 +59,7 @@ type OracleBackend interface {
|
||||||
PendingBlockAndReceipts() (*types.Block, types.Receipts)
|
PendingBlockAndReceipts() (*types.Block, types.Receipts)
|
||||||
ChainConfig() *params.ChainConfig
|
ChainConfig() *params.ChainConfig
|
||||||
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
|
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
|
||||||
|
StateAt(root common.Hash) (*state.StateDB, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Oracle recommends gas prices based on the content of recent
|
// Oracle recommends gas prices based on the content of recent
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/consensus/ethash"
|
"github.com/scroll-tech/go-ethereum/consensus/ethash"
|
||||||
"github.com/scroll-tech/go-ethereum/core"
|
"github.com/scroll-tech/go-ethereum/core"
|
||||||
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
||||||
|
"github.com/scroll-tech/go-ethereum/core/state"
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
"github.com/scroll-tech/go-ethereum/core/vm"
|
"github.com/scroll-tech/go-ethereum/core/vm"
|
||||||
"github.com/scroll-tech/go-ethereum/crypto"
|
"github.com/scroll-tech/go-ethereum/crypto"
|
||||||
|
|
@ -108,6 +109,9 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke
|
||||||
)
|
)
|
||||||
config.LondonBlock = londonBlock
|
config.LondonBlock = londonBlock
|
||||||
config.ArrowGlacierBlock = londonBlock
|
config.ArrowGlacierBlock = londonBlock
|
||||||
|
config.ArchimedesBlock = londonBlock
|
||||||
|
config.ShanghaiBlock = londonBlock
|
||||||
|
config.BanachBlock = londonBlock
|
||||||
engine := ethash.NewFaker()
|
engine := ethash.NewFaker()
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
genesis, err := gspec.Commit(db)
|
genesis, err := gspec.Commit(db)
|
||||||
|
|
@ -160,6 +164,10 @@ func (b *testBackend) GetBlockByNumber(number uint64) *types.Block {
|
||||||
return b.chain.GetBlockByNumber(number)
|
return b.chain.GetBlockByNumber(number)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *testBackend) StateAt(root common.Hash) (*state.StateDB, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
func TestSuggestTipCap(t *testing.T) {
|
func TestSuggestTipCap(t *testing.T) {
|
||||||
config := Config{
|
config := Config{
|
||||||
Blocks: 3,
|
Blocks: 3,
|
||||||
|
|
|
||||||
|
|
@ -159,11 +159,20 @@ func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string]*RPCTransac
|
||||||
}
|
}
|
||||||
pending, queue := s.b.TxPoolContent()
|
pending, queue := s.b.TxPoolContent()
|
||||||
curHeader := s.b.CurrentHeader()
|
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
|
// Flatten the pending transactions
|
||||||
for account, txs := range pending {
|
for account, txs := range pending {
|
||||||
dump := make(map[string]*RPCTransaction)
|
dump := make(map[string]*RPCTransaction)
|
||||||
for _, tx := range txs {
|
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
|
content["pending"][account.Hex()] = dump
|
||||||
}
|
}
|
||||||
|
|
@ -171,7 +180,7 @@ func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string]*RPCTransac
|
||||||
for account, txs := range queue {
|
for account, txs := range queue {
|
||||||
dump := make(map[string]*RPCTransaction)
|
dump := make(map[string]*RPCTransaction)
|
||||||
for _, tx := range txs {
|
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
|
content["queued"][account.Hex()] = dump
|
||||||
}
|
}
|
||||||
|
|
@ -184,17 +193,25 @@ func (s *PublicTxPoolAPI) ContentFrom(addr common.Address) map[string]map[string
|
||||||
pending, queue := s.b.TxPoolContentFrom(addr)
|
pending, queue := s.b.TxPoolContentFrom(addr)
|
||||||
curHeader := s.b.CurrentHeader()
|
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
|
// Build the pending transactions
|
||||||
dump := make(map[string]*RPCTransaction, len(pending))
|
dump := make(map[string]*RPCTransaction, len(pending))
|
||||||
for _, tx := range 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
|
content["pending"] = dump
|
||||||
|
|
||||||
// Build the queued transactions
|
// Build the queued transactions
|
||||||
dump = make(map[string]*RPCTransaction, len(queue))
|
dump = make(map[string]*RPCTransaction, len(queue))
|
||||||
for _, tx := range 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
|
content["queued"] = dump
|
||||||
|
|
||||||
|
|
@ -741,10 +758,10 @@ func (s *PublicBlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.H
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlockByNumber returns the requested canonical block.
|
// GetBlockByNumber returns the requested canonical block.
|
||||||
// * When blockNr is -1 the chain head is returned.
|
// - When blockNr is -1 the chain head is returned.
|
||||||
// * When blockNr is -2 the pending chain head is returned.
|
// - When blockNr is -2 the pending chain head is returned.
|
||||||
// * When fullTx is true all transactions in the block are returned, otherwise
|
// - When fullTx is true all transactions in the block are returned, otherwise
|
||||||
// only the transaction hash is returned.
|
// only the transaction hash is returned.
|
||||||
func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
|
func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
|
||||||
block, err := s.b.BlockByNumber(ctx, number)
|
block, err := s.b.BlockByNumber(ctx, number)
|
||||||
if block != nil && err == nil {
|
if block != nil && err == nil {
|
||||||
|
|
@ -1186,7 +1203,7 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args TransactionA
|
||||||
}
|
}
|
||||||
|
|
||||||
// RPCMarshalHeader converts the given header to the RPC output .
|
// RPCMarshalHeader converts the given header to the RPC output .
|
||||||
func RPCMarshalHeader(head *types.Header, enableBaseFee bool) map[string]interface{} {
|
func RPCMarshalHeader(head *types.Header) map[string]interface{} {
|
||||||
result := map[string]interface{}{
|
result := map[string]interface{}{
|
||||||
"number": (*hexutil.Big)(head.Number),
|
"number": (*hexutil.Big)(head.Number),
|
||||||
"hash": head.Hash(),
|
"hash": head.Hash(),
|
||||||
|
|
@ -1207,7 +1224,7 @@ func RPCMarshalHeader(head *types.Header, enableBaseFee bool) map[string]interfa
|
||||||
"receiptsRoot": head.ReceiptHash,
|
"receiptsRoot": head.ReceiptHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
if enableBaseFee && head.BaseFee != nil {
|
if head.BaseFee != nil {
|
||||||
result["baseFeePerGas"] = (*hexutil.Big)(head.BaseFee)
|
result["baseFeePerGas"] = (*hexutil.Big)(head.BaseFee)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1218,7 +1235,7 @@ func RPCMarshalHeader(head *types.Header, enableBaseFee bool) map[string]interfa
|
||||||
// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
|
// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
|
||||||
// transaction hashes.
|
// transaction hashes.
|
||||||
func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, config *params.ChainConfig) (map[string]interface{}, error) {
|
func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, config *params.ChainConfig) (map[string]interface{}, error) {
|
||||||
fields := RPCMarshalHeader(block.Header(), config.Scroll.BaseFeeEnabled())
|
fields := RPCMarshalHeader(block.Header())
|
||||||
fields["size"] = hexutil.Uint64(block.Size())
|
fields["size"] = hexutil.Uint64(block.Size())
|
||||||
|
|
||||||
if inclTx {
|
if inclTx {
|
||||||
|
|
@ -1253,7 +1270,7 @@ func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, config *param
|
||||||
// rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field, which requires
|
// rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field, which requires
|
||||||
// a `PublicBlockchainAPI`.
|
// a `PublicBlockchainAPI`.
|
||||||
func (s *PublicBlockChainAPI) rpcMarshalHeader(ctx context.Context, header *types.Header) map[string]interface{} {
|
func (s *PublicBlockChainAPI) rpcMarshalHeader(ctx context.Context, header *types.Header) map[string]interface{} {
|
||||||
fields := RPCMarshalHeader(header, s.b.ChainConfig().Scroll.BaseFeeEnabled())
|
fields := RPCMarshalHeader(header)
|
||||||
fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, header.Hash()))
|
fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, header.Hash()))
|
||||||
return fields
|
return fields
|
||||||
}
|
}
|
||||||
|
|
@ -1351,11 +1368,11 @@ func NewRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
// newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation
|
// 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
|
var baseFee *big.Int
|
||||||
blockNumber := uint64(0)
|
blockNumber := uint64(0)
|
||||||
if current != nil {
|
if current != nil {
|
||||||
baseFee = misc.CalcBaseFee(config, current)
|
baseFee = misc.CalcBaseFee(config, current, l1BaseFee)
|
||||||
blockNumber = current.Number.Uint64()
|
blockNumber = current.Number.Uint64()
|
||||||
}
|
}
|
||||||
return NewRPCTransaction(tx, common.Hash{}, blockNumber, 0, baseFee, config)
|
return NewRPCTransaction(tx, common.Hash{}, blockNumber, 0, baseFee, config)
|
||||||
|
|
@ -1594,7 +1611,17 @@ func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, has
|
||||||
}
|
}
|
||||||
// No finalized transaction, try to retrieve it from the pool
|
// No finalized transaction, try to retrieve it from the pool
|
||||||
if tx := s.b.GetPoolTransaction(hash); tx != nil {
|
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
|
// Transaction unknown, return as such
|
||||||
|
|
@ -1654,7 +1681,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha
|
||||||
"l1Fee": (*hexutil.Big)(receipt.L1Fee),
|
"l1Fee": (*hexutil.Big)(receipt.L1Fee),
|
||||||
}
|
}
|
||||||
// Assign the effective gas price paid
|
// Assign the effective gas price paid
|
||||||
if !s.b.ChainConfig().IsLondon(bigblock) {
|
if !s.b.ChainConfig().IsBanach(bigblock) {
|
||||||
fields["effectiveGasPrice"] = hexutil.Uint64(tx.GasPrice().Uint64())
|
fields["effectiveGasPrice"] = hexutil.Uint64(tx.GasPrice().Uint64())
|
||||||
} else {
|
} else {
|
||||||
header, err := s.b.HeaderByHash(ctx, blockHash)
|
header, err := s.b.HeaderByHash(ctx, blockHash)
|
||||||
|
|
@ -1866,10 +1893,19 @@ func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, err
|
||||||
}
|
}
|
||||||
curHeader := s.b.CurrentHeader()
|
curHeader := s.b.CurrentHeader()
|
||||||
transactions := make([]*RPCTransaction, 0, len(pending))
|
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 {
|
for _, tx := range pending {
|
||||||
from, _ := types.Sender(s.signer, tx)
|
from, _ := types.Sender(s.signer, tx)
|
||||||
if _, exists := accounts[from]; exists {
|
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
|
return transactions, nil
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ type Backend interface {
|
||||||
BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error)
|
BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error)
|
||||||
StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, 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)
|
StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error)
|
||||||
|
StateAt(root common.Hash) (*state.StateDB, error)
|
||||||
GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error)
|
GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error)
|
||||||
GetTd(ctx context.Context, hash common.Hash) *big.Int
|
GetTd(ctx context.Context, hash common.Hash) *big.Int
|
||||||
GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config) (*vm.EVM, func() error, error)
|
GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config) (*vm.EVM, func() error, error)
|
||||||
|
|
|
||||||
|
|
@ -78,13 +78,13 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend) error {
|
||||||
if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
|
if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
|
||||||
return errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
return errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
||||||
}
|
}
|
||||||
// After london, default to 1559 unless gasPrice is set
|
// After banach, default to 1559 unless gasPrice is set
|
||||||
head := b.CurrentHeader()
|
head := b.CurrentHeader()
|
||||||
// If user specifies both maxPriorityfee and maxFee, then we do not
|
// If user specifies both maxPriorityfee and maxFee, then we do not
|
||||||
// need to consult the chain for defaults. It's definitely a London tx.
|
// need to consult the chain for defaults. It's definitely a Banach tx.
|
||||||
if args.MaxPriorityFeePerGas == nil || args.MaxFeePerGas == nil {
|
if args.MaxPriorityFeePerGas == nil || args.MaxFeePerGas == nil {
|
||||||
// In this clause, user left some fields unspecified.
|
// In this clause, user left some fields unspecified.
|
||||||
if b.ChainConfig().IsLondon(head.Number) && args.GasPrice == nil {
|
if b.ChainConfig().IsBanach(head.Number) && args.GasPrice == nil {
|
||||||
if args.MaxPriorityFeePerGas == nil {
|
if args.MaxPriorityFeePerGas == nil {
|
||||||
tip, err := b.SuggestGasTipCap(ctx)
|
tip, err := b.SuggestGasTipCap(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -110,14 +110,14 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend) error {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil {
|
if args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil {
|
||||||
return errors.New("maxFeePerGas or maxPriorityFeePerGas specified but london is not active yet")
|
return errors.New("maxFeePerGas or maxPriorityFeePerGas specified but banach is not active yet")
|
||||||
}
|
}
|
||||||
if args.GasPrice == nil {
|
if args.GasPrice == nil {
|
||||||
price, err := b.SuggestGasTipCap(ctx)
|
price, err := b.SuggestGasTipCap(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if b.ChainConfig().IsLondon(head.Number) {
|
if b.ChainConfig().IsBanach(head.Number) {
|
||||||
// The legacy tx gas price suggestion should not add 2x base fee
|
// The legacy tx gas price suggestion should not add 2x base fee
|
||||||
// because all fees are consumed, so it would result in a spiral
|
// because all fees are consumed, so it would result in a spiral
|
||||||
// upwards.
|
// upwards.
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ package les
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -336,3 +337,6 @@ 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, error) {
|
func (b *LesApiBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, error) {
|
||||||
return b.eth.stateAtTransaction(ctx, block, txIndex, reexec)
|
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/scroll-tech/go-ethereum/metrics"
|
"github.com/scroll-tech/go-ethereum/metrics"
|
||||||
"github.com/scroll-tech/go-ethereum/params"
|
"github.com/scroll-tech/go-ethereum/params"
|
||||||
"github.com/scroll-tech/go-ethereum/rollup/circuitcapacitychecker"
|
"github.com/scroll-tech/go-ethereum/rollup/circuitcapacitychecker"
|
||||||
|
"github.com/scroll-tech/go-ethereum/rollup/fees"
|
||||||
"github.com/scroll-tech/go-ethereum/rollup/tracing"
|
"github.com/scroll-tech/go-ethereum/rollup/tracing"
|
||||||
"github.com/scroll-tech/go-ethereum/trie"
|
"github.com/scroll-tech/go-ethereum/trie"
|
||||||
)
|
)
|
||||||
|
|
@ -1322,20 +1323,15 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
|
||||||
Extra: w.extra,
|
Extra: w.extra,
|
||||||
Time: uint64(timestamp),
|
Time: uint64(timestamp),
|
||||||
}
|
}
|
||||||
// Set baseFee and GasLimit if we are on an EIP-1559 chain
|
// Set baseFee if we are on an EIP-1559 chain
|
||||||
if w.chainConfig.IsLondon(header.Number) {
|
if w.chainConfig.IsBanach(header.Number) {
|
||||||
if w.chainConfig.Scroll.BaseFeeEnabled() {
|
state, err := w.chain.StateAt(parent.Root())
|
||||||
header.BaseFee = misc.CalcBaseFee(w.chainConfig, parent.Header())
|
if err != nil {
|
||||||
} else {
|
log.Error("Failed to create mining context", "err", err)
|
||||||
// When disabling EIP-2718 or EIP-1559, we do not set baseFeePerGas in RPC response.
|
return
|
||||||
// Setting BaseFee as nil here can help outside SDK calculates l2geth's RLP encoding,
|
|
||||||
// otherwise the l2geth's BaseFee is not known from the outside.
|
|
||||||
header.BaseFee = nil
|
|
||||||
}
|
|
||||||
if !w.chainConfig.IsLondon(parent.Number()) {
|
|
||||||
parentGasLimit := parent.GasLimit() * params.ElasticityMultiplier
|
|
||||||
header.GasLimit = core.CalcGasLimit(parentGasLimit, w.config.GasCeil)
|
|
||||||
}
|
}
|
||||||
|
parentL1BaseFee := fees.GetL1BaseFee(state)
|
||||||
|
header.BaseFee = misc.CalcBaseFee(w.chainConfig, parent.Header(), parentL1BaseFee)
|
||||||
}
|
}
|
||||||
// Only set the coinbase if our consensus engine is running (avoid spurious block rewards)
|
// Only set the coinbase if our consensus engine is running (avoid spurious block rewards)
|
||||||
if w.isRunning() {
|
if w.isRunning() {
|
||||||
|
|
|
||||||
|
|
@ -289,8 +289,6 @@ var (
|
||||||
MaxTxPerBlock: &ScrollMaxTxPerBlock,
|
MaxTxPerBlock: &ScrollMaxTxPerBlock,
|
||||||
MaxTxPayloadBytesPerBlock: &ScrollMaxTxPayloadBytesPerBlock,
|
MaxTxPayloadBytesPerBlock: &ScrollMaxTxPayloadBytesPerBlock,
|
||||||
FeeVaultAddress: &rcfg.ScrollFeeVaultAddress,
|
FeeVaultAddress: &rcfg.ScrollFeeVaultAddress,
|
||||||
EnableEIP2718: false,
|
|
||||||
EnableEIP1559: false,
|
|
||||||
L1Config: &L1Config{
|
L1Config: &L1Config{
|
||||||
L1ChainId: 5,
|
L1ChainId: 5,
|
||||||
L1MessageQueueAddress: common.HexToAddress("0x79DB48002Aa861C8cb189cabc21c6B1468BC83BB"),
|
L1MessageQueueAddress: common.HexToAddress("0x79DB48002Aa861C8cb189cabc21c6B1468BC83BB"),
|
||||||
|
|
@ -328,8 +326,6 @@ var (
|
||||||
MaxTxPerBlock: &ScrollMaxTxPerBlock,
|
MaxTxPerBlock: &ScrollMaxTxPerBlock,
|
||||||
MaxTxPayloadBytesPerBlock: &ScrollMaxTxPayloadBytesPerBlock,
|
MaxTxPayloadBytesPerBlock: &ScrollMaxTxPayloadBytesPerBlock,
|
||||||
FeeVaultAddress: &rcfg.ScrollFeeVaultAddress,
|
FeeVaultAddress: &rcfg.ScrollFeeVaultAddress,
|
||||||
EnableEIP2718: false,
|
|
||||||
EnableEIP1559: false,
|
|
||||||
L1Config: &L1Config{
|
L1Config: &L1Config{
|
||||||
L1ChainId: 11155111,
|
L1ChainId: 11155111,
|
||||||
L1MessageQueueAddress: common.HexToAddress("0xF0B2293F5D834eAe920c6974D50957A1732de763"),
|
L1MessageQueueAddress: common.HexToAddress("0xF0B2293F5D834eAe920c6974D50957A1732de763"),
|
||||||
|
|
@ -367,8 +363,6 @@ var (
|
||||||
MaxTxPerBlock: &ScrollMaxTxPerBlock,
|
MaxTxPerBlock: &ScrollMaxTxPerBlock,
|
||||||
MaxTxPayloadBytesPerBlock: &ScrollMaxTxPayloadBytesPerBlock,
|
MaxTxPayloadBytesPerBlock: &ScrollMaxTxPayloadBytesPerBlock,
|
||||||
FeeVaultAddress: &rcfg.ScrollFeeVaultAddress,
|
FeeVaultAddress: &rcfg.ScrollFeeVaultAddress,
|
||||||
EnableEIP2718: false,
|
|
||||||
EnableEIP1559: false,
|
|
||||||
L1Config: &L1Config{
|
L1Config: &L1Config{
|
||||||
L1ChainId: 1,
|
L1ChainId: 1,
|
||||||
L1MessageQueueAddress: common.HexToAddress("0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B"),
|
L1MessageQueueAddress: common.HexToAddress("0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B"),
|
||||||
|
|
@ -383,12 +377,10 @@ var (
|
||||||
//
|
//
|
||||||
// This configuration is intentionally not using keyed fields to force anyone
|
// This configuration is intentionally not using keyed fields to force anyone
|
||||||
// adding flags to the config to also have to set these fields.
|
// adding flags to the config to also have to set these fields.
|
||||||
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, new(EthashConfig), nil,
|
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil,
|
||||||
ScrollConfig{
|
ScrollConfig{
|
||||||
UseZktrie: false,
|
UseZktrie: false,
|
||||||
FeeVaultAddress: nil,
|
FeeVaultAddress: nil,
|
||||||
EnableEIP2718: true,
|
|
||||||
EnableEIP1559: true,
|
|
||||||
MaxTxPerBlock: nil,
|
MaxTxPerBlock: nil,
|
||||||
MaxTxPayloadBytesPerBlock: nil,
|
MaxTxPayloadBytesPerBlock: nil,
|
||||||
L1Config: &L1Config{5, common.HexToAddress("0x0000000000000000000000000000000000000000"), 0, common.HexToAddress("0x0000000000000000000000000000000000000000")},
|
L1Config: &L1Config{5, common.HexToAddress("0x0000000000000000000000000000000000000000"), 0, common.HexToAddress("0x0000000000000000000000000000000000000000")},
|
||||||
|
|
@ -399,35 +391,29 @@ var (
|
||||||
//
|
//
|
||||||
// This configuration is intentionally not using keyed fields to force anyone
|
// This configuration is intentionally not using keyed fields to force anyone
|
||||||
// adding flags to the config to also have to set these fields.
|
// adding flags to the config to also have to set these fields.
|
||||||
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000},
|
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000},
|
||||||
ScrollConfig{
|
ScrollConfig{
|
||||||
UseZktrie: false,
|
UseZktrie: false,
|
||||||
FeeVaultAddress: nil,
|
FeeVaultAddress: nil,
|
||||||
EnableEIP2718: true,
|
|
||||||
EnableEIP1559: true,
|
|
||||||
MaxTxPerBlock: nil,
|
MaxTxPerBlock: nil,
|
||||||
MaxTxPayloadBytesPerBlock: nil,
|
MaxTxPayloadBytesPerBlock: nil,
|
||||||
L1Config: &L1Config{5, common.HexToAddress("0x0000000000000000000000000000000000000000"), 0, common.HexToAddress("0x0000000000000000000000000000000000000000")},
|
L1Config: &L1Config{5, common.HexToAddress("0x0000000000000000000000000000000000000000"), 0, common.HexToAddress("0x0000000000000000000000000000000000000000")},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, new(EthashConfig), nil,
|
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil,
|
||||||
ScrollConfig{
|
ScrollConfig{
|
||||||
UseZktrie: false,
|
UseZktrie: false,
|
||||||
FeeVaultAddress: &common.Address{123},
|
FeeVaultAddress: &common.Address{123},
|
||||||
EnableEIP2718: true,
|
|
||||||
EnableEIP1559: true,
|
|
||||||
MaxTxPerBlock: nil,
|
MaxTxPerBlock: nil,
|
||||||
MaxTxPayloadBytesPerBlock: nil,
|
MaxTxPayloadBytesPerBlock: nil,
|
||||||
L1Config: &L1Config{5, common.HexToAddress("0x0000000000000000000000000000000000000000"), 0, common.HexToAddress("0x0000000000000000000000000000000000000000")},
|
L1Config: &L1Config{5, common.HexToAddress("0x0000000000000000000000000000000000000000"), 0, common.HexToAddress("0x0000000000000000000000000000000000000000")},
|
||||||
}}
|
}}
|
||||||
TestRules = TestChainConfig.Rules(new(big.Int))
|
TestRules = TestChainConfig.Rules(new(big.Int))
|
||||||
|
|
||||||
TestNoL1DataFeeChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, new(EthashConfig), nil,
|
TestNoL1DataFeeChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil,
|
||||||
ScrollConfig{
|
ScrollConfig{
|
||||||
UseZktrie: false,
|
UseZktrie: false,
|
||||||
FeeVaultAddress: nil,
|
FeeVaultAddress: nil,
|
||||||
EnableEIP2718: true,
|
|
||||||
EnableEIP1559: true,
|
|
||||||
MaxTxPerBlock: nil,
|
MaxTxPerBlock: nil,
|
||||||
MaxTxPayloadBytesPerBlock: nil,
|
MaxTxPayloadBytesPerBlock: nil,
|
||||||
L1Config: &L1Config{5, common.HexToAddress("0x0000000000000000000000000000000000000000"), 0, common.HexToAddress("0x0000000000000000000000000000000000000000")},
|
L1Config: &L1Config{5, common.HexToAddress("0x0000000000000000000000000000000000000000"), 0, common.HexToAddress("0x0000000000000000000000000000000000000000")},
|
||||||
|
|
@ -539,12 +525,6 @@ type ScrollConfig struct {
|
||||||
// Transaction fee vault address [optional]
|
// Transaction fee vault address [optional]
|
||||||
FeeVaultAddress *common.Address `json:"feeVaultAddress,omitempty"`
|
FeeVaultAddress *common.Address `json:"feeVaultAddress,omitempty"`
|
||||||
|
|
||||||
// Enable EIP-2718 in tx pool [optional]
|
|
||||||
EnableEIP2718 bool `json:"enableEIP2718,omitempty"`
|
|
||||||
|
|
||||||
// Enable EIP-1559 in tx pool, EnableEIP2718 should be true too [optional]
|
|
||||||
EnableEIP1559 bool `json:"enableEIP1559,omitempty"`
|
|
||||||
|
|
||||||
// L1 config
|
// L1 config
|
||||||
L1Config *L1Config `json:"l1Config,omitempty"`
|
L1Config *L1Config `json:"l1Config,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
@ -566,10 +546,6 @@ func (c *L1Config) String() string {
|
||||||
c.L1ChainId, c.L1MessageQueueAddress.Hex(), c.NumL1MessagesPerBlock, c.ScrollChainAddress.Hex())
|
c.L1ChainId, c.L1MessageQueueAddress.Hex(), c.NumL1MessagesPerBlock, c.ScrollChainAddress.Hex())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s ScrollConfig) BaseFeeEnabled() bool {
|
|
||||||
return s.EnableEIP2718 && s.EnableEIP1559
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s ScrollConfig) FeeVaultEnabled() bool {
|
func (s ScrollConfig) FeeVaultEnabled() bool {
|
||||||
return s.FeeVaultAddress != nil
|
return s.FeeVaultAddress != nil
|
||||||
}
|
}
|
||||||
|
|
@ -593,8 +569,8 @@ func (s ScrollConfig) String() string {
|
||||||
maxTxPayloadBytesPerBlock = fmt.Sprintf("%v", *s.MaxTxPayloadBytesPerBlock)
|
maxTxPayloadBytesPerBlock = fmt.Sprintf("%v", *s.MaxTxPayloadBytesPerBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("{useZktrie: %v, maxTxPerBlock: %v, MaxTxPayloadBytesPerBlock: %v, feeVaultAddress: %v, enableEIP2718: %v, enableEIP1559: %v, l1Config: %v}",
|
return fmt.Sprintf("{useZktrie: %v, maxTxPerBlock: %v, MaxTxPayloadBytesPerBlock: %v, feeVaultAddress: %v, l1Config: %v}",
|
||||||
s.UseZktrie, maxTxPerBlock, maxTxPayloadBytesPerBlock, s.FeeVaultAddress, s.EnableEIP2718, s.EnableEIP1559, s.L1Config.String())
|
s.UseZktrie, maxTxPerBlock, maxTxPayloadBytesPerBlock, s.FeeVaultAddress, s.L1Config.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValidTxCount returns whether the given block's transaction count is below the limit.
|
// IsValidTxCount returns whether the given block's transaction count is below the limit.
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import (
|
||||||
const (
|
const (
|
||||||
VersionMajor = 5 // Major version component of the current release
|
VersionMajor = 5 // Major version component of the current release
|
||||||
VersionMinor = 1 // Minor version component of the current release
|
VersionMinor = 1 // Minor version component of the current release
|
||||||
VersionPatch = 21 // Patch version component of the current release
|
VersionPatch = 22 // Patch version component of the current release
|
||||||
VersionMeta = "mainnet" // Version metadata to append to the version string
|
VersionMeta = "mainnet" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -187,3 +187,7 @@ func CalculateL1DataFee(tx *types.Transaction, state StateDB) (*big.Int, error)
|
||||||
l1DataFee := calculateEncodedL1DataFee(raw, overhead, l1BaseFee, scalar)
|
l1DataFee := calculateEncodedL1DataFee(raw, overhead, l1BaseFee, scalar)
|
||||||
return l1DataFee, nil
|
return l1DataFee, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetL1BaseFee(state StateDB) *big.Int {
|
||||||
|
return state.GetState(rcfg.L1GasPriceOracleAddress, rcfg.L1BaseFeeSlot).Big()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
|
||||||
snaps, statedb := MakePreState(rawdb.NewMemoryDatabase(), t.json.Pre, snapshotter)
|
snaps, statedb := MakePreState(rawdb.NewMemoryDatabase(), t.json.Pre, snapshotter)
|
||||||
|
|
||||||
var baseFee *big.Int
|
var baseFee *big.Int
|
||||||
if config.IsLondon(new(big.Int)) {
|
if config.IsBanach(new(big.Int)) {
|
||||||
baseFee = t.json.Env.BaseFee
|
baseFee = t.json.Env.BaseFee
|
||||||
if baseFee == nil {
|
if baseFee == nil {
|
||||||
// Retesteth uses `0x10` for genesis baseFee. Therefore, it defaults to
|
// Retesteth uses `0x10` for genesis baseFee. Therefore, it defaults to
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue