Skip to content

fix: panic in p-diff-sync after diff chunking feature#669

Merged
lucksus merged 4 commits intodevfrom
fix/panic-after-chunked-diffs
Feb 12, 2026
Merged

fix: panic in p-diff-sync after diff chunking feature#669
lucksus merged 4 commits intodevfrom
fix/panic-after-chunked-diffs

Conversation

@lucksus
Copy link
Member

@lucksus lucksus commented Feb 12, 2026

Most of this is cargo fmt, and also removal of old tryorama tests. CI now runs new rust based sweetest tests.

Fix: Handle nested chunked entries in from_entries()

  • Bug: ChunkedDiffs::from_entries() was directly accessing diff_entry.diff without checking if entries were chunked. If chunk hashes accidentally pointed to chunked entries (instead of inline chunks), it would load empty diffs, causing corrupted BTreeSet data structures that triggered RuntimeError: unreachable at memcmp in WASM.
  • Fix: Changed from_entries() to use load_diff_from_entry() which recursively handles both inline and chunked storage, preventing data corruption.

Also: Optimized into_aggregated_diff() to eliminate unnecessary cloning.

Tests: Added 3 comprehensive tests covering nested chunks, mixed inline/chunked entries, and empty entries.

Summary by CodeRabbit

  • New Features

    • Added HashBroadcast signal handling capability
    • Improved support for nested chunked entry retrieval in perspective diffs
  • Chores

    • Consolidated testing infrastructure to streamlined Rust-focused CI/CD pipeline
    • Removed legacy Node.js and Deno test suites and dependencies
    • Simplified build configuration and development setup

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

📝 Walkthrough

Walkthrough

This PR migrates the p-diff-sync test infrastructure from TypeScript/Tryorama to Rust/sweettest by consolidating a multi-job GitHub Actions workflow into a single Rust container job, removing Nix shell configuration, deleting all TypeScript test files, and adding limited new Rust functionality including HashBroadcast signal handling and a diff-loading helper function.

Changes

Cohort / File(s) Summary
GitHub Actions Workflow
.github/workflows/p-diff-sync-tests.yml
Consolidates multi-job matrix-driven workflow into single rust-tests job running in container. Removes Node.js, Deno, and various test suites (unit, pull, render, revisions, stress, telepresence). Introduces Cargo.lock-based dependency cache and sweettest integration test execution.
Nix Configuration
bootstrap-languages/p-diff-sync/hc-dna/default.nix, bootstrap-languages/p-diff-sync/hc-dna/holochain_version.nix
Removes entire Nix shell configuration and holochain version pinning derivation, eliminating dependencies on holonix, nodejs-16_x, swiProlog, and holochain-0.2.2 specification.
Signal Handling & Data Structure
bootstrap-languages/p-diff-sync/hc-dna/zomes/perspective_diff_sync/src/lib.rs, bootstrap-languages/p-diff-sync/hc-dna/zomes/perspective_diff_sync/src/telepresence/signal.rs
Adds new HashBroadcast signal handling pathway via link_adapter::pull::handle_broadcast in lib.rs. Expands RoutedSignalPayload with author, data, and timestamp fields alongside recipient_did in signal.rs. Adds multi-line debug logging for signal metadata.
Chunked Diff Loading
bootstrap-languages/p-diff-sync/hc-dna/zomes/perspective_diff_sync/src/link_adapter/chunked_diffs.rs
Introduces public load_diff_from_entry helper function enabling recursive loading of nested chunked entries. Expands imports and test coverage for nested/mixed inline-chunked entry scenarios.
Retriever Trait Updates
bootstrap-languages/p-diff-sync/hc-dna/zomes/perspective_diff_sync/src/retriever.rs
Adds WasmError trait bounds (WasmError: From, WasmError: From) to create_entry method signature. Reorders imports for consistency.
Formatting & Style Updates
bootstrap-languages/p-diff-sync/hc-dna/zomes/perspective_diff_sync/src/link_adapter/commit.rs, bootstrap-languages/p-diff-sync/hc-dna/zomes/perspective_diff_sync/src/link_adapter/render.rs, bootstrap-languages/p-diff-sync/hc-dna/zomes/perspective_diff_sync/src/link_adapter/snapshots.rs, bootstrap-languages/p-diff-sync/hc-dna/zomes/perspective_diff_sync/src/link_adapter/test_graphs.rs, bootstrap-languages/p-diff-sync/hc-dna/zomes/perspective_diff_sync/src/link_adapter/topo_sort.rs, bootstrap-languages/p-diff-sync/hc-dna/zomes/perspective_diff_sync/src/link_adapter/workspace.rs, bootstrap-languages/p-diff-sync/hc-dna/zomes/perspective_diff_sync/src/retriever/holochain.rs, bootstrap-languages/p-diff-sync/hc-dna/zomes/perspective_diff_sync/src/retriever/mock.rs, bootstrap-languages/p-diff-sync/hc-dna/zomes/perspective_diff_sync/src/telepresence/status.rs
Line-wrapping, import reordering, multi-line debug logging reformatting, and LinkQuery construction consolidation. No behavioral changes to logic or control flow.
TypeScript Test Suite Removal
bootstrap-languages/p-diff-sync/hc-dna/zomes/tests/*
Deletes all TypeScript test files and infrastructure: common.ts, download-hc-binaries.sh, index.ts, package.json, pull.ts (~284 lines), queue.ts (~82 lines), render.ts (~285 lines), revisions.ts (~92 lines), signals.ts (~106 lines), stress.ts (~355 lines), telepresence.ts (~172 lines), tsconfig.json, utils.ts (~114 lines). Eliminates Tryorama-based e2e test suite and test scaffolding.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PR #655: Directly related—both add chunked-diff support via load_diff_from_entry function and migrate tests to Rust sweettest.
  • PR #645: Updates p-diff-sync hc-dna Holochain dependencies in Cargo.toml alongside this PR's Rust source modifications.
  • PR #630: Both modify p-diff-sync Holochain DNA and zome code adapting to HDK API changes (GetLinksInputBuilder → LinkQuery).

Suggested reviewers

  • jhweir

Poem

🐰 The TypeScript tests hop away in the night,
while Rust sweetness takes the stage in pure delight.
New signals broadcast through the p-diff air,
chunked diffs load nested with recursive care.
Old workflows retire, one container remains—
tidy, fast, and free of JavaScript chains! 🌾

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 67.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: panic in p-diff-sync after diff chunking feature' accurately describes the main fix: resolving a panic/bug that occurred after implementing the diff chunking feature. It is specific, concise, and directly relates to the primary change.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into dev

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/panic-after-chunked-diffs

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@lucksus lucksus merged commit 43d03af into dev Feb 12, 2026
0 of 2 checks passed
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/p-diff-sync-tests.yml (1)

5-11: ⚠️ Potential issue | 🟠 Major

dev branch is missing from the trigger list, and no pull_request event is configured.

This PR targets dev, but dev is not listed under on.push.branches, so these tests won't run on merges to dev. Additionally, there's no pull_request trigger, so the workflow won't validate PRs before merging.

Proposed fix
 on:
   push:
     branches:
       - main
       - staging
       - bootstrap-languages
+      - dev
+  pull_request:
+    branches:
+      - main
+      - dev
🤖 Fix all issues with AI agents
In @.github/workflows/p-diff-sync-tests.yml:
- Around line 21-24: The workflow uses deprecated action versions
actions/checkout@v3 and actions/cache@v3; update both references to
actions/checkout@v4 and actions/cache@v4 in the workflow file so the jobs (the
step named "uses: actions/checkout" and the step "Cache Rust dependencies" using
actions/cache) run on the supported Node.js runtime and avoid deprecation
warnings.
🧹 Nitpick comments (3)
.github/workflows/p-diff-sync-tests.yml (1)

48-58: Redundant cache save — actions/cache already auto-saves on miss.

actions/cache@v3 (Line 24) restores and saves (via a post-job hook) on cache miss. The explicit actions/cache/save@v3 here with the same key is redundant.

Either:

  • Remove this step entirely and rely on the auto-save from actions/cache, or
  • Change Line 24 to actions/cache/restore@v3 (restore-only) and keep this explicit save for full control over when the save happens.
bootstrap-languages/p-diff-sync/hc-dna/zomes/perspective_diff_sync/src/link_adapter/commit.rs (1)

136-138: Pre-existing: revision equality via Debug format is fragile.

Comparing LocalHashReference instances through format!("{:?}", r) relies on Debug output being a faithful, stable representation of all relevant fields. If the Debug impl changes or two semantically-different values produce the same debug string, this could silently miscompare. Since this is pre-existing code (only reformatted here), it's not a blocker for this PR, but consider deriving/implementing PartialEq on LocalHashReference and comparing directly.

bootstrap-languages/p-diff-sync/hc-dna/zomes/perspective_diff_sync/src/link_adapter/chunked_diffs.rs (1)

116-134: Unbounded recursion risk in load_diff_from_entry.

load_diff_from_entry calls ChunkedDiffs::from_entries, which in turn calls load_diff_from_entry for each loaded entry. If a chunked entry ever (due to a bug or data corruption) points back to itself or forms a cycle, this will stack-overflow without warning. While normal operation creates at most one level of nesting, adding a recursion depth guard would make this more robust.

♻️ Suggested depth-limited variant
-pub fn load_diff_from_entry<Retriever: PerspectiveDiffRetreiver>(
+pub fn load_diff_from_entry<Retriever: PerspectiveDiffRetreiver>(
     entry: &PerspectiveDiffEntryReference,
 ) -> SocialContextResult<PerspectiveDiff> {
+    load_diff_from_entry_inner::<Retriever>(entry, 0)
+}
+
+const MAX_CHUNK_DEPTH: u8 = 3;
+
+fn load_diff_from_entry_inner<Retriever: PerspectiveDiffRetreiver>(
+    entry: &PerspectiveDiffEntryReference,
+    depth: u8,
+) -> SocialContextResult<PerspectiveDiff> {
+    if depth > MAX_CHUNK_DEPTH {
+        return Err(crate::errors::SocialContextError::InternalError(
+            "load_diff_from_entry: max chunk nesting depth exceeded",
+        ));
+    }
     if entry.is_chunked() {
         let chunk_hashes = entry.diff_chunks.as_ref().unwrap();
-        debug!(
-            "load_diff_from_entry: Loading {} chunks",
-            chunk_hashes.len()
-        );
-        let chunked_diffs = ChunkedDiffs::from_entries::<Retriever>(chunk_hashes.clone())?;
+        // inner from_entries would need to accept depth, or use a non-recursive path
+        // for chunks (which are always leaf-level)
         ...

Comment on lines +21 to +24
uses: actions/checkout@v3

- name: Cache Rust dependencies
uses: actions/cache@v3
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Upgrade actions/checkout and actions/cache from v3 to v4.

v3 of these actions uses the Node.js 16 runtime, which GitHub has deprecated. These will produce deprecation warnings and will eventually stop working.

Proposed fix
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
-        uses: actions/cache@v3
+        uses: actions/cache@v4

And on Line 50:

-        uses: actions/cache/save@v3
+        uses: actions/cache/save@v4
🧰 Tools
🪛 actionlint (1.7.10)

[error] 21-21: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


[error] 24-24: the runner of "actions/cache@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🤖 Prompt for AI Agents
In @.github/workflows/p-diff-sync-tests.yml around lines 21 - 24, The workflow
uses deprecated action versions actions/checkout@v3 and actions/cache@v3; update
both references to actions/checkout@v4 and actions/cache@v4 in the workflow file
so the jobs (the step named "uses: actions/checkout" and the step "Cache Rust
dependencies" using actions/cache) run on the supported Node.js runtime and
avoid deprecation warnings.

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.

1 participant