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
ef3b63b3
Commit
ef3b63b3
authored
Dec 09, 2023
by
clabby
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Absolute prestate step fixes + tests
parent
cf9c41d7
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
101 additions
and
8 deletions
+101
-8
OutputBisectionGame.sol
...ges/contracts-bedrock/src/dispute/OutputBisectionGame.sol
+1
-1
OutputBisectionGame.t.sol
.../contracts-bedrock/test/dispute/OutputBisectionGame.t.sol
+92
-0
AlphabetVM2.sol
packages/contracts-bedrock/test/mocks/AlphabetVM2.sol
+8
-7
No files found.
packages/contracts-bedrock/src/dispute/OutputBisectionGame.sol
View file @
ef3b63b3
...
...
@@ -317,7 +317,7 @@ contract OutputBisectionGame is IOutputBisectionGame, Clone, ISemver {
// we add the index at depth + 1 to the genesis block number to get the L2 block number.
uint256 l2Number = Position.unwrap(startingPos) == 0
? GENESIS_BLOCK_NUMBER
: GENESIS_BLOCK_NUMBER + startingPos.
indexAtDepth(
) + 1;
: GENESIS_BLOCK_NUMBER + startingPos.
traceIndex(SPLIT_DEPTH
) + 1;
oracle.loadLocalData(_ident, Hash.unwrap(uuid), bytes32(l2Number << 0xC0), 8, _partOffset);
} else if (_ident == LocalPreimageKey.CHAIN_ID) {
...
...
packages/contracts-bedrock/test/dispute/OutputBisectionGame.t.sol
View file @
ef3b63b3
...
...
@@ -834,6 +834,98 @@ contract OutputBisection_1v1_Actors_Test is OutputBisectionGame_Init {
assertEq(uint8(gameProxy.status()), uint8(GameStatus.CHALLENGER_WINS));
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1correctAbsolutePrestate_succeeds() public {
// Create the dispute game with an honest `ROOT_CLAIM`
bytes memory absolutePrestateData = _setup({ _absolutePrestateData: 0, _rootClaim: 16 });
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
// The dishonest l2 outputs are half correct, half incorrect.
uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1;
}
// The dishonest trace is half correct, half (- 1/2 of an exec trace subgame after the midpoint) incorrect.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = i > 127 ? bytes1(0xFF) : bytes1(uint8(i));
}
// Create actors
_createActors({
_honestTrace: honestTrace,
_honestPreStateData: absolutePrestateData,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestPreStateData: absolutePrestateData,
_dishonestL2Outputs: dishonestL2Outputs
});
// Exhaust all moves from both actors
_exhaustMoves();
// Resolve the game and assert that the defender won
_warpAndResolve();
assertEq(uint8(gameProxy.status()), uint8(GameStatus.DEFENDER_WINS));
}
/// @notice Static unit test for a 1v1 output bisection dispute.
function test_static_1v1dishonestAbsolutePrestate_succeeds() public {
// Create the dispute game with an honest `ROOT_CLAIM`
bytes memory absolutePrestateData = _setup({ _absolutePrestateData: 0, _rootClaim: 0xFF });
// The honest l2 outputs are from [1, 16] in this game.
uint256[] memory honestL2Outputs = new uint256[](16);
for (uint256 i; i < honestL2Outputs.length; i++) {
honestL2Outputs[i] = i + 1;
}
// The honest trace covers all block -> block + 1 transitions, and is 256 bytes long, consisting
// of bytes [0, 255].
bytes memory honestTrace = new bytes(256);
for (uint256 i; i < honestTrace.length; i++) {
honestTrace[i] = bytes1(uint8(i));
}
// The dishonest l2 outputs are half correct, half incorrect.
uint256[] memory dishonestL2Outputs = new uint256[](16);
for (uint256 i; i < dishonestL2Outputs.length; i++) {
dishonestL2Outputs[i] = i > 7 ? 0xFF : i + 1;
}
// The dishonest trace is half correct, half (- 1/2 of an exec trace subgame after the midpoint) incorrect.
bytes memory dishonestTrace = new bytes(256);
for (uint256 i; i < dishonestTrace.length; i++) {
dishonestTrace[i] = i > 127 ? bytes1(0xFF) : bytes1(uint8(i));
}
// Create actors
_createActors({
_honestTrace: honestTrace,
_honestPreStateData: absolutePrestateData,
_honestL2Outputs: honestL2Outputs,
_dishonestTrace: dishonestTrace,
_dishonestPreStateData: absolutePrestateData,
_dishonestL2Outputs: dishonestL2Outputs
});
// Exhaust all moves from both actors
_exhaustMoves();
// Resolve the game and assert that the defender won
_warpAndResolve();
assertEq(uint8(gameProxy.status()), uint8(GameStatus.CHALLENGER_WINS));
}
////////////////////////////////////////////////////////////////
// HELPERS //
////////////////////////////////////////////////////////////////
...
...
packages/contracts-bedrock/test/mocks/AlphabetVM2.sol
View file @
ef3b63b3
...
...
@@ -2,11 +2,12 @@
pragma solidity ^0.8.15;
import { IBigStepper, IPreimageOracle } from "src/dispute/interfaces/IBigStepper.sol";
import { PreimageOracle } from "src/cannon/PreimageOracle.sol";
import { PreimageOracle
, PreimageKeyLib
} from "src/cannon/PreimageOracle.sol";
import "src/libraries/DisputeTypes.sol";
/// @title AlphabetVM2
/// @dev A mock VM for the purpose of testing the dispute game infrastructure.
/// @dev A mock VM for the purpose of testing the dispute game infrastructure. Note that this only works
/// for games with an execution trace subgame max depth of 3 (8 instructions per subgame).
contract AlphabetVM2 is IBigStepper {
Claim internal immutable ABSOLUTE_PRESTATE;
IPreimageOracle public oracle;
...
...
@@ -23,17 +24,17 @@ contract AlphabetVM2 is IBigStepper {
bytes32 _localContext
)
external
view
returns (bytes32 postState_)
{
uint256 traceIndex;
uint256 claim;
if ((keccak256(_stateData) << 8) == (Claim.unwrap(ABSOLUTE_PRESTATE) << 8)) {
// If the state data is empty, then the absolute prestate is the claim.
// NOTE: this is wrong, need to fix. Pad to current trace index + claim.
// right now this adds local data into the oracle for whatever reason.
traceIndex = 0;
(claim) = abi.decode(_stateData, (uint256));
claim = claim + uint256(oracle.loadLocalData(4, _localContext, 0, 8, 0));
(bytes32 dat,) = oracle.readPreimage(PreimageKeyLib.localizeIdent(4, _localContext), 0);
uint256 startingL2BlockNumber = (uint256(dat) >> 128) & 0xFFFFFFFF;
traceIndex = (2 ** 4) * startingL2BlockNumber;
claim = traceIndex - 1;
} else {
// Otherwise, decode the state data.
(traceIndex, claim) = abi.decode(_stateData, (uint256, uint256));
...
...
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