Commit 1625a289 authored by clabby's avatar clabby

Add `traceIndex` function to `LibPosition`

parent a95bd8c2
...@@ -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: 513436) FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 510380)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 515302) FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 512246)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot:test_resolvesCorrectly_succeeds() (gas: 502966) FaultDisputeGame_ResolvesCorrectly_CorrectRoot:test_resolvesCorrectly_succeeds() (gas: 500144)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 510311) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 507255)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 512177) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 509121)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot:test_resolvesCorrectly_succeeds() (gas: 499841) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot:test_resolvesCorrectly_succeeds() (gas: 497019)
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)
...@@ -49,10 +49,10 @@ FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 103231) ...@@ -49,10 +49,10 @@ FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 103231)
FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 407967) FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 407967)
FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 10923) FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 10923)
FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24632) FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24632)
FaultDisputeGame_Test:test_resolve_challengeContested() (gas: 221074) FaultDisputeGame_Test:test_resolve_challengeContested() (gas: 221068)
FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9657) FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9657)
FaultDisputeGame_Test:test_resolve_rootContested() (gas: 106120) FaultDisputeGame_Test:test_resolve_rootContested() (gas: 106120)
FaultDisputeGame_Test:test_resolve_rootUncontested() (gas: 23630) FaultDisputeGame_Test:test_resolve_rootUncontested() (gas: 23624)
FaultDisputeGame_Test:test_resolve_teamDeathmatch() (gas: 391731) FaultDisputeGame_Test:test_resolve_teamDeathmatch() (gas: 391731)
FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8203) FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8203)
FaultDisputeGame_Test:test_simpleAttack_succeeds() (gas: 107322) FaultDisputeGame_Test:test_simpleAttack_succeeds() (gas: 107322)
......
...@@ -31,7 +31,6 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone { ...@@ -31,7 +31,6 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
uint256 public immutable MAX_GAME_DEPTH; uint256 public immutable MAX_GAME_DEPTH;
/// @notice A hypervisor that performs single instruction steps on a fault proof program trace. /// @notice A hypervisor that performs single instruction steps on a fault proof program trace.
/// @return vm_ The address of the hypervisor contract.
IBigStepper public immutable VM; IBigStepper public immutable VM;
/// @notice The duration of the game. /// @notice The duration of the game.
...@@ -284,7 +283,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone { ...@@ -284,7 +283,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
// 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
uint256 leftMostIndex = claimData.length - 1; uint256 leftMostIndex = claimData.length - 1;
Position leftMostTraceIndex = Position.wrap(type(uint128).max); uint256 leftMostTraceIndex = type(uint128).max;
for (uint256 i = leftMostIndex; i < type(uint64).max; ) { for (uint256 i = leftMostIndex; i < type(uint64).max; ) {
// Fetch the claim at the current index. // Fetch the claim at the current index.
ClaimData storage claim = claimData[i]; ClaimData storage claim = claimData[i];
...@@ -305,8 +304,8 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone { ...@@ -305,8 +304,8 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
// 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
// left-most trace index. // left-most trace index.
Position traceIndex = claimPos.rightIndex(MAX_GAME_DEPTH); uint256 traceIndex = claimPos.traceIndex(MAX_GAME_DEPTH);
if (Position.unwrap(traceIndex) < Position.unwrap(leftMostTraceIndex)) { if (traceIndex < leftMostTraceIndex) {
leftMostTraceIndex = traceIndex; leftMostTraceIndex = traceIndex;
unchecked { unchecked {
leftMostIndex = i + 1; leftMostIndex = i + 1;
...@@ -319,7 +318,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone { ...@@ -319,7 +318,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone {
if ( if (
// slither-disable-next-line weak-prng // slither-disable-next-line weak-prng
claimData[leftMostIndex].position.depth() % 2 == 0 && claimData[leftMostIndex].position.depth() % 2 == 0 &&
Position.unwrap(leftMostTraceIndex) != type(uint128).max leftMostTraceIndex != type(uint128).max
) { ) {
status_ = GameStatus.DEFENDER_WINS; status_ = GameStatus.DEFENDER_WINS;
} else { } else {
......
...@@ -104,6 +104,26 @@ library LibPosition { ...@@ -104,6 +104,26 @@ library LibPosition {
} }
} }
/// @notice Get the deepest, right most trace index relative to the `position`. This is
/// equivalent to calling `right` on a position until the maximum depth is reached and
/// then finding its index at depth.
/// @param _position The position to get the relative trace index of.
/// @param _maxDepth The maximum depth of the game.
/// @return traceIndex_ The trace index relative to the `position`.
function traceIndex(
Position _position,
uint256 _maxDepth
) internal pure returns (uint256 traceIndex_) {
uint256 msb = depth(_position);
assembly {
let remaining := sub(_maxDepth, msb)
traceIndex_ := sub(
or(shl(remaining, _position), sub(shl(remaining, 1), 1)),
shl(_maxDepth, 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.
......
...@@ -414,7 +414,7 @@ contract GamePlayer { ...@@ -414,7 +414,7 @@ contract GamePlayer {
} }
} else { } else {
// Find the trace index that our next claim must commit to. // Find the trace index that our next claim must commit to.
uint256 traceIndex = movePos.rightIndex(maxDepth).indexAtDepth(); uint256 traceIndex = movePos.traceIndex(maxDepth);
// Grab the claim that we need to make from the helper. // Grab the claim that we need to make from the helper.
Claim ourClaim = claimAt(traceIndex); Claim ourClaim = claimAt(traceIndex);
...@@ -448,7 +448,7 @@ contract GamePlayer { ...@@ -448,7 +448,7 @@ contract GamePlayer {
/// @notice Returns the preimage of a player's claim that commits to a given trace index. /// @notice Returns the preimage of a player's claim that commits to a given trace index.
function traceAt(Position _position) public view returns (bytes memory trace_) { function traceAt(Position _position) public view returns (bytes memory trace_) {
return traceAt(_position.rightIndex(maxDepth).indexAtDepth()); return traceAt(_position.traceIndex(maxDepth));
} }
/// @notice Returns the preimage of a player's claim that commits to a given trace index. /// @notice Returns the preimage of a player's claim that commits to a given trace index.
...@@ -463,7 +463,7 @@ contract GamePlayer { ...@@ -463,7 +463,7 @@ contract GamePlayer {
/// @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(Position _position) public view returns (Claim claim_) { function claimAt(Position _position) public view returns (Claim claim_) {
return claimAt(_position.rightIndex(maxDepth).indexAtDepth()); return claimAt(_position.traceIndex(maxDepth));
} }
} }
......
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