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
c093ccdd
Unverified
Commit
c093ccdd
authored
Jun 20, 2023
by
mergify[bot]
Committed by
GitHub
Jun 20, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #6059 from ethereum-optimism/inphi/resolve-dispute
feat(ctb): Implement fault dispute game resolution
parents
48acb226
fb4aa796
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
119 additions
and
12 deletions
+119
-12
.gas-snapshot
packages/contracts-bedrock/.gas-snapshot
+14
-9
FaultDisputeGame.sol
.../contracts-bedrock/contracts/dispute/FaultDisputeGame.sol
+50
-3
FaultDisputeGame.t.sol
...s/contracts-bedrock/contracts/test/FaultDisputeGame.t.sol
+55
-0
No files found.
packages/contracts-bedrock/.gas-snapshot
View file @
c093ccdd
...
...
@@ -32,19 +32,24 @@ DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_revert
DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44243)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15950)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18642)
FaultDisputeGame_Test:test_clockTimeExceeded_reverts() (gas: 264
74
)
FaultDisputeGame_Test:test_defendRoot_reverts() (gas: 132
58
)
FaultDisputeGame_Test:test_duplicateClaim_reverts() (gas: 103
381
)
FaultDisputeGame_Test:test_clockTimeExceeded_reverts() (gas: 264
96
)
FaultDisputeGame_Test:test_defendRoot_reverts() (gas: 132
36
)
FaultDisputeGame_Test:test_duplicateClaim_reverts() (gas: 103
425
)
FaultDisputeGame_Test:test_extraData_succeeds() (gas: 17478)
FaultDisputeGame_Test:test_gameData_succeeds() (gas: 17859)
FaultDisputeGame_Test:test_gameDepthExceeded_reverts() (gas: 59072
75
)
FaultDisputeGame_Test:test_gameDepthExceeded_reverts() (gas: 59072
31
)
FaultDisputeGame_Test:test_gameStart_succeeds() (gas: 10337)
FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8
194
)
FaultDisputeGame_Test:test_initialRootClaimData_succeeds() (gas: 17
580
)
FaultDisputeGame_Test:test_moveAgainstNonexistentParent_reverts() (gas: 24
587
)
FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8
259
)
FaultDisputeGame_Test:test_initialRootClaimData_succeeds() (gas: 17
624
)
FaultDisputeGame_Test:test_moveAgainstNonexistentParent_reverts() (gas: 24
632
)
FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 10945)
FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8191)
FaultDisputeGame_Test:test_simpleAttack_succeeds() (gas: 107367)
FaultDisputeGame_Test:test_resolve_challengeContested() (gas: 222383)
FaultDisputeGame_Test:test_resolve_reverts() (gas: 27121)
FaultDisputeGame_Test:test_resolve_rootContested() (gas: 107225)
FaultDisputeGame_Test:test_resolve_rootUncontested() (gas: 24459)
FaultDisputeGame_Test:test_resolve_teamDeathmatch() (gas: 393609)
FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8169)
FaultDisputeGame_Test:test_simpleAttack_succeeds() (gas: 107389)
FaultDisputeGame_Test:test_version_succeeds() (gas: 9780)
FeeVault_Test:test_constructor_succeeds() (gas: 18185)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 352135)
...
...
packages/contracts-bedrock/contracts/dispute/FaultDisputeGame.sol
View file @
c093ccdd
...
...
@@ -219,9 +219,56 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
* @inheritdoc IDisputeGame
*/
function resolve() external returns (GameStatus status_) {
// TODO - Resolve the game
status = GameStatus.IN_PROGRESS;
status_ = status;
if (status != GameStatus.IN_PROGRESS) {
revert GameNotInProgress();
}
// Search for the left-most dangling non-bottom node
// The most recent claim is always a dangling, non-bottom node so we start with that
uint256 leftMostIndex = claimData.length - 1;
uint256 leftMostTraceIndex = LibPosition.rightIndex(
claimData[leftMostIndex].position,
MAX_GAME_DEPTH
);
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;
}
// If the claim is not a dangling node above the bottom of the tree,
// we can skip over it. These nodes are not relevant to the game resolution.
Position claimPos = claim.position;
if (LibPosition.depth(claimPos) == MAX_GAME_DEPTH || 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 = LibPosition.rightIndex(claimPos, MAX_GAME_DEPTH);
if (traceIndex < leftMostTraceIndex) {
leftMostTraceIndex = traceIndex;
leftMostIndex = i + 1;
}
}
// If the left-most dangling node is at an even depth, the defender wins.
// Otherwise, the challenger wins and the root claim is deemed invalid.
// slither-disable-next-line weak-prng
if (LibPosition.depth(claimData[leftMostIndex].position) % 2 == 0) {
status_ = GameStatus.DEFENDER_WINS;
} else {
status_ = GameStatus.CHALLENGER_WINS;
}
// Update the game status
status = status_;
emit Resolved(status_);
}
/**
...
...
packages/contracts-bedrock/contracts/test/FaultDisputeGame.t.sol
View file @
c093ccdd
...
...
@@ -268,6 +268,61 @@ contract FaultDisputeGame_Test is DisputeGameFactory_Init {
)
);
}
/**
* @dev Static unit test for the correctness an uncontested root resolution.
*/
function test_resolve_rootUncontested() public {
GameStatus status = gameProxy.resolve();
assertEq(uint8(status), uint8(GameStatus.DEFENDER_WINS));
assertEq(uint8(gameProxy.status()), uint8(GameStatus.DEFENDER_WINS));
}
/**
* @dev Static unit test asserting that resolve reverts when the game is not in progress.
*/
function test_resolve_reverts() public {
gameProxy.resolve();
vm.expectRevert(GameNotInProgress.selector);
gameProxy.resolve();
}
/**
* @dev Static unit test for the correctness of resolving a single attack game state.
*/
function test_resolve_rootContested() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
GameStatus status = gameProxy.resolve();
assertEq(uint8(status), 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.
*/
function test_resolve_challengeContested() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
gameProxy.defend(1, Claim.wrap(bytes32(uint256(6))));
GameStatus status = gameProxy.resolve();
assertEq(uint8(status), uint8(GameStatus.DEFENDER_WINS));
assertEq(uint8(gameProxy.status()), uint8(GameStatus.DEFENDER_WINS));
}
/**
* @dev Static unit test for the correctness of resolving a game with multiplayer moves.
*/
function test_resolve_teamDeathmatch() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
gameProxy.attack(0, Claim.wrap(bytes32(uint256(4))));
gameProxy.defend(1, Claim.wrap(bytes32(uint256(6))));
gameProxy.defend(1, Claim.wrap(bytes32(uint256(7))));
GameStatus status = gameProxy.resolve();
assertEq(uint8(status), uint8(GameStatus.CHALLENGER_WINS));
assertEq(uint8(gameProxy.status()), uint8(GameStatus.CHALLENGER_WINS));
}
}
/**
...
...
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