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
cece372b
Unverified
Commit
cece372b
authored
Oct 03, 2023
by
refcell.eth
Committed by
GitHub
Oct 03, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #7517 from ethereum-optimism/aj/simplify-game
op-challenger: Simplify game implementation
parents
8064f0c9
3cedb234
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
55 additions
and
242 deletions
+55
-242
agent.go
op-challenger/game/fault/agent.go
+1
-4
game_builder.go
op-challenger/game/fault/test/game_builder.go
+19
-19
game.go
op-challenger/game/fault/types/game.go
+29
-88
game_test.go
op-challenger/game/fault/types/game_test.go
+6
-131
No files found.
op-challenger/game/fault/agent.go
View file @
cece372b
...
@@ -196,9 +196,6 @@ func (a *Agent) newGameFromContracts(ctx context.Context) (types.Game, error) {
...
@@ -196,9 +196,6 @@ func (a *Agent) newGameFromContracts(ctx context.Context) (types.Game, error) {
if
len
(
claims
)
==
0
{
if
len
(
claims
)
==
0
{
return
nil
,
errors
.
New
(
"no claims"
)
return
nil
,
errors
.
New
(
"no claims"
)
}
}
game
:=
types
.
NewGameState
(
a
.
agreeWithProposedOutput
,
claims
[
0
],
uint64
(
a
.
maxDepth
))
game
:=
types
.
NewGameState
(
a
.
agreeWithProposedOutput
,
claims
,
uint64
(
a
.
maxDepth
))
if
err
:=
game
.
PutAll
(
claims
[
1
:
]);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to load claims into the local state: %w"
,
err
)
}
return
game
,
nil
return
game
,
nil
}
}
op-challenger/game/fault/test/game_builder.go
View file @
cece372b
...
@@ -6,15 +6,17 @@ import (
...
@@ -6,15 +6,17 @@ import (
)
)
type
GameBuilder
struct
{
type
GameBuilder
struct
{
builder
*
ClaimBuilder
builder
*
ClaimBuilder
Game
types
.
Game
Game
types
.
Game
ExpectedActions
[]
types
.
Action
ExpectedActions
[]
types
.
Action
agreeWithOutputRoot
bool
}
}
func
(
c
*
ClaimBuilder
)
GameBuilder
(
agreeWithOutputRoot
bool
,
rootCorrect
bool
)
*
GameBuilder
{
func
(
c
*
ClaimBuilder
)
GameBuilder
(
agreeWithOutputRoot
bool
,
rootCorrect
bool
)
*
GameBuilder
{
return
&
GameBuilder
{
return
&
GameBuilder
{
builder
:
c
,
builder
:
c
,
Game
:
types
.
NewGameState
(
agreeWithOutputRoot
,
c
.
CreateRootClaim
(
rootCorrect
),
uint64
(
c
.
maxDepth
)),
agreeWithOutputRoot
:
agreeWithOutputRoot
,
Game
:
types
.
NewGameState
(
agreeWithOutputRoot
,
[]
types
.
Claim
{
c
.
CreateRootClaim
(
rootCorrect
)},
uint64
(
c
.
maxDepth
)),
}
}
}
}
...
@@ -22,62 +24,60 @@ type GameBuilderSeq struct {
...
@@ -22,62 +24,60 @@ type GameBuilderSeq struct {
gameBuilder
*
GameBuilder
gameBuilder
*
GameBuilder
builder
*
ClaimBuilder
builder
*
ClaimBuilder
lastClaim
types
.
Claim
lastClaim
types
.
Claim
game
types
.
Game
}
}
func
(
g
*
GameBuilder
)
Seq
()
*
GameBuilderSeq
{
func
(
g
*
GameBuilder
)
Seq
()
*
GameBuilderSeq
{
return
&
GameBuilderSeq
{
return
&
GameBuilderSeq
{
gameBuilder
:
g
,
gameBuilder
:
g
,
builder
:
g
.
builder
,
builder
:
g
.
builder
,
game
:
g
.
Game
,
lastClaim
:
g
.
Game
.
Claims
()[
0
],
lastClaim
:
g
.
Game
.
Claims
()[
0
],
}
}
}
}
// addClaimToGame replaces the game being built with a new instance that has claim as the latest claim.
// The ContractIndex in claim is updated with its position in the game's claim array.
func
(
s
*
GameBuilderSeq
)
addClaimToGame
(
claim
*
types
.
Claim
)
{
claim
.
ContractIndex
=
len
(
s
.
gameBuilder
.
Game
.
Claims
())
claims
:=
append
(
s
.
gameBuilder
.
Game
.
Claims
(),
*
claim
)
s
.
gameBuilder
.
Game
=
types
.
NewGameState
(
s
.
gameBuilder
.
agreeWithOutputRoot
,
claims
,
uint64
(
s
.
builder
.
maxDepth
))
}
func
(
s
*
GameBuilderSeq
)
AttackCorrect
()
*
GameBuilderSeq
{
func
(
s
*
GameBuilderSeq
)
AttackCorrect
()
*
GameBuilderSeq
{
claim
:=
s
.
builder
.
AttackClaim
(
s
.
lastClaim
,
true
)
claim
:=
s
.
builder
.
AttackClaim
(
s
.
lastClaim
,
true
)
claim
.
ContractIndex
=
len
(
s
.
game
.
Claims
())
s
.
addClaimToGame
(
&
claim
)
s
.
builder
.
require
.
NoError
(
s
.
game
.
Put
(
claim
))
return
&
GameBuilderSeq
{
return
&
GameBuilderSeq
{
gameBuilder
:
s
.
gameBuilder
,
gameBuilder
:
s
.
gameBuilder
,
builder
:
s
.
builder
,
builder
:
s
.
builder
,
game
:
s
.
game
,
lastClaim
:
claim
,
lastClaim
:
claim
,
}
}
}
}
func
(
s
*
GameBuilderSeq
)
Attack
(
value
common
.
Hash
)
*
GameBuilderSeq
{
func
(
s
*
GameBuilderSeq
)
Attack
(
value
common
.
Hash
)
*
GameBuilderSeq
{
claim
:=
s
.
builder
.
AttackClaimWithValue
(
s
.
lastClaim
,
value
)
claim
:=
s
.
builder
.
AttackClaimWithValue
(
s
.
lastClaim
,
value
)
claim
.
ContractIndex
=
len
(
s
.
game
.
Claims
())
s
.
addClaimToGame
(
&
claim
)
s
.
builder
.
require
.
NoError
(
s
.
game
.
Put
(
claim
))
return
&
GameBuilderSeq
{
return
&
GameBuilderSeq
{
gameBuilder
:
s
.
gameBuilder
,
gameBuilder
:
s
.
gameBuilder
,
builder
:
s
.
builder
,
builder
:
s
.
builder
,
game
:
s
.
game
,
lastClaim
:
claim
,
lastClaim
:
claim
,
}
}
}
}
func
(
s
*
GameBuilderSeq
)
DefendCorrect
()
*
GameBuilderSeq
{
func
(
s
*
GameBuilderSeq
)
DefendCorrect
()
*
GameBuilderSeq
{
claim
:=
s
.
builder
.
DefendClaim
(
s
.
lastClaim
,
true
)
claim
:=
s
.
builder
.
DefendClaim
(
s
.
lastClaim
,
true
)
claim
.
ContractIndex
=
len
(
s
.
game
.
Claims
())
s
.
addClaimToGame
(
&
claim
)
s
.
builder
.
require
.
NoError
(
s
.
game
.
Put
(
claim
))
return
&
GameBuilderSeq
{
return
&
GameBuilderSeq
{
gameBuilder
:
s
.
gameBuilder
,
gameBuilder
:
s
.
gameBuilder
,
builder
:
s
.
builder
,
builder
:
s
.
builder
,
game
:
s
.
game
,
lastClaim
:
claim
,
lastClaim
:
claim
,
}
}
}
}
func
(
s
*
GameBuilderSeq
)
Defend
(
value
common
.
Hash
)
*
GameBuilderSeq
{
func
(
s
*
GameBuilderSeq
)
Defend
(
value
common
.
Hash
)
*
GameBuilderSeq
{
claim
:=
s
.
builder
.
DefendClaimWithValue
(
s
.
lastClaim
,
value
)
claim
:=
s
.
builder
.
DefendClaimWithValue
(
s
.
lastClaim
,
value
)
claim
.
ContractIndex
=
len
(
s
.
game
.
Claims
())
s
.
addClaimToGame
(
&
claim
)
s
.
builder
.
require
.
NoError
(
s
.
game
.
Put
(
claim
))
return
&
GameBuilderSeq
{
return
&
GameBuilderSeq
{
gameBuilder
:
s
.
gameBuilder
,
gameBuilder
:
s
.
gameBuilder
,
builder
:
s
.
builder
,
builder
:
s
.
builder
,
game
:
s
.
game
,
lastClaim
:
claim
,
lastClaim
:
claim
,
}
}
}
}
...
...
op-challenger/game/fault/types/game.go
View file @
cece372b
...
@@ -2,6 +2,10 @@ package types
...
@@ -2,6 +2,10 @@ package types
import
(
import
(
"errors"
"errors"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
)
var
(
var
(
...
@@ -14,12 +18,6 @@ var (
...
@@ -14,12 +18,6 @@ var (
// Game is an interface that represents the state of a dispute game.
// Game is an interface that represents the state of a dispute game.
type
Game
interface
{
type
Game
interface
{
// Put adds a claim into the game state.
Put
(
claim
Claim
)
error
// PutAll adds a list of claims into the game state.
PutAll
(
claims
[]
Claim
)
error
// Claims returns all of the claims in the game.
// Claims returns all of the claims in the game.
Claims
()
[]
Claim
Claims
()
[]
Claim
...
@@ -36,45 +34,37 @@ type Game interface {
...
@@ -36,45 +34,37 @@ type Game interface {
MaxDepth
()
uint64
MaxDepth
()
uint64
}
}
type
claimEntry
struct
{
type
claimID
common
.
Hash
ClaimData
ParentContractIndex
int
}
type
extendedClaim
struct
{
func
computeClaimID
(
claim
Claim
)
claimID
{
self
Claim
return
claimID
(
crypto
.
Keccak256Hash
(
children
[]
claimEntry
new
(
big
.
Int
)
.
SetUint64
(
claim
.
Position
.
ToGIndex
())
.
Bytes
(),
claim
.
Value
.
Bytes
(),
big
.
NewInt
(
int64
(
claim
.
ParentContractIndex
))
.
Bytes
(),
))
}
}
// gameState is a struct that represents the state of a dispute game.
// gameState is a struct that represents the state of a dispute game.
// The game state implements the [Game] interface.
// The game state implements the [Game] interface.
type
gameState
struct
{
type
gameState
struct
{
agreeWithProposedOutput
bool
agreeWithProposedOutput
bool
root
claimEntry
// claims is the list of claims in the same order as the contract
// contractIndicies maps a contract index to it's extended claim.
claims
[]
Claim
// This is used to perform O(1) parent lookups.
claimIDs
map
[
claimID
]
bool
contractIndicies
map
[
int
]
*
extendedClaim
depth
uint64
// claims maps a claim entry to it's extended claim.
claims
map
[
claimEntry
]
*
extendedClaim
depth
uint64
}
}
// NewGameState returns a new game state.
// NewGameState returns a new game state.
// The provided [Claim] is used as the root node.
// The provided [Claim] is used as the root node.
func
NewGameState
(
agreeWithProposedOutput
bool
,
root
Claim
,
depth
uint64
)
*
gameState
{
func
NewGameState
(
agreeWithProposedOutput
bool
,
claims
[]
Claim
,
depth
uint64
)
*
gameState
{
claims
:=
make
(
map
[
claimEntry
]
*
extendedClaim
)
claimIDs
:=
make
(
map
[
claimID
]
bool
)
parents
:=
make
(
map
[
int
]
*
extendedClaim
)
for
_
,
claim
:=
range
claims
{
rootClaimEntry
:=
makeClaimEntry
(
root
)
claimIDs
[
computeClaimID
(
claim
)]
=
true
claims
[
rootClaimEntry
]
=
&
extendedClaim
{
self
:
root
,
children
:
make
([]
claimEntry
,
0
),
}
}
parents
[
root
.
ContractIndex
]
=
claims
[
rootClaimEntry
]
return
&
gameState
{
return
&
gameState
{
agreeWithProposedOutput
:
agreeWithProposedOutput
,
agreeWithProposedOutput
:
agreeWithProposedOutput
,
root
:
rootClaimEntry
,
claims
:
claims
,
claims
:
claims
,
c
ontractIndicies
:
parent
s
,
c
laimIDs
:
claimID
s
,
depth
:
depth
,
depth
:
depth
,
}
}
}
}
...
@@ -91,83 +81,34 @@ func (g *gameState) AgreeWithClaimLevel(claim Claim) bool {
...
@@ -91,83 +81,34 @@ func (g *gameState) AgreeWithClaimLevel(claim Claim) bool {
}
}
}
}
// PutAll adds a list of claims into the [Game] state.
// If any of the claims already exist in the game state, an error is returned.
func
(
g
*
gameState
)
PutAll
(
claims
[]
Claim
)
error
{
for
_
,
claim
:=
range
claims
{
if
err
:=
g
.
Put
(
claim
);
err
!=
nil
{
return
err
}
}
return
nil
}
// Put adds a claim into the game state.
func
(
g
*
gameState
)
Put
(
claim
Claim
)
error
{
if
claim
.
IsRoot
()
||
g
.
IsDuplicate
(
claim
)
{
return
ErrClaimExists
}
parent
:=
g
.
getParent
(
claim
)
if
parent
==
nil
{
return
errors
.
New
(
"no parent claim"
)
}
parent
.
children
=
append
(
parent
.
children
,
makeClaimEntry
(
claim
))
claimWithExtension
:=
&
extendedClaim
{
self
:
claim
,
children
:
make
([]
claimEntry
,
0
),
}
g
.
claims
[
makeClaimEntry
(
claim
)]
=
claimWithExtension
g
.
contractIndicies
[
claim
.
ContractIndex
]
=
claimWithExtension
return
nil
}
func
(
g
*
gameState
)
IsDuplicate
(
claim
Claim
)
bool
{
func
(
g
*
gameState
)
IsDuplicate
(
claim
Claim
)
bool
{
_
,
ok
:=
g
.
claims
[
makeClaimEntry
(
claim
)]
return
g
.
claimIDs
[
computeClaimID
(
claim
)]
return
ok
}
}
func
(
g
*
gameState
)
Claims
()
[]
Claim
{
func
(
g
*
gameState
)
Claims
()
[]
Claim
{
queue
:=
[]
claimEntry
{
g
.
root
}
// Defensively copy to avoid modifications to the underlying array.
var
out
[]
Claim
return
append
([]
Claim
(
nil
),
g
.
claims
...
)
for
len
(
queue
)
>
0
{
item
:=
queue
[
0
]
queue
=
queue
[
1
:
]
queue
=
append
(
queue
,
g
.
getChildren
(
item
)
...
)
out
=
append
(
out
,
g
.
claims
[
item
]
.
self
)
}
return
out
}
}
func
(
g
*
gameState
)
MaxDepth
()
uint64
{
func
(
g
*
gameState
)
MaxDepth
()
uint64
{
return
g
.
depth
return
g
.
depth
}
}
func
(
g
*
gameState
)
getChildren
(
c
claimEntry
)
[]
claimEntry
{
return
g
.
claims
[
c
]
.
children
}
func
(
g
*
gameState
)
GetParent
(
claim
Claim
)
(
Claim
,
error
)
{
func
(
g
*
gameState
)
GetParent
(
claim
Claim
)
(
Claim
,
error
)
{
parent
:=
g
.
getParent
(
claim
)
parent
:=
g
.
getParent
(
claim
)
if
parent
==
nil
{
if
parent
==
nil
{
return
Claim
{},
ErrClaimNotFound
return
Claim
{},
ErrClaimNotFound
}
}
return
parent
.
self
,
nil
return
*
parent
,
nil
}
}
func
(
g
*
gameState
)
getParent
(
claim
Claim
)
*
extended
Claim
{
func
(
g
*
gameState
)
getParent
(
claim
Claim
)
*
Claim
{
if
claim
.
IsRoot
()
{
if
claim
.
IsRoot
()
{
return
nil
return
nil
}
}
if
parent
,
ok
:=
g
.
contractIndicies
[
claim
.
ParentContractIndex
];
ok
{
if
claim
.
ParentContractIndex
>=
len
(
g
.
claims
)
||
claim
.
ParentContractIndex
<
0
{
return
parent
return
nil
}
return
nil
}
func
makeClaimEntry
(
claim
Claim
)
claimEntry
{
return
claimEntry
{
ClaimData
:
claim
.
ClaimData
,
ParentContractIndex
:
claim
.
ParentContractIndex
,
}
}
parent
:=
g
.
claims
[
claim
.
ParentContractIndex
]
return
&
parent
}
}
op-challenger/game/fault/types/game_test.go
View file @
cece372b
...
@@ -54,8 +54,7 @@ func createTestClaims() (Claim, Claim, Claim, Claim) {
...
@@ -54,8 +54,7 @@ func createTestClaims() (Claim, Claim, Claim, Claim) {
func
TestIsDuplicate
(
t
*
testing
.
T
)
{
func
TestIsDuplicate
(
t
*
testing
.
T
)
{
// Setup the game state.
// Setup the game state.
root
,
top
,
middle
,
bottom
:=
createTestClaims
()
root
,
top
,
middle
,
bottom
:=
createTestClaims
()
g
:=
NewGameState
(
false
,
root
,
testMaxDepth
)
g
:=
NewGameState
(
false
,
[]
Claim
{
root
,
top
},
testMaxDepth
)
require
.
NoError
(
t
,
g
.
Put
(
top
))
// Root + Top should be duplicates
// Root + Top should be duplicates
require
.
True
(
t
,
g
.
IsDuplicate
(
root
))
require
.
True
(
t
,
g
.
IsDuplicate
(
root
))
...
@@ -66,137 +65,13 @@ func TestIsDuplicate(t *testing.T) {
...
@@ -66,137 +65,13 @@ func TestIsDuplicate(t *testing.T) {
require
.
False
(
t
,
g
.
IsDuplicate
(
bottom
))
require
.
False
(
t
,
g
.
IsDuplicate
(
bottom
))
}
}
// TestGame_Put_RootAlreadyExists tests the [Game.Put] method using a [gameState]
func
TestGame_Claims
(
t
*
testing
.
T
)
{
// instance errors when the root claim already exists in state.
func
TestGame_Put_RootAlreadyExists
(
t
*
testing
.
T
)
{
// Setup the game state.
// Setup the game state.
top
,
_
,
_
,
_
:=
createTestClaims
()
g
:=
NewGameState
(
false
,
top
,
testMaxDepth
)
// Try to put the root claim into the game state again.
err
:=
g
.
Put
(
top
)
require
.
ErrorIs
(
t
,
err
,
ErrClaimExists
)
}
// TestGame_PutAll_RootAlreadyExists tests the [Game.PutAll] method using a [gameState]
// instance errors when the root claim already exists in state.
func
TestGame_PutAll_RootAlreadyExists
(
t
*
testing
.
T
)
{
// Setup the game state.
root
,
_
,
_
,
_
:=
createTestClaims
()
g
:=
NewGameState
(
false
,
root
,
testMaxDepth
)
// Try to put the root claim into the game state again.
err
:=
g
.
PutAll
([]
Claim
{
root
})
require
.
ErrorIs
(
t
,
err
,
ErrClaimExists
)
}
// TestGame_PutAll_AlreadyExists tests the [Game.PutAll] method using a [gameState]
// instance errors when the given claim already exists in state.
func
TestGame_PutAll_AlreadyExists
(
t
*
testing
.
T
)
{
root
,
top
,
middle
,
bottom
:=
createTestClaims
()
root
,
top
,
middle
,
bottom
:=
createTestClaims
()
g
:=
NewGameState
(
false
,
root
,
testMaxDepth
)
expected
:=
[]
Claim
{
root
,
top
,
middle
,
bottom
}
g
:=
NewGameState
(
false
,
expected
,
testMaxDepth
)
err
:=
g
.
PutAll
([]
Claim
{
top
,
middle
})
require
.
NoError
(
t
,
err
)
err
=
g
.
PutAll
([]
Claim
{
middle
,
bottom
})
require
.
ErrorIs
(
t
,
err
,
ErrClaimExists
)
}
// TestGame_PutAll_ParentsAndChildren tests the [Game.PutAll] method using a [gameState] instance.
func
TestGame_PutAll_ParentsAndChildren
(
t
*
testing
.
T
)
{
// Setup the game state.
root
,
top
,
middle
,
bottom
:=
createTestClaims
()
g
:=
NewGameState
(
false
,
root
,
testMaxDepth
)
// We should not be able to get the parent of the root claim.
parent
,
err
:=
g
.
GetParent
(
root
)
require
.
ErrorIs
(
t
,
err
,
ErrClaimNotFound
)
require
.
Equal
(
t
,
parent
,
Claim
{})
// Put the rest of the claims in the state.
err
=
g
.
PutAll
([]
Claim
{
top
,
middle
,
bottom
})
require
.
NoError
(
t
,
err
)
parent
,
err
=
g
.
GetParent
(
top
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
parent
,
root
)
parent
,
err
=
g
.
GetParent
(
middle
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
parent
,
top
)
parent
,
err
=
g
.
GetParent
(
bottom
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
parent
,
middle
)
}
// TestGame_Put_AlreadyExists tests the [Game.Put] method using a [gameState]
// instance errors when the given claim already exists in state.
func
TestGame_Put_AlreadyExists
(
t
*
testing
.
T
)
{
// Setup the game state.
top
,
middle
,
_
,
_
:=
createTestClaims
()
g
:=
NewGameState
(
false
,
top
,
testMaxDepth
)
// Put the next claim into state.
err
:=
g
.
Put
(
middle
)
require
.
NoError
(
t
,
err
)
// Put the claim into the game state again.
err
=
g
.
Put
(
middle
)
require
.
ErrorIs
(
t
,
err
,
ErrClaimExists
)
}
// TestGame_Put_ParentsAndChildren tests the [Game.Put] method using a [gameState] instance.
func
TestGame_Put_ParentsAndChildren
(
t
*
testing
.
T
)
{
// Setup the game state.
root
,
top
,
middle
,
bottom
:=
createTestClaims
()
g
:=
NewGameState
(
false
,
root
,
testMaxDepth
)
// We should not be able to get the parent of the root claim.
parent
,
err
:=
g
.
GetParent
(
root
)
require
.
ErrorIs
(
t
,
err
,
ErrClaimNotFound
)
require
.
Equal
(
t
,
parent
,
Claim
{})
// Put + Check Top
err
=
g
.
Put
(
top
)
require
.
NoError
(
t
,
err
)
parent
,
err
=
g
.
GetParent
(
top
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
parent
,
root
)
// Put + Check Top Middle
err
=
g
.
Put
(
middle
)
require
.
NoError
(
t
,
err
)
parent
,
err
=
g
.
GetParent
(
middle
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
parent
,
top
)
// Put + Check Top Bottom
err
=
g
.
Put
(
bottom
)
require
.
NoError
(
t
,
err
)
parent
,
err
=
g
.
GetParent
(
bottom
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
parent
,
middle
)
}
// TestGame_ClaimPairs tests the [Game.ClaimPairs] method using a [gameState] instance.
func
TestGame_ClaimPairs
(
t
*
testing
.
T
)
{
// Setup the game state.
root
,
top
,
middle
,
bottom
:=
createTestClaims
()
g
:=
NewGameState
(
false
,
root
,
testMaxDepth
)
// Add top claim to the game state.
err
:=
g
.
Put
(
top
)
require
.
NoError
(
t
,
err
)
// Add the middle claim to the game state.
err
=
g
.
Put
(
middle
)
require
.
NoError
(
t
,
err
)
// Add the bottom claim to the game state.
err
=
g
.
Put
(
bottom
)
require
.
NoError
(
t
,
err
)
// Validate claim pairs.
// Validate claim pairs.
expected
:=
[]
Claim
{
root
,
top
,
middle
,
bottom
}
actual
:=
g
.
Claims
()
claims
:=
g
.
Claims
()
require
.
ElementsMatch
(
t
,
expected
,
actual
)
require
.
ElementsMatch
(
t
,
expected
,
claims
)
}
}
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