-
Notifications
You must be signed in to change notification settings - Fork 40
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
blobToSharesV0 #327
blobToSharesV0 #327
Conversation
v1.8.2
WalkthroughThe recent updates enhance configuration capabilities by adding file system permissions in Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Commitment
participant NamespaceHandler
User->>Commitment: Call bytesToSharesV0(blobData, namespace)
Commitment->>NamespaceHandler: Check if reserved namespace
NamespaceHandler-->>Commitment: Return validation result
Commitment->>Commitment: Allocate shares and write metadata
Commitment-->>User: Return shares and error flag
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configuration File (
|
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.
Actionable comments posted: 1
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (4)
- foundry.toml (1 hunks)
- src/lib/commitment/Commitment.sol (1 hunks)
- src/lib/commitment/test/Commitment.t.sol (1 hunks)
- src/lib/tree/Types.sol (1 hunks)
Additional comments not posted (11)
foundry.toml (1)
5-5
: LGTM! Verify the necessity of the added permission.The addition of
fs_permissions
looks good. Ensure that the read access to the current directory is necessary for the application's operations.src/lib/tree/Types.sol (1)
31-35
: LGTM! Verify the boundary values and function usage.The
isReservedNamespace
function appears to be correctly implemented. Ensure that the boundary valuesupper
andlower
are accurate and that the function is used correctly in the codebase.Verification successful
LGTM! The
isReservedNamespace
function and its boundary values are correctly implemented and used in the codebase.
- The function is used in
src/lib/commitment/Commitment.sol
.- The boundary values
upper
andlower
are accurately defined insrc/lib/tree/Types.sol
.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the usage of `isReservedNamespace` and the accuracy of boundary values. # Test: Search for the function usage. Expect: Correct usage of the function. rg --type solidity -A 5 $'isReservedNamespace' # Test: Ensure boundary values are accurate. Expect: No discrepancies in the values. rg --type solidity -A 5 $'hex"00000000000000000000000000000000000000000000000000000000FF"' rg --type solidity -A 5 $'hex"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00"'Length of output: 328
Script:
#!/bin/bash # Description: Verify the usage of `isReservedNamespace` and the accuracy of boundary values. # Find all Solidity files fd -e sol > solidity_files.txt # Test: Search for the function usage. Expect: Correct usage of the function. xargs -a solidity_files.txt rg -A 5 'isReservedNamespace' # Test: Ensure boundary values are accurate. Expect: No discrepancies in the values. xargs -a solidity_files.txt rg -A 5 'hex"00000000000000000000000000000000000000000000000000000000FF"' xargs -a solidity_files.txt rg -A 5 'hex"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00"'Length of output: 2430
src/lib/commitment/test/Commitment.t.sol (1)
1-67
: LGTM! Verify the correctness of the test vectors.The test file
Commitment.t.sol
looks good and thoroughly tests thebytesToSharesV0
function. Ensure that the test vectors intestVectors.json
are correct and comprehensive.src/lib/commitment/Commitment.sol (8)
10-19
: LGTM!The
reverse
function correctly converts a little-endian uint32 to big-endian using bitwise operations.
21-23
: LGTM!The
div_ceil
function correctly performs ceiling division of two uint256 numbers.
25-27
: LGTM!The
num_shares
function correctly calculates the number of shares needed for a given blob size using ceiling division and a minimum blob size of 478 bytes.
29-33
: LGTM!The
copyNamespace
function correctly copies namespace bytes into a share using a for loop.
35-37
: LGTM!The
writeInfoByteV0
function correctly writes the info byte at index 29 of the share based on thestartingSequence
flag.
39-47
: LGTM!The
writeSequenceLength
function correctly writes the sequence length as a big-endian 4-byte value at indices 30-33 of the share.
49-62
: LGTM!The
copyBytes
function correctly copies data bytes into a buffer starting from the end and pads the remaining buffer with zeros if the data is exhausted.
64-77
: LGTM!The
bytesToHexString
function correctly converts a byte array to a hexadecimal string using a fixed buffer size and a lookup table for hexadecimal digits.
src/lib/commitment/Commitment.sol
Outdated
// Share Version 0 | ||
function bytesToSharesV0(bytes memory blobData, Namespace memory namespace) pure returns (bytes[] memory shares, bool err) { | ||
if (namespace.version != 0) { | ||
return (new bytes[](0), true); | ||
} | ||
if (isReservedNamespace(namespace)) { | ||
return (new bytes[](0), true); | ||
} | ||
// Allocate memory for the shares | ||
uint256 numShares = num_shares(blobData.length); | ||
bytes[] memory _shares = new bytes[](numShares); | ||
for (uint256 i = 0; i < _shares.length; i++) { | ||
_shares[i] = new bytes(512); | ||
} | ||
// Get the namespace bytes | ||
bytes29 namespaceBytes = namespace.toBytes(); | ||
|
||
// The first share is special, because it has startingSequence set to true and the 4-byte sequence length | ||
copyNamespace(_shares[0], namespaceBytes); | ||
writeInfoByteV0(_shares[0], true); | ||
writeSequenceLength(_shares[0], uint32(blobData.length)); | ||
uint32 cursor = 0; | ||
cursor = copyBytes(_shares[0], cursor, blobData, uint32(478)); //only 478 bytes, because 4 bytes are used for the sequence length | ||
|
||
if (shares.length != 1) { | ||
// The remaining shares are all the same | ||
for (uint256 i = 1; i < _shares.length; i++) { | ||
// Copy the namespace | ||
copyNamespace(_shares[i], namespaceBytes); | ||
// Write the info byte | ||
writeInfoByteV0(_shares[i], false); | ||
// Copy the data | ||
cursor = copyBytes(_shares[i], cursor, blobData, uint32(482)); // copy the full 482 bytes | ||
} | ||
} | ||
|
||
shares = _shares; | ||
err = false; | ||
} |
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.
Handle the case where blobData
is empty.
The bytesToSharesV0
function does not handle the case where blobData
is empty. This could lead to unexpected behavior or errors.
+ if (blobData.length == 0) {
+ return (new bytes[](0), true);
+ }
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
// Share Version 0 | |
function bytesToSharesV0(bytes memory blobData, Namespace memory namespace) pure returns (bytes[] memory shares, bool err) { | |
if (namespace.version != 0) { | |
return (new bytes[](0), true); | |
} | |
if (isReservedNamespace(namespace)) { | |
return (new bytes[](0), true); | |
} | |
// Allocate memory for the shares | |
uint256 numShares = num_shares(blobData.length); | |
bytes[] memory _shares = new bytes[](numShares); | |
for (uint256 i = 0; i < _shares.length; i++) { | |
_shares[i] = new bytes(512); | |
} | |
// Get the namespace bytes | |
bytes29 namespaceBytes = namespace.toBytes(); | |
// The first share is special, because it has startingSequence set to true and the 4-byte sequence length | |
copyNamespace(_shares[0], namespaceBytes); | |
writeInfoByteV0(_shares[0], true); | |
writeSequenceLength(_shares[0], uint32(blobData.length)); | |
uint32 cursor = 0; | |
cursor = copyBytes(_shares[0], cursor, blobData, uint32(478)); //only 478 bytes, because 4 bytes are used for the sequence length | |
if (shares.length != 1) { | |
// The remaining shares are all the same | |
for (uint256 i = 1; i < _shares.length; i++) { | |
// Copy the namespace | |
copyNamespace(_shares[i], namespaceBytes); | |
// Write the info byte | |
writeInfoByteV0(_shares[i], false); | |
// Copy the data | |
cursor = copyBytes(_shares[i], cursor, blobData, uint32(482)); // copy the full 482 bytes | |
} | |
} | |
shares = _shares; | |
err = false; | |
} | |
// Share Version 0 | |
function bytesToSharesV0(bytes memory blobData, Namespace memory namespace) pure returns (bytes[] memory shares, bool err) { | |
if (namespace.version != 0) { | |
return (new bytes[](0), true); | |
} | |
if (isReservedNamespace(namespace)) { | |
return (new bytes[](0), true); | |
} | |
if (blobData.length == 0) { | |
return (new bytes[](0), true); | |
} | |
// Allocate memory for the shares | |
uint256 numShares = num_shares(blobData.length); | |
bytes[] memory _shares = new bytes[](numShares); | |
for (uint256 i = 0; i < _shares.length; i++) { | |
_shares[i] = new bytes(512); | |
} | |
// Get the namespace bytes | |
bytes29 namespaceBytes = namespace.toBytes(); | |
// The first share is special, because it has startingSequence set to true and the 4-byte sequence length | |
copyNamespace(_shares[0], namespaceBytes); | |
writeInfoByteV0(_shares[0], true); | |
writeSequenceLength(_shares[0], uint32(blobData.length)); | |
uint32 cursor = 0; | |
cursor = copyBytes(_shares[0], cursor, blobData, uint32(478)); //only 478 bytes, because 4 bytes are used for the sequence length | |
if (shares.length != 1) { | |
// The remaining shares are all the same | |
for (uint256 i = 1; i < _shares.length; i++) { | |
// Copy the namespace | |
copyNamespace(_shares[i], namespaceBytes); | |
// Write the info byte | |
writeInfoByteV0(_shares[i], false); | |
// Copy the data | |
cursor = copyBytes(_shares[i], cursor, blobData, uint32(482)); // copy the full 482 bytes | |
} | |
} | |
shares = _shares; | |
err = false; | |
} |
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.
Actionable comments posted: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- src/lib/commitment/Commitment.sol (1 hunks)
Files skipped from review as they are similar to previous changes (1)
- src/lib/commitment/Commitment.sol
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.
Actionable comments posted: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- src/lib/commitment/Commitment.sol (1 hunks)
Files skipped from review as they are similar to previous changes (1)
- src/lib/commitment/Commitment.sol
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.
Actionable comments posted: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (2)
- lib/ds-test (1 hunks)
- src/lib/commitment/Commitment.sol (1 hunks)
Files skipped from review due to trivial changes (1)
- lib/ds-test
Files skipped from review as they are similar to previous changes (1)
- src/lib/commitment/Commitment.sol
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.
Actionable comments posted: 1
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (2)
- src/lib/commitment/Commitment.sol (1 hunks)
- src/lib/commitment/test/Commitment.t.sol (1 hunks)
Additional comments not posted (13)
src/lib/commitment/test/Commitment.t.sol (4)
18-29
: LGTM!The
fromHexChar
function correctly converts a hexadecimal character to its integer value and handles invalid inputs appropriately.
31-39
: LGTM!The
fromHex
function correctly converts a hexadecimal string to a byte array, ensuring the string length is even.
41-43
: LGTM!The
compareStrings
function efficiently compares two strings using keccak256 hashing.
45-65
: LGTM!The
testBytesToSharesV0
function thoroughly tests the_bytesToSharesV0
function using test vectors, ensuring correctness.src/lib/commitment/Commitment.sol (9)
10-12
: LGTM!The
_divCeil
function correctly performs division with ceiling rounding.
14-16
: LGTM!The
_numShares
function correctly calculates the number of shares needed for a given blob size.
18-22
: LGTM!The
_copyNamespace
function correctly copies namespace bytes into a share.
24-26
: LGTM!The
_writeInfoByteV0
function correctly writes the info byte for the starting sequence.
28-36
: LGTM!The
_writeSequenceLength
function correctly writes a 4-byte sequence length to a share.
38-51
: LGTM!The
_copyBytes
function correctly copies data into a buffer and pads with zeros if necessary.
53-66
: LGTM!The
_bytesToHexString
function correctly converts a byte array to a hexadecimal string.
68-106
: LGTM!The
_bytesToSharesV0
function correctly converts blob data to V0 shares, handling namespaces and sequence lengths appropriately.
108-114
: LGTM!The
_roundDownPowerOfTwo
function correctly rounds down to the nearest power of two.
src/lib/commitment/Commitment.sol
Outdated
function _createCommitment(bytes[] memory shares) pure returns (bytes32 commitment) { | ||
uint256 subtreeWidth = _subtreeWidth(shares.length, SUBTREE_ROOT_THRESHOLD); | ||
uint256[] treeSizes = _merkleMountainRangeSizes(shares.length, subtreeWidth); | ||
bytes[][][] leafSets = new bytes[][][](treeSizes.length); | ||
uint256 cursor = 0; | ||
for (uint256 i = 0; i < treeSizes.length; i++) { | ||
leafSets[i] = new bytes[][](treeSizes[i]); | ||
|
||
} |
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.
Complete the _createCommitment
function.
The function is incomplete and does not currently return a commitment. Ensure the implementation is completed to fulfill its intended purpose.
Would you like assistance in completing the _createCommitment
function or opening a GitHub issue to track this task?
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.
Actionable comments posted: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (3)
- src/lib/commitment/Commitment.sol (1 hunks)
- src/lib/tree/namespace/NamespaceMerkleMultiproof.sol (1 hunks)
- src/lib/tree/namespace/NamespaceMerkleTree.sol (2 hunks)
Files skipped from review due to trivial changes (1)
- src/lib/tree/namespace/NamespaceMerkleMultiproof.sol
Files skipped from review as they are similar to previous changes (1)
- src/lib/commitment/Commitment.sol
Additional comments not posted (1)
src/lib/tree/namespace/NamespaceMerkleTree.sol (1)
Line range hint
196-215
:
Consider the implications of changing function visibility topublic
.Changing the visibility of
computeNMTRoot
fromprivate
topublic
exposes it to external calls. Ensure that this change is intentional and that all inputs are validated to prevent misuse. Review any security implications and verify that exposing this function aligns with the architectural goals.
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.
Actionable comments posted: 1
Outside diff range, codebase verification and nitpick comments (3)
src/lib/commitment/test/Commitment.t.sol (3)
18-29
: Improve the error message in revert.The function
fromHexChar
has a revert statement with a generic error message. Consider providing a more descriptive message to aid debugging.- revert("fail"); + revert("Invalid hex character");
31-39
: Enhance error message in require statement.The
fromHex
function's require statement lacks a detailed error message. Providing more context can help with debugging.- require(ss.length%2 == 0); // length must be even + require(ss.length%2 == 0, "Hex string length must be even");
45-65
: Consider adding comments for clarity.The
testBytesToSharesV0
function is well-structured. Adding comments to explain key steps can improve readability and maintainability.// Example comment // Load test vectors from JSON file
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (3)
- src/lib/commitment/Commitment.sol (1 hunks)
- src/lib/commitment/test/Commitment.t.sol (1 hunks)
- src/lib/tree/binary/BinaryMerkleTree.sol (1 hunks)
Files skipped from review as they are similar to previous changes (1)
- src/lib/commitment/Commitment.sol
Additional comments not posted (4)
src/lib/commitment/test/Commitment.t.sol (3)
41-43
: String comparison implementation is correct.The
compareStrings
function correctly compares two strings using their hashes.
12-16
: Struct definition is correct.The
TestVector
struct is well-defined and appropriately used in the test functions.
9-10
: Contract setup is appropriate.The
CommitmentTest
contract is set up correctly for testing theCommitment
module.src/lib/tree/binary/BinaryMerkleTree.sol (1)
129-129
: Verify implications of visibility change to public.The
processLeaves
function's visibility change to public increases its accessibility. Ensure this change does not introduce security or integrity issues in the broader system.
function testCreateCommitmentV0() view external { | ||
string memory path = "./src/lib/commitment/test/testVectors.json"; | ||
string memory jsonData = vm.readFile(path); | ||
bytes memory vecsData = vm.parseJson(jsonData); | ||
TestVector[] memory vecs = abi.decode(vecsData, (TestVector[])); | ||
|
||
bytes29 nsString = bytes29(fromHex(vecs[0].namespace)); | ||
Namespace memory ns = toNamespace(nsString); | ||
bytes memory data = fromHex(vecs[0].data); | ||
(bytes[] memory shares, bool err) = _bytesToSharesV0(data, ns); | ||
bytes32 commitment = _createCommitment(shares, ns); | ||
} |
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.
Add assertions to validate the test.
The testCreateCommitmentV0
function lacks assertions. Consider adding checks to ensure the commitment is created correctly.
// Example assertion
// assert(commitment == expectedCommitment);
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.
Actionable comments posted: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- src/lib/commitment/Commitment.sol (1 hunks)
Files skipped from review as they are similar to previous changes (1)
- src/lib/commitment/Commitment.sol
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 don't think i have enough context to review properly, but lgtm and I don't want to block
Overview
Added a function to convert blobs to V0 shares, and tested it against the Go implementation using vectors created with this repo.
Summary by CodeRabbit
New Features
Commitment
module.Commitment
module, ensuring reliability through comprehensive test cases.BinaryMerkleTree
andNamespaceMerkleTree
libraries, allowing broader integration.Bug Fixes