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
e688629c
Unverified
Commit
e688629c
authored
Aug 08, 2023
by
mergify[bot]
Committed by
GitHub
Aug 08, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into feat/oracle-immutables
parents
11129fd0
e409d0d1
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
285 additions
and
134 deletions
+285
-134
helper.go
op-e2e/e2eutils/challenger/helper.go
+14
-0
alphabet_helper.go
op-e2e/e2eutils/disputegame/alphabet_helper.go
+33
-0
cannon_helper.go
op-e2e/e2eutils/disputegame/cannon_helper.go
+35
-0
game_helper.go
op-e2e/e2eutils/disputegame/game_helper.go
+111
-0
helper.go
op-e2e/e2eutils/disputegame/helper.go
+65
-134
faultproof_test.go
op-e2e/faultproof_test.go
+27
-0
No files found.
op-e2e/e2eutils/challenger/helper.go
View file @
e688629c
...
...
@@ -3,6 +3,7 @@ package challenger
import
(
"context"
"errors"
"os"
"testing"
"time"
...
...
@@ -40,6 +41,19 @@ func NewChallenger(t *testing.T, ctx context.Context, l1Endpoint string, name st
require
.
NotEmpty
(
t
,
cfg
.
TxMgrConfig
.
PrivateKey
,
"Missing private key for TxMgrConfig"
)
require
.
NoError
(
t
,
cfg
.
Check
(),
"op-challenger config should be valid"
)
if
cfg
.
CannonBin
!=
""
{
_
,
err
:=
os
.
Stat
(
cfg
.
CannonBin
)
require
.
NoError
(
t
,
err
,
"cannon should be built. Make sure you've run make cannon-prestate"
)
}
if
cfg
.
CannonServer
!=
""
{
_
,
err
:=
os
.
Stat
(
cfg
.
CannonServer
)
require
.
NoError
(
t
,
err
,
"op-program should be built. Make sure you've run make cannon-prestate"
)
}
if
cfg
.
CannonAbsolutePreState
!=
""
{
_
,
err
:=
os
.
Stat
(
cfg
.
CannonAbsolutePreState
)
require
.
NoError
(
t
,
err
,
"cannon pre-state should be built. Make sure you've run make cannon-prestate"
)
}
errCh
:=
make
(
chan
error
,
1
)
ctx
,
cancel
:=
context
.
WithCancel
(
ctx
)
go
func
()
{
...
...
op-e2e/e2eutils/disputegame/alphabet_helper.go
0 → 100644
View file @
e688629c
package
disputegame
import
(
"context"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
)
type
AlphabetGameHelper
struct
{
FaultGameHelper
claimedAlphabet
string
}
func
(
g
*
AlphabetGameHelper
)
StartChallenger
(
ctx
context
.
Context
,
l1Endpoint
string
,
name
string
,
options
...
challenger
.
Option
)
*
challenger
.
Helper
{
opts
:=
[]
challenger
.
Option
{
func
(
c
*
config
.
Config
)
{
c
.
GameAddress
=
g
.
addr
c
.
GameDepth
=
alphabetGameDepth
c
.
TraceType
=
config
.
TraceTypeAlphabet
// By default the challenger agrees with the root claim (thus disagrees with the proposed output)
// This can be overridden by passing in options
c
.
AlphabetTrace
=
g
.
claimedAlphabet
c
.
AgreeWithProposedOutput
=
false
},
}
opts
=
append
(
opts
,
options
...
)
c
:=
challenger
.
NewChallenger
(
g
.
t
,
ctx
,
l1Endpoint
,
name
,
opts
...
)
g
.
t
.
Cleanup
(
func
()
{
_
=
c
.
Close
()
})
return
c
}
op-e2e/e2eutils/disputegame/cannon_helper.go
0 → 100644
View file @
e688629c
package
disputegame
import
(
"context"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
)
type
CannonGameHelper
struct
{
FaultGameHelper
}
func
(
g
*
CannonGameHelper
)
StartChallenger
(
ctx
context
.
Context
,
l1Endpoint
string
,
l2Endpoint
string
,
name
string
,
options
...
challenger
.
Option
)
*
challenger
.
Helper
{
opts
:=
[]
challenger
.
Option
{
func
(
c
*
config
.
Config
)
{
c
.
GameAddress
=
g
.
addr
c
.
GameDepth
=
cannonGameDepth
c
.
TraceType
=
config
.
TraceTypeCannon
c
.
AgreeWithProposedOutput
=
false
c
.
CannonL2
=
l2Endpoint
c
.
CannonBin
=
"../cannon/bin/cannon"
c
.
CannonDatadir
=
g
.
t
.
TempDir
()
c
.
CannonServer
=
"../op-program/bin/op-program"
c
.
CannonAbsolutePreState
=
"../op-program/bin/prestate.json"
c
.
CannonSnapshotFreq
=
config
.
DefaultCannonSnapshotFreq
},
}
opts
=
append
(
opts
,
options
...
)
c
:=
challenger
.
NewChallenger
(
g
.
t
,
ctx
,
l1Endpoint
,
name
,
opts
...
)
g
.
t
.
Cleanup
(
func
()
{
_
=
c
.
Close
()
})
return
c
}
op-e2e/e2eutils/disputegame/game_helper.go
0 → 100644
View file @
e688629c
package
disputegame
import
(
"context"
"fmt"
"math/big"
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-challenger/fault/types"
"github.com/ethereum-optimism/optimism/op-service/client/utils"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/stretchr/testify/require"
)
type
FaultGameHelper
struct
{
t
*
testing
.
T
require
*
require
.
Assertions
client
*
ethclient
.
Client
opts
*
bind
.
TransactOpts
game
*
bindings
.
FaultDisputeGame
maxDepth
int
addr
common
.
Address
}
func
(
g
*
FaultGameHelper
)
GameDuration
(
ctx
context
.
Context
)
time
.
Duration
{
duration
,
err
:=
g
.
game
.
GAMEDURATION
(
&
bind
.
CallOpts
{
Context
:
ctx
})
g
.
require
.
NoError
(
err
,
"failed to get game duration"
)
return
time
.
Duration
(
duration
)
*
time
.
Second
}
func
(
g
*
FaultGameHelper
)
WaitForClaimCount
(
ctx
context
.
Context
,
count
int64
)
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
time
.
Minute
)
defer
cancel
()
err
:=
utils
.
WaitFor
(
ctx
,
time
.
Second
,
func
()
(
bool
,
error
)
{
actual
,
err
:=
g
.
game
.
ClaimDataLen
(
&
bind
.
CallOpts
{
Context
:
ctx
})
if
err
!=
nil
{
return
false
,
err
}
g
.
t
.
Log
(
"Waiting for claim count"
,
"current"
,
actual
,
"expected"
,
count
,
"game"
,
g
.
addr
)
return
actual
.
Cmp
(
big
.
NewInt
(
count
))
==
0
,
nil
})
g
.
require
.
NoError
(
err
)
}
type
ContractClaim
struct
{
ParentIndex
uint32
Countered
bool
Claim
[
32
]
byte
Position
*
big
.
Int
Clock
*
big
.
Int
}
func
(
g
*
FaultGameHelper
)
WaitForClaim
(
ctx
context
.
Context
,
predicate
func
(
claim
ContractClaim
)
bool
)
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
time
.
Minute
)
defer
cancel
()
err
:=
utils
.
WaitFor
(
ctx
,
time
.
Second
,
func
()
(
bool
,
error
)
{
count
,
err
:=
g
.
game
.
ClaimDataLen
(
&
bind
.
CallOpts
{
Context
:
ctx
})
if
err
!=
nil
{
return
false
,
fmt
.
Errorf
(
"retrieve number of claims: %w"
,
err
)
}
// Search backwards because the new claims are at the end and more likely the ones we want.
for
i
:=
count
.
Int64
()
-
1
;
i
>=
0
;
i
--
{
claimData
,
err
:=
g
.
game
.
ClaimData
(
&
bind
.
CallOpts
{
Context
:
ctx
},
big
.
NewInt
(
i
))
if
err
!=
nil
{
return
false
,
fmt
.
Errorf
(
"retrieve claim %v: %w"
,
i
,
err
)
}
if
predicate
(
claimData
)
{
return
true
,
nil
}
}
return
false
,
nil
})
g
.
require
.
NoError
(
err
)
}
func
(
g
*
FaultGameHelper
)
WaitForClaimAtMaxDepth
(
ctx
context
.
Context
,
countered
bool
)
{
g
.
WaitForClaim
(
ctx
,
func
(
claim
ContractClaim
)
bool
{
pos
:=
types
.
NewPositionFromGIndex
(
claim
.
Position
.
Uint64
())
return
pos
.
Depth
()
==
g
.
maxDepth
&&
claim
.
Countered
==
countered
})
}
func
(
g
*
FaultGameHelper
)
Resolve
(
ctx
context
.
Context
)
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
time
.
Minute
)
defer
cancel
()
tx
,
err
:=
g
.
game
.
Resolve
(
g
.
opts
)
g
.
require
.
NoError
(
err
)
_
,
err
=
utils
.
WaitReceiptOK
(
ctx
,
g
.
client
,
tx
.
Hash
())
g
.
require
.
NoError
(
err
)
}
func
(
g
*
FaultGameHelper
)
WaitForGameStatus
(
ctx
context
.
Context
,
expected
Status
)
{
g
.
t
.
Logf
(
"Waiting for game %v to have status %v"
,
g
.
addr
,
expected
)
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
time
.
Minute
)
defer
cancel
()
err
:=
utils
.
WaitFor
(
ctx
,
time
.
Second
,
func
()
(
bool
,
error
)
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
30
*
time
.
Second
)
defer
cancel
()
status
,
err
:=
g
.
game
.
Status
(
&
bind
.
CallOpts
{
Context
:
ctx
})
if
err
!=
nil
{
return
false
,
fmt
.
Errorf
(
"game status unavailable: %w"
,
err
)
}
g
.
t
.
Logf
(
"Game %v has state %v, waiting for state %v"
,
g
.
addr
,
Status
(
status
),
expected
)
return
expected
==
Status
(
status
),
nil
})
g
.
require
.
NoError
(
err
,
"wait for game status"
)
}
op-e2e/e2eutils/disputegame/helper.go
View file @
e688629c
...
...
@@ -11,10 +11,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-chain-ops/deployer"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/fault/alphabet"
"github.com/ethereum-optimism/optimism/op-challenger/fault/types"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-service/client/utils"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
...
...
@@ -22,8 +19,10 @@ import (
"github.com/stretchr/testify/require"
)
const
faultGameType
uint8
=
0
const
alphabetGameType
uint8
=
0
const
cannonGameType
uint8
=
1
const
alphabetGameDepth
=
4
const
cannonGameDepth
=
64
const
lastAlphabetTraceIndex
=
1
<<
alphabetGameDepth
-
1
type
Status
uint8
...
...
@@ -86,38 +85,20 @@ func NewFactoryHelper(t *testing.T, ctx context.Context, deployments *genesis.L1
}
}
func
(
h
*
FactoryHelper
)
StartAlphabetGame
(
ctx
context
.
Context
,
claimedAlphabet
string
)
*
FaultGameHelper
{
// Wait for two output proposals to be published
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
2
*
time
.
Minute
)
defer
cancel
()
err
:=
utils
.
WaitFor
(
ctx
,
time
.
Second
,
func
()
(
bool
,
error
)
{
index
,
err
:=
h
.
l2oo
.
LatestOutputIndex
(
&
bind
.
CallOpts
{
Context
:
ctx
})
if
err
!=
nil
{
h
.
t
.
Logf
(
"Could not get latest output index: %v"
,
err
.
Error
())
return
false
,
nil
}
h
.
t
.
Logf
(
"Latest output index: %v"
,
index
)
return
index
.
Cmp
(
big
.
NewInt
(
1
))
>=
0
,
nil
})
h
.
require
.
NoError
(
err
,
"Did not get two output roots"
)
func
(
h
*
FactoryHelper
)
StartAlphabetGame
(
ctx
context
.
Context
,
claimedAlphabet
string
)
*
AlphabetGameHelper
{
h
.
waitForProposals
(
ctx
)
l1Head
:=
h
.
checkpointL1Block
(
ctx
)
ctx
,
cancel
=
context
.
WithTimeout
(
ctx
,
1
*
time
.
Minute
)
ctx
,
cancel
:
=
context
.
WithTimeout
(
ctx
,
1
*
time
.
Minute
)
defer
cancel
()
// Store the current block in the oracle
tx
,
err
:=
h
.
blockOracle
.
Checkpoint
(
h
.
opts
)
h
.
require
.
NoError
(
err
)
r
,
err
:=
utils
.
WaitReceiptOK
(
ctx
,
h
.
client
,
tx
.
Hash
())
h
.
require
.
NoError
(
err
,
"failed to store block in blockoracle"
)
l1Head
:=
new
(
big
.
Int
)
.
Sub
(
r
.
BlockNumber
,
big
.
NewInt
(
1
))
trace
:=
alphabet
.
NewTraceProvider
(
claimedAlphabet
,
alphabetGameDepth
)
rootClaim
,
err
:=
trace
.
Get
(
ctx
,
lastAlphabetTraceIndex
)
h
.
require
.
NoError
(
err
,
"get root claim"
)
extraData
:=
make
([]
byte
,
64
)
binary
.
BigEndian
.
PutUint64
(
extraData
[
24
:
],
uint64
(
8
))
binary
.
BigEndian
.
PutUint64
(
extraData
[
56
:
],
l1Head
.
Uint64
())
tx
,
err
=
h
.
factory
.
Create
(
h
.
opts
,
faul
tGameType
,
rootClaim
,
extraData
)
tx
,
err
:=
h
.
factory
.
Create
(
h
.
opts
,
alphabe
tGameType
,
rootClaim
,
extraData
)
h
.
require
.
NoError
(
err
,
"create fault dispute game"
)
rcpt
,
err
:=
utils
.
WaitReceiptOK
(
ctx
,
h
.
client
,
tx
.
Hash
())
h
.
require
.
NoError
(
err
,
"wait for create fault dispute game receipt to be OK"
)
...
...
@@ -126,129 +107,79 @@ func (h *FactoryHelper) StartAlphabetGame(ctx context.Context, claimedAlphabet s
h
.
require
.
NoError
(
err
)
game
,
err
:=
bindings
.
NewFaultDisputeGame
(
createdEvent
.
DisputeProxy
,
h
.
client
)
h
.
require
.
NoError
(
err
)
return
&
FaultGameHelper
{
t
:
h
.
t
,
require
:
h
.
require
,
client
:
h
.
client
,
opts
:
h
.
opts
,
game
:
game
,
maxDepth
:
alphabetGameDepth
,
addr
:
createdEvent
.
DisputeProxy
,
claimedAlphabet
:
claimedAlphabet
,
}
}
type
FaultGameHelper
struct
{
t
*
testing
.
T
require
*
require
.
Assertions
client
*
ethclient
.
Client
opts
*
bind
.
TransactOpts
game
*
bindings
.
FaultDisputeGame
maxDepth
int
addr
common
.
Address
claimedAlphabet
string
}
func
(
g
*
FaultGameHelper
)
StartChallenger
(
ctx
context
.
Context
,
l1Endpoint
string
,
name
string
,
options
...
challenger
.
Option
)
*
challenger
.
Helper
{
opts
:=
[]
challenger
.
Option
{
func
(
c
*
config
.
Config
)
{
c
.
GameAddress
=
g
.
addr
c
.
GameDepth
=
alphabetGameDepth
c
.
TraceType
=
config
.
TraceTypeAlphabet
// By default the challenger agrees with the root claim (thus disagrees with the proposed output)
// This can be overridden by passing in options
c
.
AlphabetTrace
=
g
.
claimedAlphabet
c
.
AgreeWithProposedOutput
=
false
return
&
AlphabetGameHelper
{
FaultGameHelper
:
FaultGameHelper
{
t
:
h
.
t
,
require
:
h
.
require
,
client
:
h
.
client
,
opts
:
h
.
opts
,
game
:
game
,
maxDepth
:
alphabetGameDepth
,
addr
:
createdEvent
.
DisputeProxy
,
},
claimedAlphabet
:
claimedAlphabet
,
}
opts
=
append
(
opts
,
options
...
)
c
:=
challenger
.
NewChallenger
(
g
.
t
,
ctx
,
l1Endpoint
,
name
,
opts
...
)
g
.
t
.
Cleanup
(
func
()
{
_
=
c
.
Close
()
})
return
c
}
func
(
g
*
FaultGameHelper
)
GameDuration
(
ctx
context
.
Context
)
time
.
Duration
{
duration
,
err
:=
g
.
game
.
GAMEDURATION
(
&
bind
.
CallOpts
{
Context
:
ctx
})
g
.
require
.
NoError
(
err
,
"failed to get game duration"
)
return
time
.
Duration
(
duration
)
*
time
.
Second
}
func
(
h
*
FactoryHelper
)
StartCannonGame
(
ctx
context
.
Context
,
rootClaim
common
.
Hash
)
*
CannonGameHelper
{
h
.
waitForProposals
(
ctx
)
l1Head
:=
h
.
checkpointL1Block
(
ctx
)
func
(
g
*
FaultGameHelper
)
WaitForClaimCount
(
ctx
context
.
Context
,
count
int64
)
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
1
*
time
.
Minute
)
defer
cancel
()
err
:=
utils
.
WaitFor
(
ctx
,
1
*
time
.
Second
,
func
()
(
bool
,
error
)
{
actual
,
err
:=
g
.
game
.
ClaimDataLen
(
&
bind
.
CallOpts
{
Context
:
ctx
})
if
err
!=
nil
{
return
false
,
err
}
g
.
t
.
Log
(
"Waiting for claim count"
,
"current"
,
actual
,
"expected"
,
count
,
"game"
,
g
.
addr
)
return
actual
.
Cmp
(
big
.
NewInt
(
count
))
==
0
,
nil
})
g
.
require
.
NoError
(
err
)
}
type
ContractClaim
struct
{
ParentIndex
uint32
Countered
bool
Claim
[
32
]
byte
Position
*
big
.
Int
Clock
*
big
.
Int
extraData
:=
make
([]
byte
,
64
)
binary
.
BigEndian
.
PutUint64
(
extraData
[
24
:
],
uint64
(
8
))
binary
.
BigEndian
.
PutUint64
(
extraData
[
56
:
],
l1Head
.
Uint64
())
tx
,
err
:=
h
.
factory
.
Create
(
h
.
opts
,
cannonGameType
,
rootClaim
,
extraData
)
h
.
require
.
NoError
(
err
,
"create fault dispute game"
)
rcpt
,
err
:=
utils
.
WaitReceiptOK
(
ctx
,
h
.
client
,
tx
.
Hash
())
h
.
require
.
NoError
(
err
,
"wait for create fault dispute game receipt to be OK"
)
h
.
require
.
Len
(
rcpt
.
Logs
,
1
,
"should have emitted a single DisputeGameCreated event"
)
createdEvent
,
err
:=
h
.
factory
.
ParseDisputeGameCreated
(
*
rcpt
.
Logs
[
0
])
h
.
require
.
NoError
(
err
)
game
,
err
:=
bindings
.
NewFaultDisputeGame
(
createdEvent
.
DisputeProxy
,
h
.
client
)
h
.
require
.
NoError
(
err
)
return
&
CannonGameHelper
{
FaultGameHelper
:
FaultGameHelper
{
t
:
h
.
t
,
require
:
h
.
require
,
client
:
h
.
client
,
opts
:
h
.
opts
,
game
:
game
,
maxDepth
:
cannonGameDepth
,
addr
:
createdEvent
.
DisputeProxy
,
},
}
}
func
(
g
*
FaultGameHelper
)
WaitForClaim
(
ctx
context
.
Context
,
predicate
func
(
claim
ContractClaim
)
bool
)
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
1
*
time
.
Minute
)
// waitForProposals waits until there are at least two proposals in the output oracle
// This is the minimum required for creating a game.
func
(
h
*
FactoryHelper
)
waitForProposals
(
ctx
context
.
Context
)
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
2
*
time
.
Minute
)
defer
cancel
()
err
:=
utils
.
WaitFor
(
ctx
,
1
*
time
.
Second
,
func
()
(
bool
,
error
)
{
count
,
err
:=
g
.
game
.
ClaimDataLen
(
&
bind
.
CallOpts
{
Context
:
ctx
})
err
:=
utils
.
WaitFor
(
ctx
,
time
.
Second
,
func
()
(
bool
,
error
)
{
index
,
err
:=
h
.
l2oo
.
LatestOutputIndex
(
&
bind
.
CallOpts
{
Context
:
ctx
})
if
err
!=
nil
{
return
false
,
fmt
.
Errorf
(
"retrieve number of claims: %w"
,
err
)
}
// Search backwards because the new claims are at the end and more likely the ones we want.
for
i
:=
count
.
Int64
()
-
1
;
i
>=
0
;
i
--
{
claimData
,
err
:=
g
.
game
.
ClaimData
(
&
bind
.
CallOpts
{
Context
:
ctx
},
big
.
NewInt
(
i
))
if
err
!=
nil
{
return
false
,
fmt
.
Errorf
(
"retrieve claim %v: %w"
,
i
,
err
)
}
if
predicate
(
claimData
)
{
return
true
,
nil
}
h
.
t
.
Logf
(
"Could not get latest output index: %v"
,
err
.
Error
())
return
false
,
nil
}
return
false
,
nil
})
g
.
require
.
NoError
(
err
)
}
func
(
g
*
FaultGameHelper
)
WaitForClaimAtMaxDepth
(
ctx
context
.
Context
,
countered
bool
)
{
g
.
WaitForClaim
(
ctx
,
func
(
claim
ContractClaim
)
bool
{
pos
:=
types
.
NewPositionFromGIndex
(
claim
.
Position
.
Uint64
())
return
pos
.
Depth
()
==
g
.
maxDepth
&&
claim
.
Countered
==
countered
h
.
t
.
Logf
(
"Latest output index: %v"
,
index
)
return
index
.
Cmp
(
big
.
NewInt
(
1
))
>=
0
,
nil
})
h
.
require
.
NoError
(
err
,
"Did not get two output roots"
)
}
func
(
g
*
FaultGameHelper
)
Resolve
(
ctx
context
.
Context
)
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
1
*
time
.
Minute
)
defer
cancel
()
tx
,
err
:=
g
.
game
.
Resolve
(
g
.
opts
)
g
.
require
.
NoError
(
err
)
_
,
err
=
utils
.
WaitReceiptOK
(
ctx
,
g
.
client
,
tx
.
Hash
())
g
.
require
.
NoError
(
err
)
}
func
(
g
*
FaultGameHelper
)
WaitForGameStatus
(
ctx
context
.
Context
,
expected
Status
)
{
g
.
t
.
Logf
(
"Waiting for game %v to have status %v"
,
g
.
addr
,
expected
)
// checkpointL1Block stores the current L1 block in the oracle
// Returns the L1 block number that was stored as the checkpoint
func
(
h
*
FactoryHelper
)
checkpointL1Block
(
ctx
context
.
Context
)
*
big
.
Int
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
1
*
time
.
Minute
)
defer
cancel
()
err
:=
utils
.
WaitFor
(
ctx
,
1
*
time
.
Second
,
func
()
(
bool
,
error
)
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
30
*
time
.
Second
)
defer
cancel
()
status
,
err
:=
g
.
game
.
Status
(
&
bind
.
CallOpts
{
Context
:
ctx
})
if
err
!=
nil
{
return
false
,
fmt
.
Errorf
(
"game status unavailable: %w"
,
err
)
}
g
.
t
.
Logf
(
"Game %v has state %v, waiting for state %v"
,
g
.
addr
,
Status
(
status
),
expected
)
return
expected
==
Status
(
status
),
nil
})
g
.
require
.
NoError
(
err
,
"wait for game status"
)
// Store the current block in the oracle
tx
,
err
:=
h
.
blockOracle
.
Checkpoint
(
h
.
opts
)
h
.
require
.
NoError
(
err
)
r
,
err
:=
utils
.
WaitReceiptOK
(
ctx
,
h
.
client
,
tx
.
Hash
())
h
.
require
.
NoError
(
err
,
"failed to store block in block oracle"
)
return
new
(
big
.
Int
)
.
Sub
(
r
.
BlockNumber
,
big
.
NewInt
(
1
))
}
op-e2e/faultproof_test.go
View file @
e688629c
...
...
@@ -8,6 +8,7 @@ import (
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame"
"github.com/ethereum-optimism/optimism/op-service/client/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/stretchr/testify/require"
)
...
...
@@ -143,6 +144,32 @@ func TestChallengerCompleteDisputeGame(t *testing.T) {
}
}
func
TestCannonDisputeGame
(
t
*
testing
.
T
)
{
t
.
Skip
(
"CLI-4290: op-challenger doesn't handle trace extension correctly for cannon"
)
InitParallel
(
t
)
ctx
:=
context
.
Background
()
sys
,
l1Client
:=
startFaultDisputeSystem
(
t
)
t
.
Cleanup
(
sys
.
Close
)
disputeGameFactory
:=
disputegame
.
NewFactoryHelper
(
t
,
ctx
,
sys
.
cfg
.
L1Deployments
,
l1Client
)
game
:=
disputeGameFactory
.
StartCannonGame
(
ctx
,
common
.
Hash
{
0xaa
})
require
.
NotNil
(
t
,
game
)
game
.
StartChallenger
(
ctx
,
sys
.
NodeEndpoint
(
"l1"
),
sys
.
NodeEndpoint
(
"sequencer"
),
"Challenger"
,
func
(
c
*
config
.
Config
)
{
c
.
AgreeWithProposedOutput
=
true
// Agree with the proposed output, so disagree with the root claim
c
.
TxMgrConfig
.
PrivateKey
=
e2eutils
.
EncodePrivKeyToString
(
sys
.
cfg
.
Secrets
.
Alice
)
})
// Challenger should counter the root claim
game
.
WaitForClaimCount
(
ctx
,
2
)
sys
.
TimeTravelClock
.
AdvanceTime
(
game
.
GameDuration
(
ctx
))
require
.
NoError
(
t
,
utils
.
WaitNextBlock
(
ctx
,
l1Client
))
game
.
WaitForGameStatus
(
ctx
,
disputegame
.
StatusChallengerWins
)
}
func
startFaultDisputeSystem
(
t
*
testing
.
T
)
(
*
System
,
*
ethclient
.
Client
)
{
cfg
:=
DefaultSystemConfig
(
t
)
delete
(
cfg
.
Nodes
,
"verifier"
)
...
...
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