Skip to content

Conversation

@LesnyRumcajs
Copy link
Member

@LesnyRumcajs LesnyRumcajs commented Sep 19, 2025

Summary of changes

Changes introduced in this pull request:

Reference issue to close (if applicable)

Closes #5055

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

  • Bug Fixes

    • Resolved failures caused by duplicate drand beacon entries on new devnets. Verification now handles duplicate rounds correctly, improving reliability during startup and syncing.
  • Documentation

    • Updated the changelog to record the fix under the unreleased section, including formatting adjustments.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 19, 2025

Walkthrough

Updates CHANGELOG.md with a fix note. Modifies DrandBeacon::verify_entries (unchained path) to deduplicate by round using unique_by(|e| e.round()), processing each beacon round once. Chained path unchanged.

Changes

Cohort / File(s) Summary
Documentation
CHANGELOG.md
Adds “Fixed” entry noting failure on duplicate drand entries in new devnets; inserts a blank line. No code/API changes.
Beacon verification logic
src/beacon/drand.rs
In unchained verify path, iterate entries uniquely by round via unique_by(

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Caller as Caller
  participant Drand as DrandBeacon
  participant Entries as Entries (unchained)

  Caller->>Drand: verify_entries(entries, unchained)
  Note over Drand: Deduplicate entries by round
  Drand->>Entries: iterate unique_by(round)
  loop For each unique round
    Drand->>Drand: verify entry (signature/round linkage)
    alt verification fails
      Drand-->>Caller: return Err
    else verification succeeds
      Note right of Drand: proceed to next unique round
    end
  end
  Drand-->>Caller: Ok
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • hanabi1224
  • akaladarshi

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "fix: drand verification failure on duplicate entries" is concise, specific, and accurately summarizes the primary change in the PR (preventing verification failures caused by duplicate drand entries), and it aligns with the modified file and PR objectives.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-drand-fiasco-on-duplicate-rounds

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

@LesnyRumcajs LesnyRumcajs force-pushed the fix-drand-fiasco-on-duplicate-rounds branch from 174c29d to 2da7019 Compare September 19, 2025 12:29
@LesnyRumcajs LesnyRumcajs force-pushed the fix-drand-fiasco-on-duplicate-rounds branch from 2da7019 to 5c7a88b Compare September 19, 2025 12:31
@LesnyRumcajs LesnyRumcajs marked this pull request as ready for review September 19, 2025 12:32
@LesnyRumcajs LesnyRumcajs requested a review from a team as a code owner September 19, 2025 12:32
@LesnyRumcajs LesnyRumcajs requested review from akaladarshi and removed request for a team September 19, 2025 12:32
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 (2)
CHANGELOG.md (1)

42-43: Clarify scope and casing of “Drand”; tighten phrasing.

Make it explicit this affects unchained Drand (Quicknet) beacons typically used by new devnets, and use consistent “Drand” casing.

Apply this diff:

-- [#5055](https://github.com/ChainSafe/forest/issues/5055) Fixed an issue where Forest fails on duplicate drand entries. This would only happen on new devnets.
+- [#5055](https://github.com/ChainSafe/forest/issues/5055) Fixed a failure on duplicate Drand entries for unchained beacons (Quicknet), typically affecting new devnets.
src/beacon/drand.rs (1)

292-301: Good fix: deduping unchained rounds prevents batch-verify pitfalls on duplicates.

This addresses the duplicate-rounds failure. Optional micro-optimization: since entries are documented as “sorted by round,” you can avoid a HashSet allocation in unique_by and skip contiguous dups in O(1) extra space.

Apply this diff:

-                // Deduplicate by round. See Lotus issue: https://github.com/filecoin-project/lotus/issues/13349
-                for entry in entries.iter().unique_by(|e| e.round()) {
-                    if self.is_verified(entry) {
-                        continue;
-                    }
-
-                    messages.push(BeaconEntry::message_unchained(entry.round()));
-                    signatures.push(SignatureOnG1::from_bytes(entry.signature())?);
-                    validated.push(entry);
-                }
+                // Deduplicate contiguous duplicates (entries are sorted by round).
+                let mut last_round: Option<u64> = None;
+                for entry in entries {
+                    let r = entry.round();
+                    if last_round == Some(r) || self.is_verified(entry) {
+                        continue;
+                    }
+                    last_round = Some(r);
+
+                    messages.push(BeaconEntry::message_unchained(r));
+                    signatures.push(SignatureOnG1::from_bytes(entry.signature())?);
+                    validated.push(entry);
+                }

If you prefer to retain unique_by for non-contiguous dups, consider a quick early return when messages.is_empty() to skip a no-op verify_batch. I can also add a unit test that feeds duplicated unchained entries and asserts verify_entries returns true and caches once—say, drand::tests::verify_entries_unchained_dedups_duplicates. Want me to draft it?

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between caaba3d and 5c7a88b.

📒 Files selected for processing (2)
  • CHANGELOG.md (1 hunks)
  • src/beacon/drand.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: LesnyRumcajs
PR: ChainSafe/forest#5907
File: src/rpc/methods/state.rs:523-570
Timestamp: 2025-08-06T15:44:33.467Z
Learning: LesnyRumcajs prefers to rely on BufWriter's Drop implementation for automatic flushing rather than explicit flush() calls in Forest codebase.
🧬 Code graph analysis (1)
src/beacon/drand.rs (1)
src/beacon/mock_beacon.rs (1)
  • entry (46-48)
⏰ 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). (7)
  • GitHub Check: tests-release
  • GitHub Check: tests
  • GitHub Check: Build forest binaries on Linux AMD64
  • GitHub Check: cargo-publish-dry-run
  • GitHub Check: Build MacOS
  • GitHub Check: Build Ubuntu
  • GitHub Check: All lint checks

@LesnyRumcajs LesnyRumcajs added this pull request to the merge queue Sep 19, 2025
Merged via the queue into main with commit dbf23d3 Sep 19, 2025
55 checks passed
@LesnyRumcajs LesnyRumcajs deleted the fix-drand-fiasco-on-duplicate-rounds branch September 19, 2025 13:20
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.

Forest doesn't recover from drand failure

4 participants