Commit b7755594 authored by clabby's avatar clabby

`LibPosition` documentation + perf

parent cac7a904
...@@ -459,4 +459,3 @@ SystemConfig_Setters_TestFail:test_setResourceConfig_notOwner_reverts() (gas: 11 ...@@ -459,4 +459,3 @@ SystemConfig_Setters_TestFail:test_setResourceConfig_notOwner_reverts() (gas: 11
SystemConfig_Setters_TestFail:test_setResourceConfig_zeroDenominator_reverts() (gas: 13039) SystemConfig_Setters_TestFail:test_setResourceConfig_zeroDenominator_reverts() (gas: 13039)
SystemConfig_Setters_TestFail:test_setUnsafeBlockSigner_notOwner_reverts() (gas: 10616) SystemConfig_Setters_TestFail:test_setUnsafeBlockSigner_notOwner_reverts() (gas: 10616)
TransferOnionTest:test_constructor_succeeds() (gas: 564855) TransferOnionTest:test_constructor_succeeds() (gas: 564855)
TransferOnionTest:test_unwrap_succeeds() (gas: 724955)
\ No newline at end of file
...@@ -8,20 +8,27 @@ import "../../libraries/DisputeTypes.sol"; ...@@ -8,20 +8,27 @@ import "../../libraries/DisputeTypes.sol";
* @notice This library contains helper functions for working with the `Position` type. * @notice This library contains helper functions for working with the `Position` type.
*/ */
library LibPosition { library LibPosition {
/**
* @notice Computes a generalized index (2^{depth} + indexAtDepth).
* @param _depth The depth of the position.
* @param _indexAtDepth The index at the depth of the position.
* @return position_ The computed generalized index.
*/
function wrap(uint64 _depth, uint64 _indexAtDepth) internal pure returns (Position position_) { function wrap(uint64 _depth, uint64 _indexAtDepth) internal pure returns (Position position_) {
assembly { assembly {
// gindex = 2^{_depth} + _indexAtDepth
position_ := add(shl(_depth, 1), _indexAtDepth) position_ := add(shl(_depth, 1), _indexAtDepth)
} }
} }
/** /**
* @notice Pulls the `depth` out of a packed `Position` type. * @notice Pulls the `depth` out of a `Position` type.
* @param _position The position to get the `depth` of. * @param _position The generalized index to get the `depth` of.
* @return depth_ The `depth` of the `position`. * @return depth_ The `depth` of the `position` gindex.
* @custom:attribution Solady <https://github.com/Vectorized/Solady> * @custom:attribution Solady <https://github.com/Vectorized/Solady>
*/ */
function depth(Position _position) internal pure returns (uint64 depth_) { function depth(Position _position) internal pure returns (uint64 depth_) {
// Return the most significant bit position // Return the most significant bit offset, which signifies the depth of the gindex.
assembly { assembly {
depth_ := or(depth_, shl(6, lt(0xffffffffffffffff, shr(depth_, _position)))) depth_ := or(depth_, shl(6, lt(0xffffffffffffffff, shr(depth_, _position))))
depth_ := or(depth_, shl(5, lt(0xffffffff, shr(depth_, _position)))) depth_ := or(depth_, shl(5, lt(0xffffffff, shr(depth_, _position))))
...@@ -45,12 +52,16 @@ library LibPosition { ...@@ -45,12 +52,16 @@ library LibPosition {
} }
/** /**
* @notice Pulls the `indexAtDepth` out of a packed `Position` type. * @notice Pulls the `indexAtDepth` out of a `Position` type.
* @param _position The position to get the `indexAtDepth` of. * The `indexAtDepth` is the left/right index of a position at a specific depth within
* @return indexAtDepth_ The `indexAtDepth` of the `position`. * the binary tree, starting from index 0. For example, at gindex 2, the `depth` = 1
* and the `indexAtDepth` = 0.
* @param _position The generalized index to get the `indexAtDepth` of.
* @return indexAtDepth_ The `indexAtDepth` of the `position` gindex.
*/ */
function indexAtDepth(Position _position) internal pure returns (uint64 indexAtDepth_) { function indexAtDepth(Position _position) internal pure returns (uint64 indexAtDepth_) {
// Return bits p_{msb-1}...p_{0} // Return bits p_{msb-1}...p_{0}. This effectively pulls the 2^{depth} out of the gindex,
// leaving only the `indexAtDepth`.
uint256 msb = depth(_position); uint256 msb = depth(_position);
assembly { assembly {
indexAtDepth_ := sub(_position, shl(msb, 1)) indexAtDepth_ := sub(_position, shl(msb, 1))
...@@ -58,7 +69,7 @@ library LibPosition { ...@@ -58,7 +69,7 @@ library LibPosition {
} }
/** /**
* @notice Get the position to the left of `position`. * @notice Get the left child of `_position`.
* @param _position The position to get the left position of. * @param _position The position to get the left position of.
* @return left_ The position to the left of `position`. * @return left_ The position to the left of `position`.
*/ */
...@@ -69,18 +80,18 @@ library LibPosition { ...@@ -69,18 +80,18 @@ library LibPosition {
} }
/** /**
* @notice Get the position to the right of `position`. * @notice Get the right child of `_position`
* @param _position The position to get the right position of. * @param _position The position to get the right position of.
* @return right_ The position to the right of `position`. * @return right_ The position to the right of `position`.
*/ */
function right(Position _position) internal pure returns (Position right_) { function right(Position _position) internal pure returns (Position right_) {
assembly { assembly {
right_ := add(1, shl(1, _position)) right_ := or(1, shl(1, _position))
} }
} }
/** /**
* @notice Get the parent position of `position`. * @notice Get the parent position of `_position`.
* @param _position The position to get the parent position of. * @param _position The position to get the parent position of.
* @return parent_ The parent position of `position`. * @return parent_ The parent position of `position`.
*/ */
...@@ -91,10 +102,11 @@ library LibPosition { ...@@ -91,10 +102,11 @@ library LibPosition {
} }
/** /**
* @notice Get the deepest, right most index relative to the `position`. * @notice Get the deepest, right most gindex relative to the `position`. This is equivalent to
* @param _position The position to get the relative deepest, right most index of. * calling `right` on a position until the maximum depth is reached.
* @param _position The position to get the relative deepest, right most gindex of.
* @param _maxDepth The maximum depth of the game. * @param _maxDepth The maximum depth of the game.
* @return rightIndex_ The deepest, right most index relative to the `position`. * @return rightIndex_ The deepest, right most gindex relative to the `position`.
*/ */
function rightIndex( function rightIndex(
Position _position, Position _position,
...@@ -114,22 +126,29 @@ library LibPosition { ...@@ -114,22 +126,29 @@ library LibPosition {
} }
/** /**
* @notice Get the attack position relative to `position`. * @notice Get the attack position relative to `position`. The attack position is the next
* logical point of bisection if the parent claim is disagreed with, which is the
* midway point of the trace that the attacked node commits to.
* @param _position The position to get the relative attack position of. * @param _position The position to get the relative attack position of.
* @return attack_ The attack position relative to `position`. * @return attack_ The attack position relative to `position`.
*/ */
function attack(Position _position) internal pure returns (Position attack_) { function attack(Position _position) internal pure returns (Position attack_) {
// Move: Left
return left(_position); return left(_position);
} }
/** /**
* @notice Get the defense position relative to `position`. * @notice Get the defense position relative to `position`. The defense position is the next
* logical point of bisection if the parent claim and the grandparent claim are agreed
* with, which is at the midway point of the trace that the defended node's right
* sibling commits to.
* @param _position The position to get the relative defense position of. * @param _position The position to get the relative defense position of.
* @return defense_ The defense position relative to `position`. * @return defense_ The defense position relative to `position`.
*/ */
function defend(Position _position) internal pure returns (Position defense_) { function defend(Position _position) internal pure returns (Position defense_) {
assembly { assembly {
defense_ := shl(1, add(1, shl(1, shr(1, _position)))) // Move: Parent -> Right -> Left
defense_ := shl(1, or(1, _position))
} }
} }
} }
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