Skip to content
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

Closed
wants to merge 17 commits into from
Closed

blobToSharesV0 #327

wants to merge 17 commits into from

Conversation

S1nus
Copy link
Contributor

@S1nus S1nus commented Aug 5, 2024

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

    • Introduced a configuration option for file system permissions, allowing read access to the current directory.
    • Added functionality for creating and manipulating shares of data blobs with a structured approach in the Commitment module.
    • Implemented a testing framework for the Commitment module, ensuring reliability through comprehensive test cases.
    • Added a function for validating reserved namespaces, enhancing namespace management.
    • Changed a function's visibility in the BinaryMerkleTree and NamespaceMerkleTree libraries, allowing broader integration.
  • Bug Fixes

    • Improved the handling of namespace reservations for better data integrity.

Copy link

coderabbitai bot commented Aug 5, 2024

Walkthrough

The recent updates enhance configuration capabilities by adding file system permissions in foundry.toml. A new Solidity contract, Commitment.sol, facilitates effective data sharing and namespace management. The accompanying testing contract, Commitment.t.sol, ensures the correctness of the Commitment module's functionalities. Additionally, the Types.sol file now includes an isReservedNamespace function, improving namespace validation. Overall, these changes promote better management and functionality for the application.

Changes

File Path Change Summary
foundry.toml Added fs_permissions entry for file system access configuration.
src/lib/commitment/{Commitment.sol, test/Commitment.t.sol} Introduced functions for managing shares, including byte manipulation and testing for correctness.
src/lib/tree/{namespace/NamespaceMerkleTree.sol, binary/BinaryMerkleTree.sol} Changed function visibility from private to public to enhance access.
src/lib/tree/Types.sol Added isReservedNamespace function for improved namespace validation.

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
Loading

Poem

🐇 In the burrow deep, where changes weave,
New permissions bloom, a gift to believe.
With shares in hand, our data does flow,
A namespace dance, watch it grow!
Hopping with joy, we celebrate the light,
For every new feature makes our warren bright! 🌟


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?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@S1nus S1nus added the enhancement New feature or request label Aug 5, 2024
Copy link

@coderabbitai coderabbitai bot left a 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

Commits

Files that changed from the base of the PR and between 57c8c01 and c13cba6.

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 values upper and lower 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 and lower are accurately defined in src/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 the bytesToSharesV0 function. Ensure that the test vectors in testVectors.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 the startingSequence 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.

Comment on lines 79 to 117
// 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;
}
Copy link

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.

Suggested change
// 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;
}

Copy link

@coderabbitai coderabbitai bot left a 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

Commits

Files that changed from the base of the PR and between c13cba6 and 396eca4.

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

Copy link

@coderabbitai coderabbitai bot left a 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

Commits

Files that changed from the base of the PR and between 396eca4 and 9fde028.

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

Copy link

@coderabbitai coderabbitai bot left a 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

Commits

Files that changed from the base of the PR and between 9fde028 and bdf6d18.

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

Copy link

@coderabbitai coderabbitai bot left a 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

Commits

Files that changed from the base of the PR and between bdf6d18 and 9ecf545.

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.

Comment on lines 153 to 161
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]);

}
Copy link

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?

Copy link

@coderabbitai coderabbitai bot left a 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

Commits

Files that changed from the base of the PR and between 9ecf545 and 902471c.

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 to public.

Changing the visibility of computeNMTRoot from private to public 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.

Copy link

@coderabbitai coderabbitai bot left a 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

Commits

Files that changed from the base of the PR and between 902471c and c1bb1a4.

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 the Commitment 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.

Comment on lines +68 to +79
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);
}
Copy link

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);

Copy link

@coderabbitai coderabbitai bot left a 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

Commits

Files that changed from the base of the PR and between c1bb1a4 and fab0080.

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

Copy link
Member

@evan-forbes evan-forbes left a 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

@S1nus S1nus closed this Aug 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants