Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
4cd95b84
Unverified
Commit
4cd95b84
authored
Apr 06, 2023
by
mergify[bot]
Committed by
GitHub
Apr 06, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into op-wheel-dyn-time
parents
2707b281
a7fd5bd7
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
521 additions
and
16 deletions
+521
-16
main.go
op-program/cmd/main.go
+1
-1
main_test.go
op-program/cmd/main_test.go
+34
-3
config.go
op-program/config/config.go
+25
-6
config_test.go
op-program/config/config_test.go
+35
-6
flags.go
op-program/flags/flags.go
+18
-0
engine.go
op-program/l2/engine.go
+100
-0
engine_test.go
op-program/l2/engine_test.go
+264
-0
l2.go
op-program/l2/l2.go
+44
-0
No files found.
op-program/cmd/main.go
View file @
4cd95b84
...
@@ -95,7 +95,7 @@ func FaultProofProgram(logger log.Logger, cfg *config.Config) error {
...
@@ -95,7 +95,7 @@ func FaultProofProgram(logger log.Logger, cfg *config.Config) error {
ctx
:=
context
.
Background
()
ctx
:=
context
.
Background
()
logger
.
Info
(
"Connecting to L2 node"
,
"l2"
,
cfg
.
L2URL
)
logger
.
Info
(
"Connecting to L2 node"
,
"l2"
,
cfg
.
L2URL
)
_
,
err
:=
l2
.
NewFetching
L2Oracle
(
ctx
,
logger
,
cfg
.
L2URL
)
_
,
err
:=
l2
.
NewFetching
Engine
(
ctx
,
logger
,
cfg
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"connect l2 oracle: %w"
,
err
)
return
fmt
.
Errorf
(
"connect l2 oracle: %w"
,
err
)
}
}
...
...
op-program/cmd/main_test.go
View file @
4cd95b84
...
@@ -7,10 +7,13 @@ import (
...
@@ -7,10 +7,13 @@ import (
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-program/config"
"github.com/ethereum-optimism/optimism/op-program/config"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/require"
)
)
var
l2HeadValue
=
"0x6303578b1fa9480389c51bbcef6fe045bb877da39740819e9eb5f36f94949bd0"
func
TestLogLevel
(
t
*
testing
.
T
)
{
func
TestLogLevel
(
t
*
testing
.
T
)
{
t
.
Run
(
"RejectInvalid"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"RejectInvalid"
,
func
(
t
*
testing
.
T
)
{
verifyArgsInvalid
(
t
,
"unknown level: foo"
,
addRequiredArgs
(
"--log.level=foo"
))
verifyArgsInvalid
(
t
,
"unknown level: foo"
,
addRequiredArgs
(
"--log.level=foo"
))
...
@@ -28,7 +31,7 @@ func TestLogLevel(t *testing.T) {
...
@@ -28,7 +31,7 @@ func TestLogLevel(t *testing.T) {
func
TestDefaultCLIOptionsMatchDefaultConfig
(
t
*
testing
.
T
)
{
func
TestDefaultCLIOptionsMatchDefaultConfig
(
t
*
testing
.
T
)
{
cfg
:=
configForArgs
(
t
,
addRequiredArgs
())
cfg
:=
configForArgs
(
t
,
addRequiredArgs
())
require
.
Equal
(
t
,
config
.
NewConfig
(
&
chaincfg
.
Goerli
),
cfg
)
require
.
Equal
(
t
,
config
.
NewConfig
(
&
chaincfg
.
Goerli
,
"genesis.json"
,
common
.
HexToHash
(
l2HeadValue
)
),
cfg
)
}
}
func
TestNetwork
(
t
*
testing
.
T
)
{
func
TestNetwork
(
t
*
testing
.
T
)
{
...
@@ -72,10 +75,36 @@ func TestL2(t *testing.T) {
...
@@ -72,10 +75,36 @@ func TestL2(t *testing.T) {
require
.
Equal
(
t
,
expected
,
cfg
.
L2URL
)
require
.
Equal
(
t
,
expected
,
cfg
.
L2URL
)
}
}
func
TestL2Genesis
(
t
*
testing
.
T
)
{
t
.
Run
(
"Required"
,
func
(
t
*
testing
.
T
)
{
verifyArgsInvalid
(
t
,
"flag l2.genesis is required"
,
addRequiredArgsExcept
(
"--l2.genesis"
))
})
t
.
Run
(
"Valid"
,
func
(
t
*
testing
.
T
)
{
cfg
:=
configForArgs
(
t
,
replaceRequiredArg
(
"--l2.genesis"
,
"/tmp/genesis.json"
))
require
.
Equal
(
t
,
"/tmp/genesis.json"
,
cfg
.
L2GenesisPath
)
})
}
func
TestL2Head
(
t
*
testing
.
T
)
{
t
.
Run
(
"Required"
,
func
(
t
*
testing
.
T
)
{
verifyArgsInvalid
(
t
,
"flag l2.head is required"
,
addRequiredArgsExcept
(
"--l2.head"
))
})
t
.
Run
(
"Valid"
,
func
(
t
*
testing
.
T
)
{
cfg
:=
configForArgs
(
t
,
replaceRequiredArg
(
"--l2.head"
,
l2HeadValue
))
require
.
Equal
(
t
,
common
.
HexToHash
(
l2HeadValue
),
cfg
.
L2Head
)
})
t
.
Run
(
"Invalid"
,
func
(
t
*
testing
.
T
)
{
verifyArgsInvalid
(
t
,
config
.
ErrInvalidL2Head
.
Error
(),
replaceRequiredArg
(
"--l2.head"
,
"something"
))
})
}
// Offline support will be added later, but for now it just bails out with an error
// Offline support will be added later, but for now it just bails out with an error
func
TestOfflineModeNotSupported
(
t
*
testing
.
T
)
{
func
TestOfflineModeNotSupported
(
t
*
testing
.
T
)
{
logger
:=
log
.
New
()
logger
:=
log
.
New
()
err
:=
FaultProofProgram
(
logger
,
config
.
NewConfig
(
&
chaincfg
.
Goerli
))
err
:=
FaultProofProgram
(
logger
,
config
.
NewConfig
(
&
chaincfg
.
Goerli
,
"genesis.json"
,
common
.
HexToHash
(
l2HeadValue
)
))
require
.
ErrorContains
(
t
,
err
,
"offline mode not supported"
)
require
.
ErrorContains
(
t
,
err
,
"offline mode not supported"
)
}
}
...
@@ -125,6 +154,8 @@ func replaceRequiredArg(name string, value string) []string {
...
@@ -125,6 +154,8 @@ func replaceRequiredArg(name string, value string) []string {
func
requiredArgs
()
map
[
string
]
string
{
func
requiredArgs
()
map
[
string
]
string
{
return
map
[
string
]
string
{
return
map
[
string
]
string
{
"--network"
:
"goerli"
,
"--network"
:
"goerli"
,
"--l2.genesis"
:
"genesis.json"
,
"--l2.head"
:
l2HeadValue
,
}
}
}
}
...
...
op-program/config/config.go
View file @
4cd95b84
...
@@ -6,16 +6,21 @@ import (
...
@@ -6,16 +6,21 @@ import (
opnode
"github.com/ethereum-optimism/optimism/op-node"
opnode
"github.com/ethereum-optimism/optimism/op-node"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-program/flags"
"github.com/ethereum-optimism/optimism/op-program/flags"
"github.com/ethereum/go-ethereum/common"
"github.com/urfave/cli"
"github.com/urfave/cli"
)
)
var
(
var
(
ErrMissingRollupConfig
=
errors
.
New
(
"missing rollup config"
)
ErrMissingRollupConfig
=
errors
.
New
(
"missing rollup config"
)
ErrMissingL2Genesis
=
errors
.
New
(
"missing l2 genesis"
)
ErrInvalidL2Head
=
errors
.
New
(
"invalid l2 head"
)
)
)
type
Config
struct
{
type
Config
struct
{
Rollup
*
rollup
.
Config
Rollup
*
rollup
.
Config
L2URL
string
L2URL
string
L2GenesisPath
string
L2Head
common
.
Hash
}
}
func
(
c
*
Config
)
Check
()
error
{
func
(
c
*
Config
)
Check
()
error
{
...
@@ -25,6 +30,12 @@ func (c *Config) Check() error {
...
@@ -25,6 +30,12 @@ func (c *Config) Check() error {
if
err
:=
c
.
Rollup
.
Check
();
err
!=
nil
{
if
err
:=
c
.
Rollup
.
Check
();
err
!=
nil
{
return
err
return
err
}
}
if
c
.
L2GenesisPath
==
""
{
return
ErrMissingL2Genesis
}
if
c
.
L2Head
==
(
common
.
Hash
{})
{
return
ErrInvalidL2Head
}
return
nil
return
nil
}
}
...
@@ -33,9 +44,11 @@ func (c *Config) FetchingEnabled() bool {
...
@@ -33,9 +44,11 @@ func (c *Config) FetchingEnabled() bool {
}
}
// NewConfig creates a Config with all optional values set to the CLI default value
// NewConfig creates a Config with all optional values set to the CLI default value
func
NewConfig
(
rollupCfg
*
rollup
.
Config
)
*
Config
{
func
NewConfig
(
rollupCfg
*
rollup
.
Config
,
l2GenesisPath
string
,
l2Head
common
.
Hash
)
*
Config
{
return
&
Config
{
return
&
Config
{
Rollup
:
rollupCfg
,
Rollup
:
rollupCfg
,
L2GenesisPath
:
l2GenesisPath
,
L2Head
:
l2Head
,
}
}
}
}
...
@@ -47,8 +60,14 @@ func NewConfigFromCLI(ctx *cli.Context) (*Config, error) {
...
@@ -47,8 +60,14 @@ func NewConfigFromCLI(ctx *cli.Context) (*Config, error) {
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
l2Head
:=
common
.
HexToHash
(
ctx
.
GlobalString
(
flags
.
L2Head
.
Name
))
if
l2Head
==
(
common
.
Hash
{})
{
return
nil
,
ErrInvalidL2Head
}
return
&
Config
{
return
&
Config
{
Rollup
:
rollupCfg
,
Rollup
:
rollupCfg
,
L2URL
:
ctx
.
GlobalString
(
flags
.
L2NodeAddr
.
Name
),
L2URL
:
ctx
.
GlobalString
(
flags
.
L2NodeAddr
.
Name
),
L2GenesisPath
:
ctx
.
GlobalString
(
flags
.
L2GenesisPath
.
Name
),
L2Head
:
l2Head
,
},
nil
},
nil
}
}
op-program/config/config_test.go
View file @
4cd95b84
...
@@ -5,34 +5,63 @@ import (
...
@@ -5,34 +5,63 @@ import (
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/require"
)
)
var
validRollupConfig
=
&
chaincfg
.
Goerli
var
validL2GenesisPath
=
"genesis.json"
var
validL2Head
=
common
.
HexToHash
(
"0x6303578b1fa9480389c51bbcef6fe045bb877da39740819e9eb5f36f94949bd0"
)
func
TestDefaultConfigIsValid
(
t
*
testing
.
T
)
{
func
TestDefaultConfigIsValid
(
t
*
testing
.
T
)
{
err
:=
NewConfig
(
&
chaincfg
.
Goerli
)
.
Check
()
err
:=
NewConfig
(
validRollupConfig
,
validL2GenesisPath
,
validL2Head
)
.
Check
()
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
}
}
func
TestRollupConfig
(
t
*
testing
.
T
)
{
func
TestRollupConfig
(
t
*
testing
.
T
)
{
t
.
Run
(
"Required"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"Required"
,
func
(
t
*
testing
.
T
)
{
err
:=
NewConfig
(
nil
)
.
Check
()
err
:=
NewConfig
(
nil
,
validL2GenesisPath
,
validL2Head
)
.
Check
()
require
.
ErrorIs
(
t
,
err
,
ErrMissingRollupConfig
)
require
.
ErrorIs
(
t
,
err
,
ErrMissingRollupConfig
)
})
})
t
.
Run
(
"
V
alid"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"
Inv
alid"
,
func
(
t
*
testing
.
T
)
{
err
:=
NewConfig
(
&
rollup
.
Config
{})
.
Check
()
err
:=
NewConfig
(
&
rollup
.
Config
{}
,
validL2GenesisPath
,
validL2Head
)
.
Check
()
require
.
ErrorIs
(
t
,
err
,
rollup
.
ErrBlockTimeZero
)
require
.
ErrorIs
(
t
,
err
,
rollup
.
ErrBlockTimeZero
)
})
})
}
}
func
TestL2Genesis
(
t
*
testing
.
T
)
{
t
.
Run
(
"Required"
,
func
(
t
*
testing
.
T
)
{
err
:=
NewConfig
(
validRollupConfig
,
""
,
validL2Head
)
.
Check
()
require
.
ErrorIs
(
t
,
err
,
ErrMissingL2Genesis
)
})
t
.
Run
(
"Valid"
,
func
(
t
*
testing
.
T
)
{
err
:=
NewConfig
(
validRollupConfig
,
validL2GenesisPath
,
validL2Head
)
.
Check
()
require
.
NoError
(
t
,
err
)
})
}
func
TestL2Head
(
t
*
testing
.
T
)
{
t
.
Run
(
"Required"
,
func
(
t
*
testing
.
T
)
{
err
:=
NewConfig
(
validRollupConfig
,
validL2GenesisPath
,
common
.
Hash
{})
.
Check
()
require
.
ErrorIs
(
t
,
err
,
ErrInvalidL2Head
)
})
t
.
Run
(
"Valid"
,
func
(
t
*
testing
.
T
)
{
err
:=
NewConfig
(
validRollupConfig
,
validL2GenesisPath
,
validL2Head
)
.
Check
()
require
.
NoError
(
t
,
err
)
})
}
func
TestFetchingEnabled
(
t
*
testing
.
T
)
{
func
TestFetchingEnabled
(
t
*
testing
.
T
)
{
t
.
Run
(
"FetchingNotEnabledWhenNoFetcherUrlsSpecified"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"FetchingNotEnabledWhenNoFetcherUrlsSpecified"
,
func
(
t
*
testing
.
T
)
{
cfg
:=
NewConfig
(
&
chaincfg
.
Beta1
)
cfg
:=
NewConfig
(
&
chaincfg
.
Beta1
,
validL2GenesisPath
,
validL2Head
)
require
.
False
(
t
,
cfg
.
FetchingEnabled
(),
"Should not enable fetching when node URL not supplied"
)
require
.
False
(
t
,
cfg
.
FetchingEnabled
(),
"Should not enable fetching when node URL not supplied"
)
})
})
t
.
Run
(
"FetchingEnabledWhenFetcherUrlsSpecified"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"FetchingEnabledWhenFetcherUrlsSpecified"
,
func
(
t
*
testing
.
T
)
{
cfg
:=
NewConfig
(
&
chaincfg
.
Beta1
)
cfg
:=
NewConfig
(
&
chaincfg
.
Beta1
,
validL2GenesisPath
,
validL2Head
)
cfg
.
L2URL
=
"https://example.com:1234"
cfg
.
L2URL
=
"https://example.com:1234"
require
.
True
(
t
,
cfg
.
FetchingEnabled
(),
"Should enable fetching when node URL supplied"
)
require
.
True
(
t
,
cfg
.
FetchingEnabled
(),
"Should enable fetching when node URL supplied"
)
})
})
...
...
op-program/flags/flags.go
View file @
4cd95b84
...
@@ -28,6 +28,16 @@ var (
...
@@ -28,6 +28,16 @@ var (
Usage
:
"Address of L2 JSON-RPC endpoint to use (eth and debug namespace required)"
,
Usage
:
"Address of L2 JSON-RPC endpoint to use (eth and debug namespace required)"
,
EnvVar
:
service
.
PrefixEnvVar
(
envVarPrefix
,
"L2_RPC"
),
EnvVar
:
service
.
PrefixEnvVar
(
envVarPrefix
,
"L2_RPC"
),
}
}
L2GenesisPath
=
cli
.
StringFlag
{
Name
:
"l2.genesis"
,
Usage
:
"Path to the op-geth genesis file"
,
EnvVar
:
service
.
PrefixEnvVar
(
envVarPrefix
,
"L2_GENESIS"
),
}
L2Head
=
cli
.
StringFlag
{
Name
:
"l2.head"
,
Usage
:
"Hash of the agreed L2 block to start derivation from"
,
EnvVar
:
service
.
PrefixEnvVar
(
envVarPrefix
,
"L2_HEAD"
),
}
)
)
// Flags contains the list of configuration options available to the binary.
// Flags contains the list of configuration options available to the binary.
...
@@ -37,6 +47,8 @@ var programFlags = []cli.Flag{
...
@@ -37,6 +47,8 @@ var programFlags = []cli.Flag{
RollupConfig
,
RollupConfig
,
Network
,
Network
,
L2NodeAddr
,
L2NodeAddr
,
L2GenesisPath
,
L2Head
,
}
}
func
init
()
{
func
init
()
{
...
@@ -53,5 +65,11 @@ func CheckRequired(ctx *cli.Context) error {
...
@@ -53,5 +65,11 @@ func CheckRequired(ctx *cli.Context) error {
if
rollupConfig
!=
""
&&
network
!=
""
{
if
rollupConfig
!=
""
&&
network
!=
""
{
return
fmt
.
Errorf
(
"cannot specify both %s and %s"
,
RollupConfig
.
Name
,
Network
.
Name
)
return
fmt
.
Errorf
(
"cannot specify both %s and %s"
,
RollupConfig
.
Name
,
Network
.
Name
)
}
}
if
ctx
.
GlobalString
(
L2GenesisPath
.
Name
)
==
""
{
return
fmt
.
Errorf
(
"flag %s is required"
,
L2GenesisPath
.
Name
)
}
if
ctx
.
GlobalString
(
L2Head
.
Name
)
==
""
{
return
fmt
.
Errorf
(
"flag %s is required"
,
L2Head
.
Name
)
}
return
nil
return
nil
}
}
op-program/l2/engine.go
0 → 100644
View file @
4cd95b84
package
l2
import
(
"context"
"errors"
"fmt"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-program/l2/engineapi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
)
var
(
ErrNotFound
=
errors
.
New
(
"not found"
)
)
type
OracleEngine
struct
{
api
*
engineapi
.
L2EngineAPI
backend
engineapi
.
EngineBackend
rollupCfg
*
rollup
.
Config
}
func
NewOracleEngine
(
rollupCfg
*
rollup
.
Config
,
logger
log
.
Logger
,
backend
engineapi
.
EngineBackend
)
*
OracleEngine
{
engineAPI
:=
engineapi
.
NewL2EngineAPI
(
logger
,
backend
)
return
&
OracleEngine
{
api
:
engineAPI
,
backend
:
backend
,
rollupCfg
:
rollupCfg
,
}
}
func
(
o
OracleEngine
)
GetPayload
(
ctx
context
.
Context
,
payloadId
eth
.
PayloadID
)
(
*
eth
.
ExecutionPayload
,
error
)
{
return
o
.
api
.
GetPayloadV1
(
ctx
,
payloadId
)
}
func
(
o
OracleEngine
)
ForkchoiceUpdate
(
ctx
context
.
Context
,
state
*
eth
.
ForkchoiceState
,
attr
*
eth
.
PayloadAttributes
)
(
*
eth
.
ForkchoiceUpdatedResult
,
error
)
{
return
o
.
api
.
ForkchoiceUpdatedV1
(
ctx
,
state
,
attr
)
}
func
(
o
OracleEngine
)
NewPayload
(
ctx
context
.
Context
,
payload
*
eth
.
ExecutionPayload
)
(
*
eth
.
PayloadStatusV1
,
error
)
{
return
o
.
api
.
NewPayloadV1
(
ctx
,
payload
)
}
func
(
o
OracleEngine
)
PayloadByHash
(
ctx
context
.
Context
,
hash
common
.
Hash
)
(
*
eth
.
ExecutionPayload
,
error
)
{
block
:=
o
.
backend
.
GetBlockByHash
(
hash
)
if
block
==
nil
{
return
nil
,
ErrNotFound
}
return
eth
.
BlockAsPayload
(
block
)
}
func
(
o
OracleEngine
)
PayloadByNumber
(
ctx
context
.
Context
,
n
uint64
)
(
*
eth
.
ExecutionPayload
,
error
)
{
hash
:=
o
.
backend
.
GetCanonicalHash
(
n
)
if
hash
==
(
common
.
Hash
{})
{
return
nil
,
ErrNotFound
}
return
o
.
PayloadByHash
(
ctx
,
hash
)
}
func
(
o
OracleEngine
)
L2BlockRefByLabel
(
ctx
context
.
Context
,
label
eth
.
BlockLabel
)
(
eth
.
L2BlockRef
,
error
)
{
var
header
*
types
.
Header
switch
label
{
case
eth
.
Unsafe
:
header
=
o
.
backend
.
CurrentHeader
()
case
eth
.
Safe
:
header
=
o
.
backend
.
CurrentSafeBlock
()
case
eth
.
Finalized
:
header
=
o
.
backend
.
CurrentFinalBlock
()
default
:
return
eth
.
L2BlockRef
{},
fmt
.
Errorf
(
"unknown label: %v"
,
label
)
}
if
header
==
nil
{
return
eth
.
L2BlockRef
{},
ErrNotFound
}
block
:=
o
.
backend
.
GetBlockByHash
(
header
.
Hash
())
if
block
==
nil
{
return
eth
.
L2BlockRef
{},
ErrNotFound
}
return
derive
.
L2BlockToBlockRef
(
block
,
&
o
.
rollupCfg
.
Genesis
)
}
func
(
o
OracleEngine
)
L2BlockRefByHash
(
ctx
context
.
Context
,
l2Hash
common
.
Hash
)
(
eth
.
L2BlockRef
,
error
)
{
block
:=
o
.
backend
.
GetBlockByHash
(
l2Hash
)
if
block
==
nil
{
return
eth
.
L2BlockRef
{},
ErrNotFound
}
return
derive
.
L2BlockToBlockRef
(
block
,
&
o
.
rollupCfg
.
Genesis
)
}
func
(
o
OracleEngine
)
SystemConfigByL2Hash
(
ctx
context
.
Context
,
hash
common
.
Hash
)
(
eth
.
SystemConfig
,
error
)
{
payload
,
err
:=
o
.
PayloadByHash
(
ctx
,
hash
)
if
err
!=
nil
{
return
eth
.
SystemConfig
{},
err
}
return
derive
.
PayloadToSystemConfig
(
payload
,
o
.
rollupCfg
)
}
op-program/l2/engine_test.go
0 → 100644
View file @
4cd95b84
package
l2
import
(
"context"
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/trie"
"github.com/stretchr/testify/require"
)
// Should implement derive.Engine
var
_
derive
.
Engine
=
(
*
OracleEngine
)(
nil
)
func
TestPayloadByHash
(
t
*
testing
.
T
)
{
ctx
:=
context
.
Background
()
t
.
Run
(
"KnownBlock"
,
func
(
t
*
testing
.
T
)
{
engine
,
stub
:=
createOracleEngine
(
t
)
block
:=
stub
.
head
payload
,
err
:=
engine
.
PayloadByHash
(
ctx
,
block
.
Hash
())
require
.
NoError
(
t
,
err
)
expected
,
err
:=
eth
.
BlockAsPayload
(
block
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
expected
,
payload
)
})
t
.
Run
(
"UnknownBlock"
,
func
(
t
*
testing
.
T
)
{
engine
,
_
:=
createOracleEngine
(
t
)
hash
:=
common
.
HexToHash
(
"0x878899"
)
payload
,
err
:=
engine
.
PayloadByHash
(
ctx
,
hash
)
require
.
ErrorIs
(
t
,
err
,
ErrNotFound
)
require
.
Nil
(
t
,
payload
)
})
}
func
TestPayloadByNumber
(
t
*
testing
.
T
)
{
ctx
:=
context
.
Background
()
t
.
Run
(
"KnownBlock"
,
func
(
t
*
testing
.
T
)
{
engine
,
stub
:=
createOracleEngine
(
t
)
block
:=
stub
.
head
payload
,
err
:=
engine
.
PayloadByNumber
(
ctx
,
block
.
NumberU64
())
require
.
NoError
(
t
,
err
)
expected
,
err
:=
eth
.
BlockAsPayload
(
block
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
expected
,
payload
)
})
t
.
Run
(
"NoCanonicalHash"
,
func
(
t
*
testing
.
T
)
{
engine
,
_
:=
createOracleEngine
(
t
)
payload
,
err
:=
engine
.
PayloadByNumber
(
ctx
,
uint64
(
700
))
require
.
ErrorIs
(
t
,
err
,
ErrNotFound
)
require
.
Nil
(
t
,
payload
)
})
t
.
Run
(
"UnknownBlock"
,
func
(
t
*
testing
.
T
)
{
engine
,
stub
:=
createOracleEngine
(
t
)
hash
:=
common
.
HexToHash
(
"0x878899"
)
number
:=
uint64
(
700
)
stub
.
canonical
[
number
]
=
hash
payload
,
err
:=
engine
.
PayloadByNumber
(
ctx
,
number
)
require
.
ErrorIs
(
t
,
err
,
ErrNotFound
)
require
.
Nil
(
t
,
payload
)
})
}
func
TestL2BlockRefByLabel
(
t
*
testing
.
T
)
{
ctx
:=
context
.
Background
()
engine
,
stub
:=
createOracleEngine
(
t
)
tests
:=
[]
struct
{
name
eth
.
BlockLabel
block
*
types
.
Block
}{
{
eth
.
Unsafe
,
stub
.
head
},
{
eth
.
Safe
,
stub
.
safe
},
{
eth
.
Finalized
,
stub
.
finalized
},
}
for
_
,
test
:=
range
tests
{
t
.
Run
(
string
(
test
.
name
),
func
(
t
*
testing
.
T
)
{
expected
,
err
:=
derive
.
L2BlockToBlockRef
(
test
.
block
,
&
engine
.
rollupCfg
.
Genesis
)
require
.
NoError
(
t
,
err
)
blockRef
,
err
:=
engine
.
L2BlockRefByLabel
(
ctx
,
test
.
name
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
expected
,
blockRef
)
})
}
t
.
Run
(
"UnknownLabel"
,
func
(
t
*
testing
.
T
)
{
_
,
err
:=
engine
.
L2BlockRefByLabel
(
ctx
,
"nope"
)
require
.
ErrorContains
(
t
,
err
,
"unknown label"
)
})
}
func
TestL2BlockRefByHash
(
t
*
testing
.
T
)
{
ctx
:=
context
.
Background
()
engine
,
stub
:=
createOracleEngine
(
t
)
t
.
Run
(
"KnownBlock"
,
func
(
t
*
testing
.
T
)
{
expected
,
err
:=
derive
.
L2BlockToBlockRef
(
stub
.
safe
,
&
engine
.
rollupCfg
.
Genesis
)
require
.
NoError
(
t
,
err
)
ref
,
err
:=
engine
.
L2BlockRefByHash
(
ctx
,
stub
.
safe
.
Hash
())
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
expected
,
ref
)
})
t
.
Run
(
"UnknownBlock"
,
func
(
t
*
testing
.
T
)
{
ref
,
err
:=
engine
.
L2BlockRefByHash
(
ctx
,
common
.
HexToHash
(
"0x878899"
))
require
.
ErrorIs
(
t
,
err
,
ErrNotFound
)
require
.
Equal
(
t
,
eth
.
L2BlockRef
{},
ref
)
})
}
func
TestSystemConfigByL2Hash
(
t
*
testing
.
T
)
{
ctx
:=
context
.
Background
()
engine
,
stub
:=
createOracleEngine
(
t
)
t
.
Run
(
"KnownBlock"
,
func
(
t
*
testing
.
T
)
{
payload
,
err
:=
eth
.
BlockAsPayload
(
stub
.
safe
)
require
.
NoError
(
t
,
err
)
expected
,
err
:=
derive
.
PayloadToSystemConfig
(
payload
,
engine
.
rollupCfg
)
require
.
NoError
(
t
,
err
)
cfg
,
err
:=
engine
.
SystemConfigByL2Hash
(
ctx
,
stub
.
safe
.
Hash
())
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
expected
,
cfg
)
})
t
.
Run
(
"UnknownBlock"
,
func
(
t
*
testing
.
T
)
{
ref
,
err
:=
engine
.
SystemConfigByL2Hash
(
ctx
,
common
.
HexToHash
(
"0x878899"
))
require
.
ErrorIs
(
t
,
err
,
ErrNotFound
)
require
.
Equal
(
t
,
eth
.
SystemConfig
{},
ref
)
})
}
func
createOracleEngine
(
t
*
testing
.
T
)
(
*
OracleEngine
,
*
stubEngineBackend
)
{
head
:=
createL2Block
(
t
,
4
)
safe
:=
createL2Block
(
t
,
3
)
finalized
:=
createL2Block
(
t
,
2
)
backend
:=
&
stubEngineBackend
{
head
:
head
,
safe
:
safe
,
finalized
:
finalized
,
blocks
:
map
[
common
.
Hash
]
*
types
.
Block
{
head
.
Hash
()
:
head
,
safe
.
Hash
()
:
safe
,
finalized
.
Hash
()
:
finalized
,
},
canonical
:
map
[
uint64
]
common
.
Hash
{
head
.
NumberU64
()
:
head
.
Hash
(),
safe
.
NumberU64
()
:
safe
.
Hash
(),
finalized
.
NumberU64
()
:
finalized
.
Hash
(),
},
}
engine
:=
OracleEngine
{
backend
:
backend
,
rollupCfg
:
&
chaincfg
.
Goerli
,
}
return
&
engine
,
backend
}
func
createL2Block
(
t
*
testing
.
T
,
number
int
)
*
types
.
Block
{
tx
,
err
:=
derive
.
L1InfoDeposit
(
uint64
(
1
),
eth
.
HeaderBlockInfo
(
&
types
.
Header
{
Number
:
big
.
NewInt
(
32
),
BaseFee
:
big
.
NewInt
(
7
),
}),
eth
.
SystemConfig
{},
true
)
require
.
NoError
(
t
,
err
)
header
:=
&
types
.
Header
{
Number
:
big
.
NewInt
(
int64
(
number
)),
BaseFee
:
big
.
NewInt
(
7
),
}
return
types
.
NewBlock
(
header
,
[]
*
types
.
Transaction
{
types
.
NewTx
(
tx
)},
nil
,
nil
,
trie
.
NewStackTrie
(
nil
))
}
type
stubEngineBackend
struct
{
head
*
types
.
Block
safe
*
types
.
Block
finalized
*
types
.
Block
blocks
map
[
common
.
Hash
]
*
types
.
Block
canonical
map
[
uint64
]
common
.
Hash
}
func
(
s
stubEngineBackend
)
CurrentHeader
()
*
types
.
Header
{
return
s
.
head
.
Header
()
}
func
(
s
stubEngineBackend
)
CurrentSafeBlock
()
*
types
.
Header
{
return
s
.
safe
.
Header
()
}
func
(
s
stubEngineBackend
)
CurrentFinalBlock
()
*
types
.
Header
{
return
s
.
finalized
.
Header
()
}
func
(
s
stubEngineBackend
)
GetBlockByHash
(
hash
common
.
Hash
)
*
types
.
Block
{
return
s
.
blocks
[
hash
]
}
func
(
s
stubEngineBackend
)
GetCanonicalHash
(
n
uint64
)
common
.
Hash
{
return
s
.
canonical
[
n
]
}
func
(
s
stubEngineBackend
)
GetBlock
(
hash
common
.
Hash
,
number
uint64
)
*
types
.
Block
{
panic
(
"unsupported"
)
}
func
(
s
stubEngineBackend
)
HasBlockAndState
(
hash
common
.
Hash
,
number
uint64
)
bool
{
panic
(
"unsupported"
)
}
func
(
s
stubEngineBackend
)
GetVMConfig
()
*
vm
.
Config
{
panic
(
"unsupported"
)
}
func
(
s
stubEngineBackend
)
Config
()
*
params
.
ChainConfig
{
panic
(
"unsupported"
)
}
func
(
s
stubEngineBackend
)
Engine
()
consensus
.
Engine
{
panic
(
"unsupported"
)
}
func
(
s
stubEngineBackend
)
StateAt
(
root
common
.
Hash
)
(
*
state
.
StateDB
,
error
)
{
panic
(
"unsupported"
)
}
func
(
s
stubEngineBackend
)
InsertBlockWithoutSetHead
(
block
*
types
.
Block
)
error
{
panic
(
"unsupported"
)
}
func
(
s
stubEngineBackend
)
SetCanonical
(
head
*
types
.
Block
)
(
common
.
Hash
,
error
)
{
panic
(
"unsupported"
)
}
func
(
s
stubEngineBackend
)
SetFinalized
(
header
*
types
.
Header
)
{
panic
(
"unsupported"
)
}
func
(
s
stubEngineBackend
)
SetSafe
(
header
*
types
.
Header
)
{
panic
(
"unsupported"
)
}
func
(
s
stubEngineBackend
)
GetHeader
(
hash
common
.
Hash
,
number
uint64
)
*
types
.
Header
{
panic
(
"unsupported"
)
}
func
(
s
stubEngineBackend
)
GetHeaderByNumber
(
number
uint64
)
*
types
.
Header
{
panic
(
"unsupported"
)
}
func
(
s
stubEngineBackend
)
GetHeaderByHash
(
hash
common
.
Hash
)
*
types
.
Header
{
panic
(
"unsupported"
)
}
func
(
s
stubEngineBackend
)
GetTd
(
hash
common
.
Hash
,
number
uint64
)
*
big
.
Int
{
panic
(
"unsupported"
)
}
op-program/l2/l2.go
0 → 100644
View file @
4cd95b84
package
l2
import
(
"context"
"encoding/json"
"fmt"
"os"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-program/config"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
)
func
NewFetchingEngine
(
ctx
context
.
Context
,
logger
log
.
Logger
,
cfg
*
config
.
Config
)
(
derive
.
Engine
,
error
)
{
genesis
,
err
:=
loadL2Genesis
(
cfg
)
if
err
!=
nil
{
return
nil
,
err
}
oracle
,
err
:=
NewFetchingL2Oracle
(
ctx
,
logger
,
cfg
.
L2URL
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"connect l2 oracle: %w"
,
err
)
}
engineBackend
,
err
:=
NewOracleBackedL2Chain
(
logger
,
oracle
,
genesis
,
cfg
.
L2Head
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"create l2 chain: %w"
,
err
)
}
return
NewOracleEngine
(
cfg
.
Rollup
,
logger
,
engineBackend
),
nil
}
func
loadL2Genesis
(
cfg
*
config
.
Config
)
(
*
params
.
ChainConfig
,
error
)
{
data
,
err
:=
os
.
ReadFile
(
cfg
.
L2GenesisPath
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"read l2 genesis file: %w"
,
err
)
}
var
genesis
core
.
Genesis
err
=
json
.
Unmarshal
(
data
,
&
genesis
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"parse l2 genesis file: %w"
,
err
)
}
return
genesis
.
Config
,
nil
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment