Skip to content

Commit

Permalink
op-node: regolith rollup config attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
protolambda committed Feb 23, 2023
1 parent a2db6ca commit 1a234df
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 2 deletions.
8 changes: 8 additions & 0 deletions op-node/chaincfg/chains.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ var NetworksByName = map[string]rollup.Config{
"goerli": Goerli,
}

var L2ChainIDToNetworkName = func() map[string]string {
out := make(map[string]string)
for name, netCfg := range NetworksByName {
out[netCfg.L2ChainID.String()] = name
}
return out
}()

func AvailableNetworks() []string {
var networks []string
for name := range NetworksByName {
Expand Down
2 changes: 1 addition & 1 deletion op-node/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func RollupNodeMain(ctx *cli.Context) error {
log.Error("Unable to create the rollup node", "error", err)
return err
}
log.Info("Starting rollup node")
log.Info("Starting rollup node", "version", VersionWithMeta)

if err := n.Start(context.Background()); err != nil {
log.Error("Unable to start rollup node", "error", err)
Expand Down
5 changes: 4 additions & 1 deletion op-node/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"

"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/metrics"
Expand Down Expand Up @@ -61,9 +62,11 @@ func New(ctx context.Context, cfg *Config, log log.Logger, snapshotLog log.Logge
// not a context leak, gossipsub is closed with a context.
n.resourcesCtx, n.resourcesClose = context.WithCancel(context.Background())

log.Info("rollup config:\n" + cfg.Rollup.Description(chaincfg.L2ChainIDToNetworkName))

err := n.init(ctx, cfg, snapshotLog)
if err != nil {
log.Error("Error intializing the rollup node", "err", err)
log.Error("Error initializing the rollup node", "err", err)
// ensure we always close the node resources if we fail to initialize the node.
if closeErr := n.Close(); closeErr != nil {
return nil, multierror.Append(err, closeErr)
Expand Down
57 changes: 57 additions & 0 deletions op-node/rollup/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import (
"errors"
"fmt"
"math/big"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"

"github.com/ethereum-optimism/optimism/op-node/eth"
)
Expand Down Expand Up @@ -66,6 +68,12 @@ type Config struct {
// Required to identify the L2 network and create p2p signatures unique for this chain.
L2ChainID *big.Int `json:"l2_chain_id"`

// RegolithTime sets the activation time of the Regolith network-upgrade:
// a pre-mainnet Bedrock change that addresses findings of the Sherlock contest related to deposit attributes.
// "Regolith" is the loose deposited rock that sits on top of Bedrock.
// Active if RegolithTime != nil && L2 block timestamp >= *RegolithTime, inactive otherwise.
RegolithTime *uint64 `json:"regolith_time,omitempty"`

// Note: below addresses are part of the block-derivation process,
// and required to be the same network-wide to stay in consensus.

Expand Down Expand Up @@ -228,4 +236,53 @@ func (c *Config) L1Signer() types.Signer {
return types.NewLondonSigner(c.L1ChainID)
}

// IsRegolith returns true if the Regolith hardfork is active at or past the given timestamp.
func (c *Config) IsRegolith(timestamp uint64) bool {
return c.RegolithTime != nil && timestamp >= *c.RegolithTime
}

// Description outputs a banner describing the important parts of rollup configuration in a human-readable form.
// Optionally provide a mapping of L2 chain IDs to network names to label the L2 chain with if not unknown.
// The config should be config.Check()-ed before creating a description.
func (c *Config) Description(l2Chains map[string]string) string {
// Find and report the network the user is running
var banner string
networkL2 := ""
if l2Chains != nil {
networkL2 = l2Chains[c.L2ChainID.String()]
}
if networkL2 == "" {
networkL2 = "unknown L2"
}
networkL1 := params.NetworkNames[c.L1ChainID.String()]
if networkL1 == "" {
networkL1 = "unknown L1"
}
banner += fmt.Sprintf("L2 Chain ID: %v (%s)\n", c.L2ChainID, networkL2)
banner += fmt.Sprintf("L1 Chain ID: %v (%s)\n", c.L1ChainID, networkL1)
// Report the genesis configuration
banner += "Bedrock starting point:\n"
banner += fmt.Sprintf(" L2 starting time: %d ~ %s\n", c.Genesis.L2Time, fmtTime(c.Genesis.L2Time))
banner += fmt.Sprintf(" L2 block: %s %d\n", c.Genesis.L2.Hash, c.Genesis.L2.Number)
banner += fmt.Sprintf(" L1 block: %s %d\n", c.Genesis.L1.Hash, c.Genesis.L1.Number)
// Report the upgrade configuration
banner += "Post-Bedrock Network Upgrades (timestamp based):\n"
banner += fmt.Sprintf(" - Regolith: %s\n", fmtForkTimeOrUnset(c.RegolithTime))
return banner
}

func fmtForkTimeOrUnset(v *uint64) string {
if v == nil {
return "(not configured)"
}
if *v == 0 { // don't output the unix epoch time if it's really just activated at genesis.
return "@ genesis"
}
return fmt.Sprintf("@ %-10v ~ %s", *v, fmtTime(*v))
}

func fmtTime(v uint64) string {
return time.Unix(int64(v), 0).Format(time.UnixDate)
}

type Epoch uint64
61 changes: 61 additions & 0 deletions op-node/rollup/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package rollup
import (
"context"
"encoding/json"
"fmt"
"math/big"
"math/rand"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/ethereum/go-ethereum/common"

Expand Down Expand Up @@ -136,6 +138,65 @@ func TestCheckL1BlockRefByNumber(t *testing.T) {
assert.Error(t, err)
}

// TestRandomConfigDescription tests that the description works for different variations of a random rollup config.
func TestRandomConfigDescription(t *testing.T) {
t.Run("named L2", func(t *testing.T) {
config := randConfig()
out := config.Description(map[string]string{config.L2ChainID.String(): "foobar chain"})
require.Contains(t, out, "foobar chain")
})
t.Run("named L1", func(t *testing.T) {
config := randConfig()
config.L1ChainID = big.NewInt(5)
out := config.Description(map[string]string{config.L2ChainID.String(): "foobar chain"})
require.Contains(t, out, "goerli")
})
t.Run("unnamed", func(t *testing.T) {
config := randConfig()
out := config.Description(nil)
require.Contains(t, out, "(unknown L1)")
require.Contains(t, out, "(unknown L2)")
})
t.Run("regolith unset", func(t *testing.T) {
config := randConfig()
config.RegolithTime = nil
out := config.Description(nil)
require.Contains(t, out, "Regolith: (not configured)")
})
t.Run("regolith genesis", func(t *testing.T) {
config := randConfig()
config.RegolithTime = new(uint64)
out := config.Description(nil)
require.Contains(t, out, "Regolith: @ genesis")
})
t.Run("regolith date", func(t *testing.T) {
config := randConfig()
x := uint64(1677119335)
config.RegolithTime = &x
out := config.Description(nil)
// Don't check human-readable part of the date, it's timezone-dependent.
// Don't make this test fail only in Australia :')
require.Contains(t, out, fmt.Sprintf("Regolith: @ %d ~ ", x))
})
}

// TestRegolithActivation tests the activation condition of the Regolith upgrade.
func TestRegolithActivation(t *testing.T) {
config := randConfig()
config.RegolithTime = nil
require.False(t, config.IsRegolith(0), "false if nil time, even if checking 0")
require.False(t, config.IsRegolith(123456), "false if nil time")
config.RegolithTime = new(uint64)
require.True(t, config.IsRegolith(0), "true at zero")
require.True(t, config.IsRegolith(123456), "true for any")
x := uint64(123)
config.RegolithTime = &x
require.False(t, config.IsRegolith(0))
require.False(t, config.IsRegolith(122))
require.True(t, config.IsRegolith(123))
require.True(t, config.IsRegolith(124))
}

type mockL2Client struct {
chainID *big.Int
Hash common.Hash
Expand Down

0 comments on commit 1a234df

Please sign in to comment.