1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package flags
import (
"fmt"
"strings"
"github.com/urfave/cli/v2"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
service "github.com/ethereum-optimism/optimism/op-service"
openum "github.com/ethereum-optimism/optimism/op-service/enum"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum-optimism/optimism/op-service/sources"
)
const EnvVarPrefix = "OP_PROGRAM"
func prefixEnvVars(name string) []string {
return service.PrefixEnvVar(EnvVarPrefix, name)
}
var (
RollupConfig = &cli.StringFlag{
Name: "rollup.config",
Usage: "Rollup chain parameters",
EnvVars: prefixEnvVars("ROLLUP_CONFIG"),
}
Network = &cli.StringFlag{
Name: "network",
Usage: fmt.Sprintf("Predefined network selection. Available networks: %s", strings.Join(chaincfg.AvailableNetworks(), ", ")),
EnvVars: prefixEnvVars("NETWORK"),
}
DataDir = &cli.StringFlag{
Name: "datadir",
Usage: "Directory to use for preimage data storage. Default uses in-memory storage",
EnvVars: prefixEnvVars("DATADIR"),
}
L2NodeAddr = &cli.StringFlag{
Name: "l2",
Usage: "Address of L2 JSON-RPC endpoint to use (eth and debug namespace required)",
EnvVars: prefixEnvVars("L2_RPC"),
}
L1Head = &cli.StringFlag{
Name: "l1.head",
Usage: "Hash of the L1 head block. Derivation stops after this block is processed.",
EnvVars: prefixEnvVars("L1_HEAD"),
}
L2Head = &cli.StringFlag{
Name: "l2.head",
Usage: "Hash of the L2 block at l2.outputroot",
EnvVars: prefixEnvVars("L2_HEAD"),
}
L2OutputRoot = &cli.StringFlag{
Name: "l2.outputroot",
Usage: "Agreed L2 Output Root to start derivation from",
EnvVars: prefixEnvVars("L2_OUTPUT_ROOT"),
}
L2Claim = &cli.StringFlag{
Name: "l2.claim",
Usage: "Claimed L2 output root to validate",
EnvVars: prefixEnvVars("L2_CLAIM"),
}
L2BlockNumber = &cli.Uint64Flag{
Name: "l2.blocknumber",
Usage: "Number of the L2 block that the claim is from",
EnvVars: prefixEnvVars("L2_BLOCK_NUM"),
}
L2GenesisPath = &cli.StringFlag{
Name: "l2.genesis",
Usage: "Path to the op-geth genesis file",
EnvVars: prefixEnvVars("L2_GENESIS"),
}
L1NodeAddr = &cli.StringFlag{
Name: "l1",
Usage: "Address of L1 JSON-RPC endpoint to use (eth namespace required)",
EnvVars: prefixEnvVars("L1_RPC"),
}
L1TrustRPC = &cli.BoolFlag{
Name: "l1.trustrpc",
Usage: "Trust the L1 RPC, sync faster at risk of malicious/buggy RPC providing bad or inconsistent L1 data",
EnvVars: prefixEnvVars("L1_TRUST_RPC"),
}
L1RPCProviderKind = &cli.GenericFlag{
Name: "l1.rpckind",
Usage: "The kind of RPC provider, used to inform optimal transactions receipts fetching, and thus reduce costs. Valid options: " +
openum.EnumString(sources.RPCProviderKinds),
EnvVars: prefixEnvVars("L1_RPC_KIND"),
Value: func() *sources.RPCProviderKind {
out := sources.RPCKindStandard
return &out
}(),
}
Exec = &cli.StringFlag{
Name: "exec",
Usage: "Run the specified client program as a separate process detached from the host. Default is to run the client program in the host process.",
EnvVars: prefixEnvVars("EXEC"),
}
Server = &cli.BoolFlag{
Name: "server",
Usage: "Run in pre-image server mode without executing any client program.",
EnvVars: prefixEnvVars("SERVER"),
}
)
// Flags contains the list of configuration options available to the binary.
var Flags []cli.Flag
var requiredFlags = []cli.Flag{
L1Head,
L2Head,
L2OutputRoot,
L2Claim,
L2BlockNumber,
}
var programFlags = []cli.Flag{
RollupConfig,
Network,
DataDir,
L2NodeAddr,
L2GenesisPath,
L1NodeAddr,
L1TrustRPC,
L1RPCProviderKind,
Exec,
Server,
}
func init() {
Flags = append(Flags, oplog.CLIFlags(EnvVarPrefix)...)
Flags = append(Flags, requiredFlags...)
Flags = append(Flags, programFlags...)
}
func CheckRequired(ctx *cli.Context) error {
rollupConfig := ctx.String(RollupConfig.Name)
network := ctx.String(Network.Name)
if rollupConfig == "" && network == "" {
return fmt.Errorf("flag %s or %s is required", RollupConfig.Name, Network.Name)
}
if rollupConfig != "" && network != "" {
return fmt.Errorf("cannot specify both %s and %s", RollupConfig.Name, Network.Name)
}
if network == "" && ctx.String(L2GenesisPath.Name) == "" {
return fmt.Errorf("flag %s is required for custom networks", L2GenesisPath.Name)
}
for _, flag := range requiredFlags {
if !ctx.IsSet(flag.Names()[0]) {
return fmt.Errorf("flag %s is required", flag.Names()[0])
}
}
return nil
}