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
9cd1d8b6
Commit
9cd1d8b6
authored
Aug 09, 2023
by
Andreas Bigger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fetch the game depth from the onchain fault dispute game contract
parent
4fa47249
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
74 additions
and
45 deletions
+74
-45
main_test.go
op-challenger/cmd/main_test.go
+2
-16
config.go
op-challenger/config/config.go
+0
-3
config_test.go
op-challenger/config/config_test.go
+1
-2
executor_test.go
op-challenger/fault/cannon/executor_test.go
+1
-1
loader.go
op-challenger/fault/loader.go
+16
-0
loader_test.go
op-challenger/fault/loader_test.go
+37
-6
service.go
op-challenger/fault/service.go
+17
-10
flags.go
op-challenger/flags/flags.go
+0
-7
No files found.
op-challenger/cmd/main_test.go
View file @
9cd1d8b6
...
@@ -25,7 +25,6 @@ var (
...
@@ -25,7 +25,6 @@ var (
cannonL2
=
"http://example.com:9545"
cannonL2
=
"http://example.com:9545"
alphabetTrace
=
"abcdefghijz"
alphabetTrace
=
"abcdefghijz"
agreeWithProposedOutput
=
"true"
agreeWithProposedOutput
=
"true"
gameDepth
=
"4"
)
)
func
TestLogLevel
(
t
*
testing
.
T
)
{
func
TestLogLevel
(
t
*
testing
.
T
)
{
...
@@ -45,14 +44,14 @@ func TestLogLevel(t *testing.T) {
...
@@ -45,14 +44,14 @@ func TestLogLevel(t *testing.T) {
func
TestDefaultCLIOptionsMatchDefaultConfig
(
t
*
testing
.
T
)
{
func
TestDefaultCLIOptionsMatchDefaultConfig
(
t
*
testing
.
T
)
{
cfg
:=
configForArgs
(
t
,
addRequiredArgs
(
config
.
TraceTypeAlphabet
))
cfg
:=
configForArgs
(
t
,
addRequiredArgs
(
config
.
TraceTypeAlphabet
))
defaultCfg
:=
config
.
NewConfig
(
l1EthRpc
,
common
.
HexToAddress
(
gameAddressValue
),
config
.
TraceTypeAlphabet
,
true
,
4
)
defaultCfg
:=
config
.
NewConfig
(
l1EthRpc
,
common
.
HexToAddress
(
gameAddressValue
),
config
.
TraceTypeAlphabet
,
true
)
// Add in the extra CLI options required when using alphabet trace type
// Add in the extra CLI options required when using alphabet trace type
defaultCfg
.
AlphabetTrace
=
alphabetTrace
defaultCfg
.
AlphabetTrace
=
alphabetTrace
require
.
Equal
(
t
,
defaultCfg
,
cfg
)
require
.
Equal
(
t
,
defaultCfg
,
cfg
)
}
}
func
TestDefaultConfigIsValid
(
t
*
testing
.
T
)
{
func
TestDefaultConfigIsValid
(
t
*
testing
.
T
)
{
cfg
:=
config
.
NewConfig
(
l1EthRpc
,
common
.
HexToAddress
(
gameAddressValue
),
config
.
TraceTypeAlphabet
,
true
,
4
)
cfg
:=
config
.
NewConfig
(
l1EthRpc
,
common
.
HexToAddress
(
gameAddressValue
),
config
.
TraceTypeAlphabet
,
true
)
// Add in options that are required based on the specific trace type
// Add in options that are required based on the specific trace type
// To avoid needing to specify unused options, these aren't included in the params for NewConfig
// To avoid needing to specify unused options, these aren't included in the params for NewConfig
cfg
.
AlphabetTrace
=
alphabetTrace
cfg
.
AlphabetTrace
=
alphabetTrace
...
@@ -130,18 +129,6 @@ func TestAgreeWithProposedOutput(t *testing.T) {
...
@@ -130,18 +129,6 @@ func TestAgreeWithProposedOutput(t *testing.T) {
})
})
}
}
func
TestGameDepth
(
t
*
testing
.
T
)
{
t
.
Run
(
"Required"
,
func
(
t
*
testing
.
T
)
{
verifyArgsInvalid
(
t
,
"flag game-depth is required"
,
addRequiredArgsExcept
(
config
.
TraceTypeAlphabet
,
"--game-depth"
))
})
t
.
Run
(
"Valid"
,
func
(
t
*
testing
.
T
)
{
value
:=
"4"
cfg
:=
configForArgs
(
t
,
addRequiredArgsExcept
(
config
.
TraceTypeAlphabet
,
"--game-depth"
,
"--game-depth="
+
value
))
require
.
Equal
(
t
,
value
,
fmt
.
Sprint
(
cfg
.
GameDepth
))
})
}
func
TestCannonBin
(
t
*
testing
.
T
)
{
func
TestCannonBin
(
t
*
testing
.
T
)
{
t
.
Run
(
"NotRequiredForAlphabetTrace"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"NotRequiredForAlphabetTrace"
,
func
(
t
*
testing
.
T
)
{
configForArgs
(
t
,
addRequiredArgsExcept
(
config
.
TraceTypeAlphabet
,
"--cannon-bin"
))
configForArgs
(
t
,
addRequiredArgsExcept
(
config
.
TraceTypeAlphabet
,
"--cannon-bin"
))
...
@@ -327,7 +314,6 @@ func addRequiredArgsExcept(traceType config.TraceType, name string, optionalArgs
...
@@ -327,7 +314,6 @@ func addRequiredArgsExcept(traceType config.TraceType, name string, optionalArgs
func
requiredArgs
(
traceType
config
.
TraceType
)
map
[
string
]
string
{
func
requiredArgs
(
traceType
config
.
TraceType
)
map
[
string
]
string
{
args
:=
map
[
string
]
string
{
args
:=
map
[
string
]
string
{
"--game-depth"
:
gameDepth
,
"--agree-with-proposed-output"
:
agreeWithProposedOutput
,
"--agree-with-proposed-output"
:
agreeWithProposedOutput
,
"--l1-eth-rpc"
:
l1EthRpc
,
"--l1-eth-rpc"
:
l1EthRpc
,
"--game-address"
:
gameAddressValue
,
"--game-address"
:
gameAddressValue
,
...
...
op-challenger/config/config.go
View file @
9cd1d8b6
...
@@ -67,7 +67,6 @@ type Config struct {
...
@@ -67,7 +67,6 @@ type Config struct {
L1EthRpc
string
// L1 RPC Url
L1EthRpc
string
// L1 RPC Url
GameAddress
common
.
Address
// Address of the fault game
GameAddress
common
.
Address
// Address of the fault game
AgreeWithProposedOutput
bool
// Temporary config if we agree or disagree with the posted output
AgreeWithProposedOutput
bool
// Temporary config if we agree or disagree with the posted output
GameDepth
int
// Depth of the game tree
TraceType
TraceType
// Type of trace
TraceType
TraceType
// Type of trace
...
@@ -93,14 +92,12 @@ func NewConfig(
...
@@ -93,14 +92,12 @@ func NewConfig(
gameAddress
common
.
Address
,
gameAddress
common
.
Address
,
traceType
TraceType
,
traceType
TraceType
,
agreeWithProposedOutput
bool
,
agreeWithProposedOutput
bool
,
gameDepth
int
,
)
Config
{
)
Config
{
return
Config
{
return
Config
{
L1EthRpc
:
l1EthRpc
,
L1EthRpc
:
l1EthRpc
,
GameAddress
:
gameAddress
,
GameAddress
:
gameAddress
,
AgreeWithProposedOutput
:
agreeWithProposedOutput
,
AgreeWithProposedOutput
:
agreeWithProposedOutput
,
GameDepth
:
gameDepth
,
TraceType
:
traceType
,
TraceType
:
traceType
,
...
...
op-challenger/config/config_test.go
View file @
9cd1d8b6
...
@@ -19,11 +19,10 @@ var (
...
@@ -19,11 +19,10 @@ var (
validCannonDatadir
=
"/tmp/cannon"
validCannonDatadir
=
"/tmp/cannon"
validCannonL2
=
"http://localhost:9545"
validCannonL2
=
"http://localhost:9545"
agreeWithProposedOutput
=
true
agreeWithProposedOutput
=
true
gameDepth
=
4
)
)
func
validConfig
(
traceType
TraceType
)
Config
{
func
validConfig
(
traceType
TraceType
)
Config
{
cfg
:=
NewConfig
(
validL1EthRpc
,
validGameAddress
,
traceType
,
agreeWithProposedOutput
,
gameDepth
)
cfg
:=
NewConfig
(
validL1EthRpc
,
validGameAddress
,
traceType
,
agreeWithProposedOutput
)
switch
traceType
{
switch
traceType
{
case
TraceTypeAlphabet
:
case
TraceTypeAlphabet
:
cfg
.
AlphabetTrace
=
validAlphabetTrace
cfg
.
AlphabetTrace
=
validAlphabetTrace
...
...
op-challenger/fault/cannon/executor_test.go
View file @
9cd1d8b6
...
@@ -21,7 +21,7 @@ const execTestCannonPrestate = "/foo/pre.json"
...
@@ -21,7 +21,7 @@ const execTestCannonPrestate = "/foo/pre.json"
func
TestGenerateProof
(
t
*
testing
.
T
)
{
func
TestGenerateProof
(
t
*
testing
.
T
)
{
input
:=
"starting.json"
input
:=
"starting.json"
cfg
:=
config
.
NewConfig
(
"http://localhost:8888"
,
common
.
Address
{
0xaa
},
config
.
TraceTypeCannon
,
true
,
5
)
cfg
:=
config
.
NewConfig
(
"http://localhost:8888"
,
common
.
Address
{
0xaa
},
config
.
TraceTypeCannon
,
true
)
cfg
.
CannonDatadir
=
t
.
TempDir
()
cfg
.
CannonDatadir
=
t
.
TempDir
()
cfg
.
CannonAbsolutePreState
=
"pre.json"
cfg
.
CannonAbsolutePreState
=
"pre.json"
cfg
.
CannonBin
=
"./bin/cannon"
cfg
.
CannonBin
=
"./bin/cannon"
...
...
op-challenger/fault/loader.go
View file @
9cd1d8b6
...
@@ -19,11 +19,13 @@ type ClaimFetcher interface {
...
@@ -19,11 +19,13 @@ type ClaimFetcher interface {
Clock
*
big
.
Int
Clock
*
big
.
Int
},
error
)
},
error
)
ClaimDataLen
(
opts
*
bind
.
CallOpts
)
(
*
big
.
Int
,
error
)
ClaimDataLen
(
opts
*
bind
.
CallOpts
)
(
*
big
.
Int
,
error
)
MAXGAMEDEPTH
(
opts
*
bind
.
CallOpts
)
(
*
big
.
Int
,
error
)
}
}
// Loader is a minimal interface for loading onchain [Claim] data.
// Loader is a minimal interface for loading onchain [Claim] data.
type
Loader
interface
{
type
Loader
interface
{
FetchClaims
(
ctx
context
.
Context
)
([]
types
.
Claim
,
error
)
FetchClaims
(
ctx
context
.
Context
)
([]
types
.
Claim
,
error
)
FetchGameDepth
(
ctx
context
.
Context
)
(
uint64
,
error
)
}
}
// loader pulls in fault dispute game claim data periodically and over subscriptions.
// loader pulls in fault dispute game claim data periodically and over subscriptions.
...
@@ -38,6 +40,20 @@ func NewLoader(claimFetcher ClaimFetcher) *loader {
...
@@ -38,6 +40,20 @@ func NewLoader(claimFetcher ClaimFetcher) *loader {
}
}
}
}
// FetchGameDepth fetches the game depth from the fault dispute game.
func
(
l
*
loader
)
FetchGameDepth
(
ctx
context
.
Context
)
(
uint64
,
error
)
{
callOpts
:=
bind
.
CallOpts
{
Context
:
ctx
,
}
gameDepth
,
err
:=
l
.
claimFetcher
.
MAXGAMEDEPTH
(
&
callOpts
)
if
err
!=
nil
{
return
0
,
err
}
return
gameDepth
.
Uint64
(),
nil
}
// fetchClaim fetches a single [Claim] with a hydrated parent.
// fetchClaim fetches a single [Claim] with a hydrated parent.
func
(
l
*
loader
)
fetchClaim
(
ctx
context
.
Context
,
arrIndex
uint64
)
(
types
.
Claim
,
error
)
{
func
(
l
*
loader
)
fetchClaim
(
ctx
context
.
Context
,
arrIndex
uint64
)
(
types
.
Claim
,
error
)
{
callOpts
:=
bind
.
CallOpts
{
callOpts
:=
bind
.
CallOpts
{
...
...
op-challenger/fault/loader_test.go
View file @
9cd1d8b6
...
@@ -12,15 +12,18 @@ import (
...
@@ -12,15 +12,18 @@ import (
)
)
var
(
var
(
mockClaimDataError
=
fmt
.
Errorf
(
"claim data errored"
)
mockClaimDataError
=
fmt
.
Errorf
(
"claim data errored"
)
mockClaimLenError
=
fmt
.
Errorf
(
"claim len errored"
)
mockClaimLenError
=
fmt
.
Errorf
(
"claim len errored"
)
mockMaxGameDepthError
=
fmt
.
Errorf
(
"max game depth errored"
)
)
)
type
mockClaimFetcher
struct
{
type
mockClaimFetcher
struct
{
claimDataError
bool
claimDataError
bool
claimLenError
bool
claimLenError
bool
currentIndex
uint64
maxGameDepthError
bool
returnClaims
[]
struct
{
maxGameDepth
uint64
currentIndex
uint64
returnClaims
[]
struct
{
ParentIndex
uint32
ParentIndex
uint32
Countered
bool
Countered
bool
Claim
[
32
]
byte
Claim
[
32
]
byte
...
@@ -88,6 +91,34 @@ func (m *mockClaimFetcher) ClaimDataLen(opts *bind.CallOpts) (*big.Int, error) {
...
@@ -88,6 +91,34 @@ func (m *mockClaimFetcher) ClaimDataLen(opts *bind.CallOpts) (*big.Int, error) {
return
big
.
NewInt
(
int64
(
len
(
m
.
returnClaims
))),
nil
return
big
.
NewInt
(
int64
(
len
(
m
.
returnClaims
))),
nil
}
}
func
(
m
*
mockClaimFetcher
)
MAXGAMEDEPTH
(
opts
*
bind
.
CallOpts
)
(
*
big
.
Int
,
error
)
{
if
m
.
maxGameDepthError
{
return
nil
,
mockMaxGameDepthError
}
return
big
.
NewInt
(
int64
(
m
.
maxGameDepth
)),
nil
}
// TestLoader_FetchGameDepth tests [loader.FetchGameDepth].
func
TestLoader_FetchGameDepth
(
t
*
testing
.
T
)
{
t
.
Run
(
"Succeeds"
,
func
(
t
*
testing
.
T
)
{
mockClaimFetcher
:=
newMockClaimFetcher
()
mockClaimFetcher
.
maxGameDepth
=
10
loader
:=
NewLoader
(
mockClaimFetcher
)
depth
,
err
:=
loader
.
FetchGameDepth
(
context
.
Background
())
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
uint64
(
10
),
depth
)
})
t
.
Run
(
"Errors"
,
func
(
t
*
testing
.
T
)
{
mockClaimFetcher
:=
newMockClaimFetcher
()
mockClaimFetcher
.
maxGameDepthError
=
true
loader
:=
NewLoader
(
mockClaimFetcher
)
depth
,
err
:=
loader
.
FetchGameDepth
(
context
.
Background
())
require
.
ErrorIs
(
t
,
mockMaxGameDepthError
,
err
)
require
.
Equal
(
t
,
depth
,
uint64
(
0
))
})
}
// TestLoader_FetchClaims_Succeeds tests [loader.FetchClaims].
// TestLoader_FetchClaims_Succeeds tests [loader.FetchClaims].
func
TestLoader_FetchClaims_Succeeds
(
t
*
testing
.
T
)
{
func
TestLoader_FetchClaims_Succeeds
(
t
*
testing
.
T
)
{
mockClaimFetcher
:=
newMockClaimFetcher
()
mockClaimFetcher
:=
newMockClaimFetcher
()
...
...
op-challenger/fault/service.go
View file @
9cd1d8b6
...
@@ -41,6 +41,19 @@ func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*se
...
@@ -41,6 +41,19 @@ func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*se
return
nil
,
fmt
.
Errorf
(
"failed to dial L1: %w"
,
err
)
return
nil
,
fmt
.
Errorf
(
"failed to dial L1: %w"
,
err
)
}
}
contract
,
err
:=
bindings
.
NewFaultDisputeGameCaller
(
cfg
.
GameAddress
,
client
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to bind the fault dispute game contract: %w"
,
err
)
}
loader
:=
NewLoader
(
contract
)
gameDepth
,
err
:=
loader
.
FetchGameDepth
(
ctx
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to fetch the game depth: %w"
,
err
)
}
gameDepth
=
uint64
(
gameDepth
)
var
trace
types
.
TraceProvider
var
trace
types
.
TraceProvider
var
updater
types
.
OracleUpdater
var
updater
types
.
OracleUpdater
switch
cfg
.
TraceType
{
switch
cfg
.
TraceType
{
...
@@ -54,23 +67,17 @@ func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*se
...
@@ -54,23 +67,17 @@ func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*se
return
nil
,
fmt
.
Errorf
(
"failed to create the cannon updater: %w"
,
err
)
return
nil
,
fmt
.
Errorf
(
"failed to create the cannon updater: %w"
,
err
)
}
}
case
config
.
TraceTypeAlphabet
:
case
config
.
TraceTypeAlphabet
:
trace
=
alphabet
.
NewTraceProvider
(
cfg
.
AlphabetTrace
,
uint64
(
cfg
.
GameDepth
)
)
trace
=
alphabet
.
NewTraceProvider
(
cfg
.
AlphabetTrace
,
gameDepth
)
updater
=
alphabet
.
NewOracleUpdater
(
logger
)
updater
=
alphabet
.
NewOracleUpdater
(
logger
)
default
:
default
:
return
nil
,
fmt
.
Errorf
(
"unsupported trace type: %v"
,
cfg
.
TraceType
)
return
nil
,
fmt
.
Errorf
(
"unsupported trace type: %v"
,
cfg
.
TraceType
)
}
}
return
newTypedService
(
ctx
,
logger
,
cfg
,
client
,
trace
,
updater
,
txMgr
)
return
newTypedService
(
ctx
,
logger
,
cfg
,
loader
,
gameDepth
,
client
,
trace
,
updater
,
txMgr
)
}
}
// newTypedService creates a new Service from a provided trace provider.
// newTypedService creates a new Service from a provided trace provider.
func
newTypedService
(
ctx
context
.
Context
,
logger
log
.
Logger
,
cfg
*
config
.
Config
,
client
*
ethclient
.
Client
,
provider
types
.
TraceProvider
,
updater
types
.
OracleUpdater
,
txMgr
txmgr
.
TxManager
)
(
*
service
,
error
)
{
func
newTypedService
(
ctx
context
.
Context
,
logger
log
.
Logger
,
cfg
*
config
.
Config
,
loader
Loader
,
gameDepth
uint64
,
client
*
ethclient
.
Client
,
provider
types
.
TraceProvider
,
updater
types
.
OracleUpdater
,
txMgr
txmgr
.
TxManager
)
(
*
service
,
error
)
{
contract
,
err
:=
bindings
.
NewFaultDisputeGameCaller
(
cfg
.
GameAddress
,
client
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to bind the fault dispute game contract: %w"
,
err
)
}
loader
:=
NewLoader
(
contract
)
gameLogger
:=
logger
.
New
(
"game"
,
cfg
.
GameAddress
)
gameLogger
:=
logger
.
New
(
"game"
,
cfg
.
GameAddress
)
responder
,
err
:=
NewFaultResponder
(
gameLogger
,
txMgr
,
cfg
.
GameAddress
)
responder
,
err
:=
NewFaultResponder
(
gameLogger
,
txMgr
,
cfg
.
GameAddress
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -82,7 +89,7 @@ func newTypedService(ctx context.Context, logger log.Logger, cfg *config.Config,
...
@@ -82,7 +89,7 @@ func newTypedService(ctx context.Context, logger log.Logger, cfg *config.Config,
return
nil
,
fmt
.
Errorf
(
"failed to bind the fault contract: %w"
,
err
)
return
nil
,
fmt
.
Errorf
(
"failed to bind the fault contract: %w"
,
err
)
}
}
agent
:=
NewAgent
(
loader
,
cfg
.
GameDepth
,
provider
,
responder
,
updater
,
cfg
.
AgreeWithProposedOutput
,
gameLogger
)
agent
:=
NewAgent
(
loader
,
int
(
gameDepth
)
,
provider
,
responder
,
updater
,
cfg
.
AgreeWithProposedOutput
,
gameLogger
)
return
&
service
{
return
&
service
{
agent
:
agent
,
agent
:
agent
,
...
...
op-challenger/flags/flags.go
View file @
9cd1d8b6
...
@@ -48,11 +48,6 @@ var (
...
@@ -48,11 +48,6 @@ var (
Usage
:
"Temporary hardcoded flag if we agree or disagree with the proposed output."
,
Usage
:
"Temporary hardcoded flag if we agree or disagree with the proposed output."
,
EnvVars
:
prefixEnvVars
(
"AGREE_WITH_PROPOSED_OUTPUT"
),
EnvVars
:
prefixEnvVars
(
"AGREE_WITH_PROPOSED_OUTPUT"
),
}
}
GameDepthFlag
=
&
cli
.
IntFlag
{
Name
:
"game-depth"
,
Usage
:
"Depth of the game tree."
,
EnvVars
:
prefixEnvVars
(
"GAME_DEPTH"
),
}
// Optional Flags
// Optional Flags
AlphabetFlag
=
&
cli
.
StringFlag
{
AlphabetFlag
=
&
cli
.
StringFlag
{
Name
:
"alphabet"
,
Name
:
"alphabet"
,
...
@@ -113,7 +108,6 @@ var requiredFlags = []cli.Flag{
...
@@ -113,7 +108,6 @@ var requiredFlags = []cli.Flag{
DGFAddressFlag
,
DGFAddressFlag
,
TraceTypeFlag
,
TraceTypeFlag
,
AgreeWithProposedOutputFlag
,
AgreeWithProposedOutputFlag
,
GameDepthFlag
,
}
}
// optionalFlags is a list of unchecked cli flags
// optionalFlags is a list of unchecked cli flags
...
@@ -212,7 +206,6 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) {
...
@@ -212,7 +206,6 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) {
CannonL2
:
ctx
.
String
(
CannonL2Flag
.
Name
),
CannonL2
:
ctx
.
String
(
CannonL2Flag
.
Name
),
CannonSnapshotFreq
:
ctx
.
Uint
(
CannonSnapshotFreqFlag
.
Name
),
CannonSnapshotFreq
:
ctx
.
Uint
(
CannonSnapshotFreqFlag
.
Name
),
AgreeWithProposedOutput
:
ctx
.
Bool
(
AgreeWithProposedOutputFlag
.
Name
),
AgreeWithProposedOutput
:
ctx
.
Bool
(
AgreeWithProposedOutputFlag
.
Name
),
GameDepth
:
ctx
.
Int
(
GameDepthFlag
.
Name
),
TxMgrConfig
:
txMgrConfig
,
TxMgrConfig
:
txMgrConfig
,
},
nil
},
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