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
b0114bef
Unverified
Commit
b0114bef
authored
Oct 16, 2023
by
refcell.eth
Committed by
GitHub
Oct 16, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #7663 from ethereum-optimism/aj/game-registry
op-challenger: Introduce game registry
parents
ed176b37
7203324a
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
196 additions
and
63 deletions
+196
-63
player.go
op-challenger/game/fault/player.go
+6
-20
register.go
op-challenger/game/fault/register.go
+66
-0
registry.go
op-challenger/game/registry/registry.go
+41
-0
registry_test.go
op-challenger/game/registry/registry_test.go
+40
-0
coordinator_test.go
op-challenger/game/scheduler/coordinator_test.go
+8
-23
scheduler_test.go
op-challenger/game/scheduler/scheduler_test.go
+3
-2
stub_player.go
op-challenger/game/scheduler/test/stub_player.go
+24
-0
worker_test.go
op-challenger/game/scheduler/worker_test.go
+3
-14
service.go
op-challenger/game/service.go
+5
-4
No files found.
op-challenger/game/fault/player.go
View file @
b0114bef
...
...
@@ -8,8 +8,6 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/responder"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
gameTypes
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
...
...
@@ -34,6 +32,8 @@ type GamePlayer struct {
status
gameTypes
.
GameStatus
}
type
resourceCreator
func
(
addr
common
.
Address
,
gameDepth
uint64
,
dir
string
)
(
types
.
TraceProvider
,
types
.
OracleUpdater
,
error
)
func
NewGamePlayer
(
ctx
context
.
Context
,
logger
log
.
Logger
,
...
...
@@ -43,6 +43,7 @@ func NewGamePlayer(
addr
common
.
Address
,
txMgr
txmgr
.
TxManager
,
client
bind
.
ContractCaller
,
creator
resourceCreator
,
)
(
*
GamePlayer
,
error
)
{
logger
=
logger
.
New
(
"game"
,
addr
)
contract
,
err
:=
bindings
.
NewFaultDisputeGameCaller
(
addr
,
client
)
...
...
@@ -76,24 +77,9 @@ func NewGamePlayer(
return
nil
,
fmt
.
Errorf
(
"failed to fetch the game depth: %w"
,
err
)
}
var
provider
types
.
TraceProvider
var
updater
types
.
OracleUpdater
switch
cfg
.
TraceType
{
case
config
.
TraceTypeCannon
:
cannonProvider
,
err
:=
cannon
.
NewTraceProvider
(
ctx
,
logger
,
m
,
cfg
,
client
,
dir
,
addr
,
gameDepth
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"create cannon trace provider: %w"
,
err
)
}
provider
=
cannonProvider
updater
,
err
=
cannon
.
NewOracleUpdater
(
ctx
,
logger
,
txMgr
,
addr
,
client
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to create the cannon updater: %w"
,
err
)
}
case
config
.
TraceTypeAlphabet
:
provider
=
alphabet
.
NewTraceProvider
(
cfg
.
AlphabetTrace
,
gameDepth
)
updater
=
alphabet
.
NewOracleUpdater
(
logger
)
default
:
return
nil
,
fmt
.
Errorf
(
"unsupported trace type: %v"
,
cfg
.
TraceType
)
provider
,
updater
,
err
:=
creator
(
addr
,
gameDepth
,
dir
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to create trace provider: %w"
,
err
)
}
if
err
:=
ValidateAbsolutePrestate
(
ctx
,
provider
,
loader
);
err
!=
nil
{
...
...
op-challenger/game/fault/register.go
0 → 100644
View file @
b0114bef
package
fault
import
(
"context"
"fmt"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/alphabet"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon"
faultTypes
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-challenger/game/scheduler"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
)
var
(
cannonGameType
=
uint8
(
0
)
alphabetGameType
=
uint8
(
255
)
)
type
Registry
interface
{
RegisterGameType
(
gameType
uint8
,
creator
scheduler
.
PlayerCreator
)
}
func
RegisterGameTypes
(
registry
Registry
,
ctx
context
.
Context
,
logger
log
.
Logger
,
m
metrics
.
Metricer
,
cfg
*
config
.
Config
,
txMgr
txmgr
.
TxManager
,
client
bind
.
ContractCaller
,
)
{
switch
cfg
.
TraceType
{
case
config
.
TraceTypeCannon
:
resourceCreator
:=
func
(
addr
common
.
Address
,
gameDepth
uint64
,
dir
string
)
(
faultTypes
.
TraceProvider
,
faultTypes
.
OracleUpdater
,
error
)
{
provider
,
err
:=
cannon
.
NewTraceProvider
(
ctx
,
logger
,
m
,
cfg
,
client
,
dir
,
addr
,
gameDepth
)
if
err
!=
nil
{
return
nil
,
nil
,
fmt
.
Errorf
(
"create cannon trace provider: %w"
,
err
)
}
updater
,
err
:=
cannon
.
NewOracleUpdater
(
ctx
,
logger
,
txMgr
,
addr
,
client
)
if
err
!=
nil
{
return
nil
,
nil
,
fmt
.
Errorf
(
"failed to create the cannon updater: %w"
,
err
)
}
return
provider
,
updater
,
nil
}
playerCreator
:=
func
(
game
types
.
GameMetadata
,
dir
string
)
(
scheduler
.
GamePlayer
,
error
)
{
return
NewGamePlayer
(
ctx
,
logger
,
m
,
cfg
,
dir
,
game
.
Proxy
,
txMgr
,
client
,
resourceCreator
)
}
registry
.
RegisterGameType
(
cannonGameType
,
playerCreator
)
case
config
.
TraceTypeAlphabet
:
resourceCreator
:=
func
(
addr
common
.
Address
,
gameDepth
uint64
,
dir
string
)
(
faultTypes
.
TraceProvider
,
faultTypes
.
OracleUpdater
,
error
)
{
provider
:=
alphabet
.
NewTraceProvider
(
cfg
.
AlphabetTrace
,
gameDepth
)
updater
:=
alphabet
.
NewOracleUpdater
(
logger
)
return
provider
,
updater
,
nil
}
playerCreator
:=
func
(
game
types
.
GameMetadata
,
dir
string
)
(
scheduler
.
GamePlayer
,
error
)
{
return
NewGamePlayer
(
ctx
,
logger
,
m
,
cfg
,
dir
,
game
.
Proxy
,
txMgr
,
client
,
resourceCreator
)
}
registry
.
RegisterGameType
(
alphabetGameType
,
playerCreator
)
}
}
op-challenger/game/registry/registry.go
0 → 100644
View file @
b0114bef
package
registry
import
(
"errors"
"fmt"
"github.com/ethereum-optimism/optimism/op-challenger/game/scheduler"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
)
var
(
ErrUnsupportedGameType
=
errors
.
New
(
"unsupported game type"
)
)
type
GameTypeRegistry
struct
{
types
map
[
uint8
]
scheduler
.
PlayerCreator
}
func
NewGameTypeRegistry
()
*
GameTypeRegistry
{
return
&
GameTypeRegistry
{
types
:
make
(
map
[
uint8
]
scheduler
.
PlayerCreator
),
}
}
// RegisterGameType registers a scheduler.PlayerCreator to use for a specific game type.
// Panics if the same game type is registered multiple times, since this indicates a significant programmer error.
func
(
r
*
GameTypeRegistry
)
RegisterGameType
(
gameType
uint8
,
creator
scheduler
.
PlayerCreator
)
{
if
_
,
ok
:=
r
.
types
[
gameType
];
ok
{
panic
(
fmt
.
Errorf
(
"duplicate creator registered for game type: %v"
,
gameType
))
}
r
.
types
[
gameType
]
=
creator
}
// CreatePlayer creates a new game player for the given game, using the specified directory for persisting data.
func
(
r
*
GameTypeRegistry
)
CreatePlayer
(
game
types
.
GameMetadata
,
dir
string
)
(
scheduler
.
GamePlayer
,
error
)
{
creator
,
ok
:=
r
.
types
[
game
.
GameType
]
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"%w: %v"
,
ErrUnsupportedGameType
,
game
.
GameType
)
}
return
creator
(
game
,
dir
)
}
op-challenger/game/registry/registry_test.go
0 → 100644
View file @
b0114bef
package
registry
import
(
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/scheduler"
"github.com/ethereum-optimism/optimism/op-challenger/game/scheduler/test"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/stretchr/testify/require"
)
func
TestUnknownGameType
(
t
*
testing
.
T
)
{
registry
:=
NewGameTypeRegistry
()
player
,
err
:=
registry
.
CreatePlayer
(
types
.
GameMetadata
{
GameType
:
0
},
""
)
require
.
ErrorIs
(
t
,
err
,
ErrUnsupportedGameType
)
require
.
Nil
(
t
,
player
)
}
func
TestKnownGameType
(
t
*
testing
.
T
)
{
registry
:=
NewGameTypeRegistry
()
expectedPlayer
:=
&
test
.
StubGamePlayer
{}
creator
:=
func
(
game
types
.
GameMetadata
,
dir
string
)
(
scheduler
.
GamePlayer
,
error
)
{
return
expectedPlayer
,
nil
}
registry
.
RegisterGameType
(
0
,
creator
)
player
,
err
:=
registry
.
CreatePlayer
(
types
.
GameMetadata
{
GameType
:
0
},
""
)
require
.
NoError
(
t
,
err
)
require
.
Same
(
t
,
expectedPlayer
,
player
)
}
func
TestPanicsOnDuplicateGameType
(
t
*
testing
.
T
)
{
registry
:=
NewGameTypeRegistry
()
creator
:=
func
(
game
types
.
GameMetadata
,
dir
string
)
(
scheduler
.
GamePlayer
,
error
)
{
return
nil
,
nil
}
registry
.
RegisterGameType
(
0
,
creator
)
require
.
Panics
(
t
,
func
()
{
registry
.
RegisterGameType
(
0
,
creator
)
})
}
op-challenger/game/scheduler/coordinator_test.go
View file @
b0114bef
...
...
@@ -5,6 +5,7 @@ import (
"fmt"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/scheduler/test"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-service/testlog"
...
...
@@ -30,7 +31,7 @@ func TestScheduleNewGames(t *testing.T) {
players
=
append
(
players
,
j
.
player
)
}
for
addr
,
player
:=
range
games
.
created
{
require
.
Equal
(
t
,
disk
.
DirForGame
(
addr
),
player
.
d
ir
,
"should use allocated directory"
)
require
.
Equal
(
t
,
disk
.
DirForGame
(
addr
),
player
.
D
ir
,
"should use allocated directory"
)
require
.
Containsf
(
t
,
players
,
player
,
"should have created a job for player %v"
,
addr
)
}
}
...
...
@@ -233,34 +234,18 @@ func setupCoordinatorTest(t *testing.T, bufferSize int) (*coordinator, <-chan jo
resultQueue
:=
make
(
chan
job
,
bufferSize
)
games
:=
&
createdGames
{
t
:
t
,
created
:
make
(
map
[
common
.
Address
]
*
stubGame
),
created
:
make
(
map
[
common
.
Address
]
*
test
.
StubGamePlayer
),
}
disk
:=
&
stubDiskManager
{
gameDirExists
:
make
(
map
[
common
.
Address
]
bool
)}
c
:=
newCoordinator
(
logger
,
metrics
.
NoopMetrics
,
workQueue
,
resultQueue
,
games
.
CreateGame
,
disk
)
return
c
,
workQueue
,
resultQueue
,
games
,
disk
}
type
stubGame
struct
{
addr
common
.
Address
progressCount
int
status
types
.
GameStatus
dir
string
}
func
(
g
*
stubGame
)
ProgressGame
(
_
context
.
Context
)
types
.
GameStatus
{
g
.
progressCount
++
return
g
.
status
}
func
(
g
*
stubGame
)
Status
()
types
.
GameStatus
{
return
g
.
status
}
type
createdGames
struct
{
t
*
testing
.
T
createCompleted
common
.
Address
creationFails
common
.
Address
created
map
[
common
.
Address
]
*
stubGame
created
map
[
common
.
Address
]
*
test
.
StubGamePlayer
}
func
(
c
*
createdGames
)
CreateGame
(
fdg
types
.
GameMetadata
,
dir
string
)
(
GamePlayer
,
error
)
{
...
...
@@ -275,10 +260,10 @@ func (c *createdGames) CreateGame(fdg types.GameMetadata, dir string) (GamePlaye
if
addr
==
c
.
createCompleted
{
status
=
types
.
GameStatusDefenderWon
}
game
:=
&
stubGame
{
addr
:
addr
,
status
:
status
,
dir
:
dir
,
game
:=
&
test
.
StubGamePlayer
{
Addr
:
addr
,
StatusValue
:
status
,
Dir
:
dir
,
}
c
.
created
[
addr
]
=
game
return
game
,
nil
...
...
op-challenger/game/scheduler/scheduler_test.go
View file @
b0114bef
...
...
@@ -4,6 +4,7 @@ import (
"context"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/scheduler/test"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-service/testlog"
...
...
@@ -16,7 +17,7 @@ func TestSchedulerProcessesGames(t *testing.T) {
logger
:=
testlog
.
Logger
(
t
,
log
.
LvlInfo
)
ctx
:=
context
.
Background
()
createPlayer
:=
func
(
g
types
.
GameMetadata
,
dir
string
)
(
GamePlayer
,
error
)
{
return
&
stub
Player
{},
nil
return
&
test
.
StubGame
Player
{},
nil
}
removeExceptCalls
:=
make
(
chan
[]
common
.
Address
)
disk
:=
&
trackingDiskManager
{
removeExceptCalls
:
removeExceptCalls
}
...
...
@@ -44,7 +45,7 @@ func TestSchedulerProcessesGames(t *testing.T) {
func
TestReturnBusyWhenScheduleQueueFull
(
t
*
testing
.
T
)
{
logger
:=
testlog
.
Logger
(
t
,
log
.
LvlInfo
)
createPlayer
:=
func
(
game
types
.
GameMetadata
,
dir
string
)
(
GamePlayer
,
error
)
{
return
&
stub
Player
{},
nil
return
&
test
.
StubGame
Player
{},
nil
}
removeExceptCalls
:=
make
(
chan
[]
common
.
Address
)
disk
:=
&
trackingDiskManager
{
removeExceptCalls
:
removeExceptCalls
}
...
...
op-challenger/game/scheduler/test/stub_player.go
0 → 100644
View file @
b0114bef
package
test
import
(
"context"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum/go-ethereum/common"
)
type
StubGamePlayer
struct
{
Addr
common
.
Address
ProgressCount
int
StatusValue
types
.
GameStatus
Dir
string
}
func
(
g
*
StubGamePlayer
)
ProgressGame
(
_
context
.
Context
)
types
.
GameStatus
{
g
.
ProgressCount
++
return
g
.
StatusValue
}
func
(
g
*
StubGamePlayer
)
Status
()
types
.
GameStatus
{
return
g
.
StatusValue
}
op-challenger/game/scheduler/worker_test.go
View file @
b0114bef
...
...
@@ -6,6 +6,7 @@ import (
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-challenger/game/scheduler/test"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
...
...
@@ -24,7 +25,7 @@ func TestWorkerShouldProcessJobsUntilContextDone(t *testing.T) {
go
progressGames
(
ctx
,
in
,
out
,
&
wg
,
ms
.
ThreadActive
,
ms
.
ThreadIdle
)
in
<-
job
{
player
:
&
stubPlayer
{
status
:
types
.
GameStatusInProgress
},
player
:
&
test
.
StubGamePlayer
{
StatusValue
:
types
.
GameStatusInProgress
},
}
waitErr
:=
wait
.
For
(
context
.
Background
(),
100
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
return
ms
.
activeCalls
>=
1
,
nil
...
...
@@ -34,7 +35,7 @@ func TestWorkerShouldProcessJobsUntilContextDone(t *testing.T) {
require
.
Equal
(
t
,
ms
.
idleCalls
,
1
)
in
<-
job
{
player
:
&
stubPlayer
{
status
:
types
.
GameStatusDefenderWon
},
player
:
&
test
.
StubGamePlayer
{
StatusValue
:
types
.
GameStatusDefenderWon
},
}
waitErr
=
wait
.
For
(
context
.
Background
(),
100
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
return
ms
.
activeCalls
>=
2
,
nil
...
...
@@ -67,18 +68,6 @@ func (m *metricSink) ThreadIdle() {
m
.
idleCalls
++
}
type
stubPlayer
struct
{
status
types
.
GameStatus
}
func
(
s
*
stubPlayer
)
ProgressGame
(
ctx
context
.
Context
)
types
.
GameStatus
{
return
s
.
status
}
func
(
s
*
stubPlayer
)
Status
()
types
.
GameStatus
{
return
s
.
status
}
func
readWithTimeout
[
T
any
](
t
*
testing
.
T
,
ch
<-
chan
T
)
T
{
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
10
*
time
.
Second
)
defer
cancel
()
...
...
op-challenger/game/service.go
View file @
b0114bef
...
...
@@ -9,8 +9,8 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault"
"github.com/ethereum-optimism/optimism/op-challenger/game/loader"
"github.com/ethereum-optimism/optimism/op-challenger/game/registry"
"github.com/ethereum-optimism/optimism/op-challenger/game/scheduler"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-challenger/version"
opClient
"github.com/ethereum-optimism/optimism/op-service/client"
...
...
@@ -94,15 +94,16 @@ func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*Se
}
loader
:=
loader
.
NewGameLoader
(
factoryContract
)
gameTypeRegistry
:=
registry
.
NewGameTypeRegistry
()
fault
.
RegisterGameTypes
(
gameTypeRegistry
,
ctx
,
logger
,
m
,
cfg
,
txMgr
,
l1Client
)
disk
:=
newDiskManager
(
cfg
.
Datadir
)
s
.
sched
=
scheduler
.
NewScheduler
(
logger
,
m
,
disk
,
cfg
.
MaxConcurrency
,
func
(
game
types
.
GameMetadata
,
dir
string
)
(
scheduler
.
GamePlayer
,
error
)
{
return
fault
.
NewGamePlayer
(
ctx
,
logger
,
m
,
cfg
,
dir
,
game
.
Proxy
,
txMgr
,
l1Client
)
})
gameTypeRegistry
.
CreatePlayer
)
pollClient
,
err
:=
opClient
.
NewRPCWithClient
(
ctx
,
logger
,
cfg
.
L1EthRpc
,
opClient
.
NewBaseRPCClient
(
l1Client
.
Client
()),
cfg
.
PollInterval
)
if
err
!=
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