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
9c5b2599
Commit
9c5b2599
authored
Jul 02, 2023
by
clabby
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve docs / :broom:
parent
460af9e4
Changes
4
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
100 additions
and
117 deletions
+100
-117
faultdisputegame.go
op-bindings/bindings/faultdisputegame.go
+42
-42
.gas-snapshot
packages/contracts-bedrock/.gas-snapshot
+10
-10
FaultDisputeGame.sol
.../contracts-bedrock/contracts/dispute/FaultDisputeGame.sol
+38
-58
IFaultDisputeGame.sol
...edrock/contracts/dispute/interfaces/IFaultDisputeGame.sol
+10
-7
No files found.
op-bindings/bindings/faultdisputegame.go
View file @
9c5b2599
This diff is collapsed.
Click to expand it.
packages/contracts-bedrock/.gas-snapshot
View file @
9c5b2599
...
@@ -32,12 +32,12 @@ DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_revert
...
@@ -32,12 +32,12 @@ DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_revert
DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44243)
DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44243)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15950)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15950)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18642)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18642)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 5021
74
)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 5021
69
)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 5040
53
)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 5040
48
)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot:test_resolvesCorrectly_succeeds() (gas: 49151
7
)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot:test_resolvesCorrectly_succeeds() (gas: 49151
2
)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 50093
7
)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 50093
2
)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 50281
6
)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 50281
1
)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot:test_resolvesCorrectly_succeeds() (gas: 4902
80
)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot:test_resolvesCorrectly_succeeds() (gas: 4902
75
)
FaultDisputeGame_Test:test_extraData_succeeds() (gas: 17426)
FaultDisputeGame_Test:test_extraData_succeeds() (gas: 17426)
FaultDisputeGame_Test:test_gameData_succeeds() (gas: 17917)
FaultDisputeGame_Test:test_gameData_succeeds() (gas: 17917)
FaultDisputeGame_Test:test_gameStart_succeeds() (gas: 10315)
FaultDisputeGame_Test:test_gameStart_succeeds() (gas: 10315)
...
@@ -51,12 +51,12 @@ FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 408100)
...
@@ -51,12 +51,12 @@ FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 408100)
FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 10968)
FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 10968)
FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24655)
FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24655)
FaultDisputeGame_Test:test_move_simpleAttack_succeeds() (gas: 107344)
FaultDisputeGame_Test:test_move_simpleAttack_succeeds() (gas: 107344)
FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 22478
9
)
FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 22478
4
)
FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9657)
FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9657)
FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 1097
54
)
FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 1097
49
)
FaultDisputeGame_Test:test_resolve_rootUncontestedClockNotExpired_succeeds() (gas: 21422)
FaultDisputeGame_Test:test_resolve_rootUncontestedClockNotExpired_succeeds() (gas: 21422)
FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 2725
6
)
FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 2725
1
)
FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 39544
7
)
FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 39544
2
)
FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8181)
FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8181)
FeeVault_Test:test_constructor_succeeds() (gas: 18185)
FeeVault_Test:test_constructor_succeeds() (gas: 18185)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 352113)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 352113)
...
...
packages/contracts-bedrock/contracts/dispute/FaultDisputeGame.sol
View file @
9c5b2599
...
@@ -66,19 +66,9 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
...
@@ -66,19 +66,9 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
}
}
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
//
External Logic
//
//
`IFaultDisputeGame` impl
//
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
/// @inheritdoc IFaultDisputeGame
function attack(uint256 _parentIndex, Claim _pivot) external payable {
move(_parentIndex, _pivot, true);
}
/// @inheritdoc IFaultDisputeGame
function defend(uint256 _parentIndex, Claim _pivot) external payable {
move(_parentIndex, _pivot, false);
}
/// @inheritdoc IFaultDisputeGame
/// @inheritdoc IFaultDisputeGame
function step(
function step(
uint256 _stateIndex,
uint256 _stateIndex,
...
@@ -88,9 +78,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
...
@@ -88,9 +78,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
bytes calldata _proof
bytes calldata _proof
) external {
) external {
// INVARIANT: Steps cannot be made unless the game is currently in progress.
// INVARIANT: Steps cannot be made unless the game is currently in progress.
if (status != GameStatus.IN_PROGRESS) {
if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();
revert GameNotInProgress();
}
// Get the parent. If it does not exist, the call will revert with OOB.
// Get the parent. If it does not exist, the call will revert with OOB.
ClaimData storage parent = claimData[_claimIndex];
ClaimData storage parent = claimData[_claimIndex];
...
@@ -101,9 +89,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
...
@@ -101,9 +89,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
Position stepPos = parentPos.move(_isAttack);
Position stepPos = parentPos.move(_isAttack);
// INVARIANT: A step cannot be made unless the move position is 1 below the `MAX_GAME_DEPTH`
// INVARIANT: A step cannot be made unless the move position is 1 below the `MAX_GAME_DEPTH`
if (stepPos.depth() != MAX_GAME_DEPTH + 1) {
if (stepPos.depth() != MAX_GAME_DEPTH + 1) revert InvalidParent();
revert InvalidParent();
}
// Determine the expected pre & post states of the step.
// Determine the expected pre & post states of the step.
Claim preStateClaim;
Claim preStateClaim;
...
@@ -145,43 +131,32 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
...
@@ -145,43 +131,32 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
}
}
}
}
// INVARIANT: A VM step can never counter a parent claim unless it produces an unexpected
// INVARIANT: A VM step can never counter a parent claim unless it produces a poststate
// poststate. "Unexpected" is defined as "not equal to the claim at
// that is not equal to the claim at `_parentIndex` if the step is an attack,
// `_parentIndex` if the step is an attack, or the claim at `_stateIndex` if
// or the claim at `_stateIndex` if the step is a defense.
// the step is a defense."
if (VM.step(_stateData, _proof) == Claim.unwrap(postStateClaim)) revert ValidStep();
if (VM.step(_stateData, _proof) == Claim.unwrap(postStateClaim)) {
revert ValidStep();
}
// Set the parent claim as countered. We do not need to append a new claim to the game;
// Set the parent claim as countered. We do not need to append a new claim to the game;
// instead, we can just set the existing parent as countered.
// instead, we can just set the existing parent as countered.
parent.countered = true;
parent.countered = true;
}
}
////////////////////////////////////////////////////////////////
// Internal Logic //
////////////////////////////////////////////////////////////////
/// @notice Internal move function, used by both `attack` and `defend`.
/// @notice Internal move function, used by both `attack` and `defend`.
/// @param _challengeIndex The index of the claim being moved against.
/// @param _challengeIndex The index of the claim being moved against.
/// @param _
pivot
The claim at the next logical position in the game.
/// @param _
claim
The claim at the next logical position in the game.
/// @param _isAttack Whether or not the move is an attack or defense.
/// @param _isAttack Whether or not the move is an attack or defense.
function move(
function move(
uint256 _challengeIndex,
uint256 _challengeIndex,
Claim _
pivot
,
Claim _
claim
,
bool _isAttack
bool _isAttack
) public payable {
) public payable {
// INVARIANT: Moves cannot be made unless the game is currently in progress.
// INVARIANT: Moves cannot be made unless the game is currently in progress.
if (status != GameStatus.IN_PROGRESS) {
if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();
revert GameNotInProgress();
}
// INVARIANT: A defense can never be made against the root claim. This is because the root
// INVARIANT: A defense can never be made against the root claim. This is because the root
// claim commits to the entire state. Therefore, the only valid defense is to
// claim commits to the entire state. Therefore, the only valid defense is to
// do nothing if it is agreed with.
// do nothing if it is agreed with.
if (_challengeIndex == 0 && !_isAttack) {
if (_challengeIndex == 0 && !_isAttack) revert CannotDefendRootClaim();
revert CannotDefendRootClaim();
}
// Get the parent. If it does not exist, the call will revert with OOB.
// Get the parent. If it does not exist, the call will revert with OOB.
ClaimData memory parent = claimData[_challengeIndex];
ClaimData memory parent = claimData[_challengeIndex];
...
@@ -198,9 +173,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
...
@@ -198,9 +173,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// claim at this depth is to perform a single instruction step on-chain via
// claim at this depth is to perform a single instruction step on-chain via
// the `step` function to prove that the state transition produces an unexpected
// the `step` function to prove that the state transition produces an unexpected
// post-state.
// post-state.
if (nextPosition.depth() > MAX_GAME_DEPTH) {
if (nextPosition.depth() > MAX_GAME_DEPTH) revert GameDepthExceeded();
revert GameDepthExceeded();
}
// Fetch the grandparent clock, if it exists.
// Fetch the grandparent clock, if it exists.
// The grandparent clock should always exist unless the parent is the root claim.
// The grandparent clock should always exist unless the parent is the root claim.
...
@@ -234,17 +207,15 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
...
@@ -234,17 +207,15 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// INVARIANT: A claim may only exist at a given position once. Multiple claims may exist
// INVARIANT: A claim may only exist at a given position once. Multiple claims may exist
// at the same position, however they must have different values.
// at the same position, however they must have different values.
ClaimHash claimHash = _pivot.hashClaimPos(nextPosition);
ClaimHash claimHash = _claim.hashClaimPos(nextPosition);
if (claims[claimHash]) {
if (claims[claimHash]) revert ClaimAlreadyExists();
revert ClaimAlreadyExists();
}
claims[claimHash] = true;
claims[claimHash] = true;
// Create the new claim.
// Create the new claim.
claimData.push(
claimData.push(
ClaimData({
ClaimData({
parentIndex: uint32(_challengeIndex),
parentIndex: uint32(_challengeIndex),
claim: _
pivot
,
claim: _
claim
,
position: nextPosition,
position: nextPosition,
clock: nextClock,
clock: nextClock,
countered: false
countered: false
...
@@ -252,17 +223,22 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
...
@@ -252,17 +223,22 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
);
);
// Emit the appropriate event for the attack or defense.
// Emit the appropriate event for the attack or defense.
emit Move(_challengeIndex, _
pivot
, msg.sender);
emit Move(_challengeIndex, _
claim
, msg.sender);
}
}
/// @inheritdoc IFaultDisputeGame
/// @inheritdoc IFaultDisputeGame
function
l2BlockNumber() public pure returns (uint256 l2BlockNumber_)
{
function
attack(uint256 _parentIndex, Claim _claim) external payable
{
l2BlockNumber_ = _getArgUint256(0x20
);
move(_parentIndex, _claim, true
);
}
}
/// @notice Returns the length of the `claimData` array.
/// @inheritdoc IFaultDisputeGame
function claimDataLen() external view returns (uint256 len_) {
function defend(uint256 _parentIndex, Claim _claim) external payable {
len_ = claimData.length;
move(_parentIndex, _claim, false);
}
/// @inheritdoc IFaultDisputeGame
function l2BlockNumber() public pure returns (uint256 l2BlockNumber_) {
l2BlockNumber_ = _getArgUint256(0x20);
}
}
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
...
@@ -282,9 +258,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
...
@@ -282,9 +258,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
/// @inheritdoc IDisputeGame
/// @inheritdoc IDisputeGame
function resolve() external returns (GameStatus status_) {
function resolve() external returns (GameStatus status_) {
// 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) {
if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress();
revert GameNotInProgress();
}
// Search for the left-most dangling non-bottom node
// 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
// The most recent claim is always a dangling, non-bottom node so we start with that
...
@@ -302,9 +276,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
...
@@ -302,9 +276,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// INVARIANT: A claim can never be considered as the leftMostIndex or leftMostTraceIndex
// INVARIANT: A claim can never be considered as the leftMostIndex or leftMostTraceIndex
// if it has been countered.
// if it has been countered.
if (claim.countered) {
if (claim.countered) continue;
continue;
}
// If the claim is a dangling node, we can check if it is the left-most
// 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
// dangling node we've come across so far. If it is, we can update the
...
@@ -349,8 +321,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
...
@@ -349,8 +321,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
}
}
// Update the game status
// Update the game status
status = status_;
emit Resolved(status = status_);
emit Resolved(status_);
}
}
/// @inheritdoc IDisputeGame
/// @inheritdoc IDisputeGame
...
@@ -381,6 +352,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
...
@@ -381,6 +352,10 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
extraData_ = extraData();
extraData_ = extraData();
}
}
////////////////////////////////////////////////////////////////
// MISC EXTERNAL //
////////////////////////////////////////////////////////////////
/// @inheritdoc IInitializable
/// @inheritdoc IInitializable
function initialize() external {
function initialize() external {
// Set the game start
// Set the game start
...
@@ -399,4 +374,9 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
...
@@ -399,4 +374,9 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
})
})
);
);
}
}
/// @notice Returns the length of the `claimData` array.
function claimDataLen() external view returns (uint256 len_) {
len_ = claimData.length;
}
}
}
packages/contracts-bedrock/contracts/dispute/interfaces/IFaultDisputeGame.sol
View file @
9c5b2599
...
@@ -20,19 +20,19 @@ interface IFaultDisputeGame is IDisputeGame {
...
@@ -20,19 +20,19 @@ interface IFaultDisputeGame is IDisputeGame {
/// @notice Emitted when a new claim is added to the DAG by `claimant`
/// @notice Emitted when a new claim is added to the DAG by `claimant`
/// @param parentIndex The index within the `claimData` array of the parent claim
/// @param parentIndex The index within the `claimData` array of the parent claim
/// @param
pivot
The claim being added
/// @param
claim
The claim being added
/// @param claimant The address of the claimant
/// @param claimant The address of the claimant
event Move(uint256 indexed parentIndex, Claim indexed
pivot
, address indexed claimant);
event Move(uint256 indexed parentIndex, Claim indexed
claim
, address indexed claimant);
/// @notice Attack a disagreed upon `Claim`.
/// @notice Attack a disagreed upon `Claim`.
/// @param _parentIndex Index of the `Claim` to attack in `claimData`.
/// @param _parentIndex Index of the `Claim` to attack in `claimData`.
/// @param _
pivot
The `Claim` at the relative attack position.
/// @param _
claim
The `Claim` at the relative attack position.
function attack(uint256 _parentIndex, Claim _
pivot
) external payable;
function attack(uint256 _parentIndex, Claim _
claim
) external payable;
/// @notice Defend an agreed upon `Claim`.
/// @notice Defend an agreed upon `Claim`.
/// @param _parentIndex Index of the claim to defend in `claimData`.
/// @param _parentIndex Index of the claim to defend in `claimData`.
/// @param _
pivot
The `Claim` at the relative defense position.
/// @param _
claim
The `Claim` at the relative defense position.
function defend(uint256 _parentIndex, Claim _
pivot
) external payable;
function defend(uint256 _parentIndex, Claim _
claim
) external payable;
/// @notice Perform the final step via an on-chain fault proof processor
/// @notice Perform the final step via an on-chain fault proof processor
/// @dev This function should point to a fault proof processor in order to execute
/// @dev This function should point to a fault proof processor in order to execute
...
@@ -42,7 +42,10 @@ interface IFaultDisputeGame is IDisputeGame {
...
@@ -42,7 +42,10 @@ interface IFaultDisputeGame is IDisputeGame {
/// @param _stateIndex The index of the pre/post state of the step within `claimData`.
/// @param _stateIndex The index of the pre/post state of the step within `claimData`.
/// @param _claimIndex The index of the challenged claim within `claimData`.
/// @param _claimIndex The index of the challenged claim within `claimData`.
/// @param _isAttack Whether or not the step is an attack or a defense.
/// @param _isAttack Whether or not the step is an attack or a defense.
/// @param _stateData The stateData of the step is the preimage of the claim @ `prestateIndex`
/// @param _stateData The stateData of the step is the preimage of the claim at the given
/// prestate, which is at `_stateIndex` if the move is an attack and `_claimIndex` if
/// the move is a defense. If the step is an attack on the first instruction, it is
/// the absolute prestate of the fault proof VM.
/// @param _proof Proof to access memory leaf nodes in the VM.
/// @param _proof Proof to access memory leaf nodes in the VM.
function step(
function step(
uint256 _stateIndex,
uint256 _stateIndex,
...
...
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