Commit 9d68af5b authored by clabby's avatar clabby

Move to `H(traceIndex,state)` for stf

Lint
parent 1625a289
...@@ -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: 510380) FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 502842)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 512246) FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 504699)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot:test_resolvesCorrectly_succeeds() (gas: 500144) FaultDisputeGame_ResolvesCorrectly_CorrectRoot:test_resolvesCorrectly_succeeds() (gas: 492706)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 507255) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 501717)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 509121) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 503574)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot:test_resolvesCorrectly_succeeds() (gas: 497019) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot:test_resolvesCorrectly_succeeds() (gas: 491581)
FaultDisputeGame_Test:test_defendRoot_invalidMove_reverts() (gas: 13250) FaultDisputeGame_Test:test_defendRoot_invalidMove_reverts() (gas: 13250)
FaultDisputeGame_Test:test_extraData_succeeds() (gas: 17409) FaultDisputeGame_Test:test_extraData_succeeds() (gas: 17409)
FaultDisputeGame_Test:test_gameData_succeeds() (gas: 17834) FaultDisputeGame_Test:test_gameData_succeeds() (gas: 17834)
......
...@@ -4,24 +4,24 @@ pragma solidity ^0.8.15; ...@@ -4,24 +4,24 @@ pragma solidity ^0.8.15;
/// @title IBigStepper /// @title IBigStepper
/// @notice An interface for a contract with a state transition function that /// @notice An interface for a contract with a state transition function that
/// will accept a pre state and return a post state. /// will accept a pre state and return a post state.
///⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
///⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⠶⢅⠒⢄⢔⣶⡦⣤⡤⠄⣀⠀⠀⠀⠀⠀⠀⠀ /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⠶⢅⠒⢄⢔⣶⡦⣤⡤⠄⣀⠀⠀⠀⠀⠀⠀⠀
///⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠨⡏⠀⠀⠈⠢⣙⢯⣄⠀⢨⠯⡺⡘⢄⠀⠀⠀⠀⠀ /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠨⡏⠀⠀⠈⠢⣙⢯⣄⠀⢨⠯⡺⡘⢄⠀⠀⠀⠀⠀
///⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣶⡆⠀⠀⠀⠀⠈⠓⠬⡒⠡⣀⢙⡜⡀⠓⠄⠀⠀⠀ /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣶⡆⠀⠀⠀⠀⠈⠓⠬⡒⠡⣀⢙⡜⡀⠓⠄⠀⠀⠀
///⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡷⠿⣧⣀⡀⠀⠀⠀⠀⠀⠀⠉⠣⣞⠩⠥⠀⠼⢄⠀⠀ /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡷⠿⣧⣀⡀⠀⠀⠀⠀⠀⠀⠉⠣⣞⠩⠥⠀⠼⢄⠀⠀
///⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇⠀⠀⠀⠉⢹⣶⠒⠒⠂⠈⠉⠁⠘⡆⠀⣿⣿⠫⡄⠀ /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇⠀⠀⠀⠉⢹⣶⠒⠒⠂⠈⠉⠁⠘⡆⠀⣿⣿⠫⡄⠀
///⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⢶⣤⣀⡀⠀⠀⢸⡿⠀⠀⠀⠀⠀⢀⠞⠀⠀⢡⢨⢀⡄⠀ /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⢶⣤⣀⡀⠀⠀⢸⡿⠀⠀⠀⠀⠀⢀⠞⠀⠀⢡⢨⢀⡄⠀
///⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡒⣿⢿⡤⠝⡣⠉⠁⠚⠛⠀⠤⠤⣄⡰⠁⠀⠀⠀⠉⠙⢸⠀⠀ /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡒⣿⢿⡤⠝⡣⠉⠁⠚⠛⠀⠤⠤⣄⡰⠁⠀⠀⠀⠉⠙⢸⠀⠀
///⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡤⢯⡌⡿⡇⠘⡷⠀⠁⠀⠀⢀⣰⠢⠲⠛⣈⣸⠦⠤⠶⠴⢬⣐⣊⡂⠀ /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡤⢯⡌⡿⡇⠘⡷⠀⠁⠀⠀⢀⣰⠢⠲⠛⣈⣸⠦⠤⠶⠴⢬⣐⣊⡂⠀
///⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⡪⡗⢫⠞⠀⠆⣀⠻⠤⠴⠐⠚⣉⢀⠦⠂⠋⠁⠀⠁⠀⠀⠀⠀⢋⠉⠇⠀ /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⡪⡗⢫⠞⠀⠆⣀⠻⠤⠴⠐⠚⣉⢀⠦⠂⠋⠁⠀⠁⠀⠀⠀⠀⢋⠉⠇⠀
///⠀⠀⠀⠀⣀⡤⠐⠒⠘⡹⠉⢸⠇⠸⠀⠀⠀⠀⣀⣤⠴⠚⠉⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠼⠀⣾⠀ /// ⠀⠀⠀⠀⣀⡤⠐⠒⠘⡹⠉⢸⠇⠸⠀⠀⠀⠀⣀⣤⠴⠚⠉⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠼⠀⣾⠀
///⠀⠀⠀⡰⠀⠉⠉⠀⠁⠀⠀⠈⢇⠈⠒⠒⠘⠈⢀⢡⡂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠀⢸⡄ /// ⠀⠀⠀⡰⠀⠉⠉⠀⠁⠀⠀⠈⢇⠈⠒⠒⠘⠈⢀⢡⡂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠀⢸⡄
///⠀⠀⠸⣿⣆⠤⢀⡀⠀⠀⠀⠀⢘⡌⠀⠀⣀⣀⣀⡈⣤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⢸⡇ /// ⠀⠀⠸⣿⣆⠤⢀⡀⠀⠀⠀⠀⢘⡌⠀⠀⣀⣀⣀⡈⣤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⢸⡇
///⠀⠀⢸⣀⠀⠉⠒⠐⠛⠋⠭⠭⠍⠉⠛⠒⠒⠒⠀⠒⠚⠛⠛⠛⠩⠭⠭⠭⠭⠤⠤⠤⠤⠤⠭⠭⠉⠓⡆ /// ⠀⠀⢸⣀⠀⠉⠒⠐⠛⠋⠭⠭⠍⠉⠛⠒⠒⠒⠀⠒⠚⠛⠛⠛⠩⠭⠭⠭⠭⠤⠤⠤⠤⠤⠭⠭⠉⠓⡆
///⠀⠀⠘⠿⣷⣶⣤⣤⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇ /// ⠀⠀⠘⠿⣷⣶⣤⣤⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇
///⠀⠀⠀⠀⠀⠉⠙⠛⠛⠻⠿⢿⣿⣿⣷⣶⣶⣶⣤⣤⣀⣁⣛⣃⣒⠿⠿⠿⠤⠠⠄⠤⠤⢤⣛⣓⣂⣻⡇ /// ⠀⠀⠀⠀⠀⠉⠙⠛⠛⠻⠿⢿⣿⣿⣷⣶⣶⣶⣤⣤⣀⣁⣛⣃⣒⠿⠿⠿⠤⠠⠄⠤⠤⢤⣛⣓⣂⣻⡇
///⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠉⠙⠛⠻⠿⠿⠿⢿⣿⣿⣿⣷⣶⣶⣾⣿⣿⣿⣿⠿⠟⠁ /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠉⠙⠛⠻⠿⠿⠿⢿⣿⣿⣿⣷⣶⣶⣾⣿⣿⣿⣿⠿⠟⠁
///⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠈⠉⠉⠉⠉⠁⠀⠀⠀⠀⠀ /// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠈⠉⠉⠉⠉⠁⠀⠀⠀⠀⠀
interface IBigStepper { interface IBigStepper {
/// @notice Performs a single instruction step from a given prestate and returns the poststate /// @notice Performs a single instruction step from a given prestate and returns the poststate
/// hash. /// hash.
......
...@@ -11,7 +11,6 @@ import "../libraries/DisputeTypes.sol"; ...@@ -11,7 +11,6 @@ import "../libraries/DisputeTypes.sol";
import "../libraries/DisputeErrors.sol"; import "../libraries/DisputeErrors.sol";
import { LibClock } from "../dispute/lib/LibClock.sol"; import { LibClock } from "../dispute/lib/LibClock.sol";
import { LibPosition } from "../dispute/lib/LibPosition.sol"; import { LibPosition } from "../dispute/lib/LibPosition.sol";
import { Bytes } from "../libraries/Bytes.sol";
import { IBigStepper } from "../dispute/interfaces/IBigStepper.sol"; import { IBigStepper } from "../dispute/interfaces/IBigStepper.sol";
contract FaultDisputeGame_Init is DisputeGameFactory_Init { contract FaultDisputeGame_Init is DisputeGameFactory_Init {
...@@ -30,7 +29,7 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init { ...@@ -30,7 +29,7 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init {
function init(Claim rootClaim, Claim absolutePrestate) public { function init(Claim rootClaim, Claim absolutePrestate) public {
super.setUp(); super.setUp();
// Deploy an implementation of the fault game // Deploy an implementation of the fault game
gameImpl = new FaultDisputeGame(absolutePrestate, 4, new BigStepper(absolutePrestate)); gameImpl = new FaultDisputeGame(absolutePrestate, 4, new AlphabetVM(absolutePrestate));
// Register the game implementation with the factory. // Register the game implementation with the factory.
factory.setImplementation(GAME_TYPE, gameImpl); factory.setImplementation(GAME_TYPE, gameImpl);
// Create a new game. // Create a new game.
...@@ -369,7 +368,6 @@ contract GamePlayer { ...@@ -369,7 +368,6 @@ contract GamePlayer {
// If we are past the maximum depth, break the recursion and step. // If we are past the maximum depth, break the recursion and step.
if (movePos.depth() > maxDepth) { if (movePos.depth() > maxDepth) {
uint256 stateIndex; uint256 stateIndex;
Position statePos;
bytes memory preStateTrace; bytes memory preStateTrace;
// First, we need to find the pre/post state index depending on whether we // First, we need to find the pre/post state index depending on whether we
...@@ -380,7 +378,7 @@ contract GamePlayer { ...@@ -380,7 +378,7 @@ contract GamePlayer {
Position leafPos = isAttack Position leafPos = isAttack
? Position.wrap(Position.unwrap(parentPos) - 1) ? Position.wrap(Position.unwrap(parentPos) - 1)
: Position.wrap(Position.unwrap(parentPos) + 1); : Position.wrap(Position.unwrap(parentPos) + 1);
statePos = leafPos; Position statePos = leafPos;
// Walk up until the valid position that commits to the prestate's // Walk up until the valid position that commits to the prestate's
// trace index is found. // trace index is found.
...@@ -403,7 +401,11 @@ contract GamePlayer { ...@@ -403,7 +401,11 @@ contract GamePlayer {
} }
// Grab the trace up to the prestate's trace index. // Grab the trace up to the prestate's trace index.
preStateTrace = traceAt(isAttack ? statePos : parentPos); if (isAttack) {
preStateTrace = abi.encode(statePos.traceIndex(maxDepth), traceAt(statePos));
} else {
preStateTrace = abi.encode(parentPos.traceIndex(maxDepth), traceAt(parentPos));
}
} }
// Perform the step and halt recursion. // Perform the step and halt recursion.
...@@ -446,19 +448,19 @@ contract GamePlayer { ...@@ -446,19 +448,19 @@ contract GamePlayer {
return uint256(vm.load(address(gameProxy), bytes32(uint256(1)))); return uint256(vm.load(address(gameProxy), bytes32(uint256(1))));
} }
/// @notice Returns the preimage of a player's claim that commits to a given trace index. /// @notice Returns the state at the trace index within the player's trace.
function traceAt(Position _position) public view returns (bytes memory trace_) { function traceAt(Position _position) public view returns (uint256 state_) {
return traceAt(_position.traceIndex(maxDepth)); return traceAt(_position.traceIndex(maxDepth));
} }
/// @notice Returns the preimage of a player's claim that commits to a given trace index. /// @notice Returns the state at the trace index within the player's trace.
function traceAt(uint256 _traceIndex) public view returns (bytes memory trace_) { function traceAt(uint256 _traceIndex) public view returns (uint256 state_) {
return Bytes.slice(trace, 0, _traceIndex + 1); return uint256(uint8(trace[_traceIndex]));
} }
/// @notice Returns the player's claim that commits to a given trace index. /// @notice Returns the player's claim that commits to a given trace index.
function claimAt(uint256 _traceIndex) public view returns (Claim claim_) { function claimAt(uint256 _traceIndex) public view returns (Claim claim_) {
return Claim.wrap(keccak256(traceAt(_traceIndex))); return Claim.wrap(keccak256(abi.encode(_traceIndex, traceAt(_traceIndex))));
} }
/// @notice Returns the player's claim that commits to a given trace index. /// @notice Returns the player's claim that commits to a given trace index.
...@@ -470,29 +472,24 @@ contract GamePlayer { ...@@ -470,29 +472,24 @@ contract GamePlayer {
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.
Claim internal constant ABSOLUTE_PRESTATE = Claim.wrap(bytes32(uint256(15))); Claim internal constant ABSOLUTE_PRESTATE = Claim.wrap(bytes32(uint256(15)));
/// @dev The honest participant. /// @dev The defender.
GamePlayer internal honest; GamePlayer internal defender;
/// @dev The dishonest participant. /// @dev The challenger.
GamePlayer internal dishonest; GamePlayer internal challenger;
function init( function init(GamePlayer _defender, GamePlayer _challenger) public {
GamePlayer _honest, Claim rootClaim = Claim.wrap(keccak256(abi.encode(15, _defender.traceAt(15))));
GamePlayer _dishonest, super.init(rootClaim, ABSOLUTE_PRESTATE);
Claim _rootClaim defender = _defender;
) public { challenger = _challenger;
super.init(_rootClaim, ABSOLUTE_PRESTATE);
// Deploy a new honest player.
honest = _honest;
// Deploy a new dishonest player.
dishonest = _dishonest;
// Set the counterparties. // Set the counterparties.
honest.init(gameProxy, dishonest, vm); defender.init(gameProxy, challenger, vm);
dishonest.init(gameProxy, honest, vm); challenger.init(gameProxy, defender, vm);
// Label actors for trace. // Label actors for trace.
vm.label(address(honest), "HonestPlayer"); vm.label(address(challenger), "Challenger");
vm.label(address(dishonest), "DishonestPlayer"); vm.label(address(defender), "Defender");
} }
} }
...@@ -500,17 +497,17 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot is OneVsOne_Arena { ...@@ -500,17 +497,17 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot is OneVsOne_Arena {
function setUp() public override { function setUp() public override {
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new FullyDivergentPlayer(ABSOLUTE_PRESTATE); GamePlayer dishonest = new FullyDivergentPlayer(ABSOLUTE_PRESTATE);
super.init(honest, dishonest, Claim.wrap(keccak256(dishonest.trace()))); super.init(dishonest, honest);
} }
function test_resolvesCorrectly_succeeds() public { function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced. // Play the game until a step is forced.
honest.play(0); challenger.play(0);
// 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.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertFalse(honest.failedToStep()); assertFalse(defender.failedToStep());
} }
} }
...@@ -518,17 +515,17 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot is OneVsOne_Arena { ...@@ -518,17 +515,17 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot is OneVsOne_Arena {
function setUp() public override { function setUp() public override {
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new FullyDivergentPlayer(ABSOLUTE_PRESTATE); GamePlayer dishonest = new FullyDivergentPlayer(ABSOLUTE_PRESTATE);
super.init(honest, dishonest, Claim.wrap(keccak256(honest.trace()))); super.init(honest, dishonest);
} }
function test_resolvesCorrectly_succeeds() public { function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced. // Play the game until a step is forced.
dishonest.play(0); challenger.play(0);
// 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.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(dishonest.failedToStep()); assertTrue(challenger.failedToStep());
} }
} }
...@@ -536,17 +533,17 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2 is OneVsOne_Arena { ...@@ -536,17 +533,17 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2 is OneVsOne_Arena {
function setUp() public override { function setUp() public override {
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new HalfDivergentPlayer(ABSOLUTE_PRESTATE); GamePlayer dishonest = new HalfDivergentPlayer(ABSOLUTE_PRESTATE);
super.init(honest, dishonest, Claim.wrap(keccak256(dishonest.trace()))); super.init(dishonest, honest);
} }
function test_resolvesCorrectly_succeeds() public { function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced. // Play the game until a step is forced.
honest.play(0); challenger.play(0);
// 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.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertFalse(honest.failedToStep()); assertFalse(defender.failedToStep());
} }
} }
...@@ -554,17 +551,17 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot2 is OneVsOne_Arena { ...@@ -554,17 +551,17 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot2 is OneVsOne_Arena {
function setUp() public override { function setUp() public override {
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new HalfDivergentPlayer(ABSOLUTE_PRESTATE); GamePlayer dishonest = new HalfDivergentPlayer(ABSOLUTE_PRESTATE);
super.init(honest, dishonest, Claim.wrap(keccak256(honest.trace()))); super.init(honest, dishonest);
} }
function test_resolvesCorrectly_succeeds() public { function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced. // Play the game until a step is forced.
dishonest.play(0); challenger.play(0);
// 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.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(dishonest.failedToStep()); assertTrue(challenger.failedToStep());
} }
} }
...@@ -572,17 +569,17 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3 is OneVsOne_Arena { ...@@ -572,17 +569,17 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3 is OneVsOne_Arena {
function setUp() public override { function setUp() public override {
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new EarlyDivergentPlayer(ABSOLUTE_PRESTATE); GamePlayer dishonest = new EarlyDivergentPlayer(ABSOLUTE_PRESTATE);
super.init(honest, dishonest, Claim.wrap(keccak256(dishonest.trace()))); super.init(dishonest, honest);
} }
function test_resolvesCorrectly_succeeds() public { function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced. // Play the game until a step is forced.
honest.play(0); challenger.play(0);
// 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.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS)); assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertFalse(honest.failedToStep()); assertFalse(defender.failedToStep());
} }
} }
...@@ -590,17 +587,17 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot3 is OneVsOne_Arena { ...@@ -590,17 +587,17 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot3 is OneVsOne_Arena {
function setUp() public override { function setUp() public override {
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new EarlyDivergentPlayer(ABSOLUTE_PRESTATE); GamePlayer dishonest = new EarlyDivergentPlayer(ABSOLUTE_PRESTATE);
super.init(honest, dishonest, Claim.wrap(keccak256(honest.trace()))); super.init(honest, dishonest);
} }
function test_resolvesCorrectly_succeeds() public { function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced. // Play the game until a step is forced.
dishonest.play(0); challenger.play(0);
// 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.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(dishonest.failedToStep()); assertTrue(challenger.failedToStep());
} }
} }
...@@ -659,7 +656,7 @@ contract EarlyDivergentPlayer is GamePlayer { ...@@ -659,7 +656,7 @@ contract EarlyDivergentPlayer is GamePlayer {
// MOCK VMS // // MOCK VMS //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
contract BigStepper is IBigStepper { contract AlphabetVM is IBigStepper {
Claim internal immutable ABSOLUTE_PRESTATE; Claim internal immutable ABSOLUTE_PRESTATE;
constructor(Claim _absolutePrestate) { constructor(Claim _absolutePrestate) {
...@@ -672,13 +669,18 @@ contract BigStepper is IBigStepper { ...@@ -672,13 +669,18 @@ contract BigStepper is IBigStepper {
view view
returns (bytes32 postState_) returns (bytes32 postState_)
{ {
// STF: n -> concat(n, n[n.len-1] + 1) uint256 traceIndex;
uint8 postState = ( uint256 claim;
_stateData.length == 0 if (_stateData.length == 0) {
? uint8(uint256(Claim.unwrap(ABSOLUTE_PRESTATE))) // If the state data is empty, then the absolute prestate is the claim.
: uint8(_stateData[_stateData.length - 1]) traceIndex = 0;
) + 1; claim = uint256(Claim.unwrap(ABSOLUTE_PRESTATE));
// Hash the trace for the claim. } else {
postState_ = keccak256(bytes.concat(_stateData, bytes1(postState))); // Otherwise, decode the state data.
(traceIndex, claim) = abi.decode(_stateData, (uint256, uint256));
traceIndex++;
}
// STF: n -> n + 1
postState_ = keccak256(abi.encode(traceIndex, claim + 1));
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment