Skip to content

fix: limit possible underflows/overflows - #7459

Open
LesnyRumcajs wants to merge 1 commit into
mainfrom
limit-possible-over-underflows
Open

fix: limit possible underflows/overflows#7459
LesnyRumcajs wants to merge 1 commit into
mainfrom
limit-possible-over-underflows

Conversation

@LesnyRumcajs

@LesnyRumcajs LesnyRumcajs commented Aug 6, 2026

Copy link
Copy Markdown
Member

Summary of changes

Changes introduced in this pull request:

  • limits possible underflows and overflows + adds tests to improve coverage around those
  • most of those are pretty benign (we kind of assume drand HTTP relay won't be malicious but it might have a bad day...), but it's good to deal with those proactively
  • extracted hex helper to reduce code duplication around prefixed hex-encoded values.

Reference issue to close (if applicable)

Closes #7448

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.

Outside contributions

  • This pull request is based on an issue that a maintainer has accepted (see Before Opening a Pull Request).
  • I have read and agree to the CONTRIBUTING document.
  • I have read and agree to the AI Policy document. I understand that failure to comply with the guidelines will lead to rejection of the pull request.

Summary by CodeRabbit

Bug Fixes

  • Improved validation for negative, invalid, and out-of-range epochs across chain, RPC, state, and beacon operations.
  • Prevented arithmetic overflows and underflows in timestamps, lookbacks, leases, checkpoints, and range calculations.
  • Improved beacon traversal, round validation, and error reporting.
  • Added safer handling for malformed hexadecimal values, invalid database offsets, and unsafe export ranges.
  • Prevented invalid sector durations and strengthened block-range and participation-lease validation.
  • Added clearer errors for invalid heights and malformed requests.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The PR adds checked arithmetic and explicit input validation across beacon, chain, RPC, storage, and state paths. It introduces fallible beacon round calculations, negative-height errors, shared hexadecimal parsing, and boundary regression tests.

Changes

Arithmetic validation and error handling

Layer / File(s) Summary
Fallible beacon round calculations
src/beacon/..., src/blocks/header.rs, src/rpc/methods/beacon.rs, src/rpc/methods/state.rs, src/state_manager/chain_rand.rs
Beacon round calculations, retrieval, validation, waiting, and callers now propagate checked arithmetic errors.
Epoch boundary and lookback handling
src/chain/..., src/chain_sync/validation.rs, src/rpc/methods/chain.rs, src/state_manager/message_search.rs, src/daemon/db_util.rs, src/tool/subcommands/index_cmd.rs
Epoch subtraction, tipset lookup, timestamp validation, lookback calculations, and backfill ranges now reject invalid or unrepresentable values.
Input and storage validation
src/db/car/forest/index/mod.rs, src/fil_cns/weight.rs, src/rpc/methods/eth/filter/mod.rs, src/rpc/methods/f3/types.rs, src/rpc/methods/state.rs
Storage offsets, election weights, lease ranges, sector durations, and Ethereum filter inputs now use validated bounds and checked arithmetic.
Shared hexadecimal parsing
src/utils/encoding/hex.rs, src/lotus_json/mod.rs, src/wallet/subcommands/wallet_cmd.rs
Added parse_prefixed_int and updated hexadecimal parsing callers. Tests cover prefixes, signs, digits, bounds, and panic safety.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related issues

Possibly related PRs

  • ChainSafe/forest#7427: Both PRs modify unchained beacon retrieval and round traversal in src/beacon/drand.rs and its tests.

Suggested reviewers: sudo-shashank, hanabi1224

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: preventing possible integer underflows and overflows.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch limit-possible-over-underflows
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch limit-possible-over-underflows

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

@LesnyRumcajs LesnyRumcajs added RPC requires calibnet RPC checks to run on CI Snapshot Run snapshot tests labels Aug 6, 2026
@LesnyRumcajs
LesnyRumcajs force-pushed the limit-possible-over-underflows branch from da43e98 to dcae0db Compare August 6, 2026 14:22
@LesnyRumcajs
LesnyRumcajs marked this pull request as ready for review August 6, 2026 15:19
@LesnyRumcajs
LesnyRumcajs requested a review from a team as a code owner August 6, 2026 15:19
@LesnyRumcajs
LesnyRumcajs requested review from hanabi1224 and sudo-shashank and removed request for a team August 6, 2026 15:19
@LesnyRumcajs
LesnyRumcajs force-pushed the limit-possible-over-underflows branch 2 times, most recently from 5344a31 to b8dfa6f Compare August 6, 2026 15:20

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (2)
src/beacon/mock_beacon.rs (1)

53-54: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add context to the epoch conversion error.

u64::try_from(fil_epoch)? returns a generic conversion error. Add context that identifies the invalid mock-beacon epoch.

As per coding guidelines, add context with .context() when errors occur.

Proposed fix
-        Ok(u64::try_from(fil_epoch)?)
+        u64::try_from(fil_epoch).context("mock beacon epoch must be non-negative")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/beacon/mock_beacon.rs` around lines 53 - 54, Update the epoch conversion
in the mock beacon method returning anyhow::Result<u64> to attach context with
.context() before propagating the error, identifying the invalid fil_epoch value
while preserving the successful u64 conversion result.

Source: Coding guidelines

src/state_manager/chain_rand.rs (1)

129-129: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add context to the beacon-round error.

Line 129 returns the raw error. Add .context() with the epoch before ?. This makes failures actionable across the state-manager and RPC call paths.

As per coding guidelines, use anyhow::Result<T> for most operations and add context with .context() when errors occur.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/state_manager/chain_rand.rs` at line 129, Update the error propagation in
the beacon round lookup within the surrounding epoch-processing function by
adding anyhow context containing the current epoch before the `?` operator.
Preserve the existing `max_beacon_round_for_epoch` call and return behavior
while making the failure context available to state-manager and RPC callers.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/beacon/drand.rs`:
- Around line 136-140: Validate that the `entry.round()` returned by
`curr_beacon.entry(cur)` matches `cur` before decrementing it. Reject mismatched
rounds, including `cur + 1`, and retain the existing `checked_sub(1)` handling
for a matching round.

In `@src/chain_sync/validation.rs`:
- Around line 307-309: Replace the saturating arithmetic used to compute
expected in the timestamp validation with checked multiplication and addition,
rejecting validation when either operation overflows before comparing the block
timestamp. Extend the related regression test to use timestamp u64::MAX and
assert that the block is rejected.

In `@src/rpc/methods/eth/filter/mod.rs`:
- Around line 684-688: Update the min_height validation before the range-walk
branches to require min_height >= 0, removing acceptance of the -1 sentinel. Add
a regression test alongside the existing negative-height test covering
from_block_number(-1) and verify it is rejected.

In `@src/rpc/methods/state.rs`:
- Around line 2254-2259: In the beacon-entry wait flow, update the genesis
timestamp conversion before calling beacon_entry_wait to use i64::try_from(...),
adding the requested context message and propagating conversion failure.
Preserve the existing wait calculation while rejecting u64 timestamps that
cannot be represented as i64.

---

Nitpick comments:
In `@src/beacon/mock_beacon.rs`:
- Around line 53-54: Update the epoch conversion in the mock beacon method
returning anyhow::Result<u64> to attach context with .context() before
propagating the error, identifying the invalid fil_epoch value while preserving
the successful u64 conversion result.

In `@src/state_manager/chain_rand.rs`:
- Line 129: Update the error propagation in the beacon round lookup within the
surrounding epoch-processing function by adding anyhow context containing the
current epoch before the `?` operator. Preserve the existing
`max_beacon_round_for_epoch` call and return behavior while making the failure
context available to state-manager and RPC callers.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ac8dd4e2-b749-46df-812c-3b6b1193a065

📥 Commits

Reviewing files that changed from the base of the PR and between 9c30523 and b8dfa6f.

📒 Files selected for processing (22)
  • src/beacon/drand.rs
  • src/beacon/mock_beacon.rs
  • src/beacon/tests/drand.rs
  • src/blocks/header.rs
  • src/chain/mod.rs
  • src/chain/store/chain_store.rs
  • src/chain/store/errors.rs
  • src/chain/store/index.rs
  • src/chain/tests.rs
  • src/chain_sync/validation.rs
  • src/db/car/forest/index/mod.rs
  • src/fil_cns/weight.rs
  • src/lotus_json/mod.rs
  • src/rpc/methods/beacon.rs
  • src/rpc/methods/chain.rs
  • src/rpc/methods/eth/filter/mod.rs
  • src/rpc/methods/f3/types.rs
  • src/rpc/methods/state.rs
  • src/state_manager/chain_rand.rs
  • src/state_manager/message_search.rs
  • src/utils/encoding/hex.rs
  • src/wallet/subcommands/wallet_cmd.rs
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • filecoin-project/lotus (manual)

Comment thread src/beacon/drand.rs Outdated
Comment thread src/chain_sync/validation.rs Outdated
Comment thread src/rpc/methods/eth/filter/mod.rs Outdated
Comment thread src/rpc/methods/state.rs
@LesnyRumcajs
LesnyRumcajs marked this pull request as draft August 6, 2026 15:36
@codecov

codecov Bot commented Aug 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.87879% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.22%. Comparing base (9199a82) to head (3e8983d).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/beacon/drand.rs 75.00% 1 Missing and 6 partials ⚠️
src/rpc/methods/state.rs 87.80% 2 Missing and 3 partials ⚠️
src/blocks/header.rs 66.66% 0 Missing and 2 partials ⚠️
src/chain/mod.rs 80.00% 1 Missing and 1 partial ⚠️
src/rpc/methods/chain.rs 83.33% 2 Missing ⚠️
src/wallet/subcommands/wallet_cmd.rs 0.00% 2 Missing ⚠️
src/beacon/mock_beacon.rs 50.00% 0 Missing and 1 partial ⚠️
src/chain/store/chain_store.rs 0.00% 0 Missing and 1 partial ⚠️
src/chain_sync/validation.rs 95.00% 0 Missing and 1 partial ⚠️
src/db/car/forest/index/mod.rs 95.45% 0 Missing and 1 partial ⚠️
... and 4 more
Additional details and impacted files
Files with missing lines Coverage Δ
src/chain/store/errors.rs 12.50% <ø> (ø)
src/chain/store/index.rs 93.84% <100.00%> (+0.18%) ⬆️
src/daemon/db_util.rs 55.52% <100.00%> (+0.64%) ⬆️
src/lotus_json/mod.rs 77.53% <100.00%> (-0.17%) ⬇️
src/rpc/methods/eth/filter/mod.rs 89.55% <100.00%> (+0.08%) ⬆️
src/rpc/methods/f3/types.rs 62.64% <100.00%> (+0.34%) ⬆️
src/state_manager/message_search.rs 88.29% <100.00%> (+0.32%) ⬆️
src/utils/encoding/hex.rs 96.11% <100.00%> (+1.11%) ⬆️
src/beacon/mock_beacon.rs 56.25% <50.00%> (+25.00%) ⬆️
src/chain/store/chain_store.rs 73.51% <0.00%> (-0.18%) ⬇️
... and 12 more

... and 7 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9199a82...3e8983d. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@LesnyRumcajs
LesnyRumcajs force-pushed the limit-possible-over-underflows branch 5 times, most recently from 96e41a2 to 7fc79aa Compare August 7, 2026 12:32
@LesnyRumcajs
LesnyRumcajs marked this pull request as ready for review August 7, 2026 15:13

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/rpc/methods/eth/filter/mod.rs (1)

715-717: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add context to the fallible hexadecimal conversion.

parse_prefixed_int and ChainEpoch::try_from propagate bare errors. Add context so callers can distinguish malformed hexadecimal input from an epoch-range overflow.

-    let epoch: u64 = crate::utils::encoding::hex::parse_prefixed_int(hex_str)?;
-    Ok(ChainEpoch::try_from(epoch)?)
+    let epoch: u64 = crate::utils::encoding::hex::parse_prefixed_int(hex_str)
+        .context("failed to parse hexadecimal block number")?;
+    ChainEpoch::try_from(epoch)
+        .context("hexadecimal block number exceeds the ChainEpoch range")

Ensure anyhow::Context is in scope.

As per coding guidelines, add context with .context() when errors occur.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/rpc/methods/eth/filter/mod.rs` around lines 715 - 717, Add
anyhow::Context to scope and update the conversion in the epoch-parsing flow to
attach distinct context with .context(): identify failures from
parse_prefixed_int as malformed hexadecimal input and failures from
ChainEpoch::try_from as epoch-range overflow, while preserving the existing
error propagation behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/beacon/drand.rs`:
- Line 90: Prevent underflow in the beacon-round lookups by replacing unchecked
subtraction from round values with checked_sub(1). Update both the prior-entry
fetch near the computed round and the max_round - 1 path, returning or handling
the no-prior-round case without requesting u64::MAX.

In `@src/rpc/methods/eth/filter/mod.rs`:
- Around line 684-686: Update the filter range validation around the min_height
check to reject from_block values greater than heaviest before calculating the
lookback or applying max_range. Add a regression test covering
from_block_number(heaviest + 1), while preserving valid ranges at or below the
current head.

---

Nitpick comments:
In `@src/rpc/methods/eth/filter/mod.rs`:
- Around line 715-717: Add anyhow::Context to scope and update the conversion in
the epoch-parsing flow to attach distinct context with .context(): identify
failures from parse_prefixed_int as malformed hexadecimal input and failures
from ChainEpoch::try_from as epoch-range overflow, while preserving the existing
error propagation behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 436f368b-5ec2-48da-91e3-c4005bec38da

📥 Commits

Reviewing files that changed from the base of the PR and between b8dfa6f and 7fc79aa.

📒 Files selected for processing (17)
  • src/beacon/drand.rs
  • src/beacon/tests/drand.rs
  • src/blocks/header.rs
  • src/chain/store/chain_store.rs
  • src/chain/store/index.rs
  • src/chain/tests.rs
  • src/chain_sync/validation.rs
  • src/daemon/db_util.rs
  • src/fil_cns/weight.rs
  • src/lotus_json/mod.rs
  • src/rpc/methods/chain.rs
  • src/rpc/methods/eth/filter/mod.rs
  • src/rpc/methods/f3/types.rs
  • src/rpc/methods/state.rs
  • src/state_manager/message_search.rs
  • src/tool/subcommands/index_cmd.rs
  • src/utils/encoding/hex.rs
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • filecoin-project/lotus (manual)
🚧 Files skipped from review as they are similar to previous changes (8)
  • src/rpc/methods/f3/types.rs
  • src/chain/tests.rs
  • src/lotus_json/mod.rs
  • src/rpc/methods/state.rs
  • src/fil_cns/weight.rs
  • src/chain/store/chain_store.rs
  • src/beacon/tests/drand.rs
  • src/utils/encoding/hex.rs

Comment thread src/beacon/drand.rs
Comment thread src/rpc/methods/eth/filter/mod.rs
@LesnyRumcajs
LesnyRumcajs removed the request for review from hanabi1224 August 7, 2026 15:27
@LesnyRumcajs
LesnyRumcajs force-pushed the limit-possible-over-underflows branch from 7fc79aa to 3e8983d Compare August 7, 2026 15:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

RPC requires calibnet RPC checks to run on CI Snapshot Run snapshot tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Clear out unsound overflows/underflows

1 participant