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
50b613a7
Commit
50b613a7
authored
Dec 04, 2023
by
clabby
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
`LibPosition` updates + named local preimage keys
parent
5047b63b
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
87 additions
and
13 deletions
+87
-13
OutputBisectionGame.sol
...ges/contracts-bedrock/src/dispute/OutputBisectionGame.sol
+5
-5
LibPosition.sol
packages/contracts-bedrock/src/dispute/lib/LibPosition.sol
+34
-0
DisputeTypes.sol
packages/contracts-bedrock/src/libraries/DisputeTypes.sol
+28
-8
LibPosition.t.sol
...ages/contracts-bedrock/test/dispute/lib/LibPosition.t.sol
+20
-0
No files found.
packages/contracts-bedrock/src/dispute/OutputBisectionGame.sol
View file @
50b613a7
...
@@ -296,16 +296,16 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
...
@@ -296,16 +296,16 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
Hash uuid = computeLocalContext(starting, startingPos, disputed, disputedPos);
Hash uuid = computeLocalContext(starting, startingPos, disputed, disputedPos);
IPreimageOracle oracle = VM.oracle();
IPreimageOracle oracle = VM.oracle();
if (_ident ==
1
) {
if (_ident ==
LocalPreimageKey.L1_HEAD_HASH
) {
// Load the L1 head hash
// Load the L1 head hash
oracle.loadLocalData(_ident, Hash.unwrap(uuid), Hash.unwrap(l1Head), 32, _partOffset);
oracle.loadLocalData(_ident, Hash.unwrap(uuid), Hash.unwrap(l1Head), 32, _partOffset);
} else if (_ident ==
2
) {
} else if (_ident ==
LocalPreimageKey.STARTING_OUTPUT_ROOT
) {
// Load the starting proposal's output root.
// Load the starting proposal's output root.
oracle.loadLocalData(_ident, Hash.unwrap(uuid), Claim.unwrap(starting), 32, _partOffset);
oracle.loadLocalData(_ident, Hash.unwrap(uuid), Claim.unwrap(starting), 32, _partOffset);
} else if (_ident ==
3
) {
} else if (_ident ==
LocalPreimageKey.DISPUTED_OUTPUT_ROOT
) {
// Load the disputed proposal's output root
// Load the disputed proposal's output root
oracle.loadLocalData(_ident, Hash.unwrap(uuid), Claim.unwrap(disputed), 32, _partOffset);
oracle.loadLocalData(_ident, Hash.unwrap(uuid), Claim.unwrap(disputed), 32, _partOffset);
} else if (_ident ==
4
) {
} else if (_ident ==
LocalPreimageKey.STARTING_L2_BLOCK_NUMBER
) {
// Load the starting proposal's L2 block number as a big-endian uint64 in the
// Load the starting proposal's L2 block number as a big-endian uint64 in the
// high order 8 bytes of the word.
// high order 8 bytes of the word.
...
@@ -316,7 +316,7 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
...
@@ -316,7 +316,7 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
: GENESIS_BLOCK_NUMBER + startingPos.indexAtDepth() + 1;
: GENESIS_BLOCK_NUMBER + startingPos.indexAtDepth() + 1;
oracle.loadLocalData(_ident, Hash.unwrap(uuid), bytes32(l2Number << 0xC0), 8, _partOffset);
oracle.loadLocalData(_ident, Hash.unwrap(uuid), bytes32(l2Number << 0xC0), 8, _partOffset);
} else if (_ident ==
5
) {
} else if (_ident ==
LocalPreimageKey.CHAIN_ID
) {
// Load the chain ID as a big-endian uint64 in the high order 8 bytes of the word.
// Load the chain ID as a big-endian uint64 in the high order 8 bytes of the word.
oracle.loadLocalData(_ident, Hash.unwrap(uuid), bytes32(block.chainid << 0xC0), 8, _partOffset);
oracle.loadLocalData(_ident, Hash.unwrap(uuid), bytes32(block.chainid << 0xC0), 8, _partOffset);
} else {
} else {
...
...
packages/contracts-bedrock/src/dispute/lib/LibPosition.sol
View file @
50b613a7
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
pragma solidity ^0.8.15;
pragma solidity ^0.8.15;
import "src/libraries/DisputeTypes.sol";
import "src/libraries/DisputeTypes.sol";
import "src/libraries/DisputeErrors.sol";
/// @title LibPosition
/// @title LibPosition
/// @notice This library contains helper functions for working with the `Position` type.
/// @notice This library contains helper functions for working with the `Position` type.
...
@@ -136,6 +137,39 @@ library LibPosition {
...
@@ -136,6 +137,39 @@ library LibPosition {
}
}
}
}
/// @notice Gets the position of the highest ancestor of `_position` that commits to the same
/// trace index.
/// @param _position The position to get the highest ancestor of.
/// @param _splitDepth The split depth within the tree, used to inform where to stop in order to not escape an
/// execution trace sub-game.
/// @return ancestor_ The highest ancestor of `position` that commits to the same trace index.
function traceAncestorExec(Position _position, uint256 _splitDepth) internal pure returns (Position ancestor_) {
// This function only works for positions that are below the split depth (i.e., commit to state hashes
// of the fault proof program rather than output roots)
uint256 posDepth = _position.depth();
if (posDepth <= _splitDepth) revert ClaimAboveSplit();
// Create a field with only the lowest unset bit of `_position` set.
Position lsb;
assembly {
lsb := and(not(_position), add(_position, 1))
}
// Find the index of the lowest unset bit within the field.
uint256 msb = lsb.depth();
assembly {
let a := shr(msb, _position)
// Bound the ancestor to the minimum gindex, 1.
ancestor_ := or(a, iszero(a))
}
// If the ancestor is above or at the split depth, shift it to below the split depth.
// This should be a special case that only covers positions that commit to the final trace
// index in an execution trace subtree.
if (ancestor_.depth() <= _splitDepth) {
ancestor_ = ancestor_.rightIndex(_splitDepth + 1);
}
}
/// @notice Get the move position of `_position`, which is the left child of:
/// @notice Get the move position of `_position`, which is the left child of:
/// 1. `_position + 1` if `_isAttack` is true.
/// 1. `_position + 1` if `_isAttack` is true.
/// 1. `_position` if `_isAttack` is false.
/// 1. `_position` if `_isAttack` is false.
...
...
packages/contracts-bedrock/src/libraries/DisputeTypes.sol
View file @
50b613a7
...
@@ -85,26 +85,46 @@ library GameTypes {
...
@@ -85,26 +85,46 @@ library GameTypes {
/// @dev A dispute game type that performs output bisection and then uses the cannon vm.
/// @dev A dispute game type that performs output bisection and then uses the cannon vm.
GameType internal constant OUTPUT_CANNON = GameType.wrap(1);
GameType internal constant OUTPUT_CANNON = GameType.wrap(1);
/// @
dev
A dispute game type that performs output bisection and then uses an alphabet vm.
/// @
notice
A dispute game type that performs output bisection and then uses an alphabet vm.
///
Note
intended for production use.
///
Not
intended for production use.
GameType internal constant OUTPUT_ALPHABET = GameType.wrap(254);
GameType internal constant OUTPUT_ALPHABET = GameType.wrap(254);
/// @
dev
A dispute game type that uses an alphabet vm.
/// @
notice
A dispute game type that uses an alphabet vm.
///
Note
intended for production use.
///
Not
intended for production use.
GameType internal constant ALPHABET = GameType.wrap(255);
GameType internal constant ALPHABET = GameType.wrap(255);
}
}
/// @title VMStatuses
/// @title VMStatuses
/// @notice Named type aliases for the various valid VM status bytes.
library VMStatuses {
library VMStatuses {
/// @
dev
The VM has executed successfully and the outcome is valid.
/// @
notice
The VM has executed successfully and the outcome is valid.
VMStatus internal constant VALID = VMStatus.wrap(0);
VMStatus internal constant VALID = VMStatus.wrap(0);
/// @
dev
The VM has executed successfully and the outcome is invalid.
/// @
notice
The VM has executed successfully and the outcome is invalid.
VMStatus internal constant INVALID = VMStatus.wrap(1);
VMStatus internal constant INVALID = VMStatus.wrap(1);
/// @
dev
The VM has paniced.
/// @
notice
The VM has paniced.
VMStatus internal constant PANIC = VMStatus.wrap(2);
VMStatus internal constant PANIC = VMStatus.wrap(2);
/// @
dev
The VM execution is still in progress.
/// @
notice
The VM execution is still in progress.
VMStatus internal constant UNFINISHED = VMStatus.wrap(3);
VMStatus internal constant UNFINISHED = VMStatus.wrap(3);
}
}
/// @title LocalPreimageKey
/// @notice Named type aliases for local `PreimageOracle` key identifiers.
library LocalPreimageKey {
/// @notice The identifier for the L1 head hash.
uint256 internal constant L1_HEAD_HASH = 0x01;
/// @notice The identifier for the starting output root.
uint256 internal constant STARTING_OUTPUT_ROOT = 0x02;
/// @notice The identifier for the disputed output root.
uint256 internal constant DISPUTED_OUTPUT_ROOT = 0x03;
/// @notice The identifier for the starting L2 block number.
uint256 internal constant STARTING_L2_BLOCK_NUMBER = 0x04;
/// @notice The identifier for the chain ID.
uint256 internal constant CHAIN_ID = 0x05;
}
packages/contracts-bedrock/test/dispute/lib/LibPosition.t.sol
View file @
50b613a7
...
@@ -11,6 +11,8 @@ contract LibPosition_Test is Test {
...
@@ -11,6 +11,8 @@ contract LibPosition_Test is Test {
/// @dev At the lowest level of the tree, this allows for 2 ** 63 leaves. In reality, the max game depth
/// @dev At the lowest level of the tree, this allows for 2 ** 63 leaves. In reality, the max game depth
/// will likely be much lower.
/// will likely be much lower.
uint8 internal constant MAX_DEPTH = 63;
uint8 internal constant MAX_DEPTH = 63;
/// @dev Arbitrary split depth around half way down the tree.
uint8 internal constant SPLIT_DEPTH = 30;
function boundIndexAtDepth(uint8 _depth, uint64 _indexAtDepth) internal pure returns (uint64) {
function boundIndexAtDepth(uint8 _depth, uint64 _indexAtDepth) internal pure returns (uint64) {
// Index at depth bound: [0, 2 ** _depth-1]
// Index at depth bound: [0, 2 ** _depth-1]
...
@@ -91,6 +93,24 @@ contract LibPosition_Test is Test {
...
@@ -91,6 +93,24 @@ contract LibPosition_Test is Test {
assertEq(Position.unwrap(ancestor), Position.unwrap(loopAncestor));
assertEq(Position.unwrap(ancestor), Position.unwrap(loopAncestor));
}
}
/// @notice Tests that the `traceAncestor` function correctly computes the position of the
/// highest ancestor that commits to the same trace index.
function testFuzz_traceAncestorExec_correctness_succeeds(uint8 _depth, uint64 _indexAtDepth) public {
_depth = uint8(bound(_depth, SPLIT_DEPTH + 1, MAX_DEPTH));
_indexAtDepth = boundIndexAtDepth(_depth, _indexAtDepth);
Position position = LibPosition.wrap(_depth, _indexAtDepth);
Position ancestor = position.traceAncestorExec(SPLIT_DEPTH);
Position loopAncestor = position;
// Stop at 1 below the split depth.
while (loopAncestor.parent().traceIndex(MAX_DEPTH) == position.traceIndex(MAX_DEPTH) && loopAncestor.depth() != SPLIT_DEPTH + 1) {
loopAncestor = loopAncestor.parent();
}
assertEq(Position.unwrap(ancestor), Position.unwrap(loopAncestor));
}
/// @notice Tests that the `rightIndex` function correctly computes the deepest, right most index relative
/// @notice Tests that the `rightIndex` function correctly computes the deepest, right most index relative
/// to a given position.
/// to a given position.
function testFuzz_rightIndex_correctness_succeeds(uint64 _maxDepth, uint8 _depth, uint64 _indexAtDepth) public {
function testFuzz_rightIndex_correctness_succeeds(uint64 _maxDepth, uint8 _depth, uint64 _indexAtDepth) public {
...
...
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