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
a01d02c3
Unverified
Commit
a01d02c3
authored
Apr 19, 2023
by
Adrian Sutton
Committed by
GitHub
Apr 19, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5466 from ethereum-optimism/aj/fpp-disk-store
op-program: Support running in offline mode.
parents
1ce4fdf3
3dfc5701
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
88 additions
and
44 deletions
+88
-44
main.go
op-program/host/cmd/main.go
+56
-34
main_test.go
op-program/host/cmd/main_test.go
+6
-8
config.go
op-program/host/config/config.go
+6
-0
config_test.go
op-program/host/config/config_test.go
+14
-2
flags.go
op-program/host/flags/flags.go
+6
-0
No files found.
op-program/host/cmd/main.go
View file @
a01d02c3
...
...
@@ -21,6 +21,7 @@ import (
"github.com/ethereum-optimism/optimism/op-program/host/version"
"github.com/ethereum-optimism/optimism/op-program/preimage"
oplog
"github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/urfave/cli"
)
...
...
@@ -106,45 +107,66 @@ type L2Source struct {
// FaultProofProgram is the programmatic entry-point for the fault proof program
func
FaultProofProgram
(
logger
log
.
Logger
,
cfg
*
config
.
Config
)
error
{
cfg
.
Rollup
.
LogDescription
(
logger
,
chaincfg
.
L2ChainIDToNetworkName
)
if
!
cfg
.
FetchingEnabled
()
{
return
errors
.
New
(
"offline mode not supported"
)
if
err
:=
cfg
.
Check
();
err
!=
nil
{
return
fmt
.
Errorf
(
"invalid config: %w"
,
err
)
}
cfg
.
Rollup
.
LogDescription
(
logger
,
chaincfg
.
L2ChainIDToNetworkName
)
ctx
:=
context
.
Background
()
kv
:=
kvstore
.
NewMemKV
()
logger
.
Info
(
"Connecting to L1 node"
,
"l1"
,
cfg
.
L1URL
)
l1RPC
,
err
:=
client
.
NewRPC
(
ctx
,
logger
,
cfg
.
L1URL
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to setup L1 RPC: %w"
,
err
)
var
kv
kvstore
.
KV
if
cfg
.
DataDir
==
""
{
logger
.
Info
(
"Using in-memory storage"
)
kv
=
kvstore
.
NewMemKV
()
}
else
{
logger
.
Info
(
"Creating disk storage"
,
"datadir"
,
cfg
.
DataDir
)
if
err
:=
os
.
MkdirAll
(
cfg
.
DataDir
,
0755
);
err
!=
nil
{
return
fmt
.
Errorf
(
"creating datadir: %w"
,
err
)
}
kv
=
kvstore
.
NewDiskKV
(
cfg
.
DataDir
)
}
logger
.
Info
(
"Connecting to L2 node"
,
"l2"
,
cfg
.
L2URL
)
l2RPC
,
err
:=
client
.
NewRPC
(
ctx
,
logger
,
cfg
.
L2URL
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to setup L2 RPC: %w"
,
err
)
}
var
preimageOracle
preimage
.
OracleFn
var
hinter
preimage
.
HinterFn
if
cfg
.
FetchingEnabled
()
{
logger
.
Info
(
"Connecting to L1 node"
,
"l1"
,
cfg
.
L1URL
)
l1RPC
,
err
:=
client
.
NewRPC
(
ctx
,
logger
,
cfg
.
L1URL
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to setup L1 RPC: %w"
,
err
)
}
l1ClCfg
:=
sources
.
L1ClientDefaultConfig
(
cfg
.
Rollup
,
cfg
.
L1TrustRPC
,
cfg
.
L1RPCKind
)
l2ClCfg
:=
sources
.
L2ClientDefaultConfig
(
cfg
.
Rollup
,
true
)
l1Cl
,
err
:=
sources
.
NewL1Client
(
l1RPC
,
logger
,
nil
,
l1ClCfg
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create L1 client: %w"
,
err
)
}
l2Cl
,
err
:=
sources
.
NewL2Client
(
l2RPC
,
logger
,
nil
,
l2ClCfg
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create L2 client: %w"
,
err
)
}
l2DebugCl
:=
&
L2Source
{
L2Client
:
l2Cl
,
DebugClient
:
sources
.
NewDebugClient
(
l2RPC
.
CallContext
)}
logger
.
Info
(
"Connecting to L2 node"
,
"l2"
,
cfg
.
L2URL
)
l2RPC
,
err
:=
client
.
NewRPC
(
ctx
,
logger
,
cfg
.
L2URL
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to setup L2 RPC: %w"
,
err
)
}
logger
.
Info
(
"Setting up pre-fetcher"
)
prefetch
:=
prefetcher
.
NewPrefetcher
(
l1Cl
,
l2DebugCl
,
kv
)
preimageOracle
:=
asOracleFn
(
ctx
,
prefetch
)
hinter
:=
asHinter
(
prefetch
)
l1ClCfg
:=
sources
.
L1ClientDefaultConfig
(
cfg
.
Rollup
,
cfg
.
L1TrustRPC
,
cfg
.
L1RPCKind
)
l2ClCfg
:=
sources
.
L2ClientDefaultConfig
(
cfg
.
Rollup
,
true
)
l1Cl
,
err
:=
sources
.
NewL1Client
(
l1RPC
,
logger
,
nil
,
l1ClCfg
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create L1 client: %w"
,
err
)
}
l2Cl
,
err
:=
sources
.
NewL2Client
(
l2RPC
,
logger
,
nil
,
l2ClCfg
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create L2 client: %w"
,
err
)
}
l2DebugCl
:=
&
L2Source
{
L2Client
:
l2Cl
,
DebugClient
:
sources
.
NewDebugClient
(
l2RPC
.
CallContext
)}
logger
.
Info
(
"Setting up pre-fetcher"
)
prefetch
:=
prefetcher
.
NewPrefetcher
(
l1Cl
,
l2DebugCl
,
kv
)
preimageOracle
=
asOracleFn
(
func
(
key
common
.
Hash
)
([]
byte
,
error
)
{
return
prefetch
.
GetPreimage
(
ctx
,
key
)
})
hinter
=
asHinter
(
prefetch
.
Hint
)
}
else
{
logger
.
Info
(
"Using offline mode. All required pre-images must be pre-populated."
)
preimageOracle
=
asOracleFn
(
kv
.
Get
)
hinter
=
func
(
v
preimage
.
Hint
)
{
logger
.
Debug
(
"ignoring prefetch hint"
,
"hint"
,
v
)
}
}
l1Source
:=
l1
.
NewSource
(
logger
,
preimageOracle
,
hinter
,
cfg
.
L1Head
)
logger
.
Info
(
"Connecting to L2 node"
,
"l2"
,
cfg
.
L2URL
)
l2Source
,
err
:=
l2
.
NewEngine
(
logger
,
preimageOracle
,
hinter
,
cfg
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"connect l2 oracle: %w"
,
err
)
...
...
@@ -166,9 +188,9 @@ func FaultProofProgram(logger log.Logger, cfg *config.Config) error {
return
nil
}
func
asOracleFn
(
ctx
context
.
Context
,
prefetcher
*
prefetcher
.
Prefetcher
)
preimage
.
OracleFn
{
func
asOracleFn
(
getter
func
(
key
common
.
Hash
)
([]
byte
,
error
)
)
preimage
.
OracleFn
{
return
func
(
key
preimage
.
Key
)
[]
byte
{
pre
,
err
:=
prefetcher
.
GetPreimage
(
ctx
,
key
.
PreimageKey
())
pre
,
err
:=
getter
(
key
.
PreimageKey
())
if
err
!=
nil
{
panic
(
fmt
.
Errorf
(
"preimage unavailable for key %v: %w"
,
key
,
err
))
}
...
...
@@ -176,9 +198,9 @@ func asOracleFn(ctx context.Context, prefetcher *prefetcher.Prefetcher) preimage
}
}
func
asHinter
(
prefetcher
*
prefetcher
.
Prefetche
r
)
preimage
.
HinterFn
{
func
asHinter
(
hint
func
(
hint
string
)
erro
r
)
preimage
.
HinterFn
{
return
func
(
v
preimage
.
Hint
)
{
err
:=
prefetcher
.
H
int
(
v
.
Hint
())
err
:=
h
int
(
v
.
Hint
())
if
err
!=
nil
{
panic
(
fmt
.
Errorf
(
"hint rejected %v: %w"
,
v
,
err
))
}
...
...
op-program/host/cmd/main_test.go
View file @
a01d02c3
...
...
@@ -79,6 +79,12 @@ func TestNetwork(t *testing.T) {
}
}
func
TestDataDir
(
t
*
testing
.
T
)
{
expected
:=
"/tmp/mainTestDataDir"
cfg
:=
configForArgs
(
t
,
addRequiredArgs
(
"--datadir"
,
expected
))
require
.
Equal
(
t
,
expected
,
cfg
.
DataDir
)
}
func
TestL2
(
t
*
testing
.
T
)
{
expected
:=
"https://example.com:8545"
cfg
:=
configForArgs
(
t
,
addRequiredArgs
(
"--l2"
,
expected
))
...
...
@@ -170,14 +176,6 @@ func TestL1RPCKind(t *testing.T) {
})
}
// Offline support will be added later, but for now it just bails out with an error
func
TestOfflineModeNotSupported
(
t
*
testing
.
T
)
{
logger
:=
log
.
New
()
cfg
:=
config
.
NewConfig
(
&
chaincfg
.
Goerli
,
"genesis.json"
,
common
.
HexToHash
(
l1HeadValue
),
common
.
HexToHash
(
l2HeadValue
),
common
.
HexToHash
(
l2ClaimValue
))
err
:=
FaultProofProgram
(
logger
,
cfg
)
require
.
ErrorContains
(
t
,
err
,
"offline mode not supported"
)
}
func
TestL2Claim
(
t
*
testing
.
T
)
{
t
.
Run
(
"Required"
,
func
(
t
*
testing
.
T
)
{
verifyArgsInvalid
(
t
,
"flag l2.claim is required"
,
addRequiredArgsExcept
(
"--l2.claim"
))
...
...
op-program/host/config/config.go
View file @
a01d02c3
...
...
@@ -18,10 +18,12 @@ var (
ErrInvalidL2Head
=
errors
.
New
(
"invalid l2 head"
)
ErrL1AndL2Inconsistent
=
errors
.
New
(
"l1 and l2 options must be specified together or both omitted"
)
ErrInvalidL2Claim
=
errors
.
New
(
"invalid l2 claim"
)
ErrDataDirRequired
=
errors
.
New
(
"datadir must be specified when in non-fetching mode"
)
)
type
Config
struct
{
Rollup
*
rollup
.
Config
DataDir
string
L2URL
string
L2GenesisPath
string
L1Head
common
.
Hash
...
...
@@ -54,6 +56,9 @@ func (c *Config) Check() error {
if
(
c
.
L1URL
!=
""
)
!=
(
c
.
L2URL
!=
""
)
{
return
ErrL1AndL2Inconsistent
}
if
!
c
.
FetchingEnabled
()
&&
c
.
DataDir
==
""
{
return
ErrDataDirRequired
}
return
nil
}
...
...
@@ -95,6 +100,7 @@ func NewConfigFromCLI(ctx *cli.Context) (*Config, error) {
}
return
&
Config
{
Rollup
:
rollupCfg
,
DataDir
:
ctx
.
GlobalString
(
flags
.
DataDir
.
Name
),
L2URL
:
ctx
.
GlobalString
(
flags
.
L2NodeAddr
.
Name
),
L2GenesisPath
:
ctx
.
GlobalString
(
flags
.
L2GenesisPath
.
Name
),
L2Head
:
l2Head
,
...
...
op-program/host/config/config_test.go
View file @
a01d02c3
...
...
@@ -15,7 +15,8 @@ var validL1Head = common.Hash{0xaa}
var
validL2Head
=
common
.
Hash
{
0xbb
}
var
validL2Claim
=
common
.
Hash
{
0xcc
}
func
TestDefaultConfigIsValid
(
t
*
testing
.
T
)
{
// TestValidConfigIsValid checks that the config provided by validConfig is actually valid
func
TestValidConfigIsValid
(
t
*
testing
.
T
)
{
err
:=
validConfig
()
.
Check
()
require
.
NoError
(
t
,
err
)
}
...
...
@@ -121,6 +122,17 @@ func TestFetchingEnabled(t *testing.T) {
})
}
func
TestRequireDataDirInNonFetchingMode
(
t
*
testing
.
T
)
{
cfg
:=
validConfig
()
cfg
.
DataDir
=
""
cfg
.
L1URL
=
""
cfg
.
L2URL
=
""
err
:=
cfg
.
Check
()
require
.
ErrorIs
(
t
,
err
,
ErrDataDirRequired
)
}
func
validConfig
()
*
Config
{
return
NewConfig
(
validRollupConfig
,
validL2GenesisPath
,
validL1Head
,
validL2Head
,
validL2Claim
)
cfg
:=
NewConfig
(
validRollupConfig
,
validL2GenesisPath
,
validL1Head
,
validL2Head
,
validL2Claim
)
cfg
.
DataDir
=
"/tmp/configTest"
return
cfg
}
op-program/host/flags/flags.go
View file @
a01d02c3
...
...
@@ -26,6 +26,11 @@ var (
Usage
:
fmt
.
Sprintf
(
"Predefined network selection. Available networks: %s"
,
strings
.
Join
(
chaincfg
.
AvailableNetworks
(),
", "
)),
EnvVar
:
service
.
PrefixEnvVar
(
envVarPrefix
,
"NETWORK"
),
}
DataDir
=
cli
.
StringFlag
{
Name
:
"datadir"
,
Usage
:
"Directory to use for preimage data storage. Default uses in-memory storage"
,
EnvVar
:
service
.
PrefixEnvVar
(
envVarPrefix
,
"DATADIR"
),
}
L2NodeAddr
=
cli
.
StringFlag
{
Name
:
"l2"
,
Usage
:
"Address of L2 JSON-RPC endpoint to use (eth and debug namespace required)"
,
...
...
@@ -85,6 +90,7 @@ var requiredFlags = []cli.Flag{
var
programFlags
=
[]
cli
.
Flag
{
RollupConfig
,
Network
,
DataDir
,
L2NodeAddr
,
L1NodeAddr
,
L1TrustRPC
,
...
...
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