mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
load L1 fee hooks (#8)
This commit is contained in:
parent
a1b6b2229a
commit
630a9f6f65
13 changed files with 209 additions and 24 deletions
|
|
@ -32,6 +32,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/accounts/scwallet"
|
||||
"github.com/ethereum/go-ethereum/accounts/usbwallet"
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/eth/catalyst"
|
||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
||||
|
|
@ -43,6 +44,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/naoina/toml"
|
||||
"github.com/specularL2/specular/lib/el_golang_lib/hook"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
|
|
@ -178,6 +180,17 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
|
|||
}
|
||||
backend, eth := utils.RegisterEthService(stack, &cfg.Eth)
|
||||
|
||||
// <specular modification>
|
||||
log.Info("initializing specular hooks")
|
||||
l2ChainId := ctx.Uint64(utils.NetworkIdFlag.Name)
|
||||
l1FeeRecipient := backend.ChainConfig().L1FeeRecipient
|
||||
if (l1FeeRecipient != common.Address{}) {
|
||||
vm := eth.BlockChain().GetVMConfig()
|
||||
vm.SpecularEVMPreTransferHook = hook.MakeSpecularEVMPreTransferHook(l2ChainId, l1FeeRecipient)
|
||||
vm.SpecularL1FeeReader = hook.MakeSpecularL1FeeReader(l2ChainId)
|
||||
}
|
||||
// <specular modification/>
|
||||
|
||||
// Create gauge with geth system and build information
|
||||
if eth != nil { // The 'eth' backend may be nil in light mode
|
||||
var protos []string
|
||||
|
|
|
|||
|
|
@ -71,6 +71,9 @@ var (
|
|||
utils.TxPoolLocalsFlag,
|
||||
utils.TxPoolNoLocalsFlag,
|
||||
utils.TxPoolJournalFlag,
|
||||
// <specular modification>
|
||||
utils.TxPoolJournalRemotesFlag,
|
||||
// <specular modification />
|
||||
utils.TxPoolRejournalFlag,
|
||||
utils.TxPoolPriceLimitFlag,
|
||||
utils.TxPoolPriceBumpFlag,
|
||||
|
|
|
|||
|
|
@ -387,6 +387,13 @@ var (
|
|||
Value: ethconfig.Defaults.TxPool.Lifetime,
|
||||
Category: flags.TxPoolCategory,
|
||||
}
|
||||
// <specular modification>
|
||||
TxPoolJournalRemotesFlag = &cli.BoolFlag{
|
||||
Name: "txpool.journalremotes",
|
||||
Usage: "Includes remote transactions in the journal",
|
||||
Category: flags.TxPoolCategory,
|
||||
}
|
||||
// <specular modification />
|
||||
// Blob transaction pool settings
|
||||
BlobPoolDataDirFlag = &cli.StringFlag{
|
||||
Name: "blobpool.datadir",
|
||||
|
|
@ -1532,6 +1539,11 @@ func setTxPool(ctx *cli.Context, cfg *legacypool.Config) {
|
|||
if ctx.IsSet(TxPoolJournalFlag.Name) {
|
||||
cfg.Journal = ctx.String(TxPoolJournalFlag.Name)
|
||||
}
|
||||
// <specular modification>
|
||||
if ctx.IsSet(TxPoolJournalRemotesFlag.Name) {
|
||||
cfg.JournalRemote = ctx.Bool(TxPoolJournalRemotesFlag.Name)
|
||||
}
|
||||
// <specular modification />
|
||||
if ctx.IsSet(TxPoolRejournalFlag.Name) {
|
||||
cfg.Rejournal = ctx.Duration(TxPoolRejournalFlag.Name)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -450,7 +450,9 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||
|
||||
// <specular modification>
|
||||
if st.evm.Config.SpecularEVMPreTransferHook != nil {
|
||||
err = st.evm.Config.SpecularEVMPreTransferHook(st.msg, st.evm)
|
||||
// <specular modification>
|
||||
err = st.evm.Config.SpecularEVMPreTransferHook(st.msg, st.evm.StateDB)
|
||||
// <specular modification />
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/txpool"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
|
|
@ -120,6 +121,11 @@ type BlockChain interface {
|
|||
|
||||
// StateAt returns a state database for a given root hash (generally the head).
|
||||
StateAt(root common.Hash) (*state.StateDB, error)
|
||||
|
||||
// <specular modification>
|
||||
// GetVMConfig returns the vm config
|
||||
GetVMConfig() *vm.Config
|
||||
// <specular modification />
|
||||
}
|
||||
|
||||
// Config are the configuration parameters of the transaction pool.
|
||||
|
|
@ -129,6 +135,13 @@ type Config struct {
|
|||
Journal string // Journal of local transactions to survive node restarts
|
||||
Rejournal time.Duration // Time interval to regenerate the local transaction journal
|
||||
|
||||
// <specular modification>
|
||||
// JournalRemote controls whether journaling includes remote transactions or not.
|
||||
// When true, all transactions loaded from the journal are treated as remote.
|
||||
JournalRemote bool
|
||||
// <specular modification />
|
||||
|
||||
|
||||
PriceLimit uint64 // Minimum gas price to enforce for acceptance into the pool
|
||||
PriceBump uint64 // Minimum price bump percentage to replace an already existing transaction (nonce)
|
||||
|
||||
|
|
@ -195,6 +208,10 @@ func (config *Config) sanitize() Config {
|
|||
return conf
|
||||
}
|
||||
|
||||
// <specular modification>
|
||||
type L1CostFn func(tx *types.Transaction) *big.Int //
|
||||
// <specular modification/>
|
||||
|
||||
// LegacyPool contains all currently known transactions. Transactions
|
||||
// enter the pool when they are received from the network or submitted
|
||||
// locally. They exit the pool when they are included in the blockchain.
|
||||
|
|
@ -235,6 +252,10 @@ type LegacyPool struct {
|
|||
initDoneCh chan struct{} // is closed once the pool is initialized (for tests)
|
||||
|
||||
changesSinceReorg int // A counter for how many drops we've performed in-between reorg.
|
||||
|
||||
// <specular modification>
|
||||
l1CostFn L1CostFn
|
||||
// <specular modification />
|
||||
}
|
||||
|
||||
type txpoolResetRequest struct {
|
||||
|
|
@ -271,9 +292,19 @@ func New(config Config, chain BlockChain) *LegacyPool {
|
|||
}
|
||||
pool.priced = newPricedList(pool.all)
|
||||
|
||||
if !config.NoLocals && config.Journal != "" {
|
||||
// <specular modification>
|
||||
if (!config.NoLocals || config.JournalRemote) && config.Journal != "" {
|
||||
pool.journal = newTxJournal(config.Journal)
|
||||
}
|
||||
|
||||
if pool.chain.GetVMConfig().SpecularL1FeeReader != nil {
|
||||
pool.l1CostFn = func (tx *types.Transaction) *big.Int {
|
||||
l1Fee, _ := pool.chain.GetVMConfig().SpecularL1FeeReader(tx, pool.currentState)
|
||||
return l1Fee
|
||||
}
|
||||
}
|
||||
// <specular modification />
|
||||
|
||||
return pool
|
||||
}
|
||||
|
||||
|
|
@ -307,12 +338,18 @@ func (pool *LegacyPool) Init(gasTip *big.Int, head *types.Header, reserve txpool
|
|||
|
||||
// If local transactions and journaling is enabled, load from disk
|
||||
if pool.journal != nil {
|
||||
if err := pool.journal.load(pool.addLocals); err != nil {
|
||||
// <specular modification>
|
||||
add := pool.addLocals
|
||||
if pool.config.JournalRemote {
|
||||
add = pool.addRemotesSync // Use sync version to match pool.AddLocals
|
||||
}
|
||||
if err := pool.journal.load(add); err != nil {
|
||||
log.Warn("Failed to load transaction journal", "err", err)
|
||||
}
|
||||
if err := pool.journal.rotate(pool.local()); err != nil {
|
||||
if err := pool.journal.rotate(pool.toJournal()); err != nil {
|
||||
log.Warn("Failed to rotate transaction journal", "err", err)
|
||||
}
|
||||
// <specular modification />
|
||||
}
|
||||
pool.wg.Add(1)
|
||||
go pool.loop()
|
||||
|
|
@ -380,7 +417,7 @@ func (pool *LegacyPool) loop() {
|
|||
case <-journal.C:
|
||||
if pool.journal != nil {
|
||||
pool.mu.Lock()
|
||||
if err := pool.journal.rotate(pool.local()); err != nil {
|
||||
if err := pool.journal.rotate(pool.toJournal()); err != nil {
|
||||
log.Warn("Failed to rotate local tx journal", "err", err)
|
||||
}
|
||||
pool.mu.Unlock()
|
||||
|
|
@ -555,6 +592,26 @@ func (pool *LegacyPool) Locals() []common.Address {
|
|||
return pool.locals.flatten()
|
||||
}
|
||||
|
||||
// <specular modification>
|
||||
// toJournal retrieves all transactions that should be included in the journal,
|
||||
// grouped by origin account and sorted by nonce.
|
||||
// The returned transaction set is a copy and can be freely modified by calling code.
|
||||
func (pool *LegacyPool) toJournal() map[common.Address]types.Transactions {
|
||||
if !pool.config.JournalRemote {
|
||||
return pool.local()
|
||||
}
|
||||
txs := make(map[common.Address]types.Transactions)
|
||||
for addr, pending := range pool.pending {
|
||||
txs[addr] = append(txs[addr], pending.Flatten()...)
|
||||
}
|
||||
for addr, queued := range pool.queue {
|
||||
txs[addr] = append(txs[addr], queued.Flatten()...)
|
||||
}
|
||||
return txs
|
||||
}
|
||||
|
||||
// <specular modification />
|
||||
|
||||
// local retrieves all currently known local transactions, grouped by origin
|
||||
// account and sorted by nonce. The returned transaction set is a copy and can be
|
||||
// freely modified by calling code.
|
||||
|
|
@ -620,7 +677,13 @@ func (pool *LegacyPool) validateTx(tx *types.Transaction, local bool) error {
|
|||
ExistingCost: func(addr common.Address, nonce uint64) *big.Int {
|
||||
if list := pool.pending[addr]; list != nil {
|
||||
if tx := list.txs.Get(nonce); tx != nil {
|
||||
return tx.Cost()
|
||||
// <specular modification>
|
||||
cost := tx.Cost()
|
||||
if pool.chain.GetVMConfig().SpecularL1FeeReader != nil {
|
||||
l1Fee, _ := pool.chain.GetVMConfig().SpecularL1FeeReader(tx, pool.currentState)
|
||||
cost.Add(cost, l1Fee)
|
||||
}
|
||||
// <specular modification />
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
@ -747,7 +810,7 @@ func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, e
|
|||
// Try to replace an existing transaction in the pending pool
|
||||
if list := pool.pending[from]; list != nil && list.Contains(tx.Nonce()) {
|
||||
// Nonce already pending, check if required price bump is met
|
||||
inserted, old := list.Add(tx, pool.config.PriceBump)
|
||||
inserted, old := list.Add(tx, pool.config.PriceBump, pool.l1CostFn)
|
||||
if !inserted {
|
||||
pendingDiscardMeter.Mark(1)
|
||||
return false, txpool.ErrReplaceUnderpriced
|
||||
|
|
@ -821,7 +884,7 @@ func (pool *LegacyPool) enqueueTx(hash common.Hash, tx *types.Transaction, local
|
|||
if pool.queue[from] == nil {
|
||||
pool.queue[from] = newList(false)
|
||||
}
|
||||
inserted, old := pool.queue[from].Add(tx, pool.config.PriceBump)
|
||||
inserted, old := pool.queue[from].Add(tx, pool.config.PriceBump, pool.l1CostFn)
|
||||
if !inserted {
|
||||
// An older transaction was better, discard this
|
||||
queuedDiscardMeter.Mark(1)
|
||||
|
|
@ -875,7 +938,7 @@ func (pool *LegacyPool) promoteTx(addr common.Address, hash common.Hash, tx *typ
|
|||
}
|
||||
list := pool.pending[addr]
|
||||
|
||||
inserted, old := list.Add(tx, pool.config.PriceBump)
|
||||
inserted, old := list.Add(tx, pool.config.PriceBump, pool.l1CostFn)
|
||||
if !inserted {
|
||||
// An older transaction was better, discard this
|
||||
pool.all.Remove(hash)
|
||||
|
|
@ -1406,6 +1469,23 @@ func (pool *LegacyPool) reset(oldHead, newHead *types.Header) {
|
|||
pool.addTxsLocked(reinject, false)
|
||||
}
|
||||
|
||||
// <specular modification>
|
||||
// getBalanceWithL1Fee returns the balance of the addr minus the L1 fee of the first tx in the list
|
||||
func (pool *LegacyPool) getBalanceWithL1Fee(addr common.Address, txList *list) *big.Int {
|
||||
balance := pool.currentState.GetBalance(addr)
|
||||
if !txList.Empty() && pool.chain.GetVMConfig().SpecularL1FeeReader != nil {
|
||||
// Reduce the cost-cap by L1 rollup cost of the first tx if necessary. Other txs will get filtered out afterwards.
|
||||
first := txList.txs.Get((*txList.txs.index)[0])
|
||||
l1Fee, _ := pool.chain.GetVMConfig().SpecularL1FeeReader(first, pool.currentState)
|
||||
|
||||
balance = new(big.Int).Sub(balance, l1Fee) // negative big int is fine
|
||||
}
|
||||
|
||||
return balance
|
||||
}
|
||||
|
||||
// <specular modification />
|
||||
|
||||
// promoteExecutables moves transactions that have become processable from the
|
||||
// future queue to the set of pending transactions. During this process, all
|
||||
// invalidated transactions (low nonce, low balance) are deleted.
|
||||
|
|
@ -1428,7 +1508,10 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T
|
|||
}
|
||||
log.Trace("Removed old queued transactions", "count", len(forwards))
|
||||
// Drop all transactions that are too costly (low balance or out of gas)
|
||||
drops, _ := list.Filter(pool.currentState.GetBalance(addr), gasLimit)
|
||||
// <specular modification>
|
||||
balance := pool.getBalanceWithL1Fee(addr, list)
|
||||
drops, _ := list.Filter(balance, gasLimit)
|
||||
// <specular modification />
|
||||
for _, tx := range drops {
|
||||
hash := tx.Hash()
|
||||
pool.all.Remove(hash)
|
||||
|
|
@ -1629,7 +1712,10 @@ func (pool *LegacyPool) demoteUnexecutables() {
|
|||
log.Trace("Removed old pending transaction", "hash", hash)
|
||||
}
|
||||
// Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later
|
||||
drops, invalids := list.Filter(pool.currentState.GetBalance(addr), gasLimit)
|
||||
// <specular modification>
|
||||
balance := pool.getBalanceWithL1Fee(addr, list)
|
||||
drops, invalids := list.Filter(balance, gasLimit)
|
||||
// <specular modification />
|
||||
for _, tx := range drops {
|
||||
hash := tx.Hash()
|
||||
log.Trace("Removed unpayable pending transaction", "hash", hash)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/txpool"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
|
|
@ -65,14 +66,19 @@ type testBlockChain struct {
|
|||
gasLimit atomic.Uint64
|
||||
statedb *state.StateDB
|
||||
chainHeadFeed *event.Feed
|
||||
vmConfig vm.Config
|
||||
}
|
||||
|
||||
func newTestBlockChain(config *params.ChainConfig, gasLimit uint64, statedb *state.StateDB, chainHeadFeed *event.Feed) *testBlockChain {
|
||||
bc := testBlockChain{config: config, statedb: statedb, chainHeadFeed: new(event.Feed)}
|
||||
bc := testBlockChain{config: config, statedb: statedb, chainHeadFeed: new(event.Feed), vmConfig: vm.Config{}}
|
||||
bc.gasLimit.Store(gasLimit)
|
||||
return &bc
|
||||
}
|
||||
|
||||
func (bc *testBlockChain) GetVMConfig() *vm.Config {
|
||||
return &bc.vmConfig
|
||||
}
|
||||
|
||||
func (bc *testBlockChain) Config() *params.ChainConfig {
|
||||
return bc.config
|
||||
}
|
||||
|
|
@ -171,6 +177,27 @@ func setupPoolWithConfig(config *params.ChainConfig) (*LegacyPool, *ecdsa.Privat
|
|||
return pool, key
|
||||
}
|
||||
|
||||
// returns a tx pool with an injected L1 Fee function
|
||||
// L1 fee is hardcoded to 100 wei
|
||||
func setupTxPoolWithL1Fee() (*LegacyPool, *ecdsa.PrivateKey) {
|
||||
config := params.TestChainConfig
|
||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
||||
blockchain := newTestBlockChain(config, 10000000, statedb, new(event.Feed))
|
||||
blockchain.vmConfig.SpecularL1FeeReader =
|
||||
func(tx *types.Transaction, db vm.StateDB) (*big.Int, error) {
|
||||
return big.NewInt(100), nil
|
||||
}
|
||||
|
||||
key, _ := crypto.GenerateKey()
|
||||
pool := New(testTxPoolConfig, blockchain)
|
||||
if err := pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), makeAddressReserver()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// wait for the pool to initialize
|
||||
<-pool.initDoneCh
|
||||
return pool, key
|
||||
}
|
||||
|
||||
// validatePoolInternals checks various consistency invariants within the pool.
|
||||
func validatePoolInternals(pool *LegacyPool) error {
|
||||
pool.mu.RLock()
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ func (l *list) Contains(nonce uint64) bool {
|
|||
//
|
||||
// If the new transaction is accepted into the list, the lists' cost and gas
|
||||
// thresholds are also potentially updated.
|
||||
func (l *list) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Transaction) {
|
||||
func (l *list) Add(tx *types.Transaction, priceBump uint64, l1CostFn L1CostFn) (bool, *types.Transaction) {
|
||||
// If there's an older better transaction, abort
|
||||
old := l.txs.Get(tx.Nonce())
|
||||
if old != nil {
|
||||
|
|
@ -326,6 +326,13 @@ func (l *list) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Transa
|
|||
}
|
||||
// Add new tx cost to totalcost
|
||||
l.totalcost.Add(l.totalcost, tx.Cost())
|
||||
// <specular modification />
|
||||
if l1CostFn != nil {
|
||||
if l1Cost := l1CostFn(tx); l1Cost != nil {
|
||||
l.totalcost.Add(l.totalcost, l1Cost)
|
||||
}
|
||||
}
|
||||
// <specular modification>
|
||||
// Otherwise overwrite the old transaction with the current one
|
||||
l.txs.Put(tx)
|
||||
if cost := tx.Cost(); l.costcap.Cmp(cost) < 0 {
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ func TestStrictListAdd(t *testing.T) {
|
|||
// Insert the transactions in a random order
|
||||
list := newList(true)
|
||||
for _, v := range rand.Perm(len(txs)) {
|
||||
list.Add(txs[v], DefaultConfig.PriceBump)
|
||||
list.Add(txs[v], DefaultConfig.PriceBump, nil)
|
||||
}
|
||||
// Verify internal state
|
||||
if len(list.txs.items) != len(txs) {
|
||||
|
|
@ -65,7 +65,7 @@ func BenchmarkListAdd(b *testing.B) {
|
|||
for i := 0; i < b.N; i++ {
|
||||
list := newList(true)
|
||||
for _, v := range rand.Perm(len(txs)) {
|
||||
list.Add(txs[v], DefaultConfig.PriceBump)
|
||||
list.Add(txs[v], DefaultConfig.PriceBump, nil)
|
||||
list.Filter(priceLimit, DefaultConfig.PriceBump)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,22 @@ import (
|
|||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
// <specular modification>
|
||||
// L1Oracle Update Overhead is the amount of gas consumed by updating the L1Oracle every epoch
|
||||
const l1OracleUpdateOverhead = uint64(70_000)
|
||||
|
||||
func EffectiveGasLimit(gasLimit uint64, config *params.ChainConfig) uint64 {
|
||||
if (config.L1FeeRecipient != common.Address{}) {
|
||||
if l1OracleUpdateOverhead < gasLimit {
|
||||
gasLimit -= l1OracleUpdateOverhead
|
||||
} else {
|
||||
gasLimit = 0
|
||||
}
|
||||
}
|
||||
return gasLimit
|
||||
}
|
||||
// <specular modification />
|
||||
|
||||
// ValidationOptions define certain differences between transaction validation
|
||||
// across the different pools without having to duplicate those checks.
|
||||
type ValidationOptions struct {
|
||||
|
|
@ -76,7 +92,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
|
|||
return ErrNegativeValue
|
||||
}
|
||||
// Ensure the transaction doesn't exceed the current block limit gas
|
||||
if head.GasLimit < tx.Gas() {
|
||||
if EffectiveGasLimit(head.GasLimit, opts.Config) < tx.Gas() {
|
||||
return ErrGasLimit
|
||||
}
|
||||
// Sanity check for extremely large numbers (supported by RLP or RPC)
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ type MessageInterface interface {
|
|||
GetSkipAccountChecks() bool
|
||||
}
|
||||
|
||||
type EVMHook func(msg MessageInterface, evm *EVM) error
|
||||
|
||||
type EVMHook func(msg MessageInterface, db StateDB) error
|
||||
type EVMReader func(tx *types.Transaction, db StateDB) (*big.Int, error) //
|
||||
// <specular modification/>
|
||||
|
||||
// Config are the configuration options for the Interpreter
|
||||
|
|
@ -56,6 +56,7 @@ type Config struct {
|
|||
|
||||
// <specular modification>
|
||||
SpecularEVMPreTransferHook EVMHook
|
||||
SpecularL1FeeReader EVMReader
|
||||
// <specular modification/>
|
||||
}
|
||||
|
||||
|
|
|
|||
6
go.mod
6
go.mod
|
|
@ -2,6 +2,8 @@ module github.com/ethereum/go-ethereum
|
|||
|
||||
go 1.20
|
||||
|
||||
replace github.com/specularL2/specular/lib/el_golang_lib => ../../../lib/el_golang_lib
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0
|
||||
github.com/Microsoft/go-winio v0.6.1
|
||||
|
|
@ -24,7 +26,7 @@ require (
|
|||
github.com/fatih/color v1.7.0
|
||||
github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e
|
||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5
|
||||
github.com/fsnotify/fsnotify v1.6.0
|
||||
github.com/fsnotify/fsnotify v1.7.0
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff
|
||||
github.com/gballet/go-verkle v0.0.0-20230607174250-df487255f46b
|
||||
github.com/go-stack/stack v1.8.1
|
||||
|
|
@ -56,6 +58,7 @@ require (
|
|||
github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7
|
||||
github.com/rs/cors v1.7.0
|
||||
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible
|
||||
github.com/specularL2/specular/lib/el_golang_lib v0.0.0-00010101000000-000000000000
|
||||
github.com/status-im/keycard-go v0.2.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/supranational/blst v0.3.11
|
||||
|
|
@ -123,6 +126,7 @@ require (
|
|||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/rogpeppe/go-internal v1.6.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/specularL2/specular/ops v0.0.0-20231129092153-13f66846bd07 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
|
|
|
|||
7
go.sum
7
go.sum
|
|
@ -186,8 +186,8 @@ github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+
|
|||
github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 h1:IZqZOB2fydHte3kUgxrzK5E1fW7RQGeDwE8F/ZZnUYc=
|
||||
github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8=
|
||||
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
||||
|
|
@ -517,6 +517,8 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
|
|||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/specularL2/specular/ops v0.0.0-20231129092153-13f66846bd07 h1:1GATCkcQ+bFcTq+JBr18jOrS0WKZ5B62gob7zFm0Rac=
|
||||
github.com/specularL2/specular/ops v0.0.0-20231129092153-13f66846bd07/go.mod h1:hxwB50nU3AN6FEWsb+RQ4zSrfTIIO6JGlKXPbsa5C2c=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
|
|
@ -754,7 +756,6 @@ golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
|
|
|||
|
|
@ -335,8 +335,10 @@ type ChainConfig struct {
|
|||
IsDevMode bool `json:"isDev,omitempty"`
|
||||
|
||||
// <specular modification>
|
||||
EnableL2EngineApi bool `json:"enableL2EngineApi,omitempty"`
|
||||
L2BaseFeeRecipient common.Address `json:"l2BaseFeeRecipient,omitempty"`
|
||||
EnableL2EngineApi bool `json:"enableL2EngineApi,omitempty"`
|
||||
EnableL2GasLimitApi bool `json:"enableL2GasLimitApi,omitempty"`
|
||||
L2BaseFeeRecipient common.Address `json:"l2BaseFeeRecipient,omitempty"`
|
||||
L1FeeRecipient common.Address `json:"l1FeeRecipient,omitempty"`
|
||||
// <specular modification/>
|
||||
}
|
||||
|
||||
|
|
@ -374,6 +376,9 @@ func (c *ChainConfig) Description() string {
|
|||
case c.EnableL2EngineApi:
|
||||
banner += "Consensus: L2 gas limit API enabled\n"
|
||||
banner += fmt.Sprintf(" - L2 Base fee recipient: %s\n", c.L2BaseFeeRecipient)
|
||||
case c.L1FeeRecipient != common.Address{}:
|
||||
banner += "Consensus: L1 Fee is enabled\n"
|
||||
banner += fmt.Sprintf("Consensus: L1 Fee Recipient: %s\n", c.L1FeeRecipient)
|
||||
// <specular modification/>
|
||||
case c.Ethash != nil:
|
||||
if c.TerminalTotalDifficulty == nil {
|
||||
|
|
@ -396,6 +401,14 @@ func (c *ChainConfig) Description() string {
|
|||
}
|
||||
banner += "\n"
|
||||
|
||||
// <specular modification>
|
||||
if (c.L1FeeRecipient != common.Address{}) {
|
||||
banner += "Rollup: L1 Fee is enabled\n"
|
||||
banner += fmt.Sprintf("Rollup: L1 Fee Recipient: %s\n", c.L1FeeRecipient)
|
||||
banner += "\n"
|
||||
}
|
||||
// <specular modification />
|
||||
|
||||
// Create a list of forks with a short description of them. Forks that only
|
||||
// makes sense for mainnet should be optional at printing to avoid bloating
|
||||
// the output for testnets and private networks.
|
||||
|
|
|
|||
Loading…
Reference in a new issue