Skip to content

Conversation

@hanabi1224
Copy link
Contributor

@hanabi1224 hanabi1224 commented Aug 8, 2025

Summary of changes

This PR adds integration test for BeaconEntry::get_heap_size to compare the result with dhat::Alloc stats

Changes introduced in this pull request:

Reference issue to close (if applicable)

Closes

Other information and links

Change checklist

  • I have performed a self-review of my own code,
  • I have made corresponding changes to the documentation. All new code adheres to the team's documentation standards,
  • I have added tests that prove my fix is effective or that my feature works (if possible),
  • I have made sure the CHANGELOG is up-to-date. All user-facing changes should be reflected in this document.

Summary by CodeRabbit

  • New Features

    • Added a new test to verify heap size calculations for BeaconEntry instances using heap profiling.
    • Introduced a new public submodule for easier access to BeaconEntry.
  • Chores

    • Updated and added dependencies related to heap profiling and size measurement in configuration files.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 8, 2025

Walkthrough

This change introduces new development and workspace dependencies (dhat and get-size2), adds a new interop test leveraging heap profiling and size measurement, and exposes the BeaconEntry type via a new submodule for test access. No modifications to existing public interfaces were made.

Changes

Cohort / File(s) Change Summary
Workspace Dependency Updates
Cargo.toml
Added dhat and get-size2 to [workspace.dependencies]; updated [dependencies] to use workspace reference for get-size2.
Interop Test Dependency Additions
interop-tests/Cargo.toml
Added dhat and get-size2 as [dev-dependencies]; updated forest dev-dependency to include "rustalloc" feature.
New Heap Profiling Interop Test
interop-tests/tests/dhat_get_size_beacon_entry.rs
Added a test that uses dhat to profile heap allocations of BeaconEntry instances and checks against get-size2 measurements.
Test-Only Module Exposure
src/lib.rs
Added a submodule under interop_tests_private to re-export BeaconEntry for test access.

Sequence Diagram(s)

sequenceDiagram
    participant Test as dhat_get_size_beacon_entry.rs
    participant Allocator as dhat (global allocator)
    participant Beacon as BeaconEntry
    participant GetSize as get-size2

    Test->>Allocator: Start heap profiling
    Test->>Beacon: Create BeaconEntry instance(s)
    Test->>GetSize: Call get_heap_size() on BeaconEntry
    Test->>Allocator: Query HeapStats (current_bytes)
    Test->>Test: Assert HeapStats ≈ get_heap_size()
    Test->>Beacon: Modify vector capacity (reserve, shrink_to_fit)
    Test->>Allocator: Query HeapStats again
    Test->>GetSize: Call get_heap_size() on Vec<BeaconEntry>
    Test->>Test: Assert HeapStats ≈ get_heap_size()
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes


📜 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 5f16ad4 and a82fdec.

📒 Files selected for processing (1)
  • interop-tests/tests/dhat_get_size_beacon_entry.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • interop-tests/tests/dhat_get_size_beacon_entry.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: Build forest binaries on Linux AMD64
  • GitHub Check: tests-release
  • GitHub Check: tests
  • GitHub Check: Build Ubuntu
  • GitHub Check: cargo-publish-dry-run
  • GitHub Check: Build MacOS
  • GitHub Check: All lint checks
  • GitHub Check: Analyze (rust)
  • GitHub Check: Analyze (go)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch hm/test-get-size-for-beacon-entry

🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
  • 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 explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests 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.

@hanabi1224 hanabi1224 force-pushed the hm/test-get-size-for-beacon-entry branch from 5fcf065 to 9872c83 Compare August 8, 2025 07:56
@hanabi1224 hanabi1224 force-pushed the hm/test-get-size-for-beacon-entry branch from 9872c83 to 3f435ea Compare August 8, 2025 07:56
@hanabi1224 hanabi1224 marked this pull request as ready for review August 8, 2025 07:57
@hanabi1224 hanabi1224 requested a review from a team as a code owner August 8, 2025 07:57
@hanabi1224 hanabi1224 requested review from LesnyRumcajs and elmattic and removed request for a team August 8, 2025 07:57
elmattic
elmattic previously approved these changes Aug 8, 2025
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: 1

🧹 Nitpick comments (1)
interop-tests/tests/dhat_get_size_beacon_entry.rs (1)

15-18: Avoid brittle constant (10); rely on GetSize

Hardcoding 10 bytes assumes exact allocator behavior and Vec capacity. The next assertion already compares against b.get_heap_size(). Drop the literal to reduce brittleness.

     let stats = dhat::HeapStats::get();
-    dhat::assert_eq!(stats.curr_bytes, 10);
     dhat::assert_eq!(stats.curr_bytes, b.get_heap_size());
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 163eeb4 and 3f435ea.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • Cargo.toml (2 hunks)
  • interop-tests/Cargo.toml (1 hunks)
  • interop-tests/tests/dhat_get_size_beacon_entry.rs (1 hunks)
  • src/lib.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-08-07T13:39:15.080Z
Learnt from: hanabi1224
PR: ChainSafe/forest#5886
File: interop-tests/src/tests/go_app/gen.go:29-29
Timestamp: 2025-08-07T13:39:15.080Z
Learning: Auto-generated files like those created by rust2go (indicated by "Generated by rust2go. Please DO NOT edit this C part manually." comment) in the Forest project should be skipped during code review as they are not intended for manual editing.

Applied to files:

  • interop-tests/Cargo.toml
📚 Learning: 2025-08-06T15:42:43.520Z
Learnt from: LesnyRumcajs
PR: ChainSafe/forest#5907
File: Cargo.toml:25-36
Timestamp: 2025-08-06T15:42:43.520Z
Learning: Forest project requires fvm_ipld_amt version 0.7.5 functionality which is available in the Git revision a633547ae414a333b2d076beef87d4d30cdb7fb4 of the ref-fvm repository, but version 0.7.5 is not yet published to crates.io (only 0.7.4 is available). The Git patch must remain until 0.7.5 is published.

Applied to files:

  • interop-tests/Cargo.toml
  • src/lib.rs
  • Cargo.toml
📚 Learning: 2025-08-06T15:42:43.520Z
Learnt from: LesnyRumcajs
PR: ChainSafe/forest#5907
File: Cargo.toml:25-36
Timestamp: 2025-08-06T15:42:43.520Z
Learning: The fvm_ipld_amt crate version 0.7.5 is required for the Forest project, but it's not yet published to crates.io, which is why the Git patch pointing to the ref-fvm repository is still necessary.

Applied to files:

  • interop-tests/Cargo.toml
  • src/lib.rs
  • Cargo.toml
📚 Learning: 2025-07-17T15:21:40.753Z
Learnt from: hanabi1224
PR: ChainSafe/forest#5841
File: src/utils/get_size/mod.rs:10-10
Timestamp: 2025-07-17T15:21:40.753Z
Learning: The get_size2 crate's GetSize trait provides default implementations: get_stack_size() uses std::mem::size_of, get_heap_size() returns 0, and get_size() returns their sum. An empty impl like `impl GetSize for MyType {}` is valid and uses these defaults, making it suitable for simple wrapper types that don't allocate heap memory.

Applied to files:

  • interop-tests/tests/dhat_get_size_beacon_entry.rs
📚 Learning: 2025-08-04T13:36:22.993Z
Learnt from: hanabi1224
PR: ChainSafe/forest#5835
File: src/chain/tests.rs:58-76
Timestamp: 2025-08-04T13:36:22.993Z
Learning: In the Forest codebase, `Vec<u8>` can be used as an `AsyncWrite` implementation in test contexts. The user confirmed that tests using `&mut Vec<u8>` with `export` and `export_v2` functions compile and pass both locally and on CI.

Applied to files:

  • interop-tests/tests/dhat_get_size_beacon_entry.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: cargo-publish-dry-run
  • GitHub Check: Build MacOS
  • GitHub Check: Build Ubuntu
  • GitHub Check: All lint checks
  • GitHub Check: Build forest binaries on Linux AMD64
  • GitHub Check: tests-release
  • GitHub Check: tests
  • GitHub Check: Analyze (rust)
  • GitHub Check: Analyze (go)
🔇 Additional comments (5)
Cargo.toml (2)

17-20: Workspace-scoped dhat and get-size2 look good

Keeping dhat only as a workspace dependency and consuming it from interop-tests avoids pulling it into the main crate. Unifying get-size2 with the "derive" feature at the workspace level prevents version drift across crates.


96-96: Switch to workspace-managed get-size2

Referencing get-size2 via workspace = true here ensures a single feature set and version across the workspace.

interop-tests/Cargo.toml (1)

16-24: Dev-only additions align with test intent

Adding dhat and get-size2 as dev-dependencies is appropriate for the heap profiling test. No impact on production builds.

src/lib.rs (1)

116-118: Minimal, feature-gated re-export is appropriate

Exposing only BeaconEntry under interop_tests_private::beacon keeps surface area tight and test-focused. Good separation.

interop-tests/tests/dhat_get_size_beacon_entry.rs (1)

7-9: Ignore global allocator collision warning

The only #[global_allocator] declarations are in two separate crates:

  • src/lib.rs (Jemalloc)
  • interop-tests/tests/dhat_get_size_beacon_entry.rs (dhat::Alloc)

Integration tests are built as independent binaries (separate processes), so each crate has exactly one global allocator and there’s no cross-crate or concurrent allocator interference. No changes required.

Likely an incorrect or invalid review comment.

Comment on lines 25 to 41
let stats = dhat::HeapStats::get();
assert!(v.capacity() >= v.len());
dhat::assert_eq!(stats.curr_bytes, 32 * v.capacity() + 60);
dhat::assert_eq!(stats.curr_bytes, v.get_heap_size());

v.reserve_exact(100);

let stats = dhat::HeapStats::get();
assert!(v.capacity() >= 100 + v.len());
dhat::assert_eq!(stats.curr_bytes, 32 * v.capacity() + 60);
dhat::assert_eq!(stats.curr_bytes, v.get_heap_size());

v.shrink_to_fit();
let stats = dhat::HeapStats::get();
assert_eq!(v.capacity(), v.len());
dhat::assert_eq!(stats.curr_bytes, 32 * v.capacity() + 60);
dhat::assert_eq!(stats.curr_bytes, v.get_heap_size());
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Compute sizes dynamically; don’t assume BeaconEntry is 32 bytes or that shrink_to_fit is exact

  • Replace the magic 32 with size_of::<BeaconEntry>() to be arch- and layout-safe.
  • Replace the magic 60 with a sum of element heap sizes.
  • shrink_to_fit is a non-binding request; some allocators may keep spare capacity. Avoid asserting capacity == len.
-    let stats = dhat::HeapStats::get();
-    assert!(v.capacity() >= v.len());
-    dhat::assert_eq!(stats.curr_bytes, 32 * v.capacity() + 60);
-    dhat::assert_eq!(stats.curr_bytes, v.get_heap_size());
+    let stats = dhat::HeapStats::get();
+    let entry_size = core::mem::size_of::<BeaconEntry>();
+    let inner_bytes = v.iter().map(GetSize::get_heap_size).sum::<usize>();
+    assert!(v.capacity() >= v.len());
+    dhat::assert_eq!(stats.curr_bytes, entry_size * v.capacity() + inner_bytes);
+    dhat::assert_eq!(stats.curr_bytes, v.get_heap_size());

     v.reserve_exact(100);

-    let stats = dhat::HeapStats::get();
-    assert!(v.capacity() >= 100 + v.len());
-    dhat::assert_eq!(stats.curr_bytes, 32 * v.capacity() + 60);
-    dhat::assert_eq!(stats.curr_bytes, v.get_heap_size());
+    let stats = dhat::HeapStats::get();
+    let entry_size = core::mem::size_of::<BeaconEntry>();
+    let inner_bytes = v.iter().map(GetSize::get_heap_size).sum::<usize>();
+    assert!(v.capacity() >= 100 + v.len());
+    dhat::assert_eq!(stats.curr_bytes, entry_size * v.capacity() + inner_bytes);
+    dhat::assert_eq!(stats.curr_bytes, v.get_heap_size());

     v.shrink_to_fit();
     let stats = dhat::HeapStats::get();
-    assert_eq!(v.capacity(), v.len());
-    dhat::assert_eq!(stats.curr_bytes, 32 * v.capacity() + 60);
-    dhat::assert_eq!(stats.curr_bytes, v.get_heap_size());
+    // Non-binding: capacity may remain >= len on some allocators.
+    assert!(v.capacity() >= v.len());
+    let entry_size = core::mem::size_of::<BeaconEntry>();
+    let inner_bytes = v.iter().map(GetSize::get_heap_size).sum::<usize>();
+    dhat::assert_eq!(stats.curr_bytes, entry_size * v.capacity() + inner_bytes);
+    dhat::assert_eq!(stats.curr_bytes, v.get_heap_size());

To support this, add the import near the other use lines:

 use forest::interop_tests_private::beacon::BeaconEntry;
 use get_size2::GetSize;
+use core::mem;
🤖 Prompt for AI Agents
In interop-tests/tests/dhat_get_size_beacon_entry.rs around lines 25 to 41,
replace the hardcoded size 32 with size_of::<BeaconEntry>() to dynamically
compute element size, and replace the fixed 60 with a calculation of the sum of
element heap sizes for accuracy. Remove or modify the assertion that capacity
equals length after shrink_to_fit, since shrink_to_fit is not guaranteed to
reduce capacity exactly to length. Also, add the necessary import for size_of
near the other use statements.

@LesnyRumcajs
Copy link
Member

no green checkmark, no review!

Copy link
Member

@LesnyRumcajs LesnyRumcajs left a comment

Choose a reason for hiding this comment

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

Nice, I didn't know about this crate. I guess it might've been useful for profiling, though I'm not sure it adds to any other tools I used.

@hanabi1224 hanabi1224 enabled auto-merge August 8, 2025 09:54
@hanabi1224 hanabi1224 requested a review from elmattic August 8, 2025 11:35
@hanabi1224 hanabi1224 added this pull request to the merge queue Aug 11, 2025
Merged via the queue into main with commit a0de302 Aug 11, 2025
43 checks passed
@hanabi1224 hanabi1224 deleted the hm/test-get-size-for-beacon-entry branch August 11, 2025 09:06
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.

4 participants