Commit cac7a904 authored by clabby's avatar clabby

Add support for defense in the `GamePlayer`

lint
parent c2d6700c
...@@ -32,9 +32,11 @@ DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_revert ...@@ -32,9 +32,11 @@ 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: 497017) FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 498304)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot4:test_resolvesCorrectly_succeeds() (gas: 500038)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot:test_resolvesCorrectly_succeeds() (gas: 490057) FaultDisputeGame_ResolvesCorrectly_CorrectRoot:test_resolvesCorrectly_succeeds() (gas: 490057)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 493886) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 495173)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 496907)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot:test_resolvesCorrectly_succeeds() (gas: 486926) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot:test_resolvesCorrectly_succeeds() (gas: 486926)
FaultDisputeGame_Test:test_clockTimeExceeded_reverts() (gas: 26444) FaultDisputeGame_Test:test_clockTimeExceeded_reverts() (gas: 26444)
FaultDisputeGame_Test:test_defendRoot_reverts() (gas: 13281) FaultDisputeGame_Test:test_defendRoot_reverts() (gas: 13281)
......
...@@ -140,24 +140,27 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone { ...@@ -140,24 +140,27 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
postStateClaim = claimData[_claimIndex].claim; postStateClaim = claimData[_claimIndex].claim;
} else { } else {
Position preStatePos; Position preStatePos;
Position postStatePos;
if (_isAttack) { if (_isAttack) {
// If the step is an attack, the prestate exists elsewhere in the game state, // If the step is an attack, the prestate exists elsewhere in the game state,
// and the parent claim is the expected post-state. // and the parent claim is the expected post-state.
preStatePos = claimData[_stateIndex].position; preStatePos = claimData[_stateIndex].position;
preStateClaim = claimData[_stateIndex].claim; preStateClaim = claimData[_stateIndex].claim;
postStatePos = parentPos;
postStateClaim = parent.claim; postStateClaim = parent.claim;
} else { } else {
// If the step is a defense, the poststate exists elsewhere in the game state, // If the step is a defense, the poststate exists elsewhere in the game state,
// and the parent claim is the expected pre-state. // and the parent claim is the expected pre-state.
preStatePos = parent.position; preStatePos = parent.position;
preStateClaim = parent.claim; preStateClaim = parent.claim;
postStatePos = claimData[_stateIndex].position;
postStateClaim = claimData[_stateIndex].claim; postStateClaim = claimData[_stateIndex].claim;
} }
// Assert that the given prestate commits to the instruction at `gindex - 1`. // Assert that the given prestate commits to the instruction at `gindex - 1`.
if ( if (
Position.unwrap(preStatePos.rightIndex(MAX_GAME_DEPTH)) != Position.unwrap(preStatePos.rightIndex(MAX_GAME_DEPTH)) !=
Position.unwrap(parentPos) - 1 Position.unwrap(postStatePos.rightIndex(MAX_GAME_DEPTH)) - 1
) { ) {
revert InvalidPrestate(); revert InvalidPrestate();
} }
......
...@@ -427,20 +427,18 @@ contract GamePlayer { ...@@ -427,20 +427,18 @@ contract GamePlayer {
// move position is 0, the prestate is the absolute prestate and we need to // move position is 0, the prestate is the absolute prestate and we need to
// do nothing. // do nothing.
if (movePos.indexAtDepth() > 0) { if (movePos.indexAtDepth() > 0) {
Position statePos; Position leafPos = isAttack
if (isAttack) { ? Position.wrap(Position.unwrap(parentPos) - 1)
statePos = Position.wrap(Position.unwrap(parentPos) - 1); : Position.wrap(Position.unwrap(parentPos) + 1);
Position statePos = leafPos;
// Walk up until the valid position that commits to the prestate's
// trace index is found. // Walk up until the valid position that commits to the prestate's
while ( // trace index is found.
Position.unwrap(statePos.parent().rightIndex(maxDepth)) == while (
Position.unwrap(statePos) Position.unwrap(statePos.parent().rightIndex(maxDepth)) ==
) { Position.unwrap(leafPos)
statePos = statePos.parent().parent().parent(); ) {
} statePos = statePos.parent();
} else {
// TODO - Defend step logic.
} }
// Now, search for the index of the claim that commits to the prestate's trace // Now, search for the index of the claim that commits to the prestate's trace
...@@ -455,7 +453,7 @@ contract GamePlayer { ...@@ -455,7 +453,7 @@ contract GamePlayer {
} }
} }
// Perform the step and hault recursion. // Perform the step and halt recursion.
try gameProxy.step(stateIndex, _parentIndex, isAttack, hex"", hex"") { try gameProxy.step(stateIndex, _parentIndex, isAttack, hex"", hex"") {
// Do nothing, step succeeded. // Do nothing, step succeeded.
} catch { } catch {
...@@ -576,8 +574,8 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot is OneVsOne_Arena { ...@@ -576,8 +574,8 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot is OneVsOne_Arena {
// Play the game until a step is forced. // Play the game until a step is forced.
dishonest.play(0); dishonest.play(0);
// Resolve the game and assert that the honest player challenged the root // Resolve the game and assert that the dishonest player challenged the root
// claim successfully. // claim unsuccessfully.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(dishonest.failedToStep()); assertTrue(dishonest.failedToStep());
} }
...@@ -612,8 +610,44 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot2 is OneVsOne_Arena { ...@@ -612,8 +610,44 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot2 is OneVsOne_Arena {
// Play the game until a step is forced. // Play the game until a step is forced.
dishonest.play(0); dishonest.play(0);
// Resolve the game and assert that the dishonest player challenged the root
// claim unsuccessfully.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(dishonest.failedToStep());
}
}
contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3 is OneVsOne_Arena {
function setUp() public override {
GamePlayer honest = new HonestPlayer();
GamePlayer dishonest = new EarlyDivergentPlayer();
super.init(honest, dishonest, Claim.wrap(bytes32(uint256(15))));
}
function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced.
honest.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));
assertFalse(honest.failedToStep());
}
}
contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot4 is OneVsOne_Arena {
function setUp() public override {
GamePlayer honest = new HonestPlayer();
GamePlayer dishonest = new EarlyDivergentPlayer();
super.init(honest, dishonest, Claim.wrap(bytes32(uint256(31))));
}
function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced.
dishonest.play(0);
// Resolve the game and assert that the dishonest player challenged the root
// claim unsuccessfully.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS)); assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(dishonest.failedToStep()); assertTrue(dishonest.failedToStep());
} }
...@@ -672,3 +706,20 @@ contract HalfDivergentPlayer is GamePlayer { ...@@ -672,3 +706,20 @@ contract HalfDivergentPlayer is GamePlayer {
trace = dishonestTrace; trace = dishonestTrace;
} }
} }
contract EarlyDivergentPlayer is GamePlayer {
function init(
FaultDisputeGame _gameProxy,
GamePlayer _counterParty,
Vm _vm
) public virtual override {
super.init(_gameProxy, _counterParty, _vm);
uint8 absolutePrestate = uint8(uint256(Claim.unwrap(_gameProxy.ABSOLUTE_PRESTATE())));
bytes memory dishonestTrace = new bytes(16);
for (uint8 i = 0; i < dishonestTrace.length; i++) {
// Offset the trace after the first half.
dishonestTrace[i] = i > 2 ? bytes1(i) : bytes1(absolutePrestate + i + 1);
}
trace = dishonestTrace;
}
}
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