-
Notifications
You must be signed in to change notification settings - Fork 4
modify traceAncestor to support N-ary #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
merge optimism
merge from optimism
| // state's depth in relation to the parent, we don't need another | ||
| // branch because (n - n) % 2 == 0. | ||
| bool validStep = VM.step(_stateData, _proof, uuid.raw()) == postState.claim.raw(); | ||
| bool parentPostAgree = (parentPos.depth() - postState.position.depth()) % 2 == 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be great if we can update the comment accordingly.
| { | ||
| // Grab the trace ancestor's expected position. | ||
| Position traceAncestorPos = _global ? _pos.traceAncestor() : _pos.traceAncestorBounded(SPLIT_DEPTH); | ||
| Position traceAncestorPos = _global ? _pos.traceAncestorBounded(nBits - 1) : _pos.traceAncestorBounded(SPLIT_DEPTH); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure _pos.traceAncestorBounded(nBits - 1) is correct for both nBits == 1 and nBits > 1 cases.
For example, traceAncestor(3) = 1, while traceAncestorBounded(3, 0) = 3
| function traceAncestorV2(Position _position) public view returns (Position ancestor_) { | ||
| if (_position.depth() < nBits) { | ||
| revert ClaimAboveSplit(); | ||
| } | ||
| ancestor_ = _position.traceAncestor(); | ||
| // Position 1 is not the value submitted by the Actors. | ||
| if (1 == ancestor_.raw()) { | ||
| return ancestor_; | ||
| } | ||
| // The depth of the ancestor must not be less than the depth of the first attack position. | ||
| for (uint64 start = ancestor_.depth(); start < nBits; start++) { | ||
| ancestor_ = Position.wrap(ancestor_.raw() * 2 + 1); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the code should be
| function traceAncestorV2(Position _position) public view returns (Position ancestor_) { | |
| if (_position.depth() < nBits) { | |
| revert ClaimAboveSplit(); | |
| } | |
| ancestor_ = _position.traceAncestor(); | |
| // Position 1 is not the value submitted by the Actors. | |
| if (1 == ancestor_.raw()) { | |
| return ancestor_; | |
| } | |
| // The depth of the ancestor must not be less than the depth of the first attack position. | |
| for (uint64 start = ancestor_.depth(); start < nBits; start++) { | |
| ancestor_ = Position.wrap(ancestor_.raw() * 2 + 1); | |
| } | |
| } | |
| function traceAncestorV2(Position _position) public view returns (Position ancestor_) { | |
| if (_position.depth() % nBits != 0) { | |
| revert SomeError(); | |
| } | |
| return _position.traceAncestor().roundUp(nBits); | |
| } |
For example, when nBits = 2 and position = 17, it should return 17 rather than 8.
| // Grab the trace ancestor's expected position. | ||
| Position traceAncestorPos = _global ? _pos.traceAncestor() : _pos.traceAncestorBounded(SPLIT_DEPTH); | ||
| Position traceAncestorPos = _global | ||
| ? traceAncestorV2(_pos) : _pos.traceAncestorBounded(findFirstValueDepth(SPLIT_DEPTH)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we assume SPLIT_DEPTH % nBits == 0, I believe code can be
| ? traceAncestorV2(_pos) : _pos.traceAncestorBounded(findFirstValueDepth(SPLIT_DEPTH)); | |
| ? traceAncestor(_pos).roundUp(nBits): _pos.traceAncestorBounded(SPLIT_DEPTH + nBits - 1).roundUp(nBits); |
where
function roundUp(Position _position, uint256 _nBits) internal pure returns (Position _roundUp) {
_roundUp = _position;
for (uint64 start = _roundUp.depth(); start % _nBits != 0; start++) {
_roundUp = _roundUp.right();
}
return _roundUp;
}
or
function roundUp(Position _position, uint256 _nBits) internal pure returns (Position _roundUp) {
uint256 targetDepth = _position.depth();
if (targetDepth % _nBits != 0) {
targetDepth = targetDepth + _nBits - targetDepth % nBits;
}
return _position.rightIndex(targetDepth);
}
| function _traceAncestorV2(Position _position, uint256 _intervalDepth) | ||
| internal | ||
| pure | ||
| returns (Position ancestor_) | ||
| { | ||
| if (_position.depth() % _intervalDepth != 0 || _position.depth() < _intervalDepth) { | ||
| revert InvalidClaim(); | ||
| } | ||
| ancestor_ = _position.traceAncestor(); | ||
| // Position 1 is not the value submitted by the Actors. | ||
| if (1 == ancestor_.raw()) { | ||
| return ancestor_; | ||
| } | ||
| return _firstValidPosition(ancestor_, _intervalDepth); | ||
| } |
Check failure
Code scanning / Slither
Weak PRNG
| pure | ||
| returns (Position ancestor_) | ||
| { | ||
| if (_position.depth() % _intervalDepth != 0 || _position.depth() < _intervalDepth) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think _traceAncestorV2(pos, 1) should behave the same as _traceAncestor, which accept
| revert InvalidClaim(); | ||
| } | ||
| ancestor_ = _position.traceAncestor(); | ||
| // Position 1 is not the value submitted by the Actors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure of the comment's meaning. In addition, I do not think we need a special check for 1 == ancestor_.raw()
| /// @param _position Current location | ||
| /// @param _intervalDepth The depth of the interval with each submission. | ||
| /// @return first_ First valid location | ||
| function _firstValidPosition(Position _position, uint256 _intervalDepth) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
first may be confusing since it can be vertical (depth) or horizontal.
I think we can use validRightIndex or firstValidRightIndex.
| function _firstValidRightIndex(Position _position, uint256 _intervalDepth) | ||
| internal | ||
| pure | ||
| returns (Position first_) | ||
| { | ||
| first_ = _position; | ||
| for (uint64 start = first_.depth(); start % _intervalDepth != 0; start++) { | ||
| first_ = first_.right(); | ||
| } | ||
| } |
Check failure
Code scanning / Slither
Weak PRNG
| /// @param _position Current location | ||
| /// @param _intervalDepth The depth of the interval with each submission. | ||
| /// @return first_ First valid location | ||
| function _firstValidRightIndex(Position _position, uint256 _intervalDepth) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may be moved to LibPosition.sol
|
fix by #35 |
No description provided.