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
8053be9d
Unverified
Commit
8053be9d
authored
May 04, 2023
by
OptimismBot
Committed by
GitHub
May 04, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5617 from ethereum-optimism/pops/main/challenger
feat(pops): Main Challenger Binary Logic
parents
351a53e8
a4689784
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
305 additions
and
4 deletions
+305
-4
challenger.go
op-challenger/challenger/challenger.go
+245
-0
utils.go
op-challenger/challenger/utils.go
+49
-0
main.go
op-challenger/cmd/main.go
+11
-4
No files found.
op-challenger/challenger/challenger.go
0 → 100644
View file @
8053be9d
package
challenger
import
(
"context"
"fmt"
_
"net/http/pprof"
"os"
"os/signal"
"sync"
"syscall"
"time"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/urfave/cli"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-node/sources"
oplog
"github.com/ethereum-optimism/optimism/op-service/log"
oppprof
"github.com/ethereum-optimism/optimism/op-service/pprof"
oprpc
"github.com/ethereum-optimism/optimism/op-service/rpc"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
)
// Main is the entrypoint into the Challenger. This method executes the
// service and blocks until the service exits.
func
Main
(
version
string
,
cliCtx
*
cli
.
Context
)
error
{
cfg
:=
NewConfig
(
cliCtx
)
if
err
:=
cfg
.
Check
();
err
!=
nil
{
return
fmt
.
Errorf
(
"invalid CLI flags: %w"
,
err
)
}
l
:=
oplog
.
NewLogger
(
cfg
.
LogConfig
)
m
:=
metrics
.
NewMetrics
(
"default"
)
l
.
Info
(
"Initializing Challenger"
)
challengerConfig
,
err
:=
NewChallengerConfigFromCLIConfig
(
cfg
,
l
,
m
)
if
err
!=
nil
{
l
.
Error
(
"Unable to create the Challenger"
,
"error"
,
err
)
return
err
}
challenger
,
err
:=
NewChallenger
(
*
challengerConfig
,
l
,
m
)
if
err
!=
nil
{
l
.
Error
(
"Unable to create the Challenger"
,
"error"
,
err
)
return
err
}
l
.
Info
(
"Starting Challenger"
)
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
if
err
:=
challenger
.
Start
();
err
!=
nil
{
cancel
()
l
.
Error
(
"Unable to start Challenger"
,
"error"
,
err
)
return
err
}
defer
challenger
.
Stop
()
l
.
Info
(
"Challenger started"
)
pprofConfig
:=
cfg
.
PprofConfig
if
pprofConfig
.
Enabled
{
l
.
Info
(
"starting pprof"
,
"addr"
,
pprofConfig
.
ListenAddr
,
"port"
,
pprofConfig
.
ListenPort
)
go
func
()
{
if
err
:=
oppprof
.
ListenAndServe
(
ctx
,
pprofConfig
.
ListenAddr
,
pprofConfig
.
ListenPort
);
err
!=
nil
{
l
.
Error
(
"error starting pprof"
,
"err"
,
err
)
}
}()
}
metricsCfg
:=
cfg
.
MetricsConfig
if
metricsCfg
.
Enabled
{
l
.
Info
(
"starting metrics server"
,
"addr"
,
metricsCfg
.
ListenAddr
,
"port"
,
metricsCfg
.
ListenPort
)
go
func
()
{
if
err
:=
m
.
Serve
(
ctx
,
metricsCfg
.
ListenAddr
,
metricsCfg
.
ListenPort
);
err
!=
nil
{
l
.
Error
(
"error starting metrics server"
,
err
)
}
}()
m
.
StartBalanceMetrics
(
ctx
,
l
,
challengerConfig
.
L1Client
,
challengerConfig
.
TxManager
.
From
())
}
rpcCfg
:=
cfg
.
RPCConfig
server
:=
oprpc
.
NewServer
(
rpcCfg
.
ListenAddr
,
rpcCfg
.
ListenPort
,
version
,
oprpc
.
WithLogger
(
l
))
if
err
:=
server
.
Start
();
err
!=
nil
{
cancel
()
return
fmt
.
Errorf
(
"error starting RPC server: %w"
,
err
)
}
m
.
RecordInfo
(
version
)
m
.
RecordUp
()
interruptChannel
:=
make
(
chan
os
.
Signal
,
1
)
signal
.
Notify
(
interruptChannel
,
[]
os
.
Signal
{
os
.
Interrupt
,
os
.
Kill
,
syscall
.
SIGTERM
,
syscall
.
SIGQUIT
,
}
...
)
<-
interruptChannel
cancel
()
return
nil
}
// challenger contests invalid L2OutputOracle outputs
type
Challenger
struct
{
txMgr
txmgr
.
TxManager
wg
sync
.
WaitGroup
done
chan
struct
{}
log
log
.
Logger
metr
metrics
.
Metricer
ctx
context
.
Context
cancel
context
.
CancelFunc
l1Client
*
ethclient
.
Client
rollupClient
*
sources
.
RollupClient
// l2 Output Oracle contract
l2ooContract
*
bindings
.
L2OutputOracleCaller
l2ooContractAddr
common
.
Address
l2ooABI
*
abi
.
ABI
// dispute game factory contract
// TODO(@refcell): add a binding for this contract
// dgfContract *bindings.DisputeGameFactoryCaller
dgfContractAddr
common
.
Address
// dgfABI *abi.ABI
networkTimeout
time
.
Duration
}
// NewChallengerFromCLIConfig creates a new challenger given the CLI Config
func
NewChallengerFromCLIConfig
(
cfg
CLIConfig
,
l
log
.
Logger
,
m
metrics
.
Metricer
)
(
*
Challenger
,
error
)
{
challengerConfig
,
err
:=
NewChallengerConfigFromCLIConfig
(
cfg
,
l
,
m
)
if
err
!=
nil
{
return
nil
,
err
}
return
NewChallenger
(
*
challengerConfig
,
l
,
m
)
}
// NewChallengerConfigFromCLIConfig creates the challenger config from the CLI config.
func
NewChallengerConfigFromCLIConfig
(
cfg
CLIConfig
,
l
log
.
Logger
,
m
metrics
.
Metricer
)
(
*
Config
,
error
)
{
l2ooAddress
,
err
:=
parseAddress
(
cfg
.
L2OOAddress
)
if
err
!=
nil
{
return
nil
,
err
}
dgfAddress
,
err
:=
parseAddress
(
cfg
.
DGFAddress
)
if
err
!=
nil
{
return
nil
,
err
}
txManager
,
err
:=
txmgr
.
NewSimpleTxManager
(
"challenger"
,
l
,
m
,
cfg
.
TxMgrConfig
)
if
err
!=
nil
{
return
nil
,
err
}
// Connect to L1 and L2 providers. Perform these last since they are the most expensive.
ctx
:=
context
.
Background
()
l1Client
,
err
:=
dialEthClientWithTimeout
(
ctx
,
cfg
.
L1EthRpc
)
if
err
!=
nil
{
return
nil
,
err
}
rollupClient
,
err
:=
dialRollupClientWithTimeout
(
ctx
,
cfg
.
RollupRpc
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
Config
{
L2OutputOracleAddr
:
l2ooAddress
,
DisputeGameFactory
:
dgfAddress
,
NetworkTimeout
:
cfg
.
TxMgrConfig
.
NetworkTimeout
,
L1Client
:
l1Client
,
RollupClient
:
rollupClient
,
TxManager
:
txManager
,
},
nil
}
// NewChallenger creates a new Challenger
func
NewChallenger
(
cfg
Config
,
l
log
.
Logger
,
m
metrics
.
Metricer
)
(
*
Challenger
,
error
)
{
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
l2ooContract
,
err
:=
bindings
.
NewL2OutputOracleCaller
(
cfg
.
L2OutputOracleAddr
,
cfg
.
L1Client
)
if
err
!=
nil
{
cancel
()
return
nil
,
err
}
cCtx
,
cCancel
:=
context
.
WithTimeout
(
ctx
,
cfg
.
NetworkTimeout
)
defer
cCancel
()
version
,
err
:=
l2ooContract
.
Version
(
&
bind
.
CallOpts
{
Context
:
cCtx
})
if
err
!=
nil
{
cancel
()
return
nil
,
err
}
log
.
Info
(
"Connected to L2OutputOracle"
,
"address"
,
cfg
.
L2OutputOracleAddr
,
"version"
,
version
)
parsed
,
err
:=
bindings
.
L2OutputOracleMetaData
.
GetAbi
()
if
err
!=
nil
{
cancel
()
return
nil
,
err
}
return
&
Challenger
{
txMgr
:
cfg
.
TxManager
,
done
:
make
(
chan
struct
{}),
log
:
l
,
metr
:
m
,
ctx
:
ctx
,
cancel
:
cancel
,
rollupClient
:
cfg
.
RollupClient
,
l1Client
:
cfg
.
L1Client
,
l2ooContract
:
l2ooContract
,
l2ooContractAddr
:
cfg
.
L2OutputOracleAddr
,
l2ooABI
:
parsed
,
dgfContractAddr
:
cfg
.
DisputeGameFactory
,
networkTimeout
:
cfg
.
NetworkTimeout
,
},
nil
}
// Start runs the challenger in a goroutine.
func
(
c
*
Challenger
)
Start
()
error
{
c
.
log
.
Error
(
"challenger not implemented."
)
return
nil
}
// Stop closes the challenger and waits for spawned goroutines to exit.
func
(
c
*
Challenger
)
Stop
()
{
c
.
cancel
()
close
(
c
.
done
)
c
.
wg
.
Wait
()
}
op-challenger/challenger/utils.go
0 → 100644
View file @
8053be9d
package
challenger
import
(
"context"
"fmt"
"time"
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/rpc"
)
var
defaultDialTimeout
=
5
*
time
.
Second
// dialEthClientWithTimeout attempts to dial the L1 provider using the provided
// URL. If the dial doesn't complete within defaultDialTimeout seconds, this
// method will return an error.
func
dialEthClientWithTimeout
(
ctx
context
.
Context
,
url
string
)
(
*
ethclient
.
Client
,
error
)
{
ctxt
,
cancel
:=
context
.
WithTimeout
(
ctx
,
defaultDialTimeout
)
defer
cancel
()
return
ethclient
.
DialContext
(
ctxt
,
url
)
}
// dialRollupClientWithTimeout attempts to dial the RPC provider using the provided
// URL. If the dial doesn't complete within defaultDialTimeout seconds, this
// method will return an error.
func
dialRollupClientWithTimeout
(
ctx
context
.
Context
,
url
string
)
(
*
sources
.
RollupClient
,
error
)
{
ctxt
,
cancel
:=
context
.
WithTimeout
(
ctx
,
defaultDialTimeout
)
defer
cancel
()
rpcCl
,
err
:=
rpc
.
DialContext
(
ctxt
,
url
)
if
err
!=
nil
{
return
nil
,
err
}
return
sources
.
NewRollupClient
(
client
.
NewBaseRPCClient
(
rpcCl
)),
nil
}
// parseAddress parses an ETH address from a hex string. This method will fail if
// the address is not a valid hexadecimal address.
func
parseAddress
(
address
string
)
(
common
.
Address
,
error
)
{
if
common
.
IsHexAddress
(
address
)
{
return
common
.
HexToAddress
(
address
),
nil
}
return
common
.
Address
{},
fmt
.
Errorf
(
"invalid address: %v"
,
address
)
}
op-challenger/cmd/main.go
View file @
8053be9d
...
...
@@ -3,6 +3,7 @@ package main
import
(
"os"
challenger
"github.com/ethereum-optimism/optimism/op-challenger/challenger"
flags
"github.com/ethereum-optimism/optimism/op-challenger/flags"
log
"github.com/ethereum/go-ethereum/log"
...
...
@@ -22,13 +23,19 @@ func main() {
app
.
Name
=
"op-challenger"
app
.
Usage
=
"Challenge invalid L2OutputOracle outputs"
app
.
Description
=
"A modular op-stack challenge agent for dispute games written in golang."
app
.
Action
=
curryMain
(
Version
)
app
.
Commands
=
[]
cli
.
Command
{}
app
.
Action
=
func
(
ctx
*
cli
.
Context
)
error
{
log
.
Debug
(
"Challenger not implemented..."
)
return
nil
}
err
:=
app
.
Run
(
os
.
Args
)
if
err
!=
nil
{
log
.
Crit
(
"Application failed"
,
"message"
,
err
)
}
}
// curryMain transforms the challenger.Main function into an app.Action
// This is done to capture the Version of the challenger.
func
curryMain
(
version
string
)
func
(
ctx
*
cli
.
Context
)
error
{
return
func
(
ctx
*
cli
.
Context
)
error
{
return
challenger
.
Main
(
version
,
ctx
)
}
}
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