Commit 0a6a781b authored by Adrian Sutton's avatar Adrian Sutton

op-challenger: Simplify game implementation

Stores claims in an array with the same order as the contracts would. Computes a claim ID by hashing the values that must be unique.
parent 0025fff1
......@@ -2,6 +2,10 @@ package types
import (
"errors"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
var (
......@@ -36,45 +40,35 @@ type Game interface {
MaxDepth() uint64
}
type claimEntry struct {
ClaimData
ParentContractIndex int
}
type claimID common.Hash
type extendedClaim struct {
self Claim
children []claimEntry
func computeClaimID(claim Claim) claimID {
return claimID(crypto.Keccak256Hash(
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.
// The game state implements the [Game] interface.
type gameState struct {
agreeWithProposedOutput bool
root claimEntry
// contractIndicies maps a contract index to it's extended claim.
// This is used to perform O(1) parent lookups.
contractIndicies map[int]*extendedClaim
// claims maps a claim entry to it's extended claim.
claims map[claimEntry]*extendedClaim
depth uint64
// claims is the list of claims in the same order as the contract
claims []Claim
claimIDs map[claimID]bool
depth uint64
}
// NewGameState returns a new game state.
// The provided [Claim] is used as the root node.
func NewGameState(agreeWithProposedOutput bool, root Claim, depth uint64) *gameState {
claims := make(map[claimEntry]*extendedClaim)
parents := make(map[int]*extendedClaim)
rootClaimEntry := makeClaimEntry(root)
claims[rootClaimEntry] = &extendedClaim{
self: root,
children: make([]claimEntry, 0),
}
parents[root.ContractIndex] = claims[rootClaimEntry]
claimIDs := make(map[claimID]bool)
claimIDs[computeClaimID(root)] = true
return &gameState{
agreeWithProposedOutput: agreeWithProposedOutput,
root: rootClaimEntry,
claims: claims,
contractIndicies: parents,
claims: []Claim{root},
claimIDs: claimIDs,
depth: depth,
}
}
......@@ -112,62 +106,40 @@ func (g *gameState) Put(claim Claim) error {
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
g.claims = append(g.claims, claim)
g.claimIDs[computeClaimID(claim)] = true
return nil
}
func (g *gameState) IsDuplicate(claim Claim) bool {
_, ok := g.claims[makeClaimEntry(claim)]
return ok
return g.claimIDs[computeClaimID(claim)]
}
func (g *gameState) Claims() []Claim {
queue := []claimEntry{g.root}
var out []Claim
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
// Defensively copy to avoid modifications to the underlying array.
return append([]Claim(nil), g.claims...)
}
func (g *gameState) MaxDepth() uint64 {
return g.depth
}
func (g *gameState) getChildren(c claimEntry) []claimEntry {
return g.claims[c].children
}
func (g *gameState) GetParent(claim Claim) (Claim, error) {
parent := g.getParent(claim)
if parent == nil {
return Claim{}, ErrClaimNotFound
}
return parent.self, nil
return *parent, nil
}
func (g *gameState) getParent(claim Claim) *extendedClaim {
func (g *gameState) getParent(claim Claim) *Claim {
if claim.IsRoot() {
return nil
}
if parent, ok := g.contractIndicies[claim.ParentContractIndex]; ok {
return parent
}
return nil
}
func makeClaimEntry(claim Claim) claimEntry {
return claimEntry{
ClaimData: claim.ClaimData,
ParentContractIndex: claim.ParentContractIndex,
if claim.ParentContractIndex >= len(g.claims) || claim.ParentContractIndex < 0 {
return nil
}
parent := g.claims[claim.ParentContractIndex]
return &parent
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment