Skip to content

Conversation

@fbac
Copy link
Collaborator

@fbac fbac commented Apr 22, 2025

Closes #726

I'd assume our code will always run in 64 bit hardware, but it's non cost to also make this package compatible with 32 bits, as we don't expect such huge trees anyway.

Summary by CodeRabbit

  • Bug Fixes
    • Improved input validation for node count limits, now using signed 32-bit integer boundaries for more accurate error handling.
    • Updated error messages to clearly indicate the new maximum allowed value.
  • Tests
    • Adjusted tests to check for the updated error message and relaxed the assertion to allow for message changes.

@fbac fbac requested a review from a team as a code owner April 22, 2025 09:32
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 22, 2025

Walkthrough

The changes update the internal handling of node count parameters in the Merkle tree implementation from unsigned 32-bit integers (uint32) to signed integers (int). This includes modifying function signatures, error checks, and bitwise operations to use int. Error messages and corresponding tests are updated to reflect the new validation logic, ensuring that counts do not exceed the maximum value of a signed 32-bit integer. The test assertions are also adjusted to accommodate the revised error messages.

Changes

Files / Paths Change Summary
pkg/merkle/tree.go Updated CalculateBalancedNodesCount and roundUpToPowerOf2 to use int instead of uint32. Changed error checks and messages accordingly. Updated bitwise operations to work with int.
pkg/merkle/tree_test.go Modified test to check for updated error message substring instead of exact string match.

Assessment against linked issues

Objective Addressed Explanation
Unify types in Merkle tree logic to uint64 or handle both architectures (#726) Code changes switch to int, not uint64, and do not handle both int and uint64.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (1.64.8)

Error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2
Failed executing command with error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1569bf7 and d88b88d.

📒 Files selected for processing (2)
  • pkg/merkle/tree.go (1 hunks)
  • pkg/merkle/tree_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/merkle/tree_test.go
  • pkg/merkle/tree.go
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Push Docker Images to GitHub Packages (xmtpd-cli)
  • GitHub Check: Upgrade Tests
  • GitHub Check: Push Docker Images to GitHub Packages (xmtpd)
  • GitHub Check: Test (Node)
  • GitHub Check: Code Review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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>, please review it.
    • 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @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 using 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 generate docstrings to generate docstrings for this 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.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

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.

@macroscopeapp
Copy link

macroscopeapp bot commented Apr 22, 2025

Update merkle.CalculateBalancedNodesCount to handle int type and adjust maximum count to 2^31-1

  • Modify CalculateBalancedNodesCount in tree.go to use int type instead of uint32 and adjust maximum allowed count to 2^31-1
  • Update roundUpToPowerOf2 helper function to work with int type instead of uint32
  • Revise error message in tree_test.go to include the actual maximum value and use partial matching in assertions

📍Where to Start

Start with the CalculateBalancedNodesCount function in tree.go which contains the core logic changes for handling int type and maximum count adjustment.


Macroscope summarized d88b88d.

Copy link
Contributor

@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

🧹 Nitpick comments (1)
pkg/merkle/tree.go (1)

288-289: Consider revising error message grammar.

The error message uses awkward phrasing with "less or equal than". While functionally correct, it would be more natural to say "less than or equal to" which is standard English.

-		return 0, fmt.Errorf("count must be less or equal than max int32 (%d)", 1<<31-1)
+		return 0, fmt.Errorf("count must be less than or equal to max int32 (%d)", 1<<31-1)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 25c7dd3 and c237d3a.

📒 Files selected for processing (2)
  • pkg/merkle/tree.go (1 hunks)
  • pkg/merkle/tree_test.go (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Push Docker Images to GitHub Packages (xmtpd-cli)
  • GitHub Check: Test (Node)
  • GitHub Check: Code Review
  • GitHub Check: Upgrade Tests
  • GitHub Check: Push Docker Images to GitHub Packages (xmtpd)
🔇 Additional comments (5)
pkg/merkle/tree.go (3)

282-283: Function documentation correctly updated.

The documentation now properly reflects that the function returns an error if the count is too large for an int32 representation, aligning with the change from uint32 to int.


292-292: Function call correctly updated to match new signature.

The call to roundUpToPowerOf2 properly passes the int parameter, which aligns with the updated function signature.


296-297: Appropriate type conversion for bit counting.

The function type has been changed from uint32 to int, and the bit counting logic has been properly updated to use bits.OnesCount with an explicit cast to uint. This maintains the functionality while supporting the type change.

pkg/merkle/tree_test.go (2)

440-440: Test assertion correctly updated to match new error message.

The assertion has been updated to check for the new error message used in the implementation, maintaining test coverage for the maximum size validation.


437-439:

Details

✅ Verification successful

Verify handling of large values.

The test properly verifies the function rejects values larger than int32 maximum. This is critical for the PR's goal of ensuring compatibility with 32-bit systems.


🏁 Script executed:

#!/bin/bash
# Check if there are other test cases that might need updating due to the uint32 to int type change

echo "Checking for potentially affected tests:"
rg --no-heading "uint32" pkg/merkle/

Length of output: 273


All large-value test cases are correctly handled

  • Only two references to uint32 appear in pkg/merkle/tree_test.go (the comment and the massiveInput declaration on lines 437–439).
  • No other tests use uint32, so no further updates are required.
  • This test ensures CalculateBalancedNodesCount returns an error for values exceeding 32‑bit limits.

@fbac fbac force-pushed the 04-22-merkle_fixes branch from c237d3a to 1569bf7 Compare April 22, 2025 09:35
@fbac fbac force-pushed the 04-22-merkle_fixes branch from 1569bf7 to d88b88d Compare April 22, 2025 09:42
// roundUpToPowerOf2 rounds up a number to the next power of 2.
func roundUpToPowerOf2(n uint32) uint32 {
if bits.OnesCount32(n) == 1 {
func roundUpToPowerOf2(n int) int {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai is this function correct for 64 bit numbers?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No description provided.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai try again

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mkysel Looking at the updated CalculateBalancedNodesCount function more carefully:

The function is correctly implemented but with a deliberate 32-bit integer limit, even on 64-bit systems. Here's why:

  1. On a 64-bit system, Go's int type can theoretically hold values up to 2^63-1
  2. However, the function explicitly checks if count > 1<<31-1 (max int32 value)
  3. This intentionally limits input to 31-bit positive integers regardless of platform

To fully utilize 64-bit integers on 64-bit systems, you would need to:

  • Replace the check with if count > 1<<63-1 (for max int64)
  • The updated roundUpToPowerOf2 function would already handle 64-bit numbers correctly with its bits.OnesCount(uint(n)) call

According to the PR description, this limitation is by design since "the code does not expect to handle very large trees."


🧠 Learnings used
Learnt from: fbac
PR: xmtp/xmtpd#712
File: pkg/merkle/proof.go:291-311
Timestamp: 2025-04-17T11:38:12.315Z
Learning: In the Merkle tree implementation, padded leaves (added to make leaf count a power of 2) are considered valid and should be taken into account for bounds checking. These padded leaves are initialized as empty byte arrays (`[]byte{}`) and can be accessed through indices. The validation should use `balancedLeafCount` (which includes padding) rather than just `leafCount` (actual leaves).

@xmtp xmtp deleted a comment from coderabbitai bot Apr 22, 2025
@fbac fbac merged commit a657935 into main Apr 22, 2025
8 checks passed
@fbac fbac deleted the 04-22-merkle_fixes branch April 22, 2025 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Merkle Tree: unify types to uint64

3 participants