Skip to content

Commit

Permalink
Merge pull request #8 from EspressoSystems/update/upstream
Browse files Browse the repository at this point in the history
Update upstream
  • Loading branch information
jbearer authored Sep 18, 2023
2 parents 2ee8f79 + bc17d83 commit 13c02d5
Show file tree
Hide file tree
Showing 15 changed files with 486 additions and 50 deletions.
3 changes: 2 additions & 1 deletion cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,13 @@ var (
utils.GpoPercentileFlag,
utils.GpoMaxGasPriceFlag,
utils.GpoIgnoreGasPriceFlag,
utils.GpoMinSuggestedPriorityFeeFlag,
utils.RollupSequencerHTTPFlag,
utils.RollupHistoricalRPCFlag,
utils.RollupHistoricalRPCTimeoutFlag,
utils.RollupDisableTxPoolGossipFlag,
utils.RollupComputePendingBlock,
utils.RollupAllowPendingTxFilters,
utils.RollupHaltOnIncompatibleProtocolVersionFlag,
configFileFlag,
}, utils.NetworkFlags, utils.DatabasePathFlags)

Expand Down
20 changes: 14 additions & 6 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,12 @@ var (
Value: ethconfig.Defaults.GPO.IgnorePrice.Int64(),
Category: flags.GasPriceCategory,
}
GpoMinSuggestedPriorityFeeFlag = &cli.Int64Flag{
Name: "gpo.minsuggestedpriorityfee",
Usage: "Minimum transaction priority fee to suggest. Used on OP chains when blocks are not full.",
Value: ethconfig.Defaults.GPO.MinSuggestedPriorityFee.Int64(),
Category: flags.GasPriceCategory,
}

// Rollup Flags
RollupSequencerHTTPFlag = &cli.StringFlag{
Expand Down Expand Up @@ -893,9 +899,9 @@ var (
Usage: "By default the pending block equals the latest block to save resources and not leak txs from the tx-pool, this flag enables computing of the pending block from the tx-pool instead.",
Category: flags.RollupCategory,
}
RollupAllowPendingTxFilters = &cli.BoolFlag{
Name: "rollup.allowpendingtxfilters",
Usage: "By default 'eth_subscribe' with 'NewPendingTransaction' and 'eth_newPendingTransactionFilter' are disabled to prevent leaking txs from the tx-pool.",
RollupHaltOnIncompatibleProtocolVersionFlag = &cli.StringFlag{
Name: "beta.rollup.halt",
Usage: "Opt-in option to halt on incompatible protocol version requirements of the given level (major/minor/patch/none), as signaled through the Engine API by the rollup node",
Category: flags.RollupCategory,
}

Expand Down Expand Up @@ -1563,6 +1569,9 @@ func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) {
if ctx.IsSet(GpoIgnoreGasPriceFlag.Name) {
cfg.IgnorePrice = big.NewInt(ctx.Int64(GpoIgnoreGasPriceFlag.Name))
}
if ctx.IsSet(GpoMinSuggestedPriorityFeeFlag.Name) {
cfg.MinSuggestedPriorityFee = big.NewInt(ctx.Int64(GpoMinSuggestedPriorityFeeFlag.Name))
}
}

func setTxPool(ctx *cli.Context, cfg *txpool.Config) {
Expand Down Expand Up @@ -1844,7 +1853,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
}
cfg.RollupDisableTxPoolGossip = ctx.Bool(RollupDisableTxPoolGossipFlag.Name)
cfg.RollupDisableTxPoolAdmission = cfg.RollupSequencerHTTP != "" && !ctx.Bool(RollupEnableTxPoolAdmissionFlag.Name)
cfg.RollupAllowPendingTxFilters = ctx.Bool(RollupAllowPendingTxFilters.Name)
cfg.RollupHaltOnIncompatibleProtocolVersion = ctx.String(RollupHaltOnIncompatibleProtocolVersionFlag.Name)
// Override any default configs for hard coded networks.
switch {
case ctx.Bool(MainnetFlag.Name):
Expand Down Expand Up @@ -2037,8 +2046,7 @@ func RegisterGraphQLService(stack *node.Node, backend ethapi.Backend, filterSyst
func RegisterFilterAPI(stack *node.Node, backend ethapi.Backend, ethcfg *ethconfig.Config) *filters.FilterSystem {
isLightClient := ethcfg.SyncMode == downloader.LightSync
filterSystem := filters.NewFilterSystem(backend, filters.Config{
LogCacheSize: ethcfg.FilterLogCacheSize,
AllowPendingTxs: ethcfg.RollupAllowPendingTxFilters,
LogCacheSize: ethcfg.FilterLogCacheSize,
})
stack.RegisterAPIs([]rpc.API{{
Namespace: "eth",
Expand Down
33 changes: 33 additions & 0 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ type Ethereum struct {
lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase)

shutdownTracker *shutdowncheck.ShutdownTracker // Tracks if and when the node has shutdown ungracefully

nodeCloser func() error
}

// New creates a new Ethereum object (including the
Expand Down Expand Up @@ -162,6 +164,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
bloomIndexer: core.NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms),
p2pServer: stack.Server(),
shutdownTracker: shutdowncheck.NewShutdownTracker(chainDb),
nodeCloser: stack.Close,
}

bcVersion := rawdb.ReadDatabaseVersion(chainDb)
Expand Down Expand Up @@ -575,3 +578,33 @@ func (s *Ethereum) Stop() error {

return nil
}

// HandleRequiredProtocolVersion handles the protocol version signal. This implements opt-in halting,
// the protocol version data is already logged and metered when signaled through the Engine API.
func (s *Ethereum) HandleRequiredProtocolVersion(required params.ProtocolVersion) error {
var needLevel int
switch s.config.RollupHaltOnIncompatibleProtocolVersion {
case "major":
needLevel = 3
case "minor":
needLevel = 2
case "patch":
needLevel = 1
default:
return nil // do not consider halting if not configured to
}
haveLevel := 0
switch params.OPStackSupport.Compare(required) {
case params.OutdatedMajor:
haveLevel = 3
case params.OutdatedMinor:
haveLevel = 2
case params.OutdatedPatch:
haveLevel = 1
}
if haveLevel >= needLevel { // halt if we opted in to do so at this granularity
log.Error("Opted to halt, unprepared for protocol change", "required", required, "local", params.OPStackSupport)
return s.nodeCloser()
}
return nil
}
7 changes: 6 additions & 1 deletion eth/catalyst/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,11 @@ func TestEth2DeepReorg(t *testing.T) {

// startEthService creates a full node instance for testing.
func startEthService(t *testing.T, genesis *core.Genesis, blocks []*types.Block) (*node.Node, *eth.Ethereum) {
ethcfg := &ethconfig.Config{Genesis: genesis, SyncMode: downloader.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256}
return startEthServiceWithConfigFn(t, blocks, ethcfg)
}

func startEthServiceWithConfigFn(t *testing.T, blocks []*types.Block, ethcfg *ethconfig.Config) (*node.Node, *eth.Ethereum) {
t.Helper()

n, err := node.New(&node.Config{
Expand All @@ -440,7 +445,7 @@ func startEthService(t *testing.T, genesis *core.Genesis, blocks []*types.Block)
t.Fatal("can't create node:", err)
}

ethcfg := &ethconfig.Config{Genesis: genesis, SyncMode: downloader.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256}
// default eth config is moved to startEthService
ethservice, err := eth.New(n, ethcfg)
if err != nil {
t.Fatal("can't create eth service:", err)
Expand Down
64 changes: 64 additions & 0 deletions eth/catalyst/superchain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package catalyst

import (
"fmt"

"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/params"
)

var (
requiredProtocolDeltaGauge = metrics.NewRegisteredGauge("superchain/required/delta", nil)
recommendedProtocolDeltaGauge = metrics.NewRegisteredGauge("superchain/recommended/delta", nil)
)

type SuperchainSignal struct {
Recommended params.ProtocolVersion `json:"recommended"`
Required params.ProtocolVersion `json:"required"`
}

func (api *ConsensusAPI) SignalSuperchainV1(signal *SuperchainSignal) (params.ProtocolVersion, error) {
if signal == nil {
log.Info("Received empty superchain version signal", "local", params.OPStackSupport)
return params.OPStackSupport, nil
}
// update metrics and log any warnings/info
requiredProtocolDeltaGauge.Update(int64(params.OPStackSupport.Compare(signal.Required)))
recommendedProtocolDeltaGauge.Update(int64(params.OPStackSupport.Compare(signal.Recommended)))
logger := log.New("local", params.OPStackSupport, "required", signal.Required, "recommended", signal.Recommended)
LogProtocolVersionSupport(logger, params.OPStackSupport, signal.Recommended, "recommended")
LogProtocolVersionSupport(logger, params.OPStackSupport, signal.Required, "required")

if err := api.eth.HandleRequiredProtocolVersion(signal.Required); err != nil {
log.Error("Failed to handle required protocol version", "err", err, "required", signal.Required)
return params.OPStackSupport, err
}

return params.OPStackSupport, nil
}

func LogProtocolVersionSupport(logger log.Logger, local, other params.ProtocolVersion, name string) {
switch local.Compare(other) {
case params.AheadMajor:
logger.Info(fmt.Sprintf("Ahead with major %s protocol version change", name))
case params.AheadMinor, params.AheadPatch, params.AheadPrerelease:
logger.Debug(fmt.Sprintf("Ahead with compatible %s protocol version change", name))
case params.Matching:
logger.Debug(fmt.Sprintf("Latest %s protocol version is supported", name))
case params.OutdatedMajor:
logger.Error(fmt.Sprintf("Outdated with major %s protocol change", name))
case params.OutdatedMinor:
logger.Warn(fmt.Sprintf("Outdated with minor backward-compatible %s protocol change", name))
case params.OutdatedPatch:
logger.Info(fmt.Sprintf("Outdated with support backward-compatible %s protocol change", name))
case params.OutdatedPrerelease:
logger.Debug(fmt.Sprintf("New %s protocol pre-release is available", name))
case params.DiffBuild:
logger.Debug(fmt.Sprintf("Ignoring %s protocolversion signal, local build is different", name))
case params.DiffVersionType:
logger.Warn(fmt.Sprintf("Failed to recognize %s protocol version signal version-type", name))
case params.EmptyVersion:
logger.Debug(fmt.Sprintf("No %s protocol version available to check", name))
}
}
100 changes: 100 additions & 0 deletions eth/catalyst/superchain_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package catalyst

import (
"testing"
"time"

"github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/eth/ethconfig"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/params"
)

func TestSignalSuperchainV1(t *testing.T) {
genesis, preMergeBlocks := generateMergeChain(2, false)
n, ethservice := startEthService(t, genesis, preMergeBlocks)
defer n.Close()
api := NewConsensusAPI(ethservice)
t.Run("matching", func(t *testing.T) {
out, err := api.SignalSuperchainV1(&SuperchainSignal{
Recommended: params.OPStackSupport,
Required: params.OPStackSupport,
})
if err != nil {
t.Fatalf("failed to process signal: %v", err)
}
if out != params.OPStackSupport {
t.Fatalf("expected %s but got %s", params.OPStackSupport, out)
}
})
t.Run("null_arg", func(t *testing.T) {
out, err := api.SignalSuperchainV1(nil)
if err != nil {
t.Fatalf("failed to process signal: %v", err)
}
if out != params.OPStackSupport {
t.Fatalf("expected %s but got %s", params.OPStackSupport, out)
}
})
}

func TestSignalSuperchainV1Halt(t *testing.T) {
testCases := []struct {
cfg string
bump string
halt bool
}{
{"none", "major", false},
{"major", "major", true},
{"minor", "major", true},
{"patch", "major", true},
{"major", "minor", false},
{"minor", "minor", true},
{"patch", "minor", true},
{"major", "patch", false},
{"minor", "patch", false},
{"patch", "patch", true},
}
for _, tc := range testCases {
t.Run(tc.cfg+"_"+tc.bump, func(t *testing.T) {
genesis, preMergeBlocks := generateMergeChain(2, false)
ethcfg := &ethconfig.Config{Genesis: genesis, SyncMode: downloader.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256}
ethcfg.RollupHaltOnIncompatibleProtocolVersion = tc.cfg // opt-in to halting (or not)
n, ethservice := startEthServiceWithConfigFn(t, preMergeBlocks, ethcfg)
defer n.Close() // close at the end, regardless of any prior (failed) closing
api := NewConsensusAPI(ethservice)
_, build, major, minor, patch, preRelease := params.OPStackSupport.Parse()
majorSignal, minorSignal, patchSignal := major, minor, patch
switch tc.bump {
case "major":
majorSignal += 1
case "minor":
minorSignal += 1
case "patch":
patchSignal += 1
}
out, err := api.SignalSuperchainV1(&SuperchainSignal{
Recommended: params.OPStackSupport, // required version change should be enough
Required: params.ProtocolVersionV0{Build: build, Major: majorSignal, Minor: minorSignal, Patch: patchSignal, PreRelease: preRelease}.Encode(),
})
if err != nil {
t.Fatalf("failed to process signal: %v", err)
}
if out != params.OPStackSupport {
t.Fatalf("expected %s but got %s", params.OPStackSupport, out)
}
closeErr := n.Close()
if tc.halt {
// assert no halt by closing, and not getting any error
if closeErr == nil {
t.Fatalf("expected not to have closed already, but just closed without error")
}
} else {
// assert halt by closing again, and seeing if things error
if closeErr == node.ErrNodeStopped {
t.Fatalf("expected to have already closed and get a ErrNodeStopped error, but got %v", closeErr)
}
}
})
}
}
25 changes: 13 additions & 12 deletions eth/ethconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ import (

// FullNodeGPO contains default gasprice oracle settings for full node.
var FullNodeGPO = gasprice.Config{
Blocks: 20,
Percentile: 60,
MaxHeaderHistory: 1024,
MaxBlockHistory: 1024,
MaxPrice: gasprice.DefaultMaxPrice,
IgnorePrice: gasprice.DefaultIgnorePrice,
Blocks: 20,
Percentile: 60,
MaxHeaderHistory: 1024,
MaxBlockHistory: 1024,
MaxPrice: gasprice.DefaultMaxPrice,
IgnorePrice: gasprice.DefaultIgnorePrice,
MinSuggestedPriorityFee: gasprice.DefaultMinSuggestedPriorityFee,
}

// LightClientGPO contains default gasprice oracle settings for light client.
Expand Down Expand Up @@ -168,12 +169,12 @@ type Config struct {
OverrideOptimismRegolith *uint64 `toml:",omitempty"`
OverrideOptimism *bool

RollupSequencerHTTP string
RollupHistoricalRPC string
RollupHistoricalRPCTimeout time.Duration
RollupDisableTxPoolGossip bool
RollupDisableTxPoolAdmission bool
RollupAllowPendingTxFilters bool
RollupSequencerHTTP string
RollupHistoricalRPC string
RollupHistoricalRPCTimeout time.Duration
RollupDisableTxPoolGossip bool
RollupDisableTxPoolAdmission bool
RollupHaltOnIncompatibleProtocolVersion string
}

// CreateConsensusEngine creates a consensus engine for the given chain config.
Expand Down
14 changes: 2 additions & 12 deletions eth/filters/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ import (
var (
errInvalidTopic = errors.New("invalid topic(s)")
errFilterNotFound = errors.New("filter not found")
// errPendingDisabled is returned from NewPendingTransaction* when access to the mempool is not allowed
errPendingDisabled = errors.New("pending tx filters are disabled")
)

// filter is a helper struct that holds meta information over the filter type
Expand Down Expand Up @@ -111,11 +109,7 @@ func (api *FilterAPI) timeoutLoop(timeout time.Duration) {
//
// It is part of the filter package because this filter can be used through the
// `eth_getFilterChanges` polling method that is also used for log filters.
func (api *FilterAPI) NewPendingTransactionFilter(fullTx *bool) (rpc.ID, error) {
if !api.sys.cfg.AllowPendingTxs {
return "", errPendingDisabled
}

func (api *FilterAPI) NewPendingTransactionFilter(fullTx *bool) rpc.ID {
var (
pendingTxs = make(chan []*types.Transaction)
pendingTxSub = api.events.SubscribePendingTxs(pendingTxs)
Expand Down Expand Up @@ -143,17 +137,13 @@ func (api *FilterAPI) NewPendingTransactionFilter(fullTx *bool) (rpc.ID, error)
}
}()

return pendingTxSub.ID, nil
return pendingTxSub.ID
}

// NewPendingTransactions creates a subscription that is triggered each time a
// transaction enters the transaction pool. If fullTx is true the full tx is
// sent to the client, otherwise the hash is sent.
func (api *FilterAPI) NewPendingTransactions(ctx context.Context, fullTx *bool) (*rpc.Subscription, error) {
if !api.sys.cfg.AllowPendingTxs {
return &rpc.Subscription{}, errPendingDisabled
}

notifier, supported := rpc.NotifierFromContext(ctx)
if !supported {
return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported
Expand Down
2 changes: 0 additions & 2 deletions eth/filters/filter_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ import (
type Config struct {
LogCacheSize int // maximum number of cached blocks (default: 32)
Timeout time.Duration // how long filters stay active (default: 5min)
// allow filtering or subscriptions to new pending txs:
AllowPendingTxs bool
}

func (cfg Config) withDefaults() Config {
Expand Down
Loading

0 comments on commit 13c02d5

Please sign in to comment.