Skip to content

chore: minor changes from audit tool#3165

Open
tac0turtle wants to merge 5 commits intomainfrom
marko/audit-bits
Open

chore: minor changes from audit tool#3165
tac0turtle wants to merge 5 commits intomainfrom
marko/audit-bits

Conversation

@tac0turtle
Copy link
Contributor

@tac0turtle tac0turtle commented Mar 16, 2026

Overview

Testing out an audit tool and it found these items.

Summary by CodeRabbit

  • Bug Fixes

    • Added memory bounds for block synchronization to prevent unbounded resource growth
    • Enhanced channel closure safety with proper synchronization mechanisms
  • Tests

    • Added comprehensive fuzzing tests for data serialization and deserialization operations
  • Chores

    • Updated project dependencies

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 16, 2026

Warning

Rate limit exceeded

@tac0turtle has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 2 minutes and 51 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d3804616-2853-4ca5-bcff-e033b081f3b3

📥 Commits

Reviewing files that changed from the base of the PR and between 5fa641d and 9d42c81.

⛔ Files ignored due to path filters (2)
  • apps/grpc/go.sum is excluded by !**/*.sum
  • apps/testapp/go.sum is excluded by !**/*.sum
📒 Files selected for processing (2)
  • apps/grpc/go.mod
  • apps/testapp/go.mod
📝 Walkthrough

Walkthrough

This PR updates memory management in the syncing module by adding memory bounds and concurrency safety guards, migrates the mapstructure dependency to a newer version, updates code assertions to use byte comparisons, and introduces comprehensive fuzzing tests for serialization operations.

Changes

Cohort / File(s) Summary
Memory Management & Concurrency Safety
block/internal/syncing/syncer.go
Adds maxSeenBlockTxs memory bound constant, introduces closeOnce sync.Once field to prevent multiple channel closes, implements warning log when memory threshold exceeded.
Assertion Logic
block/internal/syncing/assert.go
Replaces string-based proposer address comparison with bytes.Equal for direct byte slice comparison; adds bytes import.
Dependency Migration
go.mod, pkg/config/config.go
Upgrades mapstructure dependency from mitchellh/mapstructure v1.5.0 to go-viper/mapstructure/v2 v2.4.0; updates import path in config module accordingly.
Fuzzing Tests
types/serialization_fuzz_test.go
Adds comprehensive fuzzing test suite covering binary marshaling/unmarshaling for Header, Data, SignedHeader, SignedData, DAEnvelope and protobuf conversion paths (FromProto/ToProto).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • feat(sequencer): catchup from base #3057: Modifies block/internal/syncing/syncer.go and VerifyForcedInclusionTxs with changes to signature and DA-height handling that intersect with this PR's memory bounds and logging additions.

Suggested reviewers

  • Manav-Aggarwal
  • tuxcanfly
  • tzdybal

Poem

🐰 A bunny bounds through memory tight,
With closeOnce guards to seal up right,
Dependencies refresh and shine anew,
While fuzz tests find what breaks on cue! 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is incomplete. The Overview section only briefly mentions testing an audit tool but lacks substantive detail about the changes, their rationale, impact, or which files were modified. Expand the Overview section to explain what specific issues the audit tool identified, why these changes are necessary, and summarize the modifications made (e.g., byte comparison optimization, memory bounds, dependency upgrade, fuzzing tests).
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'chore: minor changes from audit tool' accurately summarizes the main objective of the PR, which applies audit tool recommendations across multiple files.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch marko/audit-bits
📝 Coding Plan
  • Generate coding plan for human review comments

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.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 16, 2026

The latest Buf updates on your PR. Results from workflow CI / buf-check (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed⏩ skipped✅ passed✅ passedMar 16, 2026, 1:09 PM

@claude
Copy link
Contributor

claude bot commented Mar 16, 2026

Claude finished @tac0turtle's task in 1m 39s —— View job


Claude finished @tac0turtle's task in 2m 39s —— View job


Code Review

  • Gather context and understand PR changes
  • Review block/internal/syncing/syncer.go changes
  • Review block/internal/syncing/assert.go changes
  • Review types/serialization_fuzz_test.go
  • Review dependency changes (go.mod, pkg/config/config.go)
  • Synthesize and post final review

Summary

The PR applies a set of targeted improvements from an audit tool: a byte-comparison fix in the assertion logic, a fuzz test suite for serialization, and a dependency migration. Two changes (closeOnce + maxSeenBlockTxs) were added and then reverted following reviewer feedback, leaving the net diff clean and focused.


block/internal/syncing/assert.go — ✅ Correct fix

bytes.Equal is the right way to compare byte slices in Go. The previous string-conversion approach worked but was semantically misleading and slightly less efficient. No issues here.


types/serialization_fuzz_test.go⚠️ Minor issues

Misleading test name / variable — FuzzDAEnvelopeUnmarshalBinary (lines 75–85)

The function name implies it targets a DAEnvelope type, but the body operates on SignedHeader via UnmarshalDAEnvelope/MarshalDAEnvelope. The variable is named sh too. This will confuse readers later. Should be renamed to something like FuzzSignedHeaderDAEnvelope. Fix this →

Sparse seed corpus for FuzzSignedHeaderUnmarshalBinary / FuzzSignedDataUnmarshalBinary

Both functions seed only with []byte{} and a minimal byte pair. Compare FuzzHeaderUnmarshalBinary which constructs a valid populated struct, marshals it, and seeds with that — giving the fuzzer a much richer starting point. Consider doing the same:

func FuzzSignedHeaderUnmarshalBinary(f *testing.F) {
    sh := SignedHeader{}
    if data, err := sh.MarshalBinary(); err == nil {
        f.Add(data)
    }
    f.Add([]byte{})
    f.Add([]byte{0x0a, 0x00})
    // ...
}

MarshalDAEnvelope(nil) at line 83

The round-trip calls sh.MarshalDAEnvelope(nil). If MarshalDAEnvelope has any behaviour that depends on a non-nil argument (e.g., encoding metadata), the round-trip may not actually exercise the full serialization path. Worth verifying in the implementation that nil is explicitly handled and produces the same result as an empty struct.

No fuzz test for SignedData.ToProto / FromProto

The suite covers State protobuf round-trips but not SignedData or SignedHeader proto paths. Given these types cross the network boundary, adding those would increase coverage in the most security-sensitive paths.


go.mod + pkg/config/config.go — ✅ Correct migration

mitchellh/mapstructure is unmaintained; go-viper/mapstructure/v2 is the actively maintained fork used by the Viper ecosystem. The import path update in config.go is correct. The v2 major bump can introduce subtle behaviour changes (e.g., stricter type coercion defaults), but this is a well-tested migration path.

Recommendation: Run the existing config tests after this change in CI to confirm no silent breakage from v2 coercion differences.


block/internal/syncing/syncer.go — ℹ️ Net-zero delta (reverted)

The closeOnce and maxSeenBlockTxs additions from the initial commits were reverted per reviewer feedback (as julienrbrt noted, Stop's s.cancel == nil guard already prevents double-close, and the maxSeenBlockTxs constant added nothing actionable). The revert is correct — no lingering issues from those.

One pre-existing observation worth noting: pruneUpTo (line 995) holds forcedInclusionMu while iterating and deleting from all three maps. This is safe and correct, but the lock is held for O(epochs × txs-per-epoch) which could be non-trivial under high load. Not a blocker, just something to watch.


General observations

  • Docstring coverage: CodeRabbit's pre-merge check flagged 0% docstring coverage on changed functions. The fuzz test functions themselves don't need doc comments, but the existing assertExpectedProposer and assertValidSignedData in assert.go have none. Not a blocker for this PR but worth addressing in a follow-up.
  • Test coverage: Codecov shows the only uncovered lines are in syncer.go's memory-bound warning path — which is the part that was reverted, so coverage numbers are expected.

Verdict: Mostly good. The bytes.Equal fix and dependency migration are clean. The fuzz tests are a welcome addition but FuzzDAEnvelopeUnmarshalBinary naming should be fixed before merge.

@tac0turtle tac0turtle marked this pull request as ready for review March 16, 2026 12:12
@codecov
Copy link

codecov bot commented Mar 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 60.31%. Comparing base (eabde1a) to head (9d42c81).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3165      +/-   ##
==========================================
+ Coverage   60.20%   60.31%   +0.10%     
==========================================
  Files         115      115              
  Lines       11902    11902              
==========================================
+ Hits         7166     7179      +13     
+ Misses       3925     3914      -11     
+ Partials      811      809       -2     
Flag Coverage Δ
combined 60.31% <100.00%> (+0.10%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

🧹 Nitpick comments (1)
types/serialization_fuzz_test.go (1)

75-85: Consider renaming for clarity.

The function FuzzDAEnvelopeUnmarshalBinary operates on SignedHeader type rather than a dedicated DAEnvelope type. While functionally correct (testing UnmarshalDAEnvelope and MarshalDAEnvelope methods), the variable name sh and type SignedHeader could be confusing to readers expecting a separate envelope type.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@types/serialization_fuzz_test.go` around lines 75 - 85, Rename the fuzz test
and local variable to reflect it operates on SignedHeader: update the test
function name FuzzDAEnvelopeUnmarshalBinary to something like
FuzzSignedHeaderUnmarshalDAEnvelope (or FuzzSignedHeaderDAEnvelope) and rename
the local variable sh to a clearer name such as signedHeader; keep calling
SignedHeader.UnmarshalDAEnvelope and SignedHeader.MarshalDAEnvelope as-is so the
test behavior is unchanged but the intent is clearer.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@types/serialization_fuzz_test.go`:
- Around line 75-85: Rename the fuzz test and local variable to reflect it
operates on SignedHeader: update the test function name
FuzzDAEnvelopeUnmarshalBinary to something like
FuzzSignedHeaderUnmarshalDAEnvelope (or FuzzSignedHeaderDAEnvelope) and rename
the local variable sh to a clearer name such as signedHeader; keep calling
SignedHeader.UnmarshalDAEnvelope and SignedHeader.MarshalDAEnvelope as-is so the
test behavior is unchanged but the intent is clearer.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a24d85d2-edf9-4954-be1d-3682cd38fa19

📥 Commits

Reviewing files that changed from the base of the PR and between eabde1a and 5fa641d.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (5)
  • block/internal/syncing/assert.go
  • block/internal/syncing/syncer.go
  • go.mod
  • pkg/config/config.go
  • types/serialization_fuzz_test.go

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.

2 participants