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
16f0aad4
Unverified
Commit
16f0aad4
authored
Sep 19, 2023
by
OptimismBot
Committed by
GitHub
Sep 19, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #7061 from ethereum-optimism/inphi/fdg-rez
feat(ctb): Rework FaultDisputeGame resolution
parents
220846d9
0b5f3aba
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
1019 additions
and
388 deletions
+1019
-388
faultdisputegame.go
op-bindings/bindings/faultdisputegame.go
+23
-2
faultdisputegame_more.go
op-bindings/bindings/faultdisputegame_more.go
+2
-2
agent.go
op-challenger/game/fault/agent.go
+61
-0
agent_test.go
op-challenger/game/fault/agent_test.go
+20
-3
responder.go
op-challenger/game/fault/responder/responder.go
+28
-0
responder_test.go
op-challenger/game/fault/responder/responder_test.go
+34
-0
game_solver.go
op-challenger/game/fault/solver/game_solver.go
+9
-3
game_solver_test.go
op-challenger/game/fault/solver/game_solver_test.go
+9
-11
rules.go
op-challenger/game/fault/solver/rules.go
+1
-10
solver.go
op-challenger/game/fault/solver/solver.go
+60
-9
solver_test.go
op-challenger/game/fault/solver/solver_test.go
+118
-153
claim_builder.go
op-challenger/game/fault/test/claim_builder.go
+2
-1
game.go
op-challenger/game/fault/types/game.go
+53
-26
game_test.go
op-challenger/game/fault/types/game_test.go
+21
-39
helper.go
op-e2e/e2eutils/challenger/helper.go
+7
-1
alphabet_helper.go
op-e2e/e2eutils/disputegame/alphabet_helper.go
+10
-0
game_helper.go
op-e2e/e2eutils/disputegame/game_helper.go
+200
-2
faultproof_test.go
op-e2e/faultproof_test.go
+109
-25
.gas-snapshot
packages/contracts-bedrock/.gas-snapshot
+37
-31
semver-lock.json
packages/contracts-bedrock/semver-lock.json
+1
-1
FaultDisputeGame.sol
packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol
+60
-53
IFaultDisputeGame.sol
...acts-bedrock/src/dispute/interfaces/IFaultDisputeGame.sol
+8
-0
LibHashing.sol
packages/contracts-bedrock/src/dispute/lib/LibHashing.sol
+12
-3
DisputeErrors.sol
packages/contracts-bedrock/src/libraries/DisputeErrors.sol
+6
-0
FaultDisputeGame.t.sol
packages/contracts-bedrock/test/FaultDisputeGame.t.sol
+128
-13
No files found.
op-bindings/bindings/faultdisputegame.go
View file @
16f0aad4
...
@@ -37,8 +37,8 @@ type IFaultDisputeGameOutputProposal struct {
...
@@ -37,8 +37,8 @@ type IFaultDisputeGameOutputProposal struct {
// FaultDisputeGameMetaData contains all meta data concerning the FaultDisputeGame contract.
// FaultDisputeGameMetaData contains all meta data concerning the FaultDisputeGame contract.
var
FaultDisputeGameMetaData
=
&
bind
.
MetaData
{
var
FaultDisputeGameMetaData
=
&
bind
.
MetaData
{
ABI
:
"[{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
GameType
\"
,
\"
name
\"
:
\"
_gameType
\"
,
\"
type
\"
:
\"
uint8
\"
},{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
_absolutePrestate
\"
,
\"
type
\"
:
\"
bytes32
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_maxGameDepth
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
Duration
\"
,
\"
name
\"
:
\"
_gameDuration
\"
,
\"
type
\"
:
\"
uint64
\"
},{
\"
internalType
\"
:
\"
contractIBigStepper
\"
,
\"
name
\"
:
\"
_vm
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
contractL2OutputOracle
\"
,
\"
name
\"
:
\"
_l2oo
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
contractBlockOracle
\"
,
\"
name
\"
:
\"
_blockOracle
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
constructor
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
CannotDefendRootClaim
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
ClaimAlreadyExists
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
Cl
ockNotExpired
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
ClockTimeExceeded
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
GameDepthExceeded
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
GameNotInProgress
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
InvalidParent
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
InvalidPrestate
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
L1HeadTooOld
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
rootClaim
\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
name
\"
:
\"
UnexpectedRootClaim
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
ValidStep
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
parentIndex
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
claim
\"
,
\"
type
\"
:
\"
bytes32
\"
},{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
claimant
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
Move
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
enumGameStatus
\"
,
\"
name
\"
:
\"
status
\"
,
\"
type
\"
:
\"
uint8
\"
}],
\"
name
\"
:
\"
Resolved
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
ABSOLUTE_PRESTATE
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
BLOCK_ORACLE
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
contractBlockOracle
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
GAME_DURATION
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
Duration
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint64
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
L2_OUTPUT_ORACLE
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
contractL2OutputOracle
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
MAX_GAME_DEPTH
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
VM
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
contractIBigStepper
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_ident
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_partOffset
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
addLocalData
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_parentIndex
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
_claim
\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
name
\"
:
\"
attack
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
payable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
bondManager
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
contractIBondManager
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
claimData
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint32
\"
,
\"
name
\"
:
\"
parentIndex
\"
,
\"
type
\"
:
\"
uint32
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
countered
\"
,
\"
type
\"
:
\"
bool
\"
},{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
claim
\"
,
\"
type
\"
:
\"
bytes32
\"
},{
\"
internalType
\"
:
\"
Position
\"
,
\"
name
\"
:
\"
position
\"
,
\"
type
\"
:
\"
uint128
\"
},{
\"
internalType
\"
:
\"
Clock
\"
,
\"
name
\"
:
\"
clock
\"
,
\"
type
\"
:
\"
uint128
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
claimDataLen
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
len_
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
createdAt
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
Timestamp
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint64
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_parentIndex
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
_claim
\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
name
\"
:
\"
defend
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
payable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
extraData
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bytes
\"
,
\"
name
\"
:
\"
extraData_
\"
,
\"
type
\"
:
\"
bytes
\"
}],
\"
stateMutability
\"
:
\"
pure
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
gameData
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
GameType
\"
,
\"
name
\"
:
\"
gameType_
\"
,
\"
type
\"
:
\"
uint8
\"
},{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
rootClaim_
\"
,
\"
type
\"
:
\"
bytes32
\"
},{
\"
internalType
\"
:
\"
bytes
\"
,
\"
name
\"
:
\"
extraData_
\"
,
\"
type
\"
:
\"
bytes
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
gameType
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
GameType
\"
,
\"
name
\"
:
\"
gameType_
\"
,
\"
type
\"
:
\"
uint8
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
initialize
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
l1BlockNumber
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
l1BlockNumber_
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
pure
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
l1Head
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
Hash
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
l2BlockNumber
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
l2BlockNumber_
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
pure
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_challengeIndex
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
_claim
\"
,
\"
type
\"
:
\"
bytes32
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
_isAttack
\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
name
\"
:
\"
move
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
payable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
proposals
\"
,
\"
outputs
\"
:[{
\"
components
\"
:[{
\"
internalType
\"
:
\"
uint128
\"
,
\"
name
\"
:
\"
index
\"
,
\"
type
\"
:
\"
uint128
\"
},{
\"
internalType
\"
:
\"
uint128
\"
,
\"
name
\"
:
\"
l2BlockNumber
\"
,
\"
type
\"
:
\"
uint128
\"
},{
\"
internalType
\"
:
\"
Hash
\"
,
\"
name
\"
:
\"
outputRoot
\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
internalType
\"
:
\"
structIFaultDisputeGame.OutputProposal
\"
,
\"
name
\"
:
\"
starting
\"
,
\"
type
\"
:
\"
tuple
\"
},{
\"
components
\"
:[{
\"
internalType
\"
:
\"
uint128
\"
,
\"
name
\"
:
\"
index
\"
,
\"
type
\"
:
\"
uint128
\"
},{
\"
internalType
\"
:
\"
uint128
\"
,
\"
name
\"
:
\"
l2BlockNumber
\"
,
\"
type
\"
:
\"
uint128
\"
},{
\"
internalType
\"
:
\"
Hash
\"
,
\"
name
\"
:
\"
outputRoot
\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
internalType
\"
:
\"
structIFaultDisputeGame.OutputProposal
\"
,
\"
name
\"
:
\"
disputed
\"
,
\"
type
\"
:
\"
tuple
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
resolve
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
enumGameStatus
\"
,
\"
name
\"
:
\"
status_
\"
,
\"
type
\"
:
\"
uint8
\"
}],
\"
stateMutability
\"
:
\"
non
payable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
rootClaim
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
rootClaim_
\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
stateMutability
\"
:
\"
pure
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
status
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
enumGameStatus
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint8
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_claimIndex
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
_isAttack
\"
,
\"
type
\"
:
\"
bool
\"
},{
\"
internalType
\"
:
\"
bytes
\"
,
\"
name
\"
:
\"
_stateData
\"
,
\"
type
\"
:
\"
bytes
\"
},{
\"
internalType
\"
:
\"
bytes
\"
,
\"
name
\"
:
\"
_proof
\"
,
\"
type
\"
:
\"
bytes
\"
}],
\"
name
\"
:
\"
step
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
version
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
string
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
string
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
}]"
,
ABI
:
"[{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
GameType
\"
,
\"
name
\"
:
\"
_gameType
\"
,
\"
type
\"
:
\"
uint8
\"
},{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
_absolutePrestate
\"
,
\"
type
\"
:
\"
bytes32
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_maxGameDepth
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
Duration
\"
,
\"
name
\"
:
\"
_gameDuration
\"
,
\"
type
\"
:
\"
uint64
\"
},{
\"
internalType
\"
:
\"
contractIBigStepper
\"
,
\"
name
\"
:
\"
_vm
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
contractL2OutputOracle
\"
,
\"
name
\"
:
\"
_l2oo
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
contractBlockOracle
\"
,
\"
name
\"
:
\"
_blockOracle
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
constructor
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
CannotDefendRootClaim
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
ClaimAlreadyExists
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
Cl
aimAlreadyResolved
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
ClockNotExpired
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
ClockTimeExceeded
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
GameDepthExceeded
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
GameNotInProgress
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
InvalidParent
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
InvalidPrestate
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
L1HeadTooOld
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
OutOfOrderResolution
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
rootClaim
\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
name
\"
:
\"
UnexpectedRootClaim
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
ValidStep
\"
,
\"
type
\"
:
\"
error
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
parentIndex
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
claim
\"
,
\"
type
\"
:
\"
bytes32
\"
},{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
claimant
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
Move
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
enumGameStatus
\"
,
\"
name
\"
:
\"
status
\"
,
\"
type
\"
:
\"
uint8
\"
}],
\"
name
\"
:
\"
Resolved
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
ABSOLUTE_PRESTATE
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
BLOCK_ORACLE
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
contractBlockOracle
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
GAME_DURATION
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
Duration
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint64
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
L2_OUTPUT_ORACLE
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
contractL2OutputOracle
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
MAX_GAME_DEPTH
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
VM
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
contractIBigStepper
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_ident
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_partOffset
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
addLocalData
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_parentIndex
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
_claim
\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
name
\"
:
\"
attack
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
payable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
bondManager
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
contractIBondManager
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
claimData
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint32
\"
,
\"
name
\"
:
\"
parentIndex
\"
,
\"
type
\"
:
\"
uint32
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
countered
\"
,
\"
type
\"
:
\"
bool
\"
},{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
claim
\"
,
\"
type
\"
:
\"
bytes32
\"
},{
\"
internalType
\"
:
\"
Position
\"
,
\"
name
\"
:
\"
position
\"
,
\"
type
\"
:
\"
uint128
\"
},{
\"
internalType
\"
:
\"
Clock
\"
,
\"
name
\"
:
\"
clock
\"
,
\"
type
\"
:
\"
uint128
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
claimDataLen
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
len_
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
createdAt
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
Timestamp
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint64
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_parentIndex
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
_claim
\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
name
\"
:
\"
defend
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
payable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
extraData
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bytes
\"
,
\"
name
\"
:
\"
extraData_
\"
,
\"
type
\"
:
\"
bytes
\"
}],
\"
stateMutability
\"
:
\"
pure
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
gameData
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
GameType
\"
,
\"
name
\"
:
\"
gameType_
\"
,
\"
type
\"
:
\"
uint8
\"
},{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
rootClaim_
\"
,
\"
type
\"
:
\"
bytes32
\"
},{
\"
internalType
\"
:
\"
bytes
\"
,
\"
name
\"
:
\"
extraData_
\"
,
\"
type
\"
:
\"
bytes
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
gameType
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
GameType
\"
,
\"
name
\"
:
\"
gameType_
\"
,
\"
type
\"
:
\"
uint8
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
initialize
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
l1BlockNumber
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
l1BlockNumber_
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
pure
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
l1Head
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
Hash
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
l2BlockNumber
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
l2BlockNumber_
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
pure
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_challengeIndex
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
_claim
\"
,
\"
type
\"
:
\"
bytes32
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
_isAttack
\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
name
\"
:
\"
move
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
payable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
proposals
\"
,
\"
outputs
\"
:[{
\"
components
\"
:[{
\"
internalType
\"
:
\"
uint128
\"
,
\"
name
\"
:
\"
index
\"
,
\"
type
\"
:
\"
uint128
\"
},{
\"
internalType
\"
:
\"
uint128
\"
,
\"
name
\"
:
\"
l2BlockNumber
\"
,
\"
type
\"
:
\"
uint128
\"
},{
\"
internalType
\"
:
\"
Hash
\"
,
\"
name
\"
:
\"
outputRoot
\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
internalType
\"
:
\"
structIFaultDisputeGame.OutputProposal
\"
,
\"
name
\"
:
\"
starting
\"
,
\"
type
\"
:
\"
tuple
\"
},{
\"
components
\"
:[{
\"
internalType
\"
:
\"
uint128
\"
,
\"
name
\"
:
\"
index
\"
,
\"
type
\"
:
\"
uint128
\"
},{
\"
internalType
\"
:
\"
uint128
\"
,
\"
name
\"
:
\"
l2BlockNumber
\"
,
\"
type
\"
:
\"
uint128
\"
},{
\"
internalType
\"
:
\"
Hash
\"
,
\"
name
\"
:
\"
outputRoot
\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
internalType
\"
:
\"
structIFaultDisputeGame.OutputProposal
\"
,
\"
name
\"
:
\"
disputed
\"
,
\"
type
\"
:
\"
tuple
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
resolve
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
enumGameStatus
\"
,
\"
name
\"
:
\"
status_
\"
,
\"
type
\"
:
\"
uint8
\"
}],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_claimIndex
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
resolveClaim
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
payable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
rootClaim
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
Claim
\"
,
\"
name
\"
:
\"
rootClaim_
\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
stateMutability
\"
:
\"
pure
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
status
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
enumGameStatus
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint8
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
_claimIndex
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
_isAttack
\"
,
\"
type
\"
:
\"
bool
\"
},{
\"
internalType
\"
:
\"
bytes
\"
,
\"
name
\"
:
\"
_stateData
\"
,
\"
type
\"
:
\"
bytes
\"
},{
\"
internalType
\"
:
\"
bytes
\"
,
\"
name
\"
:
\"
_proof
\"
,
\"
type
\"
:
\"
bytes
\"
}],
\"
name
\"
:
\"
step
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
version
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
string
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
string
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
}]"
,
Bin
:
"0x6101c06040523480156200001257600080fd5b5060405162002d
6238038062002d628339810160408190526200003591620000a1565b6000608081905260a052600960c05260ff9096166101a05260e094909452610100929092526001600160401b0316610120526001600160a01b039081166101405290811661016052166101805262000145565b6001600160a01b03811681146200009e57600080fd5b50565b600080600080600080600060e0888a031215620000bd57600080fd5b875160ff81168114620000cf57600080fd5b602089015160408a015160608b015192995090975095506001600160401b0381168114620000fc57600080fd5b60808901519094506200010f8162000088565b60a0890151909350620001228162000088565b60c0890151909250620001358162000088565b8091505092959891949750929550565b60805160a05160c05160e05161010051610120516101405161016051610180516101a051612b466200021c600039600081816105220152611f0c01526000818161035e015261178d01526000818161059b0152818161155a0152818161162e01526117070152600081816104ec015281816107450152611c8b0152600081816105cf01528181610ab7015261109801526000818161032a015281816109bf01528181610ed70152611a8a0152600081816102210152611be601526000610d3401526000610d0b01526000610ce20152612b466000f3fe6080604052600436106101ac5760003560e01c80636361506d116100ec578063c0c3a0921161008a578063c6f0308c11610064578063c6f0308c1461061d578063cf09e0d014610681578063d8cc1a3c146106a2578063fa24f743146106c257600080fd5b8063c0c3a09214610589578063c31b29ce146105bd578063c55cd0c71461060a57600080fd5b80638b85902b116100c65780638b85902b1461049a57806392931298146104da578063bbdc02db1461050e578063bcef3b551461054c57600080fd5b80636361506d1461045a5780638129fc1c146104705780638980e0cc1461048557600080fd5b8063363cc4271161015957806354fd4d501161013357806354fd4d501461038057806355ef20e6146103a2578063609d333414610432578063632247ea1461044757600080fd5b8063363cc427146102b95780634778efe814610318578063529184c91461034c57600080fd5b80632810e1d61161018a5780632810e1d614610251578063298c90051461026657806335fef567146102a657600080fd5b80631e27052a146101b1578063200d2ed2146101d3578063266198f91461020f575b600080fd5b3480156101bd57600080fd5b506101d16101cc3660046123e7565b6106e6565b005b3480156101df57600080fd5b506000546101f99068010000000000000000900460ff1681565b6040516102069190612438565b60405180910390f35b34801561021b57600080fd5b506102437f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610206565b34801561025d57600080fd5b506101f96108a5565b34801561027257600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360400135610243565b6101d16102b43660046123e7565b610ccb565b3480156102c557600080fd5b506000546102f3906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610206565b34801561032457600080fd5b506102437f000000000000000000000000000000000000000000000000000000000000000081565b34801561035857600080fd5b506102f37f000000000000000000000000000000000000000000000000000000000000000081565b34801561038c57600080fd5b50610395610cdb565b60405161020691906124ef565b3480156103ae57600080fd5b5060408051606080820183526003546fffffffffffffffffffffffffffffffff808216845270010000000000000000000000000000000091829004811660208086019190915260045485870152855193840186526005548083168552929092041690820152600654928101929092526104249182565b604051610206929190612509565b34801561043e57600080fd5b50610395610d7e565b6101d1610455366004612572565b610d8c565b34801561046657600080fd5b5061024360015481565b34801561047c57600080fd5b506101d1611360565b34801561049157600080fd5b50600254610243565b3480156104a657600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360200135610243565b3480156104e657600080fd5b506102f37f000000000000000000000000000000000000000000000000000000000000000081565b34801561051a57600080fd5b5060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610206565b34801561055857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335610243565b34801561059557600080fd5b506102f37f000000000000000000000000000000000000000000000000000000000000000081565b3480156105c957600080fd5b506105f17f000000000000000000000000000000000000000000000000000000000000000081565b60405167ffffffffffffffff9091168152602001610206565b6101d16106183660046123e7565b611964565b34801561062957600080fd5b5061063d6106383660046125a7565b611970565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a001610206565b34801561068d57600080fd5b506000546105f19067ffffffffffffffff1681565b3480156106ae57600080fd5b506101d16106bd366004612609565b6119e1565b3480156106ce57600080fd5b506106d7611f0a565b60405161020693929190612693565b6000805468010000000000000000900460ff16600281111561070a5761070a612409565b14610741576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d291906126be565b7f9a1f5e7f00000000000000000000000000000000000000000000000000000000601c8190526020859052909150600084600181146108395760028114610843576003811461084d576004811461085757600581146108675763ff137e656000526004601cfd5b600154915061086e565b600454915061086e565b600654915061086e565b60035460801c60c01b915061086e565b4660c01b91505b50604052600160038511811b6005031b60605260808390526000806084601c82865af161089f573d6000803e3d6000fd5b50505050565b60008060005468010000000000000000900460ff1660028111156108cb576108cb612409565b14610902576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460009061091490600190612723565b90506fffffffffffffffffffffffffffffffff815b67ffffffffffffffff8110156109fe5760006002828154811061094e5761094e61273a565b6000918252602090912060039091020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9093019290915060ff640100000000909104161561099f5750610929565b60028101546000906109e3906fffffffffffffffffffffffffffffffff167f0000000000000000000000000000000000000000000000000000000000000000611f67565b9050838110156109f7578093508260010194505b5050610929565b50600060028381548110610a1457610a1461273a565b600091825260208220600390910201805490925063ffffffff90811691908214610a7e5760028281548110610a4b57610a4b61273a565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff16610aaa565b600283015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff165b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c16610aee67ffffffffffffffff831642612723565b610b0a836fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610b1e9190612769565b11610b55576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600283810154610bf7906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b610c0191906127b0565b67ffffffffffffffff16158015610c2857506fffffffffffffffffffffffffffffffff8414155b15610c365760029550610c3b565b600195505b600080548791907fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff1668010000000000000000836002811115610c8057610c80612409565b021790556002811115610c9557610c95612409565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a2505050505090565b905090565b610cd782826000610d8c565b5050565b6060610d067f000000000000000000000000000000000000000000000000000000000000000061201c565b610d2f7f000000000000000000000000000000000000000000000000000000000000000061201c565b610d587f000000000000000000000000000000000000000000000000000000000000000061201c565b604051602001610d6a939291906127d7565b604051602081830303815290604052905090565b6060610cc660206040612159565b6000805468010000000000000000900460ff166002811115610db057610db0612409565b14610de7576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82158015610df3575080155b15610e2a576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110610e3f57610e3f61273a565b600091825260208083206040805160a081018252600394909402909101805463ffffffff808216865264010000000090910460ff16151593850193909352600181015491840191909152600201546fffffffffffffffffffffffffffffffff80821660608501819052700100000000000000000000000000000000909204166080840152919350610ed3919085906121f016565b90507f0000000000000000000000000000000000000000000000000000000000000000610f92826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161115610fd4576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160009063ffffffff90811614611034576002836000015163ffffffff16815481106110035761100361273a565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608083015160009067ffffffffffffffff1667ffffffffffffffff164261106d846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff166110819190612769565b61108b9190612723565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1667ffffffffffffffff821611156110fe576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b42179050600061111f888660009182526020526040902090565b60008181526007602052604090205490915060ff161561116b576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260076020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815160a08101835263ffffffff808f1682529381018581529281018d81526fffffffffffffffffffffffffffffffff808c16606084019081528982166080850190815260028054808801825599819052945160039099027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101805498511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009099169a909916999099179690961790965590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf8701559351925184167001000000000000000000000000000000000292909316919091177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad09093019290925580548b9081106112e3576112e361273a565b6000918252602082206003909102018054921515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff9093169290921790915560405133918a918c917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a4505050505050505050565b367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560001a60018114806113a0575060ff81166002145b611406576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335600482015260240160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161781556040805160a08101825263ffffffff8152602081019290925260029190810161148b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033590565b815260016020820152604001426fffffffffffffffffffffffffffffffff9081169091528254600181810185556000948552602080862085516003909402018054918601511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090921663ffffffff909416939093171782556040840151908201556060830151608090930151821670010000000000000000000000000000000002929091169190911760029091015573ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016637f0064206115b460207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c9003013590565b6040518263ffffffff1660e01b81526004016115d291815260200190565b602060405180830381865afa1580156115ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611613919061284d565b9050600073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663a25ae55761165e600185612723565b6040518263ffffffff1660e01b815260040161167c91815260200190565b606060405180830381865afa158015611699573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116bd91906128b5565b6040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810184905290915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa15801561174e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177291906128b5565b9050600073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166399d548aa367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003604001356040518263ffffffff1660e01b81526004016117fe91815260200190565b6040805180830381865afa15801561181a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061183e9190612941565b905081602001516fffffffffffffffffffffffffffffffff16816020015167ffffffffffffffff161161189d576040517f13809ba500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a0810182529081908101806118b8600189612723565b6fffffffffffffffffffffffffffffffff908116825260408881015182166020808501919091529851928101929092529183528051606081018252978216885285810151821688880152945187860152908501959095528051805181860151908716700100000000000000000000000000000000918816820217600355908401516004559084015180519481015194861694909516029290921760055591909101516006555160015550565b610cd782826001610d8c565b6002818154811061198057600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b6000805468010000000000000000900460ff166002811115611a0557611a05612409565b14611a3c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028781548110611a5157611a5161273a565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050611ab07f00000000000000000000000000000000000000000000000000000000000000006001612769565b611b4c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1614611b8d576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808915611c1057611bb1836fffffffffffffffffffffffffffffffff166121f8565b67ffffffffffffffff1615611be457611bdb611bce6001866129c8565b865463ffffffff1661229e565b60010154611c06565b7f00000000000000000000000000000000000000000000000000000000000000005b9150849050611c2a565b84600101549150611c27846001611bce91906129f9565b90505b600882901b60088a8a604051611c41929190612a2d565b6040518091039020901b14611c82576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600101547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f8e0cb968c8c8c8c6040518563ffffffff1660e01b8152600401611ce89493929190612a86565b6020604051808303816000875af1158015611d07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2b919061284d565b600284810154929091149250600091611dd6906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b611e72886fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b611e7c9190612ab8565b611e8691906127b0565b67ffffffffffffffff161590508115158103611ece576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505084547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff166401000000001790945550505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356060611f60610d7e565b9050909192565b600080611ff4847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b60608160000361205f57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115612089578061207381612ad9565b91506120829050600a83612b11565b9150612063565b60008167ffffffffffffffff8111156120a4576120a4612866565b6040519080825280601f01601f1916602001820160405280156120ce576020820181803683370190505b5090505b8415612151576120e3600183612723565b91506120f0600a86612b25565b6120fb906030612769565b60f81b8183815181106121105761211061273a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061214a600a86612b11565b94506120d2565b949350505050565b6060600061219084367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003612769565b90508267ffffffffffffffff1667ffffffffffffffff8111156121b5576121b5612866565b6040519080825280601f01601f1916602001820160405280156121df576020820181803683370190505b509150828160208401375092915050565b151760011b90565b600080612285837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b6000806122bc846fffffffffffffffffffffffffffffffff1661233b565b9050600283815481106122d1576122d161273a565b906000526020600020906003020191505b60028201546fffffffffffffffffffffffffffffffff82811691161461233457815460028054909163ffffffff1690811061231f5761231f61273a565b906000526020600020906003020191506122e2565b5092915050565b600081196001830116816123cf827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b600080604083850312156123fa57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612473577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60005b8381101561249457818101518382015260200161247c565b8381111561089f5750506000910152565b600081518084526124bd816020860160208601612479565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061250260208301846124a5565b9392505050565b82516fffffffffffffffffffffffffffffffff90811682526020808501518216818401526040808601518185015284518316606085015290840151909116608083015282015160a082015260c08101612502565b8035801515811461256d57600080fd5b919050565b60008060006060848603121561258757600080fd5b833592506020840135915061259e6040850161255d565b90509250925092565b6000602082840312156125b957600080fd5b5035919050565b60008083601f8401126125d257600080fd5b50813567ffffffffffffffff8111156125ea57600080fd5b60208301915083602082850101111561260257600080fd5b9250929050565b6000806000806000806080878903121561262257600080fd5b863595506126326020880161255d565b9450604087013567ffffffffffffffff8082111561264f57600080fd5b61265b8a838b016125c0565b9096509450606089013591508082111561267457600080fd5b5061268189828a016125c0565b979a9699509497509295939492505050565b60ff841681528260208201526060604082015260006126b560608301846124a5565b95945050505050565b6000602082840312156126d057600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461250257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612735576127356126f4565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561277c5761277c6126f4565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff808416806127cb576127cb612781565b92169190910692915050565b600084516127e9818460208901612479565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551612825816001850160208a01612479565b60019201918201528351612840816002840160208801612479565b0160020195945050505050565b60006020828403121561285f57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80516fffffffffffffffffffffffffffffffff8116811461256d57600080fd5b6000606082840312156128c757600080fd5b6040516060810181811067ffffffffffffffff82111715612911577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528251815261292460208401612895565b602082015261293560408401612895565b60408201529392505050565b60006040828403121561295357600080fd5b6040516040810167ffffffffffffffff828210818311171561299e577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b81604052845183526020850151915080821682146129bb57600080fd5b5060208201529392505050565b60006fffffffffffffffffffffffffffffffff838116908316818110156129f1576129f16126f4565b039392505050565b60006fffffffffffffffffffffffffffffffff808316818516808303821115612a2457612a246126f4565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b604081526000612a9a604083018688612a3d565b8281036020840152612aad818587612a3d565b979650505050505050565b600067ffffffffffffffff838116908316818110156129f1576129f16126f4565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612b0a57612b0a6126f4565b5060010190565b600082612b2057612b20612781565b500490565b600082612b3457612b34612781
565b50069056fea164736f6c634300080f000a"
,
Bin
:
"0x6101c06040523480156200001257600080fd5b5060405162002d
af38038062002daf8339810160408190526200003591620000a1565b6000608081905260a052600960c05260ff9096166101a05260e094909452610100929092526001600160401b0316610120526001600160a01b039081166101405290811661016052166101805262000145565b6001600160a01b03811681146200009e57600080fd5b50565b600080600080600080600060e0888a031215620000bd57600080fd5b875160ff81168114620000cf57600080fd5b602089015160408a015160608b015192995090975095506001600160401b0381168114620000fc57600080fd5b60808901519094506200010f8162000088565b60a0890151909350620001228162000088565b60c0890151909250620001358162000088565b8091505092959891949750929550565b60805160a05160c05160e05161010051610120516101405161016051610180516101a051612b9a620002156000396000818161052d0152611caa015260008181610369015261152b0152600081816105a6015281816112f8015281816113cc01526114a50152600081816104f7015281816107630152611a290152600081816105da01528181610df40152611d9901526000818161033501528181610c33015261182801526000818161022c015261198401526000610a9001526000610a6701526000610a3e0152612b9a6000f3fe6080604052600436106101b75760003560e01c80638129fc1c116100ec578063c31b29ce1161008a578063cf09e0d011610064578063cf09e0d01461068c578063d8cc1a3c146106ad578063fa24f743146106cd578063fdffbb28146106f157600080fd5b8063c31b29ce146105c8578063c55cd0c714610615578063c6f0308c1461062857600080fd5b806392931298116100c657806392931298146104e5578063bbdc02db14610519578063bcef3b5514610557578063c0c3a0921461059457600080fd5b80638129fc1c1461047b5780638980e0cc146104905780638b85902b146104a557600080fd5b80634778efe81161015957806355ef20e61161013357806355ef20e6146103ad578063609d33341461043d578063632247ea146104525780636361506d1461046557600080fd5b80634778efe814610323578063529184c91461035757806354fd4d501461038b57600080fd5b80632810e1d6116101955780632810e1d61461025c578063298c90051461027157806335fef567146102b1578063363cc427146102c457600080fd5b80631e27052a146101bc578063200d2ed2146101de578063266198f91461021a575b600080fd5b3480156101c857600080fd5b506101dc6101d736600461243b565b610704565b005b3480156101ea57600080fd5b506000546102049068010000000000000000900460ff1681565b604051610211919061248c565b60405180910390f35b34801561022657600080fd5b5061024e7f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610211565b34801561026857600080fd5b506102046108c3565b34801561027d57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036040013561024e565b6101dc6102bf36600461243b565b610a27565b3480156102d057600080fd5b506000546102fe906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610211565b34801561032f57600080fd5b5061024e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561036357600080fd5b506102fe7f000000000000000000000000000000000000000000000000000000000000000081565b34801561039757600080fd5b506103a0610a37565b6040516102119190612543565b3480156103b957600080fd5b5060408051606080820183526003546fffffffffffffffffffffffffffffffff8082168452700100000000000000000000000000000000918290048116602080860191909152600454858701528551938401865260055480831685529290920416908201526006549281019290925261042f9182565b60405161021192919061255d565b34801561044957600080fd5b506103a0610ada565b6101dc6104603660046125c6565b610ae8565b34801561047157600080fd5b5061024e60015481565b34801561048757600080fd5b506101dc6110fe565b34801561049c57600080fd5b5060025461024e565b3480156104b157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013561024e565b3480156104f157600080fd5b506102fe7f000000000000000000000000000000000000000000000000000000000000000081565b34801561052557600080fd5b5060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610211565b34801561056357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033561024e565b3480156105a057600080fd5b506102fe7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105d457600080fd5b506105fc7f000000000000000000000000000000000000000000000000000000000000000081565b60405167ffffffffffffffff9091168152602001610211565b6101dc61062336600461243b565b611702565b34801561063457600080fd5b506106486106433660046125fb565b61170e565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a001610211565b34801561069857600080fd5b506000546105fc9067ffffffffffffffff1681565b3480156106b957600080fd5b506101dc6106c836600461265d565b61177f565b3480156106d957600080fd5b506106e2611ca8565b604051610211939291906126e7565b6101dc6106ff3660046125fb565b611d05565b6000805468010000000000000000900460ff1660028111156107285761072861245d565b1461075f576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f09190612712565b7f9a1f5e7f00000000000000000000000000000000000000000000000000000000601c8190526020859052909150600084600181146108575760028114610861576003811461086b576004811461087557600581146108855763ff137e656000526004601cfd5b600154915061088c565b600454915061088c565b600654915061088c565b60035460801c60c01b915061088c565b4660c01b91505b50604052600160038511811b6005031b60605260808390526000806084601c82865af16108bd573d6000803e3d6000fd5b50505050565b60008060005468010000000000000000900460ff1660028111156108e9576108e961245d565b14610920576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095460ff1661095c576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600260008154811061097057610970612748565b6000918252602090912060039091020154640100000000900460ff1661099757600261099a565b60015b6000805491925082917fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000008360028111156109e1576109e161245d565b0217905560028111156109f6576109f661245d565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a290565b905090565b610a3382826000610ae8565b5050565b6060610a627f0000000000000000000000000000000000000000000000000000000000000000612036565b610a8b7f0000000000000000000000000000000000000000000000000000000000000000612036565b610ab47f0000000000000000000000000000000000000000000000000000000000000000612036565b604051602001610ac693929190612777565b604051602081830303815290604052905090565b6060610a2260206040612173565b6000805468010000000000000000900460ff166002811115610b0c57610b0c61245d565b14610b43576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82158015610b4f575080155b15610b86576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110610b9b57610b9b612748565b600091825260208083206040805160a081018252600394909402909101805463ffffffff808216865264010000000090910460ff16151593850193909352600181015491840191909152600201546fffffffffffffffffffffffffffffffff80821660608501819052700100000000000000000000000000000000909204166080840152919350610c2f9190859061220a16565b90507f0000000000000000000000000000000000000000000000000000000000000000610cee826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161115610d30576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160009063ffffffff90811614610d90576002836000015163ffffffff1681548110610d5f57610d5f612748565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608083015160009067ffffffffffffffff1667ffffffffffffffff1642610dc9846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610ddd919061281c565b610de79190612834565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1667ffffffffffffffff82161115610e5a576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b42176000888152608086901b6fffffffffffffffffffffffffffffffff8b1617602052604081209192509060008181526007602052604090205490915060ff1615610ed8576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260076020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815160a08101835263ffffffff808f1682529381018581529281018d81526fffffffffffffffffffffffffffffffff808c16606084019081528982166080850190815260028054808801825599819052945160039099027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101805498511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009099169a909916999099179690961790965590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf8701559351925184167001000000000000000000000000000000000292909316919091177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad09093019290925580548b90811061105057611050612748565b6000918252602080832060039092029091018054931515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff909416939093179092558a81526008909152604090206002546110b490600190612834565b8154600181018355600092835260208320015560405133918a918c917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a4505050505050505050565b367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560001a600181148061113e575060ff81166002145b6111a4576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335600482015260240160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161781556040805160a08101825263ffffffff815260208101929092526002919081016112297ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033590565b815260016020820152604001426fffffffffffffffffffffffffffffffff9081169091528254600181810185556000948552602080862085516003909402018054918601511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090921663ffffffff909416939093171782556040840151908201556060830151608090930151821670010000000000000000000000000000000002929091169190911760029091015573ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016637f00642061135260207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c9003013590565b6040518263ffffffff1660e01b815260040161137091815260200190565b602060405180830381865afa15801561138d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b1919061284b565b9050600073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663a25ae5576113fc600185612834565b6040518263ffffffff1660e01b815260040161141a91815260200190565b606060405180830381865afa158015611437573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145b91906128b3565b6040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810184905290915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa1580156114ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151091906128b3565b9050600073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166399d548aa367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003604001356040518263ffffffff1660e01b815260040161159c91815260200190565b6040805180830381865afa1580156115b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115dc919061293f565b905081602001516fffffffffffffffffffffffffffffffff16816020015167ffffffffffffffff161161163b576040517f13809ba500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a081018252908190810180611656600189612834565b6fffffffffffffffffffffffffffffffff908116825260408881015182166020808501919091529851928101929092529183528051606081018252978216885285810151821688880152945187860152908501959095528051805181860151908716700100000000000000000000000000000000918816820217600355908401516004559084015180519481015194861694909516029290921760055591909101516006555160015550565b610a3382826001610ae8565b6002818154811061171e57600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b6000805468010000000000000000900460ff1660028111156117a3576117a361245d565b146117da576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600287815481106117ef576117ef612748565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b905061184e7f0000000000000000000000000000000000000000000000000000000000000000600161281c565b6118ea826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161461192b576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008089156119ae5761194f836fffffffffffffffffffffffffffffffff16612212565b67ffffffffffffffff16156119825761197961196c6001866129c6565b865463ffffffff166122b8565b600101546119a4565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506119c8565b846001015491506119c584600161196c91906129f7565b90505b600882901b60088a8a6040516119df929190612a2b565b6040518091039020901b14611a20576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600101547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f8e0cb968c8c8c8c6040518563ffffffff1660e01b8152600401611a869493929190612a84565b6020604051808303816000875af1158015611aa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac9919061284b565b600284810154929091149250600091611b74906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b611c10886fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b611c1a9190612ab6565b611c249190612b06565b67ffffffffffffffff161590508115158103611c6c576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505084547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff166401000000001790945550505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356060611cfe610ada565b9050909192565b6000805468010000000000000000900460ff166002811115611d2957611d2961245d565b14611d60576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611d7557611d75612748565b60009182526020909120600260039092020190810154909150677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1690611de590700100000000000000000000000000000000900467ffffffffffffffff1642612834565b6002830154611e159190700100000000000000000000000000000000900460401c67ffffffffffffffff1661281c565b11611e4c576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260086020526040902082158015611e6a575060095460ff165b15611ea1576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8054158015611eaf57508215155b15611ee6576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8254811015611fb4576000838281548110611f0757611f07612748565b6000918252602080832090910154808352600890915260409091205490915015611f5d576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611f7257611f72612748565b600091825260209091206003909102018054909150640100000000900460ff16611fa157600193505050611fb4565b505080611fad90612b2d565b9050611eea565b5082547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000821515021783556000848152600860205260408120611ffd91612401565b836000036108bd57600980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905550505050565b60608160000361207957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156120a3578061208d81612b2d565b915061209c9050600a83612b65565b915061207d565b60008167ffffffffffffffff8111156120be576120be612864565b6040519080825280601f01601f1916602001820160405280156120e8576020820181803683370190505b5090505b841561216b576120fd600183612834565b915061210a600a86612b79565b61211590603061281c565b60f81b81838151811061212a5761212a612748565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612164600a86612b65565b94506120ec565b949350505050565b606060006121aa84367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900361281c565b90508267ffffffffffffffff1667ffffffffffffffff8111156121cf576121cf612864565b6040519080825280601f01601f1916602001820160405280156121f9576020820181803683370190505b509150828160208401375092915050565b151760011b90565b60008061229f837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b6000806122d6846fffffffffffffffffffffffffffffffff16612355565b9050600283815481106122eb576122eb612748565b906000526020600020906003020191505b60028201546fffffffffffffffffffffffffffffffff82811691161461234e57815460028054909163ffffffff1690811061233957612339612748565b906000526020600020906003020191506122fc565b5092915050565b600081196001830116816123e9827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b508054600082559060005260206000209081019061241f9190612422565b50565b5b808211156124375760008155600101612423565b5090565b6000806040838503121561244e57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106124c7577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60005b838110156124e85781810151838201526020016124d0565b838111156108bd5750506000910152565b600081518084526125118160208601602086016124cd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061255660208301846124f9565b9392505050565b82516fffffffffffffffffffffffffffffffff90811682526020808501518216818401526040808601518185015284518316606085015290840151909116608083015282015160a082015260c08101612556565b803580151581146125c157600080fd5b919050565b6000806000606084860312156125db57600080fd5b83359250602084013591506125f2604085016125b1565b90509250925092565b60006020828403121561260d57600080fd5b5035919050565b60008083601f84011261262657600080fd5b50813567ffffffffffffffff81111561263e57600080fd5b60208301915083602082850101111561265657600080fd5b9250929050565b6000806000806000806080878903121561267657600080fd5b86359550612686602088016125b1565b9450604087013567ffffffffffffffff808211156126a357600080fd5b6126af8a838b01612614565b909650945060608901359150808211156126c857600080fd5b506126d589828a01612614565b979a9699509497509295939492505050565b60ff8416815282602082015260606040820152600061270960608301846124f9565b95945050505050565b60006020828403121561272457600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461255657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600084516127898184602089016124cd565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516127c5816001850160208a016124cd565b600192019182015283516127e08160028401602088016124cd565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561282f5761282f6127ed565b500190565b600082821015612846576128466127ed565b500390565b60006020828403121561285d57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80516fffffffffffffffffffffffffffffffff811681146125c157600080fd5b6000606082840312156128c557600080fd5b6040516060810181811067ffffffffffffffff8211171561290f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528251815261292260208401612893565b602082015261293360408401612893565b60408201529392505050565b60006040828403121561295157600080fd5b6040516040810167ffffffffffffffff828210818311171561299c577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b81604052845183526020850151915080821682146129b957600080fd5b5060208201529392505050565b60006fffffffffffffffffffffffffffffffff838116908316818110156129ef576129ef6127ed565b039392505050565b60006fffffffffffffffffffffffffffffffff808316818516808303821115612a2257612a226127ed565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b604081526000612a98604083018688612a3b565b8281036020840152612aab818587612a3b565b979650505050505050565b600067ffffffffffffffff838116908316818110156129ef576129ef6127ed565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680612b2157612b21612ad7565b92169190910692915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612b5e57612b5e6127ed565b5060010190565b600082612b7457612b74612ad7565b500490565b600082612b8857612b88612ad7
565b50069056fea164736f6c634300080f000a"
,
}
}
// FaultDisputeGameABI is the input ABI used to generate the binding from.
// FaultDisputeGameABI is the input ABI used to generate the binding from.
...
@@ -1016,6 +1016,27 @@ func (_FaultDisputeGame *FaultDisputeGameTransactorSession) Resolve() (*types.Tr
...
@@ -1016,6 +1016,27 @@ func (_FaultDisputeGame *FaultDisputeGameTransactorSession) Resolve() (*types.Tr
return
_FaultDisputeGame
.
Contract
.
Resolve
(
&
_FaultDisputeGame
.
TransactOpts
)
return
_FaultDisputeGame
.
Contract
.
Resolve
(
&
_FaultDisputeGame
.
TransactOpts
)
}
}
// ResolveClaim is a paid mutator transaction binding the contract method 0xfdffbb28.
//
// Solidity: function resolveClaim(uint256 _claimIndex) payable returns()
func
(
_FaultDisputeGame
*
FaultDisputeGameTransactor
)
ResolveClaim
(
opts
*
bind
.
TransactOpts
,
_claimIndex
*
big
.
Int
)
(
*
types
.
Transaction
,
error
)
{
return
_FaultDisputeGame
.
contract
.
Transact
(
opts
,
"resolveClaim"
,
_claimIndex
)
}
// ResolveClaim is a paid mutator transaction binding the contract method 0xfdffbb28.
//
// Solidity: function resolveClaim(uint256 _claimIndex) payable returns()
func
(
_FaultDisputeGame
*
FaultDisputeGameSession
)
ResolveClaim
(
_claimIndex
*
big
.
Int
)
(
*
types
.
Transaction
,
error
)
{
return
_FaultDisputeGame
.
Contract
.
ResolveClaim
(
&
_FaultDisputeGame
.
TransactOpts
,
_claimIndex
)
}
// ResolveClaim is a paid mutator transaction binding the contract method 0xfdffbb28.
//
// Solidity: function resolveClaim(uint256 _claimIndex) payable returns()
func
(
_FaultDisputeGame
*
FaultDisputeGameTransactorSession
)
ResolveClaim
(
_claimIndex
*
big
.
Int
)
(
*
types
.
Transaction
,
error
)
{
return
_FaultDisputeGame
.
Contract
.
ResolveClaim
(
&
_FaultDisputeGame
.
TransactOpts
,
_claimIndex
)
}
// Step is a paid mutator transaction binding the contract method 0xd8cc1a3c.
// Step is a paid mutator transaction binding the contract method 0xd8cc1a3c.
//
//
// Solidity: function step(uint256 _claimIndex, bool _isAttack, bytes _stateData, bytes _proof) returns()
// Solidity: function step(uint256 _claimIndex, bool _isAttack, bytes _stateData, bytes _proof) returns()
...
...
op-bindings/bindings/faultdisputegame_more.go
View file @
16f0aad4
...
@@ -9,11 +9,11 @@ import (
...
@@ -9,11 +9,11 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
)
const
FaultDisputeGameStorageLayoutJSON
=
"{
\"
storage
\"
:[{
\"
astId
\"
:1000,
\"
contract
\"
:
\"
src/dispute/FaultDisputeGame.sol:FaultDisputeGame
\"
,
\"
label
\"
:
\"
createdAt
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_userDefinedValueType(Timestamp)101
7
\"
},{
\"
astId
\"
:1001,
\"
contract
\"
:
\"
src/dispute/FaultDisputeGame.sol:FaultDisputeGame
\"
,
\"
label
\"
:
\"
status
\"
,
\"
offset
\"
:8,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_enum(GameStatus)1008
\"
},{
\"
astId
\"
:1002,
\"
contract
\"
:
\"
src/dispute/FaultDisputeGame.sol:FaultDisputeGame
\"
,
\"
label
\"
:
\"
bondManager
\"
,
\"
offset
\"
:9,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_contract(IBondManager)1007
\"
},{
\"
astId
\"
:1003,
\"
contract
\"
:
\"
src/dispute/FaultDisputeGame.sol:FaultDisputeGame
\"
,
\"
label
\"
:
\"
l1Head
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
1
\"
,
\"
type
\"
:
\"
t_userDefinedValueType(Hash)1015
\"
},{
\"
astId
\"
:1004,
\"
contract
\"
:
\"
src/dispute/FaultDisputeGame.sol:FaultDisputeGame
\"
,
\"
label
\"
:
\"
claimData
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
2
\"
,
\"
type
\"
:
\"
t_array(t_struct(ClaimData)1009_storage)dyn_storage
\"
},{
\"
astId
\"
:1005,
\"
contract
\"
:
\"
src/dispute/FaultDisputeGame.sol:FaultDisputeGame
\"
,
\"
label
\"
:
\"
proposals
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
3
\"
,
\"
type
\"
:
\"
t_struct(OutputProposals)1011_storage
\"
},{
\"
astId
\"
:1006,
\"
contract
\"
:
\"
src/dispute/FaultDisputeGame.sol:FaultDisputeGame
\"
,
\"
label
\"
:
\"
claims
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
7
\"
,
\"
type
\"
:
\"
t_mapping(t_userDefinedValueType(ClaimHash)1013,t_bool)
\"
}],
\"
types
\"
:{
\"
t_array(t_struct(ClaimData)1009_storage)dyn_storage
\"
:{
\"
encoding
\"
:
\"
dynamic_array
\"
,
\"
label
\"
:
\"
struct IFaultDisputeGame.ClaimData[]
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
,
\"
base
\"
:
\"
t_struct(ClaimData)1009_storage
\"
},
\"
t_bool
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
bool
\"
,
\"
numberOfBytes
\"
:
\"
1
\"
},
\"
t_contract(IBondManager)1007
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
contract IBondManager
\"
,
\"
numberOfBytes
\"
:
\"
20
\"
},
\"
t_enum(GameStatus)1008
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
enum GameStatus
\"
,
\"
numberOfBytes
\"
:
\"
1
\"
},
\"
t_mapping(t_userDefinedValueType(ClaimHash)1013,t_bool)
\"
:{
\"
encoding
\"
:
\"
mapping
\"
,
\"
label
\"
:
\"
mapping(ClaimHash =
\u003e
bool)
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
,
\"
key
\"
:
\"
t_userDefinedValueType(ClaimHash)1013
\"
,
\"
value
\"
:
\"
t_bool
\"
},
\"
t_struct(ClaimData)1009_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
struct IFaultDisputeGame.ClaimData
\"
,
\"
numberOfBytes
\"
:
\"
96
\"
},
\"
t_struct(OutputProposal)1010_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
struct IFaultDisputeGame.OutputProposal
\"
,
\"
numberOfBytes
\"
:
\"
64
\"
},
\"
t_struct(OutputProposals)1011_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
struct IFaultDisputeGame.OutputProposals
\"
,
\"
numberOfBytes
\"
:
\"
128
\"
},
\"
t_uint128
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint128
\"
,
\"
numberOfBytes
\"
:
\"
16
\"
},
\"
t_uint32
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint32
\"
,
\"
numberOfBytes
\"
:
\"
4
\"
},
\"
t_userDefinedValueType(Claim)1012
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
Claim
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_userDefinedValueType(ClaimHash)1013
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
ClaimHash
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_userDefinedValueType(Clock)1014
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
Clock
\"
,
\"
numberOfBytes
\"
:
\"
16
\"
},
\"
t_userDefinedValueType(Hash)1015
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
Hash
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_userDefinedValueType(Position)1016
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
Position
\"
,
\"
numberOfBytes
\"
:
\"
16
\"
},
\"
t_userDefinedValueType(Timestamp)1017
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
Timestamp
\"
,
\"
numberOfBytes
\"
:
\"
8
\"
}}}"
const
FaultDisputeGameStorageLayoutJSON
=
"{
\"
storage
\"
:[{
\"
astId
\"
:1000,
\"
contract
\"
:
\"
src/dispute/FaultDisputeGame.sol:FaultDisputeGame
\"
,
\"
label
\"
:
\"
createdAt
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_userDefinedValueType(Timestamp)101
9
\"
},{
\"
astId
\"
:1001,
\"
contract
\"
:
\"
src/dispute/FaultDisputeGame.sol:FaultDisputeGame
\"
,
\"
label
\"
:
\"
status
\"
,
\"
offset
\"
:8,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_enum(GameStatus)1010
\"
},{
\"
astId
\"
:1002,
\"
contract
\"
:
\"
src/dispute/FaultDisputeGame.sol:FaultDisputeGame
\"
,
\"
label
\"
:
\"
bondManager
\"
,
\"
offset
\"
:9,
\"
slot
\"
:
\"
0
\"
,
\"
type
\"
:
\"
t_contract(IBondManager)1009
\"
},{
\"
astId
\"
:1003,
\"
contract
\"
:
\"
src/dispute/FaultDisputeGame.sol:FaultDisputeGame
\"
,
\"
label
\"
:
\"
l1Head
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
1
\"
,
\"
type
\"
:
\"
t_userDefinedValueType(Hash)1017
\"
},{
\"
astId
\"
:1004,
\"
contract
\"
:
\"
src/dispute/FaultDisputeGame.sol:FaultDisputeGame
\"
,
\"
label
\"
:
\"
claimData
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
2
\"
,
\"
type
\"
:
\"
t_array(t_struct(ClaimData)1011_storage)dyn_storage
\"
},{
\"
astId
\"
:1005,
\"
contract
\"
:
\"
src/dispute/FaultDisputeGame.sol:FaultDisputeGame
\"
,
\"
label
\"
:
\"
proposals
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
3
\"
,
\"
type
\"
:
\"
t_struct(OutputProposals)1013_storage
\"
},{
\"
astId
\"
:1006,
\"
contract
\"
:
\"
src/dispute/FaultDisputeGame.sol:FaultDisputeGame
\"
,
\"
label
\"
:
\"
claims
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
7
\"
,
\"
type
\"
:
\"
t_mapping(t_userDefinedValueType(ClaimHash)1015,t_bool)
\"
},{
\"
astId
\"
:1007,
\"
contract
\"
:
\"
src/dispute/FaultDisputeGame.sol:FaultDisputeGame
\"
,
\"
label
\"
:
\"
subgames
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
8
\"
,
\"
type
\"
:
\"
t_mapping(t_uint256,t_array(t_uint256)dyn_storage)
\"
},{
\"
astId
\"
:1008,
\"
contract
\"
:
\"
src/dispute/FaultDisputeGame.sol:FaultDisputeGame
\"
,
\"
label
\"
:
\"
subgameAtRootResolved
\"
,
\"
offset
\"
:0,
\"
slot
\"
:
\"
9
\"
,
\"
type
\"
:
\"
t_bool
\"
}],
\"
types
\"
:{
\"
t_array(t_struct(ClaimData)1011_storage)dyn_storage
\"
:{
\"
encoding
\"
:
\"
dynamic_array
\"
,
\"
label
\"
:
\"
struct IFaultDisputeGame.ClaimData[]
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
,
\"
base
\"
:
\"
t_struct(ClaimData)1011_storage
\"
},
\"
t_array(t_uint256)dyn_storage
\"
:{
\"
encoding
\"
:
\"
dynamic_array
\"
,
\"
label
\"
:
\"
uint256[]
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
,
\"
base
\"
:
\"
t_uint256
\"
},
\"
t_bool
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
bool
\"
,
\"
numberOfBytes
\"
:
\"
1
\"
},
\"
t_contract(IBondManager)1009
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
contract IBondManager
\"
,
\"
numberOfBytes
\"
:
\"
20
\"
},
\"
t_enum(GameStatus)1010
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
enum GameStatus
\"
,
\"
numberOfBytes
\"
:
\"
1
\"
},
\"
t_mapping(t_uint256,t_array(t_uint256)dyn_storage)
\"
:{
\"
encoding
\"
:
\"
mapping
\"
,
\"
label
\"
:
\"
mapping(uint256 =
\u003e
uint256[])
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
,
\"
key
\"
:
\"
t_uint256
\"
,
\"
value
\"
:
\"
t_array(t_uint256)dyn_storage
\"
},
\"
t_mapping(t_userDefinedValueType(ClaimHash)1015,t_bool)
\"
:{
\"
encoding
\"
:
\"
mapping
\"
,
\"
label
\"
:
\"
mapping(ClaimHash =
\u003e
bool)
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
,
\"
key
\"
:
\"
t_userDefinedValueType(ClaimHash)1015
\"
,
\"
value
\"
:
\"
t_bool
\"
},
\"
t_struct(ClaimData)1011_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
struct IFaultDisputeGame.ClaimData
\"
,
\"
numberOfBytes
\"
:
\"
96
\"
},
\"
t_struct(OutputProposal)1012_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
struct IFaultDisputeGame.OutputProposal
\"
,
\"
numberOfBytes
\"
:
\"
64
\"
},
\"
t_struct(OutputProposals)1013_storage
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
struct IFaultDisputeGame.OutputProposals
\"
,
\"
numberOfBytes
\"
:
\"
128
\"
},
\"
t_uint128
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint128
\"
,
\"
numberOfBytes
\"
:
\"
16
\"
},
\"
t_uint256
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint256
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_uint32
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
uint32
\"
,
\"
numberOfBytes
\"
:
\"
4
\"
},
\"
t_userDefinedValueType(Claim)1014
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
Claim
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_userDefinedValueType(ClaimHash)1015
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
ClaimHash
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_userDefinedValueType(Clock)1016
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
Clock
\"
,
\"
numberOfBytes
\"
:
\"
16
\"
},
\"
t_userDefinedValueType(Hash)1017
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
Hash
\"
,
\"
numberOfBytes
\"
:
\"
32
\"
},
\"
t_userDefinedValueType(Position)1018
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
Position
\"
,
\"
numberOfBytes
\"
:
\"
16
\"
},
\"
t_userDefinedValueType(Timestamp)1019
\"
:{
\"
encoding
\"
:
\"
inplace
\"
,
\"
label
\"
:
\"
Timestamp
\"
,
\"
numberOfBytes
\"
:
\"
8
\"
}}}"
var
FaultDisputeGameStorageLayout
=
new
(
solc
.
StorageLayout
)
var
FaultDisputeGameStorageLayout
=
new
(
solc
.
StorageLayout
)
var
FaultDisputeGameDeployedBin
=
"0x6080604052600436106101
ac5760003560e01c80636361506d116100ec578063c0c3a0921161008a578063c6f0308c11610064578063c6f0308c1461061d578063cf09e0d014610681578063d8cc1a3c146106a2578063fa24f743146106c257600080fd5b8063c0c3a09214610589578063c31b29ce146105bd578063c55cd0c71461060a57600080fd5b80638b85902b116100c65780638b85902b1461049a57806392931298146104da578063bbdc02db1461050e578063bcef3b551461054c57600080fd5b80636361506d1461045a5780638129fc1c146104705780638980e0cc1461048557600080fd5b8063363cc4271161015957806354fd4d501161013357806354fd4d501461038057806355ef20e6146103a2578063609d333414610432578063632247ea1461044757600080fd5b8063363cc427146102b95780634778efe814610318578063529184c91461034c57600080fd5b80632810e1d61161018a5780632810e1d614610251578063298c90051461026657806335fef567146102a657600080fd5b80631e27052a146101b1578063200d2ed2146101d3578063266198f91461020f575b600080fd5b3480156101bd57600080fd5b506101d16101cc3660046123e7565b6106e6565b005b3480156101df57600080fd5b506000546101f99068010000000000000000900460ff1681565b6040516102069190612438565b60405180910390f35b34801561021b57600080fd5b506102437f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610206565b34801561025d57600080fd5b506101f96108a5565b34801561027257600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360400135610243565b6101d16102b43660046123e7565b610ccb565b3480156102c557600080fd5b506000546102f3906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610206565b34801561032457600080fd5b506102437f000000000000000000000000000000000000000000000000000000000000000081565b34801561035857600080fd5b506102f37f000000000000000000000000000000000000000000000000000000000000000081565b34801561038c57600080fd5b50610395610cdb565b60405161020691906124ef565b3480156103ae57600080fd5b5060408051606080820183526003546fffffffffffffffffffffffffffffffff808216845270010000000000000000000000000000000091829004811660208086019190915260045485870152855193840186526005548083168552929092041690820152600654928101929092526104249182565b604051610206929190612509565b34801561043e57600080fd5b50610395610d7e565b6101d1610455366004612572565b610d8c565b34801561046657600080fd5b5061024360015481565b34801561047c57600080fd5b506101d1611360565b34801561049157600080fd5b50600254610243565b3480156104a657600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900360200135610243565b3480156104e657600080fd5b506102f37f000000000000000000000000000000000000000000000000000000000000000081565b34801561051a57600080fd5b5060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610206565b34801561055857600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335610243565b34801561059557600080fd5b506102f37f000000000000000000000000000000000000000000000000000000000000000081565b3480156105c957600080fd5b506105f17f000000000000000000000000000000000000000000000000000000000000000081565b60405167ffffffffffffffff9091168152602001610206565b6101d16106183660046123e7565b611964565b34801561062957600080fd5b5061063d6106383660046125a7565b611970565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a001610206565b34801561068d57600080fd5b506000546105f19067ffffffffffffffff1681565b3480156106ae57600080fd5b506101d16106bd366004612609565b6119e1565b3480156106ce57600080fd5b506106d7611f0a565b60405161020693929190612693565b6000805468010000000000000000900460ff16600281111561070a5761070a612409565b14610741576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d291906126be565b7f9a1f5e7f00000000000000000000000000000000000000000000000000000000601c8190526020859052909150600084600181146108395760028114610843576003811461084d576004811461085757600581146108675763ff137e656000526004601cfd5b600154915061086e565b600454915061086e565b600654915061086e565b60035460801c60c01b915061086e565b4660c01b91505b50604052600160038511811b6005031b60605260808390526000806084601c82865af161089f573d6000803e3d6000fd5b50505050565b60008060005468010000000000000000900460ff1660028111156108cb576108cb612409565b14610902576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460009061091490600190612723565b90506fffffffffffffffffffffffffffffffff815b67ffffffffffffffff8110156109fe5760006002828154811061094e5761094e61273a565b6000918252602090912060039091020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9093019290915060ff640100000000909104161561099f5750610929565b60028101546000906109e3906fffffffffffffffffffffffffffffffff167f0000000000000000000000000000000000000000000000000000000000000000611f67565b9050838110156109f7578093508260010194505b5050610929565b50600060028381548110610a1457610a1461273a565b600091825260208220600390910201805490925063ffffffff90811691908214610a7e5760028281548110610a4b57610a4b61273a565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff16610aaa565b600283015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff165b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c16610aee67ffffffffffffffff831642612723565b610b0a836fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610b1e9190612769565b11610b55576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600283810154610bf7906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b610c0191906127b0565b67ffffffffffffffff16158015610c2857506fffffffffffffffffffffffffffffffff8414155b15610c365760029550610c3b565b600195505b600080548791907fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff1668010000000000000000836002811115610c8057610c80612409565b021790556002811115610c9557610c95612409565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a2505050505090565b905090565b610cd782826000610d8c565b5050565b6060610d067f000000000000000000000000000000000000000000000000000000000000000061201c565b610d2f7f000000000000000000000000000000000000000000000000000000000000000061201c565b610d587f000000000000000000000000000000000000000000000000000000000000000061201c565b604051602001610d6a939291906127d7565b604051602081830303815290604052905090565b6060610cc660206040612159565b6000805468010000000000000000900460ff166002811115610db057610db0612409565b14610de7576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82158015610df3575080155b15610e2a576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110610e3f57610e3f61273a565b600091825260208083206040805160a081018252600394909402909101805463ffffffff808216865264010000000090910460ff16151593850193909352600181015491840191909152600201546fffffffffffffffffffffffffffffffff80821660608501819052700100000000000000000000000000000000909204166080840152919350610ed3919085906121f016565b90507f0000000000000000000000000000000000000000000000000000000000000000610f92826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161115610fd4576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160009063ffffffff90811614611034576002836000015163ffffffff16815481106110035761100361273a565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608083015160009067ffffffffffffffff1667ffffffffffffffff164261106d846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff166110819190612769565b61108b9190612723565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1667ffffffffffffffff821611156110fe576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b42179050600061111f888660009182526020526040902090565b60008181526007602052604090205490915060ff161561116b576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260076020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815160a08101835263ffffffff808f1682529381018581529281018d81526fffffffffffffffffffffffffffffffff808c16606084019081528982166080850190815260028054808801825599819052945160039099027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101805498511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009099169a909916999099179690961790965590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf8701559351925184167001000000000000000000000000000000000292909316919091177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad09093019290925580548b9081106112e3576112e361273a565b6000918252602082206003909102018054921515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff9093169290921790915560405133918a918c917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a4505050505050505050565b367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560001a60018114806113a0575060ff81166002145b611406576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335600482015260240160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161781556040805160a08101825263ffffffff8152602081019290925260029190810161148b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033590565b815260016020820152604001426fffffffffffffffffffffffffffffffff9081169091528254600181810185556000948552602080862085516003909402018054918601511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090921663ffffffff909416939093171782556040840151908201556060830151608090930151821670010000000000000000000000000000000002929091169190911760029091015573ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016637f0064206115b460207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c9003013590565b6040518263ffffffff1660e01b81526004016115d291815260200190565b602060405180830381865afa1580156115ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611613919061284d565b9050600073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663a25ae55761165e600185612723565b6040518263ffffffff1660e01b815260040161167c91815260200190565b606060405180830381865afa158015611699573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116bd91906128b5565b6040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810184905290915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa15801561174e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177291906128b5565b9050600073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166399d548aa367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003604001356040518263ffffffff1660e01b81526004016117fe91815260200190565b6040805180830381865afa15801561181a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061183e9190612941565b905081602001516fffffffffffffffffffffffffffffffff16816020015167ffffffffffffffff161161189d576040517f13809ba500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a0810182529081908101806118b8600189612723565b6fffffffffffffffffffffffffffffffff908116825260408881015182166020808501919091529851928101929092529183528051606081018252978216885285810151821688880152945187860152908501959095528051805181860151908716700100000000000000000000000000000000918816820217600355908401516004559084015180519481015194861694909516029290921760055591909101516006555160015550565b610cd782826001610d8c565b6002818154811061198057600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b6000805468010000000000000000900460ff166002811115611a0557611a05612409565b14611a3c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028781548110611a5157611a5161273a565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b9050611ab07f00000000000000000000000000000000000000000000000000000000000000006001612769565b611b4c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1614611b8d576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808915611c1057611bb1836fffffffffffffffffffffffffffffffff166121f8565b67ffffffffffffffff1615611be457611bdb611bce6001866129c8565b865463ffffffff1661229e565b60010154611c06565b7f00000000000000000000000000000000000000000000000000000000000000005b9150849050611c2a565b84600101549150611c27846001611bce91906129f9565b90505b600882901b60088a8a604051611c41929190612a2d565b6040518091039020901b14611c82576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600101547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f8e0cb968c8c8c8c6040518563ffffffff1660e01b8152600401611ce89493929190612a86565b6020604051808303816000875af1158015611d07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2b919061284d565b600284810154929091149250600091611dd6906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b611e72886fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b611e7c9190612ab8565b611e8691906127b0565b67ffffffffffffffff161590508115158103611ece576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505084547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff166401000000001790945550505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356060611f60610d7e565b9050909192565b600080611ff4847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b60608160000361205f57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115612089578061207381612ad9565b91506120829050600a83612b11565b9150612063565b60008167ffffffffffffffff8111156120a4576120a4612866565b6040519080825280601f01601f1916602001820160405280156120ce576020820181803683370190505b5090505b8415612151576120e3600183612723565b91506120f0600a86612b25565b6120fb906030612769565b60f81b8183815181106121105761211061273a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061214a600a86612b11565b94506120d2565b949350505050565b6060600061219084367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003612769565b90508267ffffffffffffffff1667ffffffffffffffff8111156121b5576121b5612866565b6040519080825280601f01601f1916602001820160405280156121df576020820181803683370190505b509150828160208401375092915050565b151760011b90565b600080612285837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b6000806122bc846fffffffffffffffffffffffffffffffff1661233b565b9050600283815481106122d1576122d161273a565b906000526020600020906003020191505b60028201546fffffffffffffffffffffffffffffffff82811691161461233457815460028054909163ffffffff1690811061231f5761231f61273a565b906000526020600020906003020191506122e2565b5092915050565b600081196001830116816123cf827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b600080604083850312156123fa57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612473577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60005b8381101561249457818101518382015260200161247c565b8381111561089f5750506000910152565b600081518084526124bd816020860160208601612479565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061250260208301846124a5565b9392505050565b82516fffffffffffffffffffffffffffffffff90811682526020808501518216818401526040808601518185015284518316606085015290840151909116608083015282015160a082015260c08101612502565b8035801515811461256d57600080fd5b919050565b60008060006060848603121561258757600080fd5b833592506020840135915061259e6040850161255d565b90509250925092565b6000602082840312156125b957600080fd5b5035919050565b60008083601f8401126125d257600080fd5b50813567ffffffffffffffff8111156125ea57600080fd5b60208301915083602082850101111561260257600080fd5b9250929050565b6000806000806000806080878903121561262257600080fd5b863595506126326020880161255d565b9450604087013567ffffffffffffffff8082111561264f57600080fd5b61265b8a838b016125c0565b9096509450606089013591508082111561267457600080fd5b5061268189828a016125c0565b979a9699509497509295939492505050565b60ff841681528260208201526060604082015260006126b560608301846124a5565b95945050505050565b6000602082840312156126d057600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461250257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612735576127356126f4565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000821982111561277c5761277c6126f4565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff808416806127cb576127cb612781565b92169190910692915050565b600084516127e9818460208901612479565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551612825816001850160208a01612479565b60019201918201528351612840816002840160208801612479565b0160020195945050505050565b60006020828403121561285f57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80516fffffffffffffffffffffffffffffffff8116811461256d57600080fd5b6000606082840312156128c757600080fd5b6040516060810181811067ffffffffffffffff82111715612911577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528251815261292460208401612895565b602082015261293560408401612895565b60408201529392505050565b60006040828403121561295357600080fd5b6040516040810167ffffffffffffffff828210818311171561299e577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b81604052845183526020850151915080821682146129bb57600080fd5b5060208201529392505050565b60006fffffffffffffffffffffffffffffffff838116908316818110156129f1576129f16126f4565b039392505050565b60006fffffffffffffffffffffffffffffffff808316818516808303821115612a2457612a246126f4565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b604081526000612a9a604083018688612a3d565b8281036020840152612aad818587612a3d565b979650505050505050565b600067ffffffffffffffff838116908316818110156129f1576129f16126f4565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612b0a57612b0a6126f4565b5060010190565b600082612b2057612b20612781565b500490565b600082612b3457612b34612781
565b50069056fea164736f6c634300080f000a"
var
FaultDisputeGameDeployedBin
=
"0x6080604052600436106101
b75760003560e01c80638129fc1c116100ec578063c31b29ce1161008a578063cf09e0d011610064578063cf09e0d01461068c578063d8cc1a3c146106ad578063fa24f743146106cd578063fdffbb28146106f157600080fd5b8063c31b29ce146105c8578063c55cd0c714610615578063c6f0308c1461062857600080fd5b806392931298116100c657806392931298146104e5578063bbdc02db14610519578063bcef3b5514610557578063c0c3a0921461059457600080fd5b80638129fc1c1461047b5780638980e0cc146104905780638b85902b146104a557600080fd5b80634778efe81161015957806355ef20e61161013357806355ef20e6146103ad578063609d33341461043d578063632247ea146104525780636361506d1461046557600080fd5b80634778efe814610323578063529184c91461035757806354fd4d501461038b57600080fd5b80632810e1d6116101955780632810e1d61461025c578063298c90051461027157806335fef567146102b1578063363cc427146102c457600080fd5b80631e27052a146101bc578063200d2ed2146101de578063266198f91461021a575b600080fd5b3480156101c857600080fd5b506101dc6101d736600461243b565b610704565b005b3480156101ea57600080fd5b506000546102049068010000000000000000900460ff1681565b604051610211919061248c565b60405180910390f35b34801561022657600080fd5b5061024e7f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610211565b34801561026857600080fd5b506102046108c3565b34801561027d57600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036040013561024e565b6101dc6102bf36600461243b565b610a27565b3480156102d057600080fd5b506000546102fe906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610211565b34801561032f57600080fd5b5061024e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561036357600080fd5b506102fe7f000000000000000000000000000000000000000000000000000000000000000081565b34801561039757600080fd5b506103a0610a37565b6040516102119190612543565b3480156103b957600080fd5b5060408051606080820183526003546fffffffffffffffffffffffffffffffff8082168452700100000000000000000000000000000000918290048116602080860191909152600454858701528551938401865260055480831685529290920416908201526006549281019290925261042f9182565b60405161021192919061255d565b34801561044957600080fd5b506103a0610ada565b6101dc6104603660046125c6565b610ae8565b34801561047157600080fd5b5061024e60015481565b34801561048757600080fd5b506101dc6110fe565b34801561049c57600080fd5b5060025461024e565b3480156104b157600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90036020013561024e565b3480156104f157600080fd5b506102fe7f000000000000000000000000000000000000000000000000000000000000000081565b34801561052557600080fd5b5060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610211565b34801561056357600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033561024e565b3480156105a057600080fd5b506102fe7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105d457600080fd5b506105fc7f000000000000000000000000000000000000000000000000000000000000000081565b60405167ffffffffffffffff9091168152602001610211565b6101dc61062336600461243b565b611702565b34801561063457600080fd5b506106486106433660046125fb565b61170e565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a001610211565b34801561069857600080fd5b506000546105fc9067ffffffffffffffff1681565b3480156106b957600080fd5b506101dc6106c836600461265d565b61177f565b3480156106d957600080fd5b506106e2611ca8565b604051610211939291906126e7565b6101dc6106ff3660046125fb565b611d05565b6000805468010000000000000000900460ff1660028111156107285761072861245d565b1461075f576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637dc0d1d06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f09190612712565b7f9a1f5e7f00000000000000000000000000000000000000000000000000000000601c8190526020859052909150600084600181146108575760028114610861576003811461086b576004811461087557600581146108855763ff137e656000526004601cfd5b600154915061088c565b600454915061088c565b600654915061088c565b60035460801c60c01b915061088c565b4660c01b91505b50604052600160038511811b6005031b60605260808390526000806084601c82865af16108bd573d6000803e3d6000fd5b50505050565b60008060005468010000000000000000900460ff1660028111156108e9576108e961245d565b14610920576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095460ff1661095c576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600260008154811061097057610970612748565b6000918252602090912060039091020154640100000000900460ff1661099757600261099a565b60015b6000805491925082917fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000008360028111156109e1576109e161245d565b0217905560028111156109f6576109f661245d565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a290565b905090565b610a3382826000610ae8565b5050565b6060610a627f0000000000000000000000000000000000000000000000000000000000000000612036565b610a8b7f0000000000000000000000000000000000000000000000000000000000000000612036565b610ab47f0000000000000000000000000000000000000000000000000000000000000000612036565b604051602001610ac693929190612777565b604051602081830303815290604052905090565b6060610a2260206040612173565b6000805468010000000000000000900460ff166002811115610b0c57610b0c61245d565b14610b43576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82158015610b4f575080155b15610b86576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028481548110610b9b57610b9b612748565b600091825260208083206040805160a081018252600394909402909101805463ffffffff808216865264010000000090910460ff16151593850193909352600181015491840191909152600201546fffffffffffffffffffffffffffffffff80821660608501819052700100000000000000000000000000000000909204166080840152919350610c2f9190859061220a16565b90507f0000000000000000000000000000000000000000000000000000000000000000610cee826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161115610d30576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160009063ffffffff90811614610d90576002836000015163ffffffff1681548110610d5f57610d5f612748565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608083015160009067ffffffffffffffff1667ffffffffffffffff1642610dc9846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610ddd919061281c565b610de79190612834565b9050677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1667ffffffffffffffff82161115610e5a576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b42176000888152608086901b6fffffffffffffffffffffffffffffffff8b1617602052604081209192509060008181526007602052604090205490915060ff1615610ed8576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260076020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815160a08101835263ffffffff808f1682529381018581529281018d81526fffffffffffffffffffffffffffffffff808c16606084019081528982166080850190815260028054808801825599819052945160039099027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101805498511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009099169a909916999099179690961790965590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf8701559351925184167001000000000000000000000000000000000292909316919091177f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad09093019290925580548b90811061105057611050612748565b6000918252602080832060039092029091018054931515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff909416939093179092558a81526008909152604090206002546110b490600190612834565b8154600181018355600092835260208320015560405133918a918c917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a4505050505050505050565b367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560001a600181148061113e575060ff81166002145b6111a4576040517ff40239db000000000000000000000000000000000000000000000000000000008152367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900335600482015260240160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff161781556040805160a08101825263ffffffff815260208101929092526002919081016112297ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033590565b815260016020820152604001426fffffffffffffffffffffffffffffffff9081169091528254600181810185556000948552602080862085516003909402018054918601511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090921663ffffffff909416939093171782556040840151908201556060830151608090930151821670010000000000000000000000000000000002929091169190911760029091015573ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016637f00642061135260207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c9003013590565b6040518263ffffffff1660e01b815260040161137091815260200190565b602060405180830381865afa15801561138d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113b1919061284b565b9050600073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663a25ae5576113fc600185612834565b6040518263ffffffff1660e01b815260040161141a91815260200190565b606060405180830381865afa158015611437573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145b91906128b3565b6040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810184905290915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa1580156114ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151091906128b3565b9050600073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166399d548aa367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003604001356040518263ffffffff1660e01b815260040161159c91815260200190565b6040805180830381865afa1580156115b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115dc919061293f565b905081602001516fffffffffffffffffffffffffffffffff16816020015167ffffffffffffffff161161163b576040517f13809ba500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a081018252908190810180611656600189612834565b6fffffffffffffffffffffffffffffffff908116825260408881015182166020808501919091529851928101929092529183528051606081018252978216885285810151821688880152945187860152908501959095528051805181860151908716700100000000000000000000000000000000918816820217600355908401516004559084015180519481015194861694909516029290921760055591909101516006555160015550565b610a3382826001610ae8565b6002818154811061171e57600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b6000805468010000000000000000900460ff1660028111156117a3576117a361245d565b146117da576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600287815481106117ef576117ef612748565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b905061184e7f0000000000000000000000000000000000000000000000000000000000000000600161281c565b6118ea826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161461192b576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008089156119ae5761194f836fffffffffffffffffffffffffffffffff16612212565b67ffffffffffffffff16156119825761197961196c6001866129c6565b865463ffffffff166122b8565b600101546119a4565b7f00000000000000000000000000000000000000000000000000000000000000005b91508490506119c8565b846001015491506119c584600161196c91906129f7565b90505b600882901b60088a8a6040516119df929190612a2b565b6040518091039020901b14611a20576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600101547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f8e0cb968c8c8c8c6040518563ffffffff1660e01b8152600401611a869493929190612a84565b6020604051808303816000875af1158015611aa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac9919061284b565b600284810154929091149250600091611b74906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b611c10886fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b611c1a9190612ab6565b611c249190612b06565b67ffffffffffffffff161590508115158103611c6c576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505084547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff166401000000001790945550505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356060611cfe610ada565b9050909192565b6000805468010000000000000000900460ff166002811115611d2957611d2961245d565b14611d60576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611d7557611d75612748565b60009182526020909120600260039092020190810154909150677fffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000060011c1690611de590700100000000000000000000000000000000900467ffffffffffffffff1642612834565b6002830154611e159190700100000000000000000000000000000000900460401c67ffffffffffffffff1661281c565b11611e4c576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260086020526040902082158015611e6a575060095460ff165b15611ea1576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8054158015611eaf57508215155b15611ee6576040517ff1a9458100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b8254811015611fb4576000838281548110611f0757611f07612748565b6000918252602080832090910154808352600890915260409091205490915015611f5d576040517f9a07664600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060028281548110611f7257611f72612748565b600091825260209091206003909102018054909150640100000000900460ff16611fa157600193505050611fb4565b505080611fad90612b2d565b9050611eea565b5082547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000821515021783556000848152600860205260408120611ffd91612401565b836000036108bd57600980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905550505050565b60608160000361207957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156120a3578061208d81612b2d565b915061209c9050600a83612b65565b915061207d565b60008167ffffffffffffffff8111156120be576120be612864565b6040519080825280601f01601f1916602001820160405280156120e8576020820181803683370190505b5090505b841561216b576120fd600183612834565b915061210a600a86612b79565b61211590603061281c565b60f81b81838151811061212a5761212a612748565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612164600a86612b65565b94506120ec565b949350505050565b606060006121aa84367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c900361281c565b90508267ffffffffffffffff1667ffffffffffffffff8111156121cf576121cf612864565b6040519080825280601f01601f1916602001820160405280156121f9576020820181803683370190505b509150828160208401375092915050565b151760011b90565b60008061229f837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b6000806122d6846fffffffffffffffffffffffffffffffff16612355565b9050600283815481106122eb576122eb612748565b906000526020600020906003020191505b60028201546fffffffffffffffffffffffffffffffff82811691161461234e57815460028054909163ffffffff1690811061233957612339612748565b906000526020600020906003020191506122fc565b5092915050565b600081196001830116816123e9827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b508054600082559060005260206000209081019061241f9190612422565b50565b5b808211156124375760008155600101612423565b5090565b6000806040838503121561244e57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106124c7577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60005b838110156124e85781810151838201526020016124d0565b838111156108bd5750506000910152565b600081518084526125118160208601602086016124cd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061255660208301846124f9565b9392505050565b82516fffffffffffffffffffffffffffffffff90811682526020808501518216818401526040808601518185015284518316606085015290840151909116608083015282015160a082015260c08101612556565b803580151581146125c157600080fd5b919050565b6000806000606084860312156125db57600080fd5b83359250602084013591506125f2604085016125b1565b90509250925092565b60006020828403121561260d57600080fd5b5035919050565b60008083601f84011261262657600080fd5b50813567ffffffffffffffff81111561263e57600080fd5b60208301915083602082850101111561265657600080fd5b9250929050565b6000806000806000806080878903121561267657600080fd5b86359550612686602088016125b1565b9450604087013567ffffffffffffffff808211156126a357600080fd5b6126af8a838b01612614565b909650945060608901359150808211156126c857600080fd5b506126d589828a01612614565b979a9699509497509295939492505050565b60ff8416815282602082015260606040820152600061270960608301846124f9565b95945050505050565b60006020828403121561272457600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461255657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600084516127898184602089016124cd565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516127c5816001850160208a016124cd565b600192019182015283516127e08160028401602088016124cd565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561282f5761282f6127ed565b500190565b600082821015612846576128466127ed565b500390565b60006020828403121561285d57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80516fffffffffffffffffffffffffffffffff811681146125c157600080fd5b6000606082840312156128c557600080fd5b6040516060810181811067ffffffffffffffff8211171561290f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528251815261292260208401612893565b602082015261293360408401612893565b60408201529392505050565b60006040828403121561295157600080fd5b6040516040810167ffffffffffffffff828210818311171561299c577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b81604052845183526020850151915080821682146129b957600080fd5b5060208201529392505050565b60006fffffffffffffffffffffffffffffffff838116908316818110156129ef576129ef6127ed565b039392505050565b60006fffffffffffffffffffffffffffffffff808316818516808303821115612a2257612a226127ed565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b604081526000612a98604083018688612a3b565b8281036020840152612aab818587612a3b565b979650505050505050565b600067ffffffffffffffff838116908316818110156129ef576129ef6127ed565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680612b2157612b21612ad7565b92169190910692915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612b5e57612b5e6127ed565b5060010190565b600082612b7457612b74612ad7565b500490565b600082612b8857612b88612ad7
565b50069056fea164736f6c634300080f000a"
func
init
()
{
func
init
()
{
if
err
:=
json
.
Unmarshal
([]
byte
(
FaultDisputeGameStorageLayoutJSON
),
FaultDisputeGameStorageLayout
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
([]
byte
(
FaultDisputeGameStorageLayoutJSON
),
FaultDisputeGameStorageLayout
);
err
!=
nil
{
...
...
op-challenger/game/fault/agent.go
View file @
16f0aad4
...
@@ -4,6 +4,7 @@ import (
...
@@ -4,6 +4,7 @@ import (
"context"
"context"
"errors"
"errors"
"fmt"
"fmt"
"sync"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/solver"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/solver"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
...
@@ -18,6 +19,8 @@ import (
...
@@ -18,6 +19,8 @@ import (
type
Responder
interface
{
type
Responder
interface
{
CallResolve
(
ctx
context
.
Context
)
(
gameTypes
.
GameStatus
,
error
)
CallResolve
(
ctx
context
.
Context
)
(
gameTypes
.
GameStatus
,
error
)
Resolve
(
ctx
context
.
Context
)
error
Resolve
(
ctx
context
.
Context
)
error
CallResolveClaim
(
ctx
context
.
Context
,
claimIdx
uint64
)
error
ResolveClaim
(
ctx
context
.
Context
,
claimIdx
uint64
)
error
PerformAction
(
ctx
context
.
Context
,
action
types
.
Action
)
error
PerformAction
(
ctx
context
.
Context
,
action
types
.
Action
)
error
}
}
...
@@ -112,6 +115,10 @@ func (a *Agent) shouldResolve(status gameTypes.GameStatus) bool {
...
@@ -112,6 +115,10 @@ func (a *Agent) shouldResolve(status gameTypes.GameStatus) bool {
// tryResolve resolves the game if it is in a winning state
// tryResolve resolves the game if it is in a winning state
// Returns true if the game is resolvable (regardless of whether it was actually resolved)
// Returns true if the game is resolvable (regardless of whether it was actually resolved)
func
(
a
*
Agent
)
tryResolve
(
ctx
context
.
Context
)
bool
{
func
(
a
*
Agent
)
tryResolve
(
ctx
context
.
Context
)
bool
{
if
err
:=
a
.
resolveClaims
(
ctx
);
err
!=
nil
{
a
.
log
.
Error
(
"Failed to resolve claims"
,
"err"
,
err
)
return
false
}
status
,
err
:=
a
.
responder
.
CallResolve
(
ctx
)
status
,
err
:=
a
.
responder
.
CallResolve
(
ctx
)
if
err
!=
nil
||
status
==
gameTypes
.
GameStatusInProgress
{
if
err
!=
nil
||
status
==
gameTypes
.
GameStatusInProgress
{
return
false
return
false
...
@@ -126,6 +133,60 @@ func (a *Agent) tryResolve(ctx context.Context) bool {
...
@@ -126,6 +133,60 @@ func (a *Agent) tryResolve(ctx context.Context) bool {
return
true
return
true
}
}
var
errNoResolvableClaims
=
errors
.
New
(
"no resolvable claims"
)
func
(
a
*
Agent
)
tryResolveClaims
(
ctx
context
.
Context
)
error
{
claims
,
err
:=
a
.
loader
.
FetchClaims
(
ctx
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to fetch claims: %w"
,
err
)
}
if
len
(
claims
)
==
0
{
return
errNoResolvableClaims
}
var
resolvableClaims
[]
int64
for
_
,
claim
:=
range
claims
{
a
.
log
.
Debug
(
"checking if claim is resolvable"
,
"claimIdx"
,
claim
.
ContractIndex
)
if
err
:=
a
.
responder
.
CallResolveClaim
(
ctx
,
uint64
(
claim
.
ContractIndex
));
err
==
nil
{
a
.
log
.
Info
(
"Resolving claim"
,
"claimIdx"
,
claim
.
ContractIndex
)
resolvableClaims
=
append
(
resolvableClaims
,
int64
(
claim
.
ContractIndex
))
}
}
a
.
log
.
Info
(
"Resolving claims"
,
"numClaims"
,
len
(
resolvableClaims
))
if
len
(
resolvableClaims
)
==
0
{
return
errNoResolvableClaims
}
var
wg
sync
.
WaitGroup
wg
.
Add
(
len
(
resolvableClaims
))
for
_
,
claimIdx
:=
range
resolvableClaims
{
claimIdx
:=
claimIdx
go
func
()
{
defer
wg
.
Done
()
err
:=
a
.
responder
.
ResolveClaim
(
ctx
,
uint64
(
claimIdx
))
if
err
!=
nil
{
a
.
log
.
Error
(
"Failed to resolve claim"
,
"err"
,
err
)
}
}()
}
wg
.
Wait
()
return
nil
}
func
(
a
*
Agent
)
resolveClaims
(
ctx
context
.
Context
)
error
{
for
{
err
:=
a
.
tryResolveClaims
(
ctx
)
switch
err
{
case
errNoResolvableClaims
:
return
nil
case
nil
:
continue
default
:
return
err
}
}
}
// newGameFromContracts initializes a new game state from the state in the contract
// newGameFromContracts initializes a new game state from the state in the contract
func
(
a
*
Agent
)
newGameFromContracts
(
ctx
context
.
Context
)
(
types
.
Game
,
error
)
{
func
(
a
*
Agent
)
newGameFromContracts
(
ctx
context
.
Context
)
(
types
.
Game
,
error
)
{
claims
,
err
:=
a
.
loader
.
FetchClaims
(
ctx
)
claims
,
err
:=
a
.
loader
.
FetchClaims
(
ctx
)
...
...
op-challenger/game/fault/agent_test.go
View file @
16f0aad4
...
@@ -77,7 +77,7 @@ func TestDoNotMakeMovesWhenGameIsResolvable(t *testing.T) {
...
@@ -77,7 +77,7 @@ func TestDoNotMakeMovesWhenGameIsResolvable(t *testing.T) {
require
.
NoError
(
t
,
agent
.
Act
(
ctx
))
require
.
NoError
(
t
,
agent
.
Act
(
ctx
))
require
.
Equal
(
t
,
1
,
responder
.
callResolveCount
,
"should check if game is resolvable"
)
require
.
Equal
(
t
,
1
,
responder
.
callResolveCount
,
"should check if game is resolvable"
)
require
.
Zero
(
t
,
claimLoader
.
callCount
,
"should not fetch claims for resolvable game
"
)
require
.
Equal
(
t
,
1
,
claimLoader
.
callCount
,
"should fetch claims once for resolveClaim
"
)
if
test
.
shouldResolve
{
if
test
.
shouldResolve
{
require
.
EqualValues
(
t
,
1
,
responder
.
resolveCount
,
"should resolve winning game"
)
require
.
EqualValues
(
t
,
1
,
responder
.
resolveCount
,
"should resolve winning game"
)
...
@@ -92,6 +92,7 @@ func TestLoadClaimsWhenGameNotResolvable(t *testing.T) {
...
@@ -92,6 +92,7 @@ func TestLoadClaimsWhenGameNotResolvable(t *testing.T) {
// Checks that if the game isn't resolvable, that the agent continues on to start checking claims
// Checks that if the game isn't resolvable, that the agent continues on to start checking claims
agent
,
claimLoader
,
responder
:=
setupTestAgent
(
t
,
false
)
agent
,
claimLoader
,
responder
:=
setupTestAgent
(
t
,
false
)
responder
.
callResolveErr
=
errors
.
New
(
"game is not resolvable"
)
responder
.
callResolveErr
=
errors
.
New
(
"game is not resolvable"
)
responder
.
callResolveClaimErr
=
errors
.
New
(
"claim is not resolvable"
)
depth
:=
4
depth
:=
4
claimBuilder
:=
test
.
NewClaimBuilder
(
t
,
depth
,
alphabet
.
NewTraceProvider
(
"abcdefg"
,
uint64
(
depth
)))
claimBuilder
:=
test
.
NewClaimBuilder
(
t
,
depth
,
alphabet
.
NewTraceProvider
(
"abcdefg"
,
uint64
(
depth
)))
...
@@ -101,7 +102,9 @@ func TestLoadClaimsWhenGameNotResolvable(t *testing.T) {
...
@@ -101,7 +102,9 @@ func TestLoadClaimsWhenGameNotResolvable(t *testing.T) {
require
.
NoError
(
t
,
agent
.
Act
(
context
.
Background
()))
require
.
NoError
(
t
,
agent
.
Act
(
context
.
Background
()))
require
.
EqualValues
(
t
,
1
,
claimLoader
.
callCount
,
"should load claims for unresolvable game"
)
require
.
EqualValues
(
t
,
2
,
claimLoader
.
callCount
,
"should load claims for unresolvable game"
)
require
.
EqualValues
(
t
,
responder
.
callResolveClaimCount
,
1
,
"should check if claim is resolvable"
)
require
.
Zero
(
t
,
responder
.
resolveClaimCount
,
"should not send resolveClaim"
)
}
}
func
setupTestAgent
(
t
*
testing
.
T
,
agreeWithProposedOutput
bool
)
(
*
Agent
,
*
stubClaimLoader
,
*
stubResponder
)
{
func
setupTestAgent
(
t
*
testing
.
T
,
agreeWithProposedOutput
bool
)
(
*
Agent
,
*
stubClaimLoader
,
*
stubResponder
)
{
...
@@ -132,6 +135,10 @@ type stubResponder struct {
...
@@ -132,6 +135,10 @@ type stubResponder struct {
resolveCount
int
resolveCount
int
resolveErr
error
resolveErr
error
callResolveClaimCount
int
callResolveClaimErr
error
resolveClaimCount
int
}
}
func
(
s
*
stubResponder
)
CallResolve
(
ctx
context
.
Context
)
(
gameTypes
.
GameStatus
,
error
)
{
func
(
s
*
stubResponder
)
CallResolve
(
ctx
context
.
Context
)
(
gameTypes
.
GameStatus
,
error
)
{
...
@@ -144,8 +151,18 @@ func (s *stubResponder) Resolve(ctx context.Context) error {
...
@@ -144,8 +151,18 @@ func (s *stubResponder) Resolve(ctx context.Context) error {
return
s
.
resolveErr
return
s
.
resolveErr
}
}
func
(
s
*
stubResponder
)
CallResolveClaim
(
ctx
context
.
Context
,
clainIdx
uint64
)
error
{
s
.
callResolveClaimCount
++
return
s
.
callResolveClaimErr
}
func
(
s
*
stubResponder
)
ResolveClaim
(
ctx
context
.
Context
,
clainIdx
uint64
)
error
{
s
.
resolveClaimCount
++
return
nil
}
func
(
s
*
stubResponder
)
PerformAction
(
ctx
context
.
Context
,
response
types
.
Action
)
error
{
func
(
s
*
stubResponder
)
PerformAction
(
ctx
context
.
Context
,
response
types
.
Action
)
error
{
panic
(
"Not implemented"
)
return
nil
}
}
type
stubUpdater
struct
{
type
stubUpdater
struct
{
...
...
op-challenger/game/fault/responder/responder.go
View file @
16f0aad4
...
@@ -94,6 +94,34 @@ func (r *FaultResponder) Resolve(ctx context.Context) error {
...
@@ -94,6 +94,34 @@ func (r *FaultResponder) Resolve(ctx context.Context) error {
return
r
.
sendTxAndWait
(
ctx
,
txData
)
return
r
.
sendTxAndWait
(
ctx
,
txData
)
}
}
// buildResolveClaimData creates the transaction data for the ResolveClaim function.
func
(
r
*
FaultResponder
)
buildResolveClaimData
(
ctx
context
.
Context
,
claimIdx
uint64
)
([]
byte
,
error
)
{
return
r
.
fdgAbi
.
Pack
(
"resolveClaim"
,
big
.
NewInt
(
int64
(
claimIdx
)))
}
// CallResolveClaim determines if the resolveClaim function on the fault dispute game contract
// would succeed.
func
(
r
*
FaultResponder
)
CallResolveClaim
(
ctx
context
.
Context
,
claimIdx
uint64
)
error
{
txData
,
err
:=
r
.
buildResolveClaimData
(
ctx
,
claimIdx
)
if
err
!=
nil
{
return
err
}
_
,
err
=
r
.
txMgr
.
Call
(
ctx
,
ethereum
.
CallMsg
{
To
:
&
r
.
fdgAddr
,
Data
:
txData
,
},
nil
)
return
err
}
// ResolveClaim executes a resolveClaim transaction to resolve a fault dispute game.
func
(
r
*
FaultResponder
)
ResolveClaim
(
ctx
context
.
Context
,
claimIdx
uint64
)
error
{
txData
,
err
:=
r
.
buildResolveClaimData
(
ctx
,
claimIdx
)
if
err
!=
nil
{
return
err
}
return
r
.
sendTxAndWait
(
ctx
,
txData
)
}
func
(
r
*
FaultResponder
)
PerformAction
(
ctx
context
.
Context
,
action
types
.
Action
)
error
{
func
(
r
*
FaultResponder
)
PerformAction
(
ctx
context
.
Context
,
action
types
.
Action
)
error
{
var
txData
[]
byte
var
txData
[]
byte
var
err
error
var
err
error
...
...
op-challenger/game/fault/responder/responder_test.go
View file @
16f0aad4
...
@@ -73,6 +73,40 @@ func TestResolve(t *testing.T) {
...
@@ -73,6 +73,40 @@ func TestResolve(t *testing.T) {
})
})
}
}
func
TestCallResolveClaim
(
t
*
testing
.
T
)
{
t
.
Run
(
"SendFails"
,
func
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
)
mockTxMgr
.
callFails
=
true
err
:=
responder
.
CallResolveClaim
(
context
.
Background
(),
0
)
require
.
ErrorIs
(
t
,
err
,
mockCallError
)
require
.
Equal
(
t
,
0
,
mockTxMgr
.
calls
)
})
t
.
Run
(
"Success"
,
func
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
)
err
:=
responder
.
CallResolveClaim
(
context
.
Background
(),
0
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
1
,
mockTxMgr
.
calls
)
})
}
func
TestResolveClaim
(
t
*
testing
.
T
)
{
t
.
Run
(
"SendFails"
,
func
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
)
mockTxMgr
.
sendFails
=
true
err
:=
responder
.
ResolveClaim
(
context
.
Background
(),
0
)
require
.
ErrorIs
(
t
,
err
,
mockSendError
)
require
.
Equal
(
t
,
0
,
mockTxMgr
.
sends
)
})
t
.
Run
(
"Success"
,
func
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
)
err
:=
responder
.
ResolveClaim
(
context
.
Background
(),
0
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
1
,
mockTxMgr
.
sends
)
})
}
// TestRespond tests the [Responder.Respond] method.
// TestRespond tests the [Responder.Respond] method.
func
TestPerformAction
(
t
*
testing
.
T
)
{
func
TestPerformAction
(
t
*
testing
.
T
)
{
t
.
Run
(
"send fails"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"send fails"
,
func
(
t
*
testing
.
T
)
{
...
...
op-challenger/game/fault/solver/game_solver.go
View file @
16f0aad4
...
@@ -48,7 +48,10 @@ func (s *GameSolver) calculateStep(ctx context.Context, game types.Game, claim t
...
@@ -48,7 +48,10 @@ func (s *GameSolver) calculateStep(ctx context.Context, game types.Game, claim t
if
game
.
AgreeWithClaimLevel
(
claim
)
{
if
game
.
AgreeWithClaimLevel
(
claim
)
{
return
nil
,
nil
return
nil
,
nil
}
}
step
,
err
:=
s
.
claimSolver
.
AttemptStep
(
ctx
,
claim
,
game
.
AgreeWithClaimLevel
(
claim
))
step
,
err
:=
s
.
claimSolver
.
AttemptStep
(
ctx
,
game
,
claim
)
if
err
==
ErrStepIgnoreInvalidPath
{
return
nil
,
nil
}
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -63,11 +66,14 @@ func (s *GameSolver) calculateStep(ctx context.Context, game types.Game, claim t
...
@@ -63,11 +66,14 @@ func (s *GameSolver) calculateStep(ctx context.Context, game types.Game, claim t
}
}
func
(
s
*
GameSolver
)
calculateMove
(
ctx
context
.
Context
,
game
types
.
Game
,
claim
types
.
Claim
)
(
*
types
.
Action
,
error
)
{
func
(
s
*
GameSolver
)
calculateMove
(
ctx
context
.
Context
,
game
types
.
Game
,
claim
types
.
Claim
)
(
*
types
.
Action
,
error
)
{
move
,
err
:=
s
.
claimSolver
.
NextMove
(
ctx
,
claim
,
game
.
AgreeWithClaimLevel
(
claim
))
if
game
.
AgreeWithClaimLevel
(
claim
)
{
return
nil
,
nil
}
move
,
err
:=
s
.
claimSolver
.
NextMove
(
ctx
,
claim
,
game
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to calculate next move for claim index %v: %w"
,
claim
.
ContractIndex
,
err
)
return
nil
,
fmt
.
Errorf
(
"failed to calculate next move for claim index %v: %w"
,
claim
.
ContractIndex
,
err
)
}
}
if
move
==
nil
||
game
.
IsDuplicate
(
move
.
ClaimData
)
{
if
move
==
nil
||
game
.
IsDuplicate
(
*
move
)
{
return
nil
,
nil
return
nil
,
nil
}
}
return
&
types
.
Action
{
return
&
types
.
Action
{
...
...
op-challenger/game/fault/solver/game_solver_test.go
View file @
16f0aad4
...
@@ -48,7 +48,6 @@ func TestCalculateNextActions(t *testing.T) {
...
@@ -48,7 +48,6 @@ func TestCalculateNextActions(t *testing.T) {
rootClaimCorrect
:
true
,
rootClaimCorrect
:
true
,
setupGame
:
func
(
builder
*
faulttest
.
GameBuilder
)
{},
setupGame
:
func
(
builder
*
faulttest
.
GameBuilder
)
{},
},
},
{
{
name
:
"DoNotPerformDuplicateMoves"
,
name
:
"DoNotPerformDuplicateMoves"
,
agreeWithOutputRoot
:
true
,
agreeWithOutputRoot
:
true
,
...
@@ -93,16 +92,15 @@ func TestCalculateNextActions(t *testing.T) {
...
@@ -93,16 +92,15 @@ func TestCalculateNextActions(t *testing.T) {
maliciousStateHash
:=
common
.
Hash
{
0x01
,
0xaa
}
maliciousStateHash
:=
common
.
Hash
{
0x01
,
0xaa
}
// Dishonest actor counters their own claims to set up a situation with an invalid prestate
// Dishonest actor counters their own claims to set up a situation with an invalid prestate
// The honest actor should attack all claims that support the root claim (disagree with the output root)
// The honest actor should ignore path created by the dishonest actor, only supporting its own attack on the root claim
builder
.
Seq
()
.
ExpectAttack
()
.
// This expected action is the winning move.
honestMove
:=
builder
.
Seq
()
.
AttackCorrect
()
// This expected action is the winning move.
Attack
(
maliciousStateHash
)
.
dishonestMove
:=
honestMove
.
Attack
(
maliciousStateHash
)
Defend
(
maliciousStateHash
)
.
ExpectAttack
()
.
// The expected action by the honest actor
Attack
(
maliciousStateHash
)
.
dishonestMove
.
ExpectAttack
()
Attack
(
maliciousStateHash
)
.
ExpectStepAttack
()
// The honest actor will ignore this poisoned path
dishonestMove
.
// The attempt to step against our malicious leaf node will fail because the pre-state won't match our
Defend
(
maliciousStateHash
)
.
// malicious state hash. However, it is the very first expected action, attacking the root claim with
Attack
(
maliciousStateHash
)
// the correct hash that wins the game since it will be the left-most uncountered claim.
},
},
},
},
}
}
...
...
op-challenger/game/fault/solver/rules.go
View file @
16f0aad4
...
@@ -13,7 +13,6 @@ var rules = []actionRule{
...
@@ -13,7 +13,6 @@ var rules = []actionRule{
parentMustExist
,
parentMustExist
,
onlyStepAtMaxDepth
,
onlyStepAtMaxDepth
,
onlyMoveBeforeMaxDepth
,
onlyMoveBeforeMaxDepth
,
onlyCounterClaimsAtDisagreeingLevels
,
doNotDuplicateExistingMoves
,
doNotDuplicateExistingMoves
,
doNotDefendRootClaim
,
doNotDefendRootClaim
,
}
}
...
@@ -57,20 +56,12 @@ func onlyMoveBeforeMaxDepth(game types.Game, action types.Action) error {
...
@@ -57,20 +56,12 @@ func onlyMoveBeforeMaxDepth(game types.Game, action types.Action) error {
return
nil
return
nil
}
}
func
onlyCounterClaimsAtDisagreeingLevels
(
game
types
.
Game
,
action
types
.
Action
)
error
{
parentClaim
:=
game
.
Claims
()[
action
.
ParentIdx
]
if
game
.
AgreeWithClaimLevel
(
parentClaim
)
{
return
fmt
.
Errorf
(
"countering a claim at depth %v that supports our view of the root"
,
parentClaim
.
Position
.
Depth
())
}
return
nil
}
func
doNotDuplicateExistingMoves
(
game
types
.
Game
,
action
types
.
Action
)
error
{
func
doNotDuplicateExistingMoves
(
game
types
.
Game
,
action
types
.
Action
)
error
{
newClaimData
:=
types
.
ClaimData
{
newClaimData
:=
types
.
ClaimData
{
Value
:
action
.
Value
,
Value
:
action
.
Value
,
Position
:
resultingPosition
(
game
,
action
),
Position
:
resultingPosition
(
game
,
action
),
}
}
if
game
.
IsDuplicate
(
newClaimData
)
{
if
game
.
IsDuplicate
(
types
.
Claim
{
ClaimData
:
newClaimData
,
ParentContractIndex
:
action
.
ParentIdx
}
)
{
return
fmt
.
Errorf
(
"creating duplicate claim at %v with value %v"
,
newClaimData
.
Position
.
ToGIndex
(),
newClaimData
.
Value
)
return
fmt
.
Errorf
(
"creating duplicate claim at %v with value %v"
,
newClaimData
.
Position
.
ToGIndex
(),
newClaimData
.
Value
)
}
}
return
nil
return
nil
...
...
op-challenger/game/fault/solver/solver.go
View file @
16f0aad4
...
@@ -11,8 +11,9 @@ import (
...
@@ -11,8 +11,9 @@ import (
)
)
var
(
var
(
ErrStepNonLeafNode
=
errors
.
New
(
"cannot step on non-leaf claims"
)
ErrStepNonLeafNode
=
errors
.
New
(
"cannot step on non-leaf claims"
)
ErrStepAgreedClaim
=
errors
.
New
(
"cannot step on claims we agree with"
)
ErrStepAgreedClaim
=
errors
.
New
(
"cannot step on claims we agree with"
)
ErrStepIgnoreInvalidPath
=
errors
.
New
(
"cannot step on claims that dispute invalid paths"
)
)
)
// claimSolver uses a [TraceProvider] to determine the moves to make in a dispute game.
// claimSolver uses a [TraceProvider] to determine the moves to make in a dispute game.
...
@@ -30,10 +31,7 @@ func newClaimSolver(gameDepth int, traceProvider types.TraceProvider) *claimSolv
...
@@ -30,10 +31,7 @@ func newClaimSolver(gameDepth int, traceProvider types.TraceProvider) *claimSolv
}
}
// NextMove returns the next move to make given the current state of the game.
// NextMove returns the next move to make given the current state of the game.
func
(
s
*
claimSolver
)
NextMove
(
ctx
context
.
Context
,
claim
types
.
Claim
,
agreeWithClaimLevel
bool
)
(
*
types
.
Claim
,
error
)
{
func
(
s
*
claimSolver
)
NextMove
(
ctx
context
.
Context
,
claim
types
.
Claim
,
game
types
.
Game
)
(
*
types
.
Claim
,
error
)
{
if
agreeWithClaimLevel
{
return
nil
,
nil
}
if
claim
.
Depth
()
==
s
.
gameDepth
{
if
claim
.
Depth
()
==
s
.
gameDepth
{
return
nil
,
types
.
ErrGameDepthReached
return
nil
,
types
.
ErrGameDepthReached
}
}
...
@@ -41,6 +39,24 @@ func (s *claimSolver) NextMove(ctx context.Context, claim types.Claim, agreeWith
...
@@ -41,6 +39,24 @@ func (s *claimSolver) NextMove(ctx context.Context, claim types.Claim, agreeWith
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
// Before challenging this claim, first check that the move wasn't warranted.
// If the parent claim is on a dishonest path, then we would have moved against it anyways. So we don't move.
// Avoiding dishonest paths ensures that there's always a valid claim available to support ours during step.
if
!
claim
.
IsRoot
()
{
parent
,
err
:=
game
.
GetParent
(
claim
)
if
err
!=
nil
{
return
nil
,
err
}
agreeWithParent
,
err
:=
s
.
agreeWithClaimPath
(
ctx
,
game
,
parent
)
if
err
!=
nil
{
return
nil
,
err
}
if
!
agreeWithParent
{
return
nil
,
nil
}
}
if
agree
{
if
agree
{
return
s
.
defend
(
ctx
,
claim
)
return
s
.
defend
(
ctx
,
claim
)
}
else
{
}
else
{
...
@@ -58,13 +74,25 @@ type StepData struct {
...
@@ -58,13 +74,25 @@ type StepData struct {
// AttemptStep determines what step should occur for a given leaf claim.
// AttemptStep determines what step should occur for a given leaf claim.
// An error will be returned if the claim is not at the max depth.
// An error will be returned if the claim is not at the max depth.
func
(
s
*
claimSolver
)
AttemptStep
(
ctx
context
.
Context
,
claim
types
.
Claim
,
agreeWithClaimLevel
bool
)
(
StepData
,
error
)
{
// Returns ErrStepIgnoreInvalidPath if the claim disputes an invalid path
func
(
s
*
claimSolver
)
AttemptStep
(
ctx
context
.
Context
,
game
types
.
Game
,
claim
types
.
Claim
)
(
StepData
,
error
)
{
if
claim
.
Depth
()
!=
s
.
gameDepth
{
if
claim
.
Depth
()
!=
s
.
gameDepth
{
return
StepData
{},
ErrStepNonLeafNode
return
StepData
{},
ErrStepNonLeafNode
}
}
if
agreeWithClaimLevel
{
return
StepData
{},
ErrStepAgreedClaim
// Step only on claims that dispute a valid path
parent
,
err
:=
game
.
GetParent
(
claim
)
if
err
!=
nil
{
return
StepData
{},
err
}
}
parentValid
,
err
:=
s
.
agreeWithClaimPath
(
ctx
,
game
,
parent
)
if
err
!=
nil
{
return
StepData
{},
err
}
if
!
parentValid
{
return
StepData
{},
ErrStepIgnoreInvalidPath
}
claimCorrect
,
err
:=
s
.
agreeWithClaim
(
ctx
,
claim
.
ClaimData
)
claimCorrect
,
err
:=
s
.
agreeWithClaim
(
ctx
,
claim
.
ClaimData
)
if
err
!=
nil
{
if
err
!=
nil
{
return
StepData
{},
err
return
StepData
{},
err
...
@@ -142,3 +170,26 @@ func (s *claimSolver) traceAtPosition(ctx context.Context, p types.Position) (co
...
@@ -142,3 +170,26 @@ func (s *claimSolver) traceAtPosition(ctx context.Context, p types.Position) (co
hash
,
err
:=
s
.
trace
.
Get
(
ctx
,
index
)
hash
,
err
:=
s
.
trace
.
Get
(
ctx
,
index
)
return
hash
,
err
return
hash
,
err
}
}
// agreeWithClaimPath returns true if the every other claim in the path to root is correct according to the internal [TraceProvider].
func
(
s
*
claimSolver
)
agreeWithClaimPath
(
ctx
context
.
Context
,
game
types
.
Game
,
claim
types
.
Claim
)
(
bool
,
error
)
{
agree
,
err
:=
s
.
agreeWithClaim
(
ctx
,
claim
.
ClaimData
)
if
err
!=
nil
{
return
false
,
err
}
if
!
agree
{
return
false
,
nil
}
if
claim
.
IsRoot
()
||
claim
.
Parent
.
IsRootPosition
()
{
return
true
,
nil
}
parent
,
err
:=
game
.
GetParent
(
claim
)
if
err
!=
nil
{
return
false
,
err
}
grandParent
,
err
:=
game
.
GetParent
(
parent
)
if
err
!=
nil
{
return
false
,
err
}
return
s
.
agreeWithClaimPath
(
ctx
,
game
,
grandParent
)
}
op-challenger/game/fault/solver/solver_test.go
View file @
16f0aad4
...
@@ -2,206 +2,171 @@ package solver
...
@@ -2,206 +2,171 @@ package solver
import
(
import
(
"context"
"context"
"errors"
"testing"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/test"
faulttest
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/test"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/require"
)
)
func
TestNextMove
(
t
*
testing
.
T
)
{
maxDepth
:=
4
builder
:=
test
.
NewAlphabetClaimBuilder
(
t
,
maxDepth
)
tests
:=
[]
struct
{
name
string
claim
types
.
Claim
agreeWithLevel
bool
expectedErr
error
expectedMove
func
(
claim
types
.
Claim
,
correct
bool
)
types
.
Claim
}{
{
name
:
"AgreeWithLevel_CorrectRoot"
,
claim
:
builder
.
CreateRootClaim
(
true
),
agreeWithLevel
:
true
,
},
{
name
:
"AgreeWithLevel_IncorrectRoot"
,
claim
:
builder
.
CreateRootClaim
(
false
),
agreeWithLevel
:
true
,
},
{
name
:
"AgreeWithLevel_EvenDepth"
,
claim
:
builder
.
Seq
(
false
)
.
Attack
(
false
)
.
Get
(),
agreeWithLevel
:
true
,
},
{
name
:
"AgreeWithLevel_OddDepth"
,
claim
:
builder
.
Seq
(
false
)
.
Attack
(
false
)
.
Defend
(
false
)
.
Get
(),
agreeWithLevel
:
true
,
},
{
name
:
"Root_CorrectValue"
,
claim
:
builder
.
CreateRootClaim
(
true
),
},
{
name
:
"Root_IncorrectValue"
,
claim
:
builder
.
CreateRootClaim
(
false
),
expectedMove
:
builder
.
AttackClaim
,
},
{
name
:
"NonRoot_AgreeWithParentAndClaim"
,
claim
:
builder
.
Seq
(
true
)
.
Attack
(
true
)
.
Get
(),
expectedMove
:
builder
.
DefendClaim
,
},
{
name
:
"NonRoot_AgreeWithParentDisagreeWithClaim"
,
claim
:
builder
.
Seq
(
true
)
.
Attack
(
false
)
.
Get
(),
expectedMove
:
builder
.
AttackClaim
,
},
{
name
:
"NonRoot_DisagreeWithParentAgreeWithClaim"
,
claim
:
builder
.
Seq
(
false
)
.
Attack
(
true
)
.
Get
(),
expectedMove
:
builder
.
DefendClaim
,
},
{
name
:
"NonRoot_DisagreeWithParentAndClaim"
,
claim
:
builder
.
Seq
(
false
)
.
Attack
(
false
)
.
Get
(),
expectedMove
:
builder
.
AttackClaim
,
},
{
name
:
"ErrorWhenClaimIsLeaf_Correct"
,
claim
:
builder
.
CreateLeafClaim
(
4
,
true
),
expectedErr
:
types
.
ErrGameDepthReached
,
},
{
name
:
"ErrorWhenClaimIsLeaf_Incorrect"
,
claim
:
builder
.
CreateLeafClaim
(
6
,
false
),
expectedErr
:
types
.
ErrGameDepthReached
,
},
}
for
_
,
test
:=
range
tests
{
test
:=
test
t
.
Run
(
test
.
name
,
func
(
t
*
testing
.
T
)
{
solver
:=
newClaimSolver
(
maxDepth
,
builder
.
CorrectTraceProvider
())
move
,
err
:=
solver
.
NextMove
(
context
.
Background
(),
test
.
claim
,
test
.
agreeWithLevel
)
if
test
.
expectedErr
==
nil
{
require
.
NoError
(
t
,
err
)
}
else
{
require
.
ErrorIs
(
t
,
err
,
test
.
expectedErr
)
}
if
test
.
expectedMove
==
nil
{
require
.
Nil
(
t
,
move
)
}
else
{
expected
:=
test
.
expectedMove
(
test
.
claim
,
true
)
require
.
Equal
(
t
,
&
expected
,
move
)
}
})
}
}
func
TestAttemptStep
(
t
*
testing
.
T
)
{
func
TestAttemptStep
(
t
*
testing
.
T
)
{
maxDepth
:=
3
maxDepth
:=
3
builder
:=
test
.
NewAlphabetClaimBuilder
(
t
,
maxDepth
)
claimBuilder
:=
fault
test
.
NewAlphabetClaimBuilder
(
t
,
maxDepth
)
// Last accessible leaf is the second last trace index
// Last accessible leaf is the second last trace index
// The root node is used for the last trace index and can only be attacked.
// The root node is used for the last trace index and can only be attacked.
lastLeafTraceIndex
:=
uint64
(
1
<<
maxDepth
-
2
)
lastLeafTraceIndex
:=
uint64
(
1
<<
maxDepth
-
2
)
errProvider
:=
errors
.
New
(
"provider error"
)
ctx
:=
context
.
Background
()
ctx
:=
context
.
Background
()
tests
:=
[]
struct
{
tests
:=
[]
struct
{
name
string
name
string
claim
types
.
Claim
agreeWithOutputRoot
bool
agreeWithLevel
bool
expectedErr
error
expect
edErr
error
expect
Attack
bool
expect
Attack
bool
expect
PreState
[]
byte
expectPr
eState
[]
byte
expectPr
oofData
[]
byte
expect
ProofData
[]
byte
expect
edOracleData
*
types
.
PreimageOracleData
expectedOracleData
*
types
.
PreimageOracleData
setupGame
func
(
builder
*
faulttest
.
GameBuilder
)
}{
}{
{
{
name
:
"AttackFirstTraceIndex"
,
name
:
"AttackFirstTraceIndex"
,
claim
:
builder
.
CreateLeafClaim
(
0
,
false
),
expectAttack
:
true
,
expectAttack
:
true
,
expectPreState
:
builder
.
CorrectPreState
(
0
),
expectPreState
:
claimBuilder
.
CorrectPreState
(
0
),
expectProofData
:
builder
.
CorrectProofData
(
0
),
expectProofData
:
claimBuilder
.
CorrectProofData
(
0
),
expectedOracleData
:
builder
.
CorrectOracleData
(
0
),
expectedOracleData
:
claimBuilder
.
CorrectOracleData
(
0
),
setupGame
:
func
(
builder
*
faulttest
.
GameBuilder
)
{
builder
.
Seq
()
.
Attack
(
common
.
Hash
{
0xaa
})
.
AttackCorrect
()
.
Attack
(
common
.
Hash
{
0xbb
})
},
},
},
{
{
name
:
"DefendFirstTraceIndex"
,
name
:
"DefendFirstTraceIndex"
,
claim
:
builder
.
CreateLeafClaim
(
0
,
true
),
expectAttack
:
false
,
expectAttack
:
false
,
expectPreState
:
builder
.
CorrectPreState
(
1
),
expectPreState
:
claimBuilder
.
CorrectPreState
(
1
),
expectProofData
:
builder
.
CorrectProofData
(
1
),
expectProofData
:
claimBuilder
.
CorrectProofData
(
1
),
expectedOracleData
:
builder
.
CorrectOracleData
(
1
),
expectedOracleData
:
claimBuilder
.
CorrectOracleData
(
1
),
setupGame
:
func
(
builder
*
faulttest
.
GameBuilder
)
{
builder
.
Seq
()
.
Attack
(
common
.
Hash
{
0xaa
})
.
AttackCorrect
()
.
AttackCorrect
()
},
},
},
{
{
name
:
"AttackMiddleTraceIndex"
,
name
:
"AttackMiddleTraceIndex"
,
claim
:
builder
.
CreateLeafClaim
(
4
,
false
),
expectAttack
:
true
,
expectAttack
:
true
,
expectPreState
:
builder
.
CorrectPreState
(
4
),
expectPreState
:
claimBuilder
.
CorrectPreState
(
4
),
expectProofData
:
builder
.
CorrectProofData
(
4
),
expectProofData
:
claimBuilder
.
CorrectProofData
(
4
),
expectedOracleData
:
builder
.
CorrectOracleData
(
4
),
expectedOracleData
:
claimBuilder
.
CorrectOracleData
(
4
),
setupGame
:
func
(
builder
*
faulttest
.
GameBuilder
)
{
builder
.
Seq
()
.
AttackCorrect
()
.
DefendCorrect
()
.
Attack
(
common
.
Hash
{
0xaa
})
},
},
},
{
{
name
:
"DefendMiddleTraceIndex"
,
name
:
"DefendMiddleTraceIndex"
,
claim
:
builder
.
CreateLeafClaim
(
4
,
true
),
expectAttack
:
false
,
expectAttack
:
false
,
expectPreState
:
builder
.
CorrectPreState
(
5
),
expectPreState
:
claimBuilder
.
CorrectPreState
(
5
),
expectProofData
:
builder
.
CorrectProofData
(
5
),
expectProofData
:
claimBuilder
.
CorrectProofData
(
5
),
expectedOracleData
:
builder
.
CorrectOracleData
(
5
),
expectedOracleData
:
claimBuilder
.
CorrectOracleData
(
5
),
setupGame
:
func
(
builder
*
faulttest
.
GameBuilder
)
{
builder
.
Seq
()
.
AttackCorrect
()
.
DefendCorrect
()
.
AttackCorrect
()
},
},
},
{
{
name
:
"AttackLastTraceIndex"
,
name
:
"AttackLastTraceIndex"
,
claim
:
builder
.
CreateLeafClaim
(
lastLeafTraceIndex
,
false
),
expectAttack
:
true
,
expectAttack
:
true
,
expectPreState
:
builder
.
CorrectPreState
(
lastLeafTraceIndex
),
expectPreState
:
claimBuilder
.
CorrectPreState
(
lastLeafTraceIndex
),
expectProofData
:
builder
.
CorrectProofData
(
lastLeafTraceIndex
),
expectProofData
:
claimBuilder
.
CorrectProofData
(
lastLeafTraceIndex
),
expectedOracleData
:
builder
.
CorrectOracleData
(
lastLeafTraceIndex
),
expectedOracleData
:
claimBuilder
.
CorrectOracleData
(
lastLeafTraceIndex
),
setupGame
:
func
(
builder
*
faulttest
.
GameBuilder
)
{
builder
.
Seq
()
.
AttackCorrect
()
.
DefendCorrect
()
.
Defend
(
common
.
Hash
{
0xaa
})
},
},
},
{
{
name
:
"DefendLastTraceIndex"
,
name
:
"DefendLastTraceIndex"
,
claim
:
builder
.
CreateLeafClaim
(
lastLeafTraceIndex
,
true
),
expectAttack
:
false
,
expectAttack
:
false
,
expectPreState
:
builder
.
CorrectPreState
(
lastLeafTraceIndex
+
1
),
expectPreState
:
claimBuilder
.
CorrectPreState
(
lastLeafTraceIndex
+
1
),
expectProofData
:
builder
.
CorrectProofData
(
lastLeafTraceIndex
+
1
),
expectProofData
:
claimBuilder
.
CorrectProofData
(
lastLeafTraceIndex
+
1
),
expectedOracleData
:
builder
.
CorrectOracleData
(
lastLeafTraceIndex
+
1
),
expectedOracleData
:
claimBuilder
.
CorrectOracleData
(
lastLeafTraceIndex
+
1
),
},
setupGame
:
func
(
builder
*
faulttest
.
GameBuilder
)
{
{
builder
.
Seq
()
.
name
:
"CannotStepNonLeaf"
,
AttackCorrect
()
.
claim
:
builder
.
Seq
(
false
)
.
Attack
(
false
)
.
Get
(),
DefendCorrect
()
.
expectedErr
:
ErrStepNonLeafNode
,
DefendCorrect
()
},
},
{
},
name
:
"CannotStepAgreedNode"
,
{
claim
:
builder
.
Seq
(
false
)
.
Attack
(
false
)
.
Get
(),
name
:
"CannotStepNonLeaf"
,
agreeWithLevel
:
true
,
setupGame
:
func
(
builder
*
faulttest
.
GameBuilder
)
{
expectedErr
:
ErrStepNonLeafNode
,
builder
.
Seq
()
.
AttackCorrect
()
.
AttackCorrect
()
},
},
{
expectedErr
:
ErrStepNonLeafNode
,
name
:
"CannotStepAgreedNode"
,
agreeWithOutputRoot
:
true
,
claim
:
builder
.
Seq
(
false
)
.
Attack
(
false
)
.
Get
(),
},
agreeWithLevel
:
true
,
{
expectedErr
:
ErrStepNonLeafNode
,
name
:
"CannotStepAgreedNode"
,
setupGame
:
func
(
builder
*
faulttest
.
GameBuilder
)
{
builder
.
Seq
()
.
AttackCorrect
()
.
Attack
(
common
.
Hash
{
0xaa
})
.
AttackCorrect
()
},
expectedErr
:
ErrStepIgnoreInvalidPath
,
agreeWithOutputRoot
:
true
,
},
{
name
:
"CannotStepInvalidPath"
,
setupGame
:
func
(
builder
*
faulttest
.
GameBuilder
)
{
builder
.
Seq
()
.
Attack
(
common
.
Hash
{
0xaa
})
.
Attack
(
common
.
Hash
{
0xbb
})
.
Attack
(
common
.
Hash
{
0xcc
})
},
expectedErr
:
ErrStepIgnoreInvalidPath
,
agreeWithOutputRoot
:
true
,
},
{
name
:
"CannotStepNearlyValidPath"
,
expectAttack
:
true
,
expectPreState
:
claimBuilder
.
CorrectPreState
(
4
),
expectProofData
:
claimBuilder
.
CorrectProofData
(
4
),
expectedOracleData
:
claimBuilder
.
CorrectOracleData
(
4
),
setupGame
:
func
(
builder
*
faulttest
.
GameBuilder
)
{
builder
.
Seq
()
.
AttackCorrect
()
.
DefendCorrect
()
.
DefendCorrect
()
},
expectedErr
:
ErrStepIgnoreInvalidPath
,
agreeWithOutputRoot
:
true
,
},
},
}
}
for
_
,
tableTest
:=
range
tests
{
for
_
,
tableTest
:=
range
tests
{
tableTest
:=
tableTest
tableTest
:=
tableTest
t
.
Run
(
tableTest
.
name
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
tableTest
.
name
,
func
(
t
*
testing
.
T
)
{
alphabetProvider
:=
test
.
NewAlphabetWithProofProvider
(
t
,
maxDepth
,
nil
)
builder
:=
claimBuilder
.
GameBuilder
(
tableTest
.
agreeWithOutputRoot
,
!
tableTest
.
agreeWithOutputRoot
)
if
errors
.
Is
(
tableTest
.
expectedErr
,
errProvider
)
{
tableTest
.
setupGame
(
builder
)
alphabetProvider
=
test
.
NewAlphabetWithProofProvider
(
t
,
maxDepth
,
errProvider
)
alphabetSolver
:=
newClaimSolver
(
maxDepth
,
claimBuilder
.
CorrectTraceProvider
()
)
}
game
:=
builder
.
Game
builder
=
test
.
NewClaimBuilder
(
t
,
maxDepth
,
alphabetProvider
)
claims
:=
game
.
Claims
(
)
alphabetSolver
:=
newClaimSolver
(
maxDepth
,
builder
.
CorrectTraceProvider
())
lastClaim
:=
claims
[
len
(
claims
)
-
1
]
step
,
err
:=
alphabetSolver
.
AttemptStep
(
ctx
,
tableTest
.
claim
,
tableTest
.
agreeWithLevel
)
step
,
err
:=
alphabetSolver
.
AttemptStep
(
ctx
,
game
,
lastClaim
)
if
tableTest
.
expectedErr
==
nil
{
if
tableTest
.
expectedErr
==
nil
{
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
tableTest
.
c
laim
,
step
.
LeafClaim
)
require
.
Equal
(
t
,
lastC
laim
,
step
.
LeafClaim
)
require
.
Equal
(
t
,
tableTest
.
expectAttack
,
step
.
IsAttack
)
require
.
Equal
(
t
,
tableTest
.
expectAttack
,
step
.
IsAttack
)
require
.
Equal
(
t
,
tableTest
.
expectPreState
,
step
.
PreState
)
require
.
Equal
(
t
,
tableTest
.
expectPreState
,
step
.
PreState
)
require
.
Equal
(
t
,
tableTest
.
expectProofData
,
step
.
ProofData
)
require
.
Equal
(
t
,
tableTest
.
expectProofData
,
step
.
ProofData
)
...
...
op-challenger/game/fault/test/claim_builder.go
View file @
16f0aad4
...
@@ -79,12 +79,13 @@ func (c *ClaimBuilder) claim(idx uint64, correct bool) common.Hash {
...
@@ -79,12 +79,13 @@ func (c *ClaimBuilder) claim(idx uint64, correct bool) common.Hash {
func
(
c
*
ClaimBuilder
)
CreateRootClaim
(
correct
bool
)
types
.
Claim
{
func
(
c
*
ClaimBuilder
)
CreateRootClaim
(
correct
bool
)
types
.
Claim
{
value
:=
c
.
claim
((
1
<<
c
.
maxDepth
)
-
1
,
correct
)
value
:=
c
.
claim
((
1
<<
c
.
maxDepth
)
-
1
,
correct
)
return
types
.
Claim
{
claim
:=
types
.
Claim
{
ClaimData
:
types
.
ClaimData
{
ClaimData
:
types
.
ClaimData
{
Value
:
value
,
Value
:
value
,
Position
:
types
.
NewPosition
(
0
,
0
),
Position
:
types
.
NewPosition
(
0
,
0
),
},
},
}
}
return
claim
}
}
func
(
c
*
ClaimBuilder
)
CreateLeafClaim
(
traceIndex
uint64
,
correct
bool
)
types
.
Claim
{
func
(
c
*
ClaimBuilder
)
CreateLeafClaim
(
traceIndex
uint64
,
correct
bool
)
types
.
Claim
{
...
...
op-challenger/game/fault/types/game.go
View file @
16f0aad4
...
@@ -23,8 +23,12 @@ type Game interface {
...
@@ -23,8 +23,12 @@ type Game interface {
// Claims returns all of the claims in the game.
// Claims returns all of the claims in the game.
Claims
()
[]
Claim
Claims
()
[]
Claim
// IsDuplicate returns true if the provided [Claim] already exists in the game state.
// GetParent returns the parent of the provided claim.
IsDuplicate
(
claim
ClaimData
)
bool
GetParent
(
claim
Claim
)
(
Claim
,
error
)
// IsDuplicate returns true if the provided [Claim] already exists in the game state
// referencing the same parent claim
IsDuplicate
(
claim
Claim
)
bool
// AgreeWithClaimLevel returns if the game state agrees with the provided claim level.
// AgreeWithClaimLevel returns if the game state agrees with the provided claim level.
AgreeWithClaimLevel
(
claim
Claim
)
bool
AgreeWithClaimLevel
(
claim
Claim
)
bool
...
@@ -32,31 +36,37 @@ type Game interface {
...
@@ -32,31 +36,37 @@ type Game interface {
MaxDepth
()
uint64
MaxDepth
()
uint64
}
}
type
claimEntry
struct
{
ClaimData
ParentContractIndex
int
}
type
extendedClaim
struct
{
type
extendedClaim
struct
{
self
Claim
self
Claim
children
[]
ClaimData
children
[]
claimEntry
}
}
// 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
ClaimData
root
claimEntry
claims
map
[
ClaimData
]
*
extendedClaim
claims
map
[
claimEntry
]
*
extendedClaim
depth
uint64
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
,
root
Claim
,
depth
uint64
)
*
gameState
{
claims
:=
make
(
map
[
ClaimData
]
*
extendedClaim
)
claims
:=
make
(
map
[
claimEntry
]
*
extendedClaim
)
claims
[
root
.
ClaimData
]
=
&
extendedClaim
{
rootClaimEntry
:=
makeClaimEntry
(
root
)
claims
[
rootClaimEntry
]
=
&
extendedClaim
{
self
:
root
,
self
:
root
,
children
:
make
([]
ClaimData
,
0
),
children
:
make
([]
claimEntry
,
0
),
}
}
return
&
gameState
{
return
&
gameState
{
agreeWithProposedOutput
:
agreeWithProposedOutput
,
agreeWithProposedOutput
:
agreeWithProposedOutput
,
root
:
root
.
ClaimData
,
root
:
root
ClaimEntry
,
claims
:
claims
,
claims
:
claims
,
depth
:
depth
,
depth
:
depth
,
}
}
...
@@ -87,29 +97,29 @@ func (g *gameState) PutAll(claims []Claim) error {
...
@@ -87,29 +97,29 @@ func (g *gameState) PutAll(claims []Claim) error {
// Put adds a claim into the game state.
// Put adds a claim into the game state.
func
(
g
*
gameState
)
Put
(
claim
Claim
)
error
{
func
(
g
*
gameState
)
Put
(
claim
Claim
)
error
{
if
claim
.
IsRoot
()
||
g
.
IsDuplicate
(
claim
.
ClaimData
)
{
if
claim
.
IsRoot
()
||
g
.
IsDuplicate
(
claim
)
{
return
ErrClaimExists
return
ErrClaimExists
}
}
parent
,
ok
:=
g
.
claims
[
claim
.
Parent
]
if
!
ok
{
parent
:=
g
.
getParent
(
claim
)
if
parent
==
nil
{
return
errors
.
New
(
"no parent claim"
)
return
errors
.
New
(
"no parent claim"
)
}
else
{
parent
.
children
=
append
(
parent
.
children
,
claim
.
ClaimData
)
}
}
g
.
claims
[
claim
.
ClaimData
]
=
&
extendedClaim
{
parent
.
children
=
append
(
parent
.
children
,
makeClaimEntry
(
claim
))
g
.
claims
[
makeClaimEntry
(
claim
)]
=
&
extendedClaim
{
self
:
claim
,
self
:
claim
,
children
:
make
([]
ClaimData
,
0
),
children
:
make
([]
claimEntry
,
0
),
}
}
return
nil
return
nil
}
}
func
(
g
*
gameState
)
IsDuplicate
(
claim
Claim
Data
)
bool
{
func
(
g
*
gameState
)
IsDuplicate
(
claim
Claim
)
bool
{
_
,
ok
:=
g
.
claims
[
claim
]
_
,
ok
:=
g
.
claims
[
makeClaimEntry
(
claim
)
]
return
ok
return
ok
}
}
func
(
g
*
gameState
)
Claims
()
[]
Claim
{
func
(
g
*
gameState
)
Claims
()
[]
Claim
{
queue
:=
[]
ClaimData
{
g
.
root
}
queue
:=
[]
claimEntry
{
g
.
root
}
var
out
[]
Claim
var
out
[]
Claim
for
len
(
queue
)
>
0
{
for
len
(
queue
)
>
0
{
item
:=
queue
[
0
]
item
:=
queue
[
0
]
...
@@ -124,17 +134,34 @@ func (g *gameState) MaxDepth() uint64 {
...
@@ -124,17 +134,34 @@ func (g *gameState) MaxDepth() uint64 {
return
g
.
depth
return
g
.
depth
}
}
func
(
g
*
gameState
)
getChildren
(
c
ClaimData
)
[]
ClaimData
{
func
(
g
*
gameState
)
getChildren
(
c
claimEntry
)
[]
claimEntry
{
return
g
.
claims
[
c
]
.
children
return
g
.
claims
[
c
]
.
children
}
}
func
(
g
*
gameState
)
getParent
(
claim
Claim
)
(
Claim
,
error
)
{
func
(
g
*
gameState
)
GetParent
(
claim
Claim
)
(
Claim
,
error
)
{
if
claim
.
IsRoot
()
{
parent
:=
g
.
getParent
(
claim
)
if
parent
==
nil
{
return
Claim
{},
ErrClaimNotFound
return
Claim
{},
ErrClaimNotFound
}
}
if
parent
,
ok
:=
g
.
claims
[
claim
.
Parent
];
!
ok
{
return
parent
.
self
,
nil
return
Claim
{},
ErrClaimNotFound
}
}
else
{
return
parent
.
self
,
nil
func
(
g
*
gameState
)
getParent
(
claim
Claim
)
*
extendedClaim
{
if
claim
.
IsRoot
()
{
return
nil
}
// TODO(inphi): refactor gameState for faster parent lookups
for
_
,
c
:=
range
g
.
claims
{
if
c
.
self
.
ContractIndex
==
claim
.
ParentContractIndex
{
return
c
}
}
return
nil
}
func
makeClaimEntry
(
claim
Claim
)
claimEntry
{
return
claimEntry
{
ClaimData
:
claim
.
ClaimData
,
ParentContractIndex
:
claim
.
ParentContractIndex
,
}
}
}
}
op-challenger/game/fault/types/game_test.go
View file @
16f0aad4
...
@@ -24,14 +24,18 @@ func createTestClaims() (Claim, Claim, Claim, Claim) {
...
@@ -24,14 +24,18 @@ func createTestClaims() (Claim, Claim, Claim, Claim) {
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000364"
),
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000364"
),
Position
:
NewPosition
(
1
,
0
),
Position
:
NewPosition
(
1
,
0
),
},
},
Parent
:
root
.
ClaimData
,
Parent
:
root
.
ClaimData
,
ContractIndex
:
1
,
ParentContractIndex
:
0
,
}
}
middle
:=
Claim
{
middle
:=
Claim
{
ClaimData
:
ClaimData
{
ClaimData
:
ClaimData
{
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000578"
),
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000578"
),
Position
:
NewPosition
(
2
,
2
),
Position
:
NewPosition
(
2
,
2
),
},
},
Parent
:
top
.
ClaimData
,
Parent
:
top
.
ClaimData
,
ContractIndex
:
2
,
ParentContractIndex
:
1
,
}
}
bottom
:=
Claim
{
bottom
:=
Claim
{
...
@@ -39,7 +43,9 @@ func createTestClaims() (Claim, Claim, Claim, Claim) {
...
@@ -39,7 +43,9 @@ func createTestClaims() (Claim, Claim, Claim, Claim) {
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000465"
),
Value
:
common
.
HexToHash
(
"0x0000000000000000000000000000000000000000000000000000000000000465"
),
Position
:
NewPosition
(
3
,
4
),
Position
:
NewPosition
(
3
,
4
),
},
},
Parent
:
middle
.
ClaimData
,
Parent
:
middle
.
ClaimData
,
ContractIndex
:
3
,
ParentContractIndex
:
2
,
}
}
return
root
,
top
,
middle
,
bottom
return
root
,
top
,
middle
,
bottom
...
@@ -52,12 +58,12 @@ func TestIsDuplicate(t *testing.T) {
...
@@ -52,12 +58,12 @@ func TestIsDuplicate(t *testing.T) {
require
.
NoError
(
t
,
g
.
Put
(
top
))
require
.
NoError
(
t
,
g
.
Put
(
top
))
// Root + Top should be duplicates
// Root + Top should be duplicates
require
.
True
(
t
,
g
.
IsDuplicate
(
root
.
ClaimData
))
require
.
True
(
t
,
g
.
IsDuplicate
(
root
))
require
.
True
(
t
,
g
.
IsDuplicate
(
top
.
ClaimData
))
require
.
True
(
t
,
g
.
IsDuplicate
(
top
))
// Middle + Bottom should not be a duplicate
// Middle + Bottom should not be a duplicate
require
.
False
(
t
,
g
.
IsDuplicate
(
middle
.
ClaimData
))
require
.
False
(
t
,
g
.
IsDuplicate
(
middle
))
require
.
False
(
t
,
g
.
IsDuplicate
(
bottom
.
ClaimData
))
require
.
False
(
t
,
g
.
IsDuplicate
(
bottom
))
}
}
// TestGame_Put_RootAlreadyExists tests the [Game.Put] method using a [gameState]
// TestGame_Put_RootAlreadyExists tests the [Game.Put] method using a [gameState]
...
@@ -104,20 +110,20 @@ func TestGame_PutAll_ParentsAndChildren(t *testing.T) {
...
@@ -104,20 +110,20 @@ func TestGame_PutAll_ParentsAndChildren(t *testing.T) {
g
:=
NewGameState
(
false
,
root
,
testMaxDepth
)
g
:=
NewGameState
(
false
,
root
,
testMaxDepth
)
// We should not be able to get the parent of the root claim.
// We should not be able to get the parent of the root claim.
parent
,
err
:=
g
.
g
etParent
(
root
)
parent
,
err
:=
g
.
G
etParent
(
root
)
require
.
ErrorIs
(
t
,
err
,
ErrClaimNotFound
)
require
.
ErrorIs
(
t
,
err
,
ErrClaimNotFound
)
require
.
Equal
(
t
,
parent
,
Claim
{})
require
.
Equal
(
t
,
parent
,
Claim
{})
// Put the rest of the claims in the state.
// Put the rest of the claims in the state.
err
=
g
.
PutAll
([]
Claim
{
top
,
middle
,
bottom
})
err
=
g
.
PutAll
([]
Claim
{
top
,
middle
,
bottom
})
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
parent
,
err
=
g
.
g
etParent
(
top
)
parent
,
err
=
g
.
G
etParent
(
top
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
parent
,
root
)
require
.
Equal
(
t
,
parent
,
root
)
parent
,
err
=
g
.
g
etParent
(
middle
)
parent
,
err
=
g
.
G
etParent
(
middle
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
parent
,
top
)
require
.
Equal
(
t
,
parent
,
top
)
parent
,
err
=
g
.
g
etParent
(
bottom
)
parent
,
err
=
g
.
G
etParent
(
bottom
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
parent
,
middle
)
require
.
Equal
(
t
,
parent
,
middle
)
}
}
...
@@ -145,28 +151,28 @@ func TestGame_Put_ParentsAndChildren(t *testing.T) {
...
@@ -145,28 +151,28 @@ func TestGame_Put_ParentsAndChildren(t *testing.T) {
g
:=
NewGameState
(
false
,
root
,
testMaxDepth
)
g
:=
NewGameState
(
false
,
root
,
testMaxDepth
)
// We should not be able to get the parent of the root claim.
// We should not be able to get the parent of the root claim.
parent
,
err
:=
g
.
g
etParent
(
root
)
parent
,
err
:=
g
.
G
etParent
(
root
)
require
.
ErrorIs
(
t
,
err
,
ErrClaimNotFound
)
require
.
ErrorIs
(
t
,
err
,
ErrClaimNotFound
)
require
.
Equal
(
t
,
parent
,
Claim
{})
require
.
Equal
(
t
,
parent
,
Claim
{})
// Put + Check Top
// Put + Check Top
err
=
g
.
Put
(
top
)
err
=
g
.
Put
(
top
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
parent
,
err
=
g
.
g
etParent
(
top
)
parent
,
err
=
g
.
G
etParent
(
top
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
parent
,
root
)
require
.
Equal
(
t
,
parent
,
root
)
// Put + Check Top Middle
// Put + Check Top Middle
err
=
g
.
Put
(
middle
)
err
=
g
.
Put
(
middle
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
parent
,
err
=
g
.
g
etParent
(
middle
)
parent
,
err
=
g
.
G
etParent
(
middle
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
parent
,
top
)
require
.
Equal
(
t
,
parent
,
top
)
// Put + Check Top Bottom
// Put + Check Top Bottom
err
=
g
.
Put
(
bottom
)
err
=
g
.
Put
(
bottom
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
parent
,
err
=
g
.
g
etParent
(
bottom
)
parent
,
err
=
g
.
G
etParent
(
bottom
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
parent
,
middle
)
require
.
Equal
(
t
,
parent
,
middle
)
}
}
...
@@ -194,27 +200,3 @@ func TestGame_ClaimPairs(t *testing.T) {
...
@@ -194,27 +200,3 @@ func TestGame_ClaimPairs(t *testing.T) {
claims
:=
g
.
Claims
()
claims
:=
g
.
Claims
()
require
.
ElementsMatch
(
t
,
expected
,
claims
)
require
.
ElementsMatch
(
t
,
expected
,
claims
)
}
}
func
TestAgreeWithClaimLevelDisagreeWithOutput
(
t
*
testing
.
T
)
{
// Setup the game state.
root
,
top
,
middle
,
bottom
:=
createTestClaims
()
g
:=
NewGameState
(
false
,
root
,
testMaxDepth
)
require
.
NoError
(
t
,
g
.
PutAll
([]
Claim
{
top
,
middle
,
bottom
}))
require
.
True
(
t
,
g
.
AgreeWithClaimLevel
(
root
))
require
.
False
(
t
,
g
.
AgreeWithClaimLevel
(
top
))
require
.
True
(
t
,
g
.
AgreeWithClaimLevel
(
middle
))
require
.
False
(
t
,
g
.
AgreeWithClaimLevel
(
bottom
))
}
func
TestAgreeWithClaimLevelAgreeWithOutput
(
t
*
testing
.
T
)
{
// Setup the game state.
root
,
top
,
middle
,
bottom
:=
createTestClaims
()
g
:=
NewGameState
(
true
,
root
,
testMaxDepth
)
require
.
NoError
(
t
,
g
.
PutAll
([]
Claim
{
top
,
middle
,
bottom
}))
require
.
False
(
t
,
g
.
AgreeWithClaimLevel
(
root
))
require
.
True
(
t
,
g
.
AgreeWithClaimLevel
(
top
))
require
.
False
(
t
,
g
.
AgreeWithClaimLevel
(
middle
))
require
.
True
(
t
,
g
.
AgreeWithClaimLevel
(
bottom
))
}
op-e2e/e2eutils/challenger/helper.go
View file @
16f0aad4
...
@@ -68,6 +68,12 @@ func WithAlphabet(alphabet string) Option {
...
@@ -68,6 +68,12 @@ func WithAlphabet(alphabet string) Option {
}
}
}
}
func
WithPollInterval
(
pollInterval
time
.
Duration
)
Option
{
return
func
(
c
*
config
.
Config
)
{
c
.
PollInterval
=
pollInterval
}
}
func
WithCannon
(
func
WithCannon
(
t
*
testing
.
T
,
t
*
testing
.
T
,
rollupCfg
*
rollup
.
Config
,
rollupCfg
*
rollup
.
Config
,
...
@@ -98,7 +104,7 @@ func WithCannon(
...
@@ -98,7 +104,7 @@ func WithCannon(
}
}
func
NewChallenger
(
t
*
testing
.
T
,
ctx
context
.
Context
,
l1Endpoint
string
,
name
string
,
options
...
Option
)
*
Helper
{
func
NewChallenger
(
t
*
testing
.
T
,
ctx
context
.
Context
,
l1Endpoint
string
,
name
string
,
options
...
Option
)
*
Helper
{
log
:=
testlog
.
Logger
(
t
,
log
.
Lvl
Info
)
.
New
(
"role"
,
name
)
log
:=
testlog
.
Logger
(
t
,
log
.
Lvl
Debug
)
.
New
(
"role"
,
name
)
log
.
Info
(
"Creating challenger"
,
"l1"
,
l1Endpoint
)
log
.
Info
(
"Creating challenger"
,
"l1"
,
l1Endpoint
)
cfg
:=
NewChallengerConfig
(
t
,
l1Endpoint
,
options
...
)
cfg
:=
NewChallengerConfig
(
t
,
l1Endpoint
,
options
...
)
...
...
op-e2e/e2eutils/disputegame/alphabet_helper.go
View file @
16f0aad4
...
@@ -4,6 +4,7 @@ import (
...
@@ -4,6 +4,7 @@ import (
"context"
"context"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"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-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
...
@@ -33,3 +34,12 @@ func (g *AlphabetGameHelper) StartChallenger(ctx context.Context, l1Endpoint str
...
@@ -33,3 +34,12 @@ func (g *AlphabetGameHelper) StartChallenger(ctx context.Context, l1Endpoint str
})
})
return
c
return
c
}
}
func
(
g
*
AlphabetGameHelper
)
CreateHonestActor
(
ctx
context
.
Context
,
alphabetTrace
string
,
depth
uint64
)
*
HonestHelper
{
return
&
HonestHelper
{
t
:
g
.
t
,
require
:
g
.
require
,
game
:
&
g
.
FaultGameHelper
,
correctTrace
:
alphabet
.
NewTraceProvider
(
alphabetTrace
,
depth
),
}
}
op-e2e/e2eutils/disputegame/game_helper.go
View file @
16f0aad4
...
@@ -2,16 +2,19 @@ package disputegame
...
@@ -2,16 +2,19 @@ package disputegame
import
(
import
(
"context"
"context"
"errors"
"fmt"
"fmt"
"math/big"
"math/big"
"testing"
"testing"
"time"
"time"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
gethtypes
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/require"
)
)
...
@@ -130,6 +133,10 @@ func (g *FaultGameHelper) getClaim(ctx context.Context, claimIdx int64) Contract
...
@@ -130,6 +133,10 @@ func (g *FaultGameHelper) getClaim(ctx context.Context, claimIdx int64) Contract
return
claimData
return
claimData
}
}
func
(
g
*
FaultGameHelper
)
GetClaimUnsafe
(
ctx
context
.
Context
,
claimIdx
int64
)
ContractClaim
{
return
g
.
getClaim
(
ctx
,
claimIdx
)
}
func
(
g
*
FaultGameHelper
)
WaitForClaimAtDepth
(
ctx
context
.
Context
,
depth
int
)
{
func
(
g
*
FaultGameHelper
)
WaitForClaimAtDepth
(
ctx
context
.
Context
,
depth
int
)
{
g
.
waitForClaim
(
g
.
waitForClaim
(
ctx
,
ctx
,
...
@@ -169,6 +176,12 @@ func (g *FaultGameHelper) Resolve(ctx context.Context) {
...
@@ -169,6 +176,12 @@ func (g *FaultGameHelper) Resolve(ctx context.Context) {
g
.
require
.
NoError
(
err
)
g
.
require
.
NoError
(
err
)
}
}
func
(
g
*
FaultGameHelper
)
Status
(
ctx
context
.
Context
)
Status
{
status
,
err
:=
g
.
game
.
Status
(
&
bind
.
CallOpts
{
Context
:
ctx
})
g
.
require
.
NoError
(
err
)
return
Status
(
status
)
}
func
(
g
*
FaultGameHelper
)
WaitForGameStatus
(
ctx
context
.
Context
,
expected
Status
)
{
func
(
g
*
FaultGameHelper
)
WaitForGameStatus
(
ctx
context
.
Context
,
expected
Status
)
{
g
.
t
.
Logf
(
"Waiting for game %v to have status %v"
,
g
.
addr
,
expected
)
g
.
t
.
Logf
(
"Waiting for game %v to have status %v"
,
g
.
addr
,
expected
)
timedCtx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
time
.
Minute
)
timedCtx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
time
.
Minute
)
...
@@ -186,6 +199,46 @@ func (g *FaultGameHelper) WaitForGameStatus(ctx context.Context, expected Status
...
@@ -186,6 +199,46 @@ func (g *FaultGameHelper) WaitForGameStatus(ctx context.Context, expected Status
g
.
require
.
NoErrorf
(
err
,
"wait for game status. Game state:
\n
%v"
,
g
.
gameData
(
ctx
))
g
.
require
.
NoErrorf
(
err
,
"wait for game status. Game state:
\n
%v"
,
g
.
gameData
(
ctx
))
}
}
func
(
g
*
FaultGameHelper
)
WaitForInactivity
(
ctx
context
.
Context
,
numInactiveBlocks
int
,
untilGameEnds
bool
)
{
g
.
t
.
Logf
(
"Waiting for game %v to have no activity for %v blocks"
,
g
.
addr
,
numInactiveBlocks
)
headCh
:=
make
(
chan
*
gethtypes
.
Header
,
100
)
headSub
,
err
:=
g
.
client
.
SubscribeNewHead
(
ctx
,
headCh
)
g
.
require
.
NoError
(
err
)
defer
headSub
.
Unsubscribe
()
var
lastActiveBlock
uint64
for
{
if
untilGameEnds
&&
g
.
Status
(
ctx
)
!=
StatusInProgress
{
break
}
select
{
case
head
:=
<-
headCh
:
if
lastActiveBlock
==
0
{
lastActiveBlock
=
head
.
Number
.
Uint64
()
continue
}
else
if
lastActiveBlock
+
uint64
(
numInactiveBlocks
)
<
head
.
Number
.
Uint64
()
{
return
}
block
,
err
:=
g
.
client
.
BlockByNumber
(
ctx
,
head
.
Number
)
g
.
require
.
NoError
(
err
)
numActions
:=
0
for
_
,
tx
:=
range
block
.
Transactions
()
{
if
tx
.
To
()
.
Hex
()
==
g
.
addr
.
Hex
()
{
numActions
++
}
}
if
numActions
!=
0
{
g
.
t
.
Logf
(
"Game %v has %v actions in block %d. Resetting inactivity timeout"
,
g
.
addr
,
numActions
,
block
.
NumberU64
())
lastActiveBlock
=
head
.
Number
.
Uint64
()
}
case
err
:=
<-
headSub
.
Err
()
:
g
.
require
.
NoError
(
err
)
case
<-
ctx
.
Done
()
:
g
.
require
.
Fail
(
"Context canceled"
,
ctx
.
Err
())
}
}
}
// Mover is a function that either attacks or defends the claim at parentClaimIdx
// Mover is a function that either attacks or defends the claim at parentClaimIdx
type
Mover
func
(
parentClaimIdx
int64
)
type
Mover
func
(
parentClaimIdx
int64
)
...
@@ -239,6 +292,21 @@ func (g *FaultGameHelper) ChallengeRootClaim(ctx context.Context, performMove Mo
...
@@ -239,6 +292,21 @@ func (g *FaultGameHelper) ChallengeRootClaim(ctx context.Context, performMove Mo
attemptStep
(
maxDepth
)
attemptStep
(
maxDepth
)
}
}
func
(
g
*
FaultGameHelper
)
WaitForNewClaim
(
ctx
context
.
Context
,
checkPoint
int64
)
(
int64
,
error
)
{
timedCtx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
2
*
time
.
Minute
)
defer
cancel
()
var
newClaimLen
int64
err
:=
wait
.
For
(
timedCtx
,
time
.
Second
,
func
()
(
bool
,
error
)
{
actual
,
err
:=
g
.
game
.
ClaimDataLen
(
&
bind
.
CallOpts
{
Context
:
ctx
})
if
err
!=
nil
{
return
false
,
err
}
newClaimLen
=
actual
.
Int64
()
return
actual
.
Cmp
(
big
.
NewInt
(
checkPoint
))
>
0
,
nil
})
return
newClaimLen
,
err
}
func
(
g
*
FaultGameHelper
)
Attack
(
ctx
context
.
Context
,
claimIdx
int64
,
claim
common
.
Hash
)
{
func
(
g
*
FaultGameHelper
)
Attack
(
ctx
context
.
Context
,
claimIdx
int64
,
claim
common
.
Hash
)
{
tx
,
err
:=
g
.
game
.
Attack
(
g
.
opts
,
big
.
NewInt
(
claimIdx
),
claim
)
tx
,
err
:=
g
.
game
.
Attack
(
g
.
opts
,
big
.
NewInt
(
claimIdx
),
claim
)
g
.
require
.
NoError
(
err
,
"Attack transaction did not send"
)
g
.
require
.
NoError
(
err
,
"Attack transaction did not send"
)
...
@@ -266,6 +334,33 @@ func (g *FaultGameHelper) StepFails(claimIdx int64, isAttack bool, stateData []b
...
@@ -266,6 +334,33 @@ func (g *FaultGameHelper) StepFails(claimIdx int64, isAttack bool, stateData []b
g
.
require
.
Equal
(
"0xfb4e40dd"
,
errData
.
ErrorData
(),
"Revert reason should be abi encoded ValidStep()"
)
g
.
require
.
Equal
(
"0xfb4e40dd"
,
errData
.
ErrorData
(),
"Revert reason should be abi encoded ValidStep()"
)
}
}
// ResolveClaim resolves a single subgame
func
(
g
*
FaultGameHelper
)
ResolveClaim
(
ctx
context
.
Context
,
claimIdx
int64
)
{
tx
,
err
:=
g
.
game
.
ResolveClaim
(
g
.
opts
,
big
.
NewInt
(
claimIdx
))
g
.
require
.
NoError
(
err
,
"ResolveClaim transaction did not send"
)
_
,
err
=
wait
.
ForReceiptOK
(
ctx
,
g
.
client
,
tx
.
Hash
())
g
.
require
.
NoError
(
err
,
"ResolveClaim transaction was not OK"
)
}
// ResolveAllClaims resolves all subgames
// This function does not resolve the game. That's the responsibility of challengers
func
(
g
*
FaultGameHelper
)
ResolveAllClaims
(
ctx
context
.
Context
)
{
loader
:=
fault
.
NewLoader
(
g
.
game
)
claims
,
err
:=
loader
.
FetchClaims
(
ctx
)
g
.
require
.
NoError
(
err
,
"Failed to fetch claims"
)
subgames
:=
make
(
map
[
int
]
bool
)
for
i
:=
len
(
claims
)
-
1
;
i
>
0
;
i
--
{
subgames
[
claims
[
i
]
.
ParentContractIndex
]
=
true
// Subgames containing only one node are implicitly resolved
// i.e. uncountered and claims at MAX_DEPTH
if
!
subgames
[
i
]
{
continue
}
g
.
ResolveClaim
(
ctx
,
int64
(
i
))
}
g
.
ResolveClaim
(
ctx
,
0
)
}
func
(
g
*
FaultGameHelper
)
gameData
(
ctx
context
.
Context
)
string
{
func
(
g
*
FaultGameHelper
)
gameData
(
ctx
context
.
Context
)
string
{
opts
:=
&
bind
.
CallOpts
{
Context
:
ctx
}
opts
:=
&
bind
.
CallOpts
{
Context
:
ctx
}
maxDepth
:=
int
(
g
.
MaxDepth
(
ctx
))
maxDepth
:=
int
(
g
.
MaxDepth
(
ctx
))
...
@@ -277,8 +372,8 @@ func (g *FaultGameHelper) gameData(ctx context.Context) string {
...
@@ -277,8 +372,8 @@ func (g *FaultGameHelper) gameData(ctx context.Context) string {
g
.
require
.
NoErrorf
(
err
,
"Fetch claim %v"
,
i
)
g
.
require
.
NoErrorf
(
err
,
"Fetch claim %v"
,
i
)
pos
:=
types
.
NewPositionFromGIndex
(
claim
.
Position
.
Uint64
())
pos
:=
types
.
NewPositionFromGIndex
(
claim
.
Position
.
Uint64
())
info
=
info
+
fmt
.
Sprintf
(
"%v - Position: %v, Depth: %v, IndexAtDepth: %v Trace Index: %v, Value: %v, Countered: %v
\n
"
,
info
=
info
+
fmt
.
Sprintf
(
"%v - Position: %v, Depth: %v, IndexAtDepth: %v Trace Index: %v, Value: %v, Countered: %v
, ParentIndex: %v
\n
"
,
i
,
claim
.
Position
.
Int64
(),
pos
.
Depth
(),
pos
.
IndexAtDepth
(),
pos
.
TraceIndex
(
maxDepth
),
common
.
Hash
(
claim
.
Claim
)
.
Hex
(),
claim
.
Countered
)
i
,
claim
.
Position
.
Int64
(),
pos
.
Depth
(),
pos
.
IndexAtDepth
(),
pos
.
TraceIndex
(
maxDepth
),
common
.
Hash
(
claim
.
Claim
)
.
Hex
(),
claim
.
Countered
,
claim
.
ParentIndex
)
}
}
status
,
err
:=
g
.
game
.
Status
(
opts
)
status
,
err
:=
g
.
game
.
Status
(
opts
)
g
.
require
.
NoError
(
err
,
"Load game status"
)
g
.
require
.
NoError
(
err
,
"Load game status"
)
...
@@ -288,3 +383,106 @@ func (g *FaultGameHelper) gameData(ctx context.Context) string {
...
@@ -288,3 +383,106 @@ func (g *FaultGameHelper) gameData(ctx context.Context) string {
func
(
g
*
FaultGameHelper
)
LogGameData
(
ctx
context
.
Context
)
{
func
(
g
*
FaultGameHelper
)
LogGameData
(
ctx
context
.
Context
)
{
g
.
t
.
Log
(
g
.
gameData
(
ctx
))
g
.
t
.
Log
(
g
.
gameData
(
ctx
))
}
}
type
dishonestClaim
struct
{
ParentIndex
int64
IsAttack
bool
Valid
bool
}
type
DishonestHelper
struct
{
*
FaultGameHelper
*
HonestHelper
claims
map
[
dishonestClaim
]
bool
defender
bool
}
func
NewDishonestHelper
(
g
*
FaultGameHelper
,
correctTrace
*
HonestHelper
,
defender
bool
)
*
DishonestHelper
{
return
&
DishonestHelper
{
g
,
correctTrace
,
make
(
map
[
dishonestClaim
]
bool
),
defender
}
}
func
(
t
*
DishonestHelper
)
Attack
(
ctx
context
.
Context
,
claimIndex
int64
)
{
c
:=
dishonestClaim
{
claimIndex
,
true
,
false
}
if
t
.
claims
[
c
]
{
return
}
t
.
claims
[
c
]
=
true
t
.
FaultGameHelper
.
Attack
(
ctx
,
claimIndex
,
common
.
Hash
{
byte
(
claimIndex
)})
}
func
(
t
*
DishonestHelper
)
Defend
(
ctx
context
.
Context
,
claimIndex
int64
)
{
c
:=
dishonestClaim
{
claimIndex
,
false
,
false
}
if
t
.
claims
[
c
]
{
return
}
t
.
claims
[
c
]
=
true
t
.
FaultGameHelper
.
Defend
(
ctx
,
claimIndex
,
common
.
Hash
{
byte
(
claimIndex
)})
}
func
(
t
*
DishonestHelper
)
AttackCorrect
(
ctx
context
.
Context
,
claimIndex
int64
)
{
c
:=
dishonestClaim
{
claimIndex
,
true
,
true
}
if
t
.
claims
[
c
]
{
return
}
t
.
claims
[
c
]
=
true
t
.
HonestHelper
.
Attack
(
ctx
,
claimIndex
)
}
func
(
t
*
DishonestHelper
)
DefendCorrect
(
ctx
context
.
Context
,
claimIndex
int64
)
{
c
:=
dishonestClaim
{
claimIndex
,
false
,
true
}
if
t
.
claims
[
c
]
{
return
}
t
.
claims
[
c
]
=
true
t
.
HonestHelper
.
Defend
(
ctx
,
claimIndex
)
}
// ExhaustDishonestClaims makes all possible significant moves (mod honest challenger's) in a game.
// It is very inefficient and should NOT be used on games with large depths
func
(
d
*
DishonestHelper
)
ExhaustDishonestClaims
(
ctx
context
.
Context
)
{
depth
:=
d
.
MaxDepth
(
ctx
)
move
:=
func
(
claimIndex
int64
,
claimData
ContractClaim
)
{
// dishonest level, valid attack
// dishonest level, invalid attack
// dishonest level, valid defense
// dishonest level, invalid defense
// honest level, invalid attack
// honest level, invalid defense
pos
:=
types
.
NewPositionFromGIndex
(
claimData
.
Position
.
Uint64
())
if
int64
(
pos
.
Depth
())
==
depth
{
return
}
d
.
LogGameData
(
ctx
)
d
.
FaultGameHelper
.
t
.
Logf
(
"Dishonest moves against claimIndex %d"
,
claimIndex
)
agreeWithLevel
:=
d
.
defender
==
(
pos
.
Depth
()
%
2
==
0
)
if
!
agreeWithLevel
{
d
.
AttackCorrect
(
ctx
,
claimIndex
)
if
claimIndex
!=
0
{
d
.
DefendCorrect
(
ctx
,
claimIndex
)
}
}
d
.
Attack
(
ctx
,
claimIndex
)
if
claimIndex
!=
0
{
d
.
Defend
(
ctx
,
claimIndex
)
}
}
var
numClaimsSeen
int64
for
{
newCount
,
err
:=
d
.
WaitForNewClaim
(
ctx
,
numClaimsSeen
)
if
errors
.
Is
(
err
,
context
.
DeadlineExceeded
)
{
// we assume that the honest challenger has stopped responding
// There's nothing to respond to.
break
}
d
.
FaultGameHelper
.
require
.
NoError
(
err
)
for
i
:=
numClaimsSeen
;
i
<
newCount
;
i
++
{
claimData
:=
d
.
getClaim
(
ctx
,
numClaimsSeen
)
move
(
numClaimsSeen
,
claimData
)
numClaimsSeen
++
}
}
}
op-e2e/faultproof_test.go
View file @
16f0aad4
...
@@ -3,7 +3,9 @@ package op_e2e
...
@@ -3,7 +3,9 @@ package op_e2e
import
(
import
(
"context"
"context"
"testing"
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame"
l2oo2
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/l2oo"
l2oo2
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/l2oo"
...
@@ -62,8 +64,12 @@ func TestMultipleCannonGames(t *testing.T) {
...
@@ -62,8 +64,12 @@ func TestMultipleCannonGames(t *testing.T) {
sys
.
TimeTravelClock
.
AdvanceTime
(
gameDuration
)
sys
.
TimeTravelClock
.
AdvanceTime
(
gameDuration
)
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
game1
.
WaitForGameStatus
(
ctx
,
disputegame
.
StatusChallengerWins
)
game1
.
WaitForInactivity
(
ctx
,
10
,
true
)
game2
.
WaitForGameStatus
(
ctx
,
disputegame
.
StatusChallengerWins
)
game2
.
WaitForInactivity
(
ctx
,
10
,
true
)
game1
.
LogGameData
(
ctx
)
game2
.
LogGameData
(
ctx
)
require
.
EqualValues
(
t
,
disputegame
.
StatusChallengerWins
,
game1
.
Status
(
ctx
))
require
.
EqualValues
(
t
,
disputegame
.
StatusChallengerWins
,
game2
.
Status
(
ctx
))
// Check that the game directories are removed
// Check that the game directories are removed
challenger
.
WaitForGameDataDeletion
(
ctx
,
game1
,
game2
)
challenger
.
WaitForGameDataDeletion
(
ctx
,
game1
,
game2
)
...
@@ -168,11 +174,72 @@ func TestChallengerCompleteDisputeGame(t *testing.T) {
...
@@ -168,11 +174,72 @@ func TestChallengerCompleteDisputeGame(t *testing.T) {
sys
.
TimeTravelClock
.
AdvanceTime
(
gameDuration
)
sys
.
TimeTravelClock
.
AdvanceTime
(
gameDuration
)
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
game
.
WaitForGameStatus
(
ctx
,
test
.
expectedResult
)
game
.
WaitForInactivity
(
ctx
,
10
,
true
)
game
.
LogGameData
(
ctx
)
require
.
EqualValues
(
t
,
test
.
expectedResult
,
game
.
Status
(
ctx
))
})
})
}
}
}
}
func
TestChallengerCompleteExhaustiveDisputeGame
(
t
*
testing
.
T
)
{
InitParallel
(
t
)
testCase
:=
func
(
t
*
testing
.
T
,
isRootCorrect
bool
)
{
ctx
:=
context
.
Background
()
sys
,
l1Client
:=
startFaultDisputeSystem
(
t
)
t
.
Cleanup
(
sys
.
Close
)
disputeGameFactory
:=
disputegame
.
NewFactoryHelper
(
t
,
ctx
,
sys
.
cfg
.
L1Deployments
,
l1Client
)
rootClaimedAlphabet
:=
disputegame
.
CorrectAlphabet
if
!
isRootCorrect
{
rootClaimedAlphabet
=
"abcdexyz"
}
game
:=
disputeGameFactory
.
StartAlphabetGame
(
ctx
,
rootClaimedAlphabet
)
require
.
NotNil
(
t
,
game
)
gameDuration
:=
game
.
GameDuration
(
ctx
)
// Start honest challenger
game
.
StartChallenger
(
ctx
,
sys
.
NodeEndpoint
(
"l1"
),
"Challenger"
,
challenger
.
WithAgreeProposedOutput
(
!
isRootCorrect
),
challenger
.
WithAlphabet
(
disputegame
.
CorrectAlphabet
),
challenger
.
WithPrivKey
(
sys
.
cfg
.
Secrets
.
Alice
),
// Ensures the challenger responds to all claims before test timeout
challenger
.
WithPollInterval
(
time
.
Millisecond
*
400
),
)
// Start dishonest challenger
correctTrace
:=
game
.
CreateHonestActor
(
ctx
,
disputegame
.
CorrectAlphabet
,
4
)
dishonestHelper
:=
disputegame
.
NewDishonestHelper
(
&
game
.
FaultGameHelper
,
correctTrace
,
!
isRootCorrect
)
dishonestHelper
.
ExhaustDishonestClaims
(
ctx
)
// Wait until we've reached max depth before checking for inactivity
game
.
WaitForClaimAtDepth
(
ctx
,
int
(
game
.
MaxDepth
(
ctx
)))
// Wait for 4 blocks of no challenger responses. The challenger may still be stepping on invalid claims at max depth
game
.
WaitForInactivity
(
ctx
,
4
,
false
)
sys
.
TimeTravelClock
.
AdvanceTime
(
gameDuration
)
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
expectedStatus
:=
disputegame
.
StatusChallengerWins
if
isRootCorrect
{
expectedStatus
=
disputegame
.
StatusDefenderWins
}
game
.
WaitForInactivity
(
ctx
,
10
,
true
)
game
.
LogGameData
(
ctx
)
require
.
EqualValues
(
t
,
expectedStatus
,
game
.
Status
(
ctx
))
}
t
.
Run
(
"RootCorrect"
,
func
(
t
*
testing
.
T
)
{
InitParallel
(
t
)
testCase
(
t
,
true
)
})
t
.
Run
(
"RootIncorrect"
,
func
(
t
*
testing
.
T
)
{
InitParallel
(
t
)
testCase
(
t
,
false
)
})
}
func
TestCannonDisputeGame
(
t
*
testing
.
T
)
{
func
TestCannonDisputeGame
(
t
*
testing
.
T
)
{
InitParallel
(
t
)
InitParallel
(
t
)
...
@@ -217,8 +284,9 @@ func TestCannonDisputeGame(t *testing.T) {
...
@@ -217,8 +284,9 @@ func TestCannonDisputeGame(t *testing.T) {
sys
.
TimeTravelClock
.
AdvanceTime
(
game
.
GameDuration
(
ctx
))
sys
.
TimeTravelClock
.
AdvanceTime
(
game
.
GameDuration
(
ctx
))
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
game
.
WaitFor
GameStatus
(
ctx
,
disputegame
.
StatusChallengerWins
)
game
.
WaitFor
Inactivity
(
ctx
,
10
,
true
)
game
.
LogGameData
(
ctx
)
game
.
LogGameData
(
ctx
)
require
.
EqualValues
(
t
,
disputegame
.
StatusChallengerWins
,
game
.
Status
(
ctx
))
})
})
}
}
}
}
...
@@ -260,8 +328,9 @@ func TestCannonDefendStep(t *testing.T) {
...
@@ -260,8 +328,9 @@ func TestCannonDefendStep(t *testing.T) {
sys
.
TimeTravelClock
.
AdvanceTime
(
game
.
GameDuration
(
ctx
))
sys
.
TimeTravelClock
.
AdvanceTime
(
game
.
GameDuration
(
ctx
))
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
game
.
WaitFor
GameStatus
(
ctx
,
disputegame
.
StatusChallengerWins
)
game
.
WaitFor
Inactivity
(
ctx
,
10
,
true
)
game
.
LogGameData
(
ctx
)
game
.
LogGameData
(
ctx
)
require
.
EqualValues
(
t
,
disputegame
.
StatusChallengerWins
,
game
.
Status
(
ctx
))
}
}
func
TestCannonProposedOutputRootInvalid
(
t
*
testing
.
T
)
{
func
TestCannonProposedOutputRootInvalid
(
t
*
testing
.
T
)
{
...
@@ -335,14 +404,14 @@ func TestCannonProposedOutputRootInvalid(t *testing.T) {
...
@@ -335,14 +404,14 @@ func TestCannonProposedOutputRootInvalid(t *testing.T) {
sys
.
TimeTravelClock
.
AdvanceTime
(
game
.
GameDuration
(
ctx
))
sys
.
TimeTravelClock
.
AdvanceTime
(
game
.
GameDuration
(
ctx
))
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
game
.
WaitFor
GameStatus
(
ctx
,
disputegame
.
StatusDefenderWins
)
game
.
WaitFor
Inactivity
(
ctx
,
10
,
true
)
game
.
LogGameData
(
ctx
)
game
.
LogGameData
(
ctx
)
require
.
EqualValues
(
t
,
disputegame
.
StatusDefenderWins
,
game
.
Status
(
ctx
))
})
})
}
}
}
}
func
TestCannonPoisonedPostState
(
t
*
testing
.
T
)
{
func
TestCannonPoisonedPostState
(
t
*
testing
.
T
)
{
t
.
Skip
(
"Known failure case"
)
InitParallel
(
t
)
InitParallel
(
t
)
ctx
:=
context
.
Background
()
ctx
:=
context
.
Background
()
...
@@ -365,9 +434,12 @@ func TestCannonPoisonedPostState(t *testing.T) {
...
@@ -365,9 +434,12 @@ func TestCannonPoisonedPostState(t *testing.T) {
// Honest defense at "dishonest" level
// Honest defense at "dishonest" level
correctTrace
.
Defend
(
ctx
,
1
)
correctTrace
.
Defend
(
ctx
,
1
)
// Dishonest attack at "honest" level - honest move would be to
defend
// Dishonest attack at "honest" level - honest move would be to
ignore
game
.
Attack
(
ctx
,
2
,
common
.
Hash
{
0x03
,
0xaa
})
game
.
Attack
(
ctx
,
2
,
common
.
Hash
{
0x03
,
0xaa
})
// Honest attack at "dishonest" level - honest move would be to ignore
correctTrace
.
Attack
(
ctx
,
3
)
// Start the honest challenger
// Start the honest challenger
game
.
StartChallenger
(
ctx
,
sys
.
RollupConfig
,
sys
.
L2GenesisCfg
,
l1Endpoint
,
l2Endpoint
,
"Honest"
,
game
.
StartChallenger
(
ctx
,
sys
.
RollupConfig
,
sys
.
L2GenesisCfg
,
l1Endpoint
,
l2Endpoint
,
"Honest"
,
// Agree with the proposed output, so disagree with the root claim
// Agree with the proposed output, so disagree with the root claim
...
@@ -376,29 +448,40 @@ func TestCannonPoisonedPostState(t *testing.T) {
...
@@ -376,29 +448,40 @@ func TestCannonPoisonedPostState(t *testing.T) {
)
)
// Start dishonest challenger that posts correct claims
// Start dishonest challenger that posts correct claims
game
.
StartChallenger
(
ctx
,
sys
.
RollupConfig
,
sys
.
L2GenesisCfg
,
l1Endpoint
,
l2Endpoint
,
"DishonestCorrect"
,
// It participates in the subgame root the honest claim index 4
// Disagree with the proposed output, so agree with the root claim
func
()
{
challenger
.
WithAgreeProposedOutput
(
false
),
claimCount
:=
int64
(
5
)
challenger
.
WithPrivKey
(
sys
.
cfg
.
Secrets
.
Mallory
),
depth
:=
game
.
MaxDepth
(
ctx
)
)
for
{
game
.
LogGameData
(
ctx
)
// Give the challengers time to progress down the full game depth
claimCount
++
depth
:=
game
.
MaxDepth
(
ctx
)
// Wait for the challenger to counter
for
i
:=
3
;
i
<=
int
(
depth
);
i
++
{
game
.
WaitForClaimCount
(
ctx
,
claimCount
)
game
.
WaitForClaimAtDepth
(
ctx
,
i
)
game
.
LogGameData
(
ctx
)
// Respond with our own move
}
correctTrace
.
Defend
(
ctx
,
claimCount
-
1
)
claimCount
++
game
.
WaitForClaimCount
(
ctx
,
claimCount
)
// Defender moves last. If we're at max depth, then we're done
dishonestClaim
:=
game
.
GetClaimUnsafe
(
ctx
,
claimCount
-
1
)
pos
:=
types
.
NewPositionFromGIndex
(
dishonestClaim
.
Position
.
Uint64
())
if
int64
(
pos
.
Depth
())
==
depth
{
break
}
}
}()
// Wait for all the leaf nodes to be countered
// Wait for the challenger to drive the subgame at 4 to the leaf node, which should be countered
// Wait for the challengers to drive the game down to the leaf node which should be countered
game
.
WaitForClaimAtMaxDepth
(
ctx
,
true
)
game
.
WaitForAllClaimsCountered
(
ctx
)
// Time travel past when the game will be resolvable.
// Time travel past when the game will be resolvable.
sys
.
TimeTravelClock
.
AdvanceTime
(
game
.
GameDuration
(
ctx
))
sys
.
TimeTravelClock
.
AdvanceTime
(
game
.
GameDuration
(
ctx
))
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
game
.
WaitFor
GameStatus
(
ctx
,
disputegame
.
StatusChallengerWins
)
game
.
WaitFor
Inactivity
(
ctx
,
10
,
true
)
game
.
LogGameData
(
ctx
)
game
.
LogGameData
(
ctx
)
require
.
EqualValues
(
t
,
disputegame
.
StatusChallengerWins
,
game
.
Status
(
ctx
))
}
}
// setupDisputeGameForInvalidOutputRoot sets up an L2 chain with at least one valid output root followed by an invalid output root.
// setupDisputeGameForInvalidOutputRoot sets up an L2 chain with at least one valid output root followed by an invalid output root.
...
@@ -470,8 +553,9 @@ func TestCannonChallengeWithCorrectRoot(t *testing.T) {
...
@@ -470,8 +553,9 @@ func TestCannonChallengeWithCorrectRoot(t *testing.T) {
sys
.
TimeTravelClock
.
AdvanceTime
(
game
.
GameDuration
(
ctx
))
sys
.
TimeTravelClock
.
AdvanceTime
(
game
.
GameDuration
(
ctx
))
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
require
.
NoError
(
t
,
wait
.
ForNextBlock
(
ctx
,
l1Client
))
game
.
WaitFor
GameStatus
(
ctx
,
disputegame
.
StatusChallengerWins
)
game
.
WaitFor
Inactivity
(
ctx
,
10
,
true
)
game
.
LogGameData
(
ctx
)
game
.
LogGameData
(
ctx
)
require
.
EqualValues
(
t
,
disputegame
.
StatusChallengerWins
,
game
.
Status
(
ctx
))
}
}
func
startFaultDisputeSystem
(
t
*
testing
.
T
)
(
*
System
,
*
ethclient
.
Client
)
{
func
startFaultDisputeSystem
(
t
*
testing
.
T
)
(
*
System
,
*
ethclient
.
Client
)
{
...
...
packages/contracts-bedrock/.gas-snapshot
View file @
16f0aad4
...
@@ -91,39 +91,45 @@ FaucetTest:test_nonAdmin_drip_fails() (gas: 262520)
...
@@ -91,39 +91,45 @@ FaucetTest:test_nonAdmin_drip_fails() (gas: 262520)
FaucetTest:test_receive_succeeds() (gas: 17401)
FaucetTest:test_receive_succeeds() (gas: 17401)
FaucetTest:test_withdraw_nonAdmin_reverts() (gas: 13145)
FaucetTest:test_withdraw_nonAdmin_reverts() (gas: 13145)
FaucetTest:test_withdraw_succeeds() (gas: 78359)
FaucetTest:test_withdraw_succeeds() (gas: 78359)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot1:test_resolvesCorrectly_succeeds() (gas:
499197
)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot1:test_resolvesCorrectly_succeeds() (gas:
660411
)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas:
506057
)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas:
667293
)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas:
502738
)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas:
663974
)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot4:test_resolvesCorrectly_succeeds() (gas:
505955
)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot4:test_resolvesCorrectly_succeeds() (gas:
667169
)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot5:test_resolvesCorrectly_succeeds() (gas:
505224
)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot5:test_resolvesCorrectly_succeeds() (gas:
666460
)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot1:test_resolvesCorrectly_succeeds() (gas:
49796
2)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot1:test_resolvesCorrectly_succeeds() (gas:
65309
2)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas:
504822
)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas:
658598
)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas:
50150
3)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas:
65594
3)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot4:test_resolvesCorrectly_succeeds() (gas:
502720
)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot4:test_resolvesCorrectly_succeeds() (gas:
656899
)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot5:test_resolvesCorrectly_succeeds() (gas:
501989
)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot5:test_resolvesCorrectly_succeeds() (gas:
656332
)
FaultDisputeGame_Test:test_addLocalData_static_succeeds() (gas: 6405
04
)
FaultDisputeGame_Test:test_addLocalData_static_succeeds() (gas: 6405
67
)
FaultDisputeGame_Test:test_createdAt_succeeds() (gas: 10342)
FaultDisputeGame_Test:test_createdAt_succeeds() (gas: 10342)
FaultDisputeGame_Test:test_extraData_succeeds() (gas: 32377)
FaultDisputeGame_Test:test_extraData_succeeds() (gas: 32355)
FaultDisputeGame_Test:test_gameData_succeeds() (gas: 32804)
FaultDisputeGame_Test:test_gameData_succeeds() (gas: 32782)
FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8309)
FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8265)
FaultDisputeGame_Test:test_initialize_correctData_succeeds() (gas: 57628)
FaultDisputeGame_Test:test_initialize_correctData_succeeds() (gas: 57739)
FaultDisputeGame_Test:test_initialize_firstOutput_reverts() (gas: 210629)
FaultDisputeGame_Test:test_initialize_firstOutput_reverts() (gas: 210563)
FaultDisputeGame_Test:test_initialize_l1HeadTooOld_reverts() (gas: 228390)
FaultDisputeGame_Test:test_initialize_l1HeadTooOld_reverts() (gas: 228368)
FaultDisputeGame_Test:test_move_clockCorrectness_succeeds() (gas: 415971)
FaultDisputeGame_Test:test_move_clockCorrectness_succeeds() (gas: 594268)
FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 23197)
FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 23175)
FaultDisputeGame_Test:test_move_defendRoot_reverts() (gas: 13344)
FaultDisputeGame_Test:test_move_defendRoot_reverts() (gas: 13366)
FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 102898)
FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 147389)
FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 407913)
FaultDisputeGame_Test:test_move_duplicateClaimsDifferentSubgames_succeeds() (gas: 556885)
FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 585897)
FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 11002)
FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 11002)
FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24710)
FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24666)
FaultDisputeGame_Test:test_move_simpleAttack_succeeds() (gas: 107384)
FaultDisputeGame_Test:test_move_simpleAttack_succeeds() (gas: 151959)
FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 224949)
FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 269413)
FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9686)
FaultDisputeGame_Test:test_resolve_claimAlreadyResolved_reverts() (gas: 272356)
FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 109879)
FaultDisputeGame_Test:test_resolve_claimAtMaxDepthAlreadyResolved_reverts() (gas: 586672)
FaultDisputeGame_Test:test_resolve_rootUncontestedClockNotExpired_succeeds() (gas: 21421)
FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9732)
FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 27279)
FaultDisputeGame_Test:test_resolve_outOfOrderResolution_reverts() (gas: 309037)
FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 395658)
FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 139044)
FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8276)
FaultDisputeGame_Test:test_resolve_rootUncontestedButUnresolved_reverts() (gas: 15883)
FaultDisputeGame_Test:test_resolve_rootUncontestedClockNotExpired_succeeds() (gas: 18406)
FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 51409)
FaultDisputeGame_Test:test_resolve_stepReached_succeeds() (gas: 498476)
FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 443373)
FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8232)
FeeVault_Test:test_constructor_succeeds() (gas: 18185)
FeeVault_Test:test_constructor_succeeds() (gas: 18185)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 354421)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 354421)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2952628)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2952628)
...
...
packages/contracts-bedrock/semver-lock.json
View file @
16f0aad4
...
@@ -18,7 +18,7 @@
...
@@ -18,7 +18,7 @@
"src/L2/L2StandardBridge.sol"
:
"0xfe01bcb1ddc947b9b8a7093d0971854b9fa8d49da5bd933a3dd106167907f882"
,
"src/L2/L2StandardBridge.sol"
:
"0xfe01bcb1ddc947b9b8a7093d0971854b9fa8d49da5bd933a3dd106167907f882"
,
"src/L2/L2ToL1MessagePasser.sol"
:
"0xafc710b4d320ef450586d96a61cbd58cac814cb3b0c4fdc280eace3efdcdf321"
,
"src/L2/L2ToL1MessagePasser.sol"
:
"0xafc710b4d320ef450586d96a61cbd58cac814cb3b0c4fdc280eace3efdcdf321"
,
"src/L2/SequencerFeeVault.sol"
:
"0xc2f733c1128d06ad60bf1e1d98c8f684a4825b11875ccdf2376ede33f5aad4e6"
,
"src/L2/SequencerFeeVault.sol"
:
"0xc2f733c1128d06ad60bf1e1d98c8f684a4825b11875ccdf2376ede33f5aad4e6"
,
"src/dispute/FaultDisputeGame.sol"
:
"0x7
b8462c29d003e96a73491c644001e1a9034bcc45c5be2a7bac3caf80d521635
"
,
"src/dispute/FaultDisputeGame.sol"
:
"0x7
6e7c16431faa32e2074e6abdfe3e86f5ec90b4ac8a6b662edba8c3ce791ad80
"
,
"src/legacy/DeployerWhitelist.sol"
:
"0xf2129ec3da75307ba8e21bc943c332bb04704642e6e263149b5c8ee92dbcb7a8"
,
"src/legacy/DeployerWhitelist.sol"
:
"0xf2129ec3da75307ba8e21bc943c332bb04704642e6e263149b5c8ee92dbcb7a8"
,
"src/legacy/L1BlockNumber.sol"
:
"0x30aae1fc85103476af0226b6e98c71c01feebbdc35d93401390b1ad438a37be6"
,
"src/legacy/L1BlockNumber.sol"
:
"0x30aae1fc85103476af0226b6e98c71c01feebbdc35d93401390b1ad438a37be6"
,
"src/legacy/LegacyMessagePasser.sol"
:
"0x5c08b0a663cc49d30e4e38540f6aefab19ef287c3ecd31c8d8c3decd5f5bd497"
,
"src/legacy/LegacyMessagePasser.sol"
:
"0x5c08b0a663cc49d30e4e38540f6aefab19ef287c3ecd31c8d8c3decd5f5bd497"
,
...
...
packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol
View file @
16f0aad4
...
@@ -75,6 +75,12 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
...
@@ -75,6 +75,12 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
/// @notice An internal mapping to allow for constant-time lookups of existing claims.
/// @notice An internal mapping to allow for constant-time lookups of existing claims.
mapping(ClaimHash => bool) internal claims;
mapping(ClaimHash => bool) internal claims;
/// @notice An internal mapping of subgames rooted at a claim index to other claim indices in the subgame.
mapping(uint256 => uint256[]) internal subgames;
/// @notice Indicates whether the subgame rooted at the root claim has been resolved.
bool internal subgameAtRootResolved;
/// @param _gameType The type ID of the game.
/// @param _gameType The type ID of the game.
/// @param _absolutePrestate The absolute prestate of the instruction trace.
/// @param _absolutePrestate The absolute prestate of the instruction trace.
/// @param _maxGameDepth The maximum depth of bisection.
/// @param _maxGameDepth The maximum depth of bisection.
...
@@ -232,9 +238,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
...
@@ -232,9 +238,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// Construct the next clock with the new duration and the current block timestamp.
// Construct the next clock with the new duration and the current block timestamp.
Clock nextClock = LibClock.wrap(nextDuration, Timestamp.wrap(uint64(block.timestamp)));
Clock nextClock = LibClock.wrap(nextDuration, Timestamp.wrap(uint64(block.timestamp)));
// INVARIANT: A claim may only exist at a given position once. Multiple claims may exist
// INVARIANT: There cannot be multiple identical claims with identical moves on the same challengeIndex. Multiple
// at the same position, however they must have different values.
// claims
ClaimHash claimHash = _claim.hashClaimPos(nextPosition);
// at the same position may dispute the same challengeIndex. However, the must have different values.
ClaimHash claimHash = _claim.hashClaimPos(nextPosition, _challengeIndex);
if (claims[claimHash]) revert ClaimAlreadyExists();
if (claims[claimHash]) revert ClaimAlreadyExists();
claims[claimHash] = true;
claims[claimHash] = true;
...
@@ -252,6 +259,9 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
...
@@ -252,6 +259,9 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// Set the parent claim as countered.
// Set the parent claim as countered.
claimData[_challengeIndex].countered = true;
claimData[_challengeIndex].countered = true;
// Update the subgame rooted at the parent claim.
subgames[_challengeIndex].push(claimData.length - 1);
// Emit the appropriate event for the attack or defense.
// Emit the appropriate event for the attack or defense.
emit Move(_challengeIndex, _claim, msg.sender);
emit Move(_challengeIndex, _claim, msg.sender);
}
}
...
@@ -348,67 +358,64 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
...
@@ -348,67 +358,64 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// INVARIANT: Resolution cannot occur unless the game is currently in progress.
// INVARIANT: Resolution cannot occur unless the game is currently in progress.
if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();
if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();
// Search for the left-most dangling non-bottom node
// INVARIANT: Resolution cannot occur unless the absolute root subgame has been resolved.
// The most recent claim is always a dangling, non-bottom node so we start with that
if (!subgameAtRootResolved) revert OutOfOrderResolution();
uint256 leftMostIndex = claimData.length - 1;
uint256 leftMostTraceIndex = type(uint128).max;
for (uint256 i = leftMostIndex; i < type(uint64).max;) {
// Fetch the claim at the current index.
ClaimData storage claim = claimData[i];
// Decrement the loop counter; If it underflows, we've reached the root
// claim and can stop searching.
unchecked {
--i;
}
// INVARIANT: A claim can never be considered as the leftMostIndex or leftMostTraceIndex
status_ = claimData[0].countered ? GameStatus.CHALLENGER_WINS : GameStatus.DEFENDER_WINS;
// if it has been countered.
emit Resolved(status = status_);
if (claim.countered) continue;
}
// If the claim is a dangling node, we can check if it is the left-most
// dangling node we've come across so far. If it is, we can update the
// left-most trace index.
uint256 traceIndex = claim.position.traceIndex(MAX_GAME_DEPTH);
if (traceIndex < leftMostTraceIndex) {
leftMostTraceIndex = traceIndex;
unchecked {
leftMostIndex = i + 1;
}
}
}
// Create a reference to the left most uncontested claim and its parent.
/// @inheritdoc IFaultDisputeGame
ClaimData storage leftMostUncontested = claimData[leftMostIndex];
function resolveClaim(uint256 _claimIndex) external payable {
// INVARIANT: Resolution cannot occur unless the game is currently in progress.
if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();
// INVARIANT: The game may never be resolved unless the clock of the left-most uncontested
ClaimData storage parent = claimData[_claimIndex];
// claim's parent has expired. If the left-most uncontested claim is the root
// claim, it is uncountered, and we check if 3.5 days has passed since its
// INVARIANT: Cannot resolve a subgame unless the clock of its root has expired
// creation.
uint256 parentIndex = leftMostUncontested.parentIndex;
Clock opposingClock = parentIndex == type(uint32).max ? leftMostUncontested.clock : claimData[parentIndex].clock;
if (
if (
Duration.unwrap(
opposingClock.duration()) + (block.timestamp - Timestamp.unwrap(opposingC
lock.timestamp()))
Duration.unwrap(
parent.clock.duration()) + (block.timestamp - Timestamp.unwrap(parent.c
lock.timestamp()))
<= Duration.unwrap(GAME_DURATION) >> 1
<= Duration.unwrap(GAME_DURATION) >> 1
) {
) {
revert ClockNotExpired();
revert ClockNotExpired();
}
}
// If the left-most dangling node is at an even depth, the defender wins.
uint256[] storage challengeIndices = subgames[_claimIndex];
// Otherwise, the challenger wins and the root claim is deemed invalid.
if (
// INVARIANT: Cannot resolve subgames twice
leftMostUncontested
// Uncontested claims are resolved implicitly unless they are the root claim
.position
if (_claimIndex == 0 && subgameAtRootResolved) revert ClaimAlreadyResolved();
// slither-disable-next-line weak-prng
if (challengeIndices.length == 0 && _claimIndex != 0) revert ClaimAlreadyResolved();
.depth() % 2 == 0 && leftMostTraceIndex != type(uint128).max
) {
// Assume parent is honest until proven otherwise
status_ = GameStatus.DEFENDER_WINS;
bool countered = false;
} else {
status_ = GameStatus.CHALLENGER_WINS;
for (uint256 i = 0; i < challengeIndices.length; ++i) {
uint256 challengeIndex = challengeIndices[i];
// INVARIANT: Cannot resolve a subgame containing an unresolved claim
if (subgames[challengeIndex].length != 0) revert OutOfOrderResolution();
ClaimData storage claim = claimData[challengeIndex];
// Ignore false claims
if (!claim.countered) {
countered = true;
break;
}
}
}
// Update the game status
// Once a subgame is resolved, we percolate the result up the DAG so subsequent calls to
emit Resolved(status = status_);
// resolveClaim will not need to traverse this subgame.
parent.countered = countered;
// Resolved subgames have no entries
delete subgames[_claimIndex];
// Indicate the game is ready to be resolved
if (_claimIndex == 0) {
subgameAtRootResolved = true;
}
}
}
/// @inheritdoc IDisputeGame
/// @inheritdoc IDisputeGame
...
...
packages/contracts-bedrock/src/dispute/interfaces/IFaultDisputeGame.sol
View file @
16f0aad4
...
@@ -73,6 +73,14 @@ interface IFaultDisputeGame is IDisputeGame {
...
@@ -73,6 +73,14 @@ interface IFaultDisputeGame is IDisputeGame {
/// @param _partOffset The offset of the data to post.
/// @param _partOffset The offset of the data to post.
function addLocalData(uint256 _ident, uint256 _partOffset) external;
function addLocalData(uint256 _ident, uint256 _partOffset) external;
/// @notice Resolves the subgame rooted at the given claim index.
/// @dev This function must be called bottom-up in the DAG
/// A subgame is a tree of claims that has a maximum depth of 1.
/// A subgame root claims is valid if, and only if, all of its child claims are invalid.
/// At the deepest level in the DAG, a claim is invalid if there's a successful step against it.
/// @param _claimIndex The index of the subgame root claim to resolve.
function resolveClaim(uint256 _claimIndex) external payable;
/// @notice An L1 block hash that contains the disputed output root, fetched from the
/// @notice An L1 block hash that contains the disputed output root, fetched from the
/// `BlockOracle` and verified by referencing the timestamp associated with the
/// `BlockOracle` and verified by referencing the timestamp associated with the
/// first L2 Output Proposal in the `L2OutputOracle` that contains the disputed
/// first L2 Output Proposal in the `L2OutputOracle` that contains the disputed
...
...
packages/contracts-bedrock/src/dispute/lib/LibHashing.sol
View file @
16f0aad4
...
@@ -9,11 +9,20 @@ library LibHashing {
...
@@ -9,11 +9,20 @@ library LibHashing {
/// @notice Hashes a claim and a position together.
/// @notice Hashes a claim and a position together.
/// @param _claim A Claim type.
/// @param _claim A Claim type.
/// @param _position The position of `claim`.
/// @param _position The position of `claim`.
/// @return claimHash_ A hash of abi.encodePacked(claim, position);
/// @param _challengeIndex The index of the claim being moved against.
function hashClaimPos(Claim _claim, Position _position) internal pure returns (ClaimHash claimHash_) {
/// @return claimHash_ A hash of abi.encodePacked(claim, position|challengeIndex);
function hashClaimPos(
Claim _claim,
Position _position,
uint256 _challengeIndex
)
internal
pure
returns (ClaimHash claimHash_)
{
assembly {
assembly {
mstore(0x00, _claim)
mstore(0x00, _claim)
mstore(0x20,
_position
)
mstore(0x20,
or(shl(128, _position), and(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, _challengeIndex))
)
claimHash_ := keccak256(0x00, 0x40)
claimHash_ := keccak256(0x00, 0x40)
}
}
}
}
...
...
packages/contracts-bedrock/src/libraries/DisputeErrors.sol
View file @
16f0aad4
...
@@ -66,6 +66,12 @@ error L1HeadTooOld();
...
@@ -66,6 +66,12 @@ error L1HeadTooOld();
/// @notice Thrown when an invalid local identifier is passed to the `addLocalData` function.
/// @notice Thrown when an invalid local identifier is passed to the `addLocalData` function.
error InvalidLocalIdent();
error InvalidLocalIdent();
/// @notice Thrown when resolving claims out of order.
error OutOfOrderResolution();
/// @notice Thrown when resolving a claim that has already been resolved.
error ClaimAlreadyResolved();
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// `AttestationDisputeGame` Errors //
// `AttestationDisputeGame` Errors //
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
...
...
packages/contracts-bedrock/test/FaultDisputeGame.t.sol
View file @
16f0aad4
...
@@ -303,6 +303,19 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
...
@@ -303,6 +303,19 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
gameProxy.attack(0, claim);
gameProxy.attack(0, claim);
}
}
/// @dev Static unit test asserting that identical claims at the same position can be made in different subgames.
function test_move_duplicateClaimsDifferentSubgames_succeeds() public {
Claim claimA = Claim.wrap(bytes32(uint256(5)));
Claim claimB = Claim.wrap(bytes32(uint256(6)));
// Make the first move. This should succeed.
gameProxy.attack(0, claimA);
gameProxy.attack(0, claimB);
gameProxy.attack(1, claimB);
gameProxy.attack(2, claimA);
}
/// @dev Static unit test for the correctness of an opening attack.
/// @dev Static unit test for the correctness of an opening attack.
function test_move_simpleAttack_succeeds() public {
function test_move_simpleAttack_succeeds() public {
// Warp ahead 5 seconds.
// Warp ahead 5 seconds.
...
@@ -344,15 +357,22 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
...
@@ -344,15 +357,22 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// @dev Static unit test for the correctness an uncontested root resolution.
/// @dev Static unit test for the correctness an uncontested root resolution.
function test_resolve_rootUncontested_succeeds() public {
function test_resolve_rootUncontested_succeeds() public {
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
GameStatus status = gameProxy.resolve();
gameProxy.resolveClaim(0);
assertEq(uint8(status), uint8(GameStatus.DEFENDER_WINS));
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertEq(uint8(gameProxy.status()), uint8(GameStatus.DEFENDER_WINS));
}
}
/// @dev Static unit test for the correctness an uncontested root resolution.
/// @dev Static unit test for the correctness an uncontested root resolution.
function test_resolve_rootUncontestedClockNotExpired_succeeds() public {
function test_resolve_rootUncontestedClockNotExpired_succeeds() public {
vm.warp(block.timestamp + 3 days + 12 hours);
vm.warp(block.timestamp + 3 days + 12 hours);
vm.expectRevert(ClockNotExpired.selector);
vm.expectRevert(ClockNotExpired.selector);
gameProxy.resolveClaim(0);
}
/// @dev Static unit test asserting that resolve reverts when the absolute root
/// subgame has not been resolved.
function test_resolve_rootUncontestedButUnresolved_reverts() public {
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
vm.expectRevert(OutOfOrderResolution.selector);
gameProxy.resolve();
gameProxy.resolve();
}
}
...
@@ -370,7 +390,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
...
@@ -370,7 +390,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
vm.store(address(gameProxy), bytes32(uint256(0)), bytes32(slot));
vm.store(address(gameProxy), bytes32(uint256(0)), bytes32(slot));
vm.expectRevert(GameNotInProgress.selector);
vm.expectRevert(GameNotInProgress.selector);
gameProxy.resolve
(
);
gameProxy.resolve
Claim(0
);
}
}
/// @dev Static unit test for the correctness of resolving a single attack game state.
/// @dev Static unit test for the correctness of resolving a single attack game state.
...
@@ -379,9 +399,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
...
@@ -379,9 +399,8 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
GameStatus status = gameProxy.resolve();
gameProxy.resolveClaim(0);
assertEq(uint8(status), uint8(GameStatus.CHALLENGER_WINS));
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertEq(uint8(gameProxy.status()), uint8(GameStatus.CHALLENGER_WINS));
}
}
/// @dev Static unit test for the correctness of resolving a game with a contested challenge claim.
/// @dev Static unit test for the correctness of resolving a game with a contested challenge claim.
...
@@ -391,9 +410,9 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
...
@@ -391,9 +410,9 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
GameStatus status = gameProxy.resolve(
);
gameProxy.resolveClaim(1
);
assertEq(uint8(status), uint8(GameStatus.DEFENDER_WINS)
);
gameProxy.resolveClaim(0
);
assertEq(uint8(gameProxy.
status
()), uint8(GameStatus.DEFENDER_WINS));
assertEq(uint8(gameProxy.
resolve
()), uint8(GameStatus.DEFENDER_WINS));
}
}
/// @dev Static unit test for the correctness of resolving a game with multiplayer moves.
/// @dev Static unit test for the correctness of resolving a game with multiplayer moves.
...
@@ -405,9 +424,62 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
...
@@ -405,9 +424,62 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
GameStatus status = gameProxy.resolve();
gameProxy.resolveClaim(1);
assertEq(uint8(status), uint8(GameStatus.CHALLENGER_WINS));
gameProxy.resolveClaim(0);
assertEq(uint8(gameProxy.status()), uint8(GameStatus.CHALLENGER_WINS));
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
}
/// @dev Static unit test for the correctness of resolving a game that reaches max game depth.
function test_resolve_stepReached_succeeds() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
gameProxy.attack(1, Claim.wrap(bytes32(uint256(5))));
gameProxy.attack(2, Claim.wrap(bytes32(uint256(5))));
gameProxy.attack(3, Claim.wrap(bytes32(uint256(5))));
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// resolving claim at 4 isn't necessary
gameProxy.resolveClaim(3);
gameProxy.resolveClaim(2);
gameProxy.resolveClaim(1);
gameProxy.resolveClaim(0);
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
}
/// @dev Static unit test asserting that resolve reverts when attempting to resolve a subgame multiple times
function test_resolve_claimAlreadyResolved_reverts() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
gameProxy.attack(1, Claim.wrap(bytes32(uint256(5))));
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
gameProxy.resolveClaim(1);
vm.expectRevert(ClaimAlreadyResolved.selector);
gameProxy.resolveClaim(1);
}
/// @dev Static unit test asserting that resolve reverts when attempting to resolve a subgame at max depth
function test_resolve_claimAtMaxDepthAlreadyResolved_reverts() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
gameProxy.attack(1, Claim.wrap(bytes32(uint256(5))));
gameProxy.attack(2, Claim.wrap(bytes32(uint256(5))));
gameProxy.attack(3, Claim.wrap(bytes32(uint256(5))));
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
vm.expectRevert(ClaimAlreadyResolved.selector);
gameProxy.resolveClaim(4);
}
/// @dev Static unit test asserting that resolve reverts when attempting to resolve subgames out of order
function test_resolve_outOfOrderResolution_reverts() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
gameProxy.attack(1, Claim.wrap(bytes32(uint256(5))));
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
vm.expectRevert(OutOfOrderResolution.selector);
gameProxy.resolveClaim(0);
}
}
/// @dev Tests that adding local data with an out of bounds identifier reverts.
/// @dev Tests that adding local data with an out of bounds identifier reverts.
...
@@ -623,6 +695,33 @@ contract GamePlayer {
...
@@ -623,6 +695,33 @@ contract GamePlayer {
}
}
}
}
contract Resolver {
FaultDisputeGame public gameProxy;
mapping(uint256 => bool) subgames;
constructor(FaultDisputeGame gameProxy_) {
gameProxy = gameProxy_;
}
/// @notice Auto-resolves all subgames in the game
function run() public {
for (uint256 i = gameProxy.claimDataLen() - 1; i > 0; i--) {
(uint32 parentIndex,,,,) = gameProxy.claimData(i);
subgames[parentIndex] = true;
// Subgames containing only one node are implicitly resolved
// i.e. uncountered claims and claims at MAX_DEPTH
if (!subgames[i]) {
continue;
}
gameProxy.resolveClaim(i);
}
gameProxy.resolveClaim(0);
}
}
contract OneVsOne_Arena is FaultDisputeGame_Init {
contract OneVsOne_Arena is FaultDisputeGame_Init {
/// @dev The absolute prestate of the trace.
/// @dev The absolute prestate of the trace.
bytes ABSOLUTE_PRESTATE = abi.encode(15);
bytes ABSOLUTE_PRESTATE = abi.encode(15);
...
@@ -633,12 +732,15 @@ contract OneVsOne_Arena is FaultDisputeGame_Init {
...
@@ -633,12 +732,15 @@ contract OneVsOne_Arena is FaultDisputeGame_Init {
GamePlayer internal defender;
GamePlayer internal defender;
/// @dev The challenger.
/// @dev The challenger.
GamePlayer internal challenger;
GamePlayer internal challenger;
/// @dev The resolver.
Resolver internal resolver;
function init(GamePlayer _defender, GamePlayer _challenger, uint256 _finalTraceIndex) public {
function init(GamePlayer _defender, GamePlayer _challenger, uint256 _finalTraceIndex) public {
Claim rootClaim = _defender.claimAt(_finalTraceIndex);
Claim rootClaim = _defender.claimAt(_finalTraceIndex);
super.init(rootClaim, ABSOLUTE_PRESTATE_CLAIM);
super.init(rootClaim, ABSOLUTE_PRESTATE_CLAIM);
defender = _defender;
defender = _defender;
challenger = _challenger;
challenger = _challenger;
resolver = new Resolver(gameProxy);
// Set the counterparties.
// Set the counterparties.
defender.init(gameProxy, challenger, vm);
defender.init(gameProxy, challenger, vm);
...
@@ -647,6 +749,7 @@ contract OneVsOne_Arena is FaultDisputeGame_Init {
...
@@ -647,6 +749,7 @@ contract OneVsOne_Arena is FaultDisputeGame_Init {
// Label actors for trace.
// Label actors for trace.
vm.label(address(challenger), "Challenger");
vm.label(address(challenger), "Challenger");
vm.label(address(defender), "Defender");
vm.label(address(defender), "Defender");
vm.label(address(resolver), "Resolver");
}
}
}
}
...
@@ -666,6 +769,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot1 is OneVsOne_Arena {
...
@@ -666,6 +769,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot1 is OneVsOne_Arena {
// Resolve the game and assert that the honest player challenged the root
// Resolve the game and assert that the honest player challenged the root
// claim successfully.
// claim successfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertFalse(defender.failedToStep());
assertFalse(defender.failedToStep());
}
}
...
@@ -687,6 +791,7 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot1 is OneVsOne_Arena {
...
@@ -687,6 +791,7 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot1 is OneVsOne_Arena {
// Resolve the game and assert that the dishonest player challenged the root
// Resolve the game and assert that the dishonest player challenged the root
// claim unsuccessfully.
// claim unsuccessfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(challenger.failedToStep());
assertTrue(challenger.failedToStep());
}
}
...
@@ -708,6 +813,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2 is OneVsOne_Arena {
...
@@ -708,6 +813,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2 is OneVsOne_Arena {
// Resolve the game and assert that the honest player challenged the root
// Resolve the game and assert that the honest player challenged the root
// claim successfully.
// claim successfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertFalse(defender.failedToStep());
assertFalse(defender.failedToStep());
}
}
...
@@ -729,6 +835,7 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot2 is OneVsOne_Arena {
...
@@ -729,6 +835,7 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot2 is OneVsOne_Arena {
// Resolve the game and assert that the dishonest player challenged the root
// Resolve the game and assert that the dishonest player challenged the root
// claim unsuccessfully.
// claim unsuccessfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(challenger.failedToStep());
assertTrue(challenger.failedToStep());
}
}
...
@@ -750,6 +857,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3 is OneVsOne_Arena {
...
@@ -750,6 +857,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3 is OneVsOne_Arena {
// Resolve the game and assert that the honest player challenged the root
// Resolve the game and assert that the honest player challenged the root
// claim successfully.
// claim successfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertFalse(defender.failedToStep());
assertFalse(defender.failedToStep());
}
}
...
@@ -771,6 +879,7 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot3 is OneVsOne_Arena {
...
@@ -771,6 +879,7 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot3 is OneVsOne_Arena {
// Resolve the game and assert that the dishonest player challenged the root
// Resolve the game and assert that the dishonest player challenged the root
// claim unsuccessfully.
// claim unsuccessfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(challenger.failedToStep());
assertTrue(challenger.failedToStep());
}
}
...
@@ -792,6 +901,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot4 is OneVsOne_Arena {
...
@@ -792,6 +901,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot4 is OneVsOne_Arena {
// Resolve the game and assert that the honest player challenged the root
// Resolve the game and assert that the honest player challenged the root
// claim successfully.
// claim successfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertFalse(challenger.failedToStep());
assertFalse(challenger.failedToStep());
}
}
...
@@ -813,6 +923,7 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot4 is OneVsOne_Arena {
...
@@ -813,6 +923,7 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot4 is OneVsOne_Arena {
// Resolve the game and assert that the dishonest player challenged the root
// Resolve the game and assert that the dishonest player challenged the root
// claim unsuccessfully.
// claim unsuccessfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(challenger.failedToStep());
assertTrue(challenger.failedToStep());
}
}
...
@@ -834,6 +945,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot5 is OneVsOne_Arena {
...
@@ -834,6 +945,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot5 is OneVsOne_Arena {
// Resolve the game and assert that the honest player challenged the root
// Resolve the game and assert that the honest player challenged the root
// claim successfully.
// claim successfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertFalse(challenger.failedToStep());
assertFalse(challenger.failedToStep());
}
}
...
@@ -855,6 +967,7 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot5 is OneVsOne_Arena {
...
@@ -855,6 +967,7 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot5 is OneVsOne_Arena {
// Resolve the game and assert that the dishonest player challenged the root
// Resolve the game and assert that the dishonest player challenged the root
// claim unsuccessfully.
// claim unsuccessfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(challenger.failedToStep());
assertTrue(challenger.failedToStep());
}
}
...
@@ -883,6 +996,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRootFuzz is OneVsOne_Arena
...
@@ -883,6 +996,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRootFuzz is OneVsOne_Arena
// Resolve the game and assert that the honest player challenged the root
// Resolve the game and assert that the honest player challenged the root
// claim successfully.
// claim successfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertFalse(defender.failedToStep());
assertFalse(defender.failedToStep());
...
@@ -913,6 +1027,7 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRootFuzz is OneVsOne_Arena {
...
@@ -913,6 +1027,7 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRootFuzz is OneVsOne_Arena {
// Resolve the game and assert that the honest player challenged the root
// Resolve the game and assert that the honest player challenged the root
// claim successfully.
// claim successfully.
resolver.run();
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(challenger.failedToStep());
assertTrue(challenger.failedToStep());
...
...
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