-
Notifications
You must be signed in to change notification settings - Fork 12.1k
Add Memory
utility library
#5189
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
🦋 Changeset detectedLatest commit: f03d149 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
IMO this PR should include the usage of this lib |
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Its sad we missed that in 5.3, as it is not controversial. Lets fix conflicts and make sure it gets into 5.4 |
Co-authored-by: Arr00 <13561405+arr00@users.noreply.github.com>
contracts/utils/Memory.sol
Outdated
} | ||
} | ||
|
||
/// @dev Returns a `Pointer` to the content of a `bytes` buffer. Skips the length word. |
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.
Everything from here onward (line 33 to 103) was recently added with no discussion about the usecase. I was personally happy with having utils to "cleanup" memory manually, which AFAIK was the original idea behind this PR.
Some of the things here ressemble `Bytes._unsafeReadBytesOffset, which was left private (and not internal) because we could not guarantee the memory safety. This library goes way furter, with assembly marked memory safe when its not something we know (depends on the user input).
Using the copy function, its quite easy to break stuff by writting to the wrong locations (for example to 0x60).
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.
The background for these changes is that they're used by the RLP library and we previously kept private:
0332ffe#diff-0399261b2cd954212dda0147b86044380b879ab21e1d1b89c564cb48f3552216L304-L328
I agree with your take. However I think it's worth pursuing this pattern since it composes pretty well imo (as long as we add proper WARNINGS and docs). See how it looks in some places in RLP:
function readRawBytes(Item memory item) internal pure returns (bytes memory) {
uint256 itemLength = item.length;
bytes memory result = new bytes(itemLength);
result.contentPointer().copy(item.ptr, itemLength);
return result;
}
I would be fine removing these functions. Want to hear your thoughts on the pattern
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.
Rather than exposing these in Memory
when they're only used in the RLP library, maybe make them private within the RLP library?
Would also consider constraining destPtr
to be greater than fmp offset.
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.
@Amxx Worth noting the original proveth implementation does essentially the same, but manually, without mcopy
.
/*
* @param src Pointer to source
* @param dest Pointer to destination
* @param len Amount of memory to copy from the source
*/
function copy(uint src, uint dest, uint len) private pure {
if (len == 0) return;
// copy as many word sizes as possible
for (; len >= WORD_SIZE; len -= WORD_SIZE) {
assembly {
mstore(dest, mload(src))
}
src += WORD_SIZE;
dest += WORD_SIZE;
}
// left over bytes. Mask is used to remove unwanted bytes from the word
uint mask = 256 ** (WORD_SIZE - len) - 1;
assembly {
let srcpart := and(mload(src), not(mask)) // zero out src
let destpart := and(mload(dest), mask) // retrieve the bytes
mstore(dest, or(destpart, srcpart))
}
}
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 removed all new controversial functions. Opened #5792 instead. Also updated the RLP PR (#5680) accordingly as suggested @0xClandestine
Co-authored-by: Arr00 <13561405+arr00@users.noreply.github.com>
Co-authored-by: Arr00 <13561405+arr00@users.noreply.github.com>
Should be covered by #5094 |
Picked from #5094
PR Checklist
npx changeset add
)