Skip to content

Refactor CChain methods to use references, tests#34440

Draft
optout21 wants to merge 7 commits intobitcoin:masterfrom
optout21:cchain-ref
Draft

Refactor CChain methods to use references, tests#34440
optout21 wants to merge 7 commits intobitcoin:masterfrom
optout21:cchain-ref

Conversation

@optout21
Copy link
Contributor

@optout21 optout21 commented Jan 29, 2026

Refactor CChain methods (Contains(), Next(), etc.) to use references instead of pointers, to minimize the risk of accidental nullptr dereference (memory access violation). Also add missing unit tests to the CChain class.

The CChain::Contains() method (in src/chain.h) dereferences its input without checking. The Next() method also calls into this with a nullptr if invoked with nullptr. While most call sites have indirect guarantee that the input is not nullptr, it's not easy to establish this to all call sites with high confidence. These methods are publicly available. There is no known high-level use case to trigger this error, but the fix is easy, and makes the code safer.

Changes:

  • Add basic unit tests for CChain class methods
  • Refactor CChain::Contains() to take reference
  • Refactor CChain::Next() to take reference
  • Add unit tests for CChain::FindFork()
  • Change PeerManagerImpl::BlockRequestAllowed() to take reference

TODO:

  • ? /Change CChain internals to store references instead of pointers/
  • ? /Explore the change to always have at least one element (genesis), that way there is always genesis and tip./
  • Check related methods to change to reference -- FindFork, FindEarliestAtLeast, FindForkInGlobalIndex, blockman.AddToBlockIndex, etc.

Alternative. A simpler change is to stick with pointers, with extra checks where needed, see #34416 .

This change is remotely related to and indirectly triggered by #32875 .

@DrahtBot
Copy link
Contributor

DrahtBot commented Jan 29, 2026

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Reviews

See the guideline for information on the review process.
A summary of reviews will appear here.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #34565 (refactor: extract BlockDownloadManager from PeerManagerImpl by w0xlt)
  • #34489 (index: batch db writes during initial sync by furszy)
  • #34416 (Add nullptr-check to CChain::Contains(), tests by optout21)
  • #33752 (rest: Query predecessor headers using negative count param by A-Manning)
  • #33477 (Rollback for dumptxoutset without invalidating blocks by fjahr)
  • #32950 (validation: remove BLOCK_FAILED_CHILD by stratospher)
  • #32875 (index: handle case where pindex_prev equals chain tip in NextSyncBlock() by HowHsu)
  • #29770 (index: Check all necessary block data is available before starting to sync by fjahr)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@DrahtBot
Copy link
Contributor

🚧 At least one of the CI tasks failed.
Task lint: https://github.com/bitcoin/bitcoin/actions/runs/21472539937/job/61848421163
LLM reason (✨ experimental): Lint check failed: RPC code uses fatal asserts (rpc_assert), which the linter flags as inappropriate, causing the lint step to exit with an error.

Hints

Try to run the tests locally, according to the documentation. However, a CI failure may still
happen due to a number of reasons, for example:

  • Possibly due to a silent merge conflict (the changes in this pull request being
    incompatible with the current code in the target branch). If so, make sure to rebase on the latest
    commit of the target branch.

  • A sanitizer issue, which can only be found by compiling with the sanitizer and running the
    affected test.

  • An intermittent issue.

Leave a comment here, if you need help tracking down a confusing failure.

@optout21
Copy link
Contributor Author

Added new commit to change PeerManagerImpl::BlockRequestAllowed() to take reference, local to src/net_processing.cpp.

@optout21
Copy link
Contributor Author

optout21 commented Feb 3, 2026

Added new commit to change CChain::FindFork() to take reference.

@DrahtBot DrahtBot removed the CI failed label Feb 3, 2026
fanquake added a commit that referenced this pull request Feb 5, 2026
1f8f7d4 Change BlockRequestAllowed() to take ref (optout)

Pull request description:

  As [suggested here](#34416 (comment)), a minor refactor of `PeerManagerImpl::BlockRequestAllowed()` to take reference parameter (instead of pointer). The motivation is to make the code safer, by minimizing the risk of null-dereference, and to be more consistent.
  The change is local to the `PeerManagerImpl::BlockRequestAllowed()` class.
  Related to #34440.

ACKs for top commit:
  maflcko:
    review ACK 1f8f7d4 🎐
  l0rinc:
    tested ACK 1f8f7d4
  stickies-v:
    ACK 1f8f7d4

Tree-SHA512: 9c2de2d3e7d067e018db7ec54c79f512ccc1da54574d4fb362f6697ee6e235783779d7094cf20856cd34e08a1dbc74609d8351fe7b2287cd8ec0c836ef07be19
Add basic unit tests to the `CChain` class, filling a gap.
Add (lengthier) unit tests for `CChain::FindFork()`.
The `CChain::Contains()` method dereferences its input without checking,
potentially resulting in nullptr-dereference if invoked with `nullptr`.
To avoid this possibility, its input is changed to a reference instead.
Call sites are adapted accoringly. In a few cases an extra check
is added to ensure the input is not null (if guard or only `Assume`,
depending on the context.
To minimize chance of erroneous nullptr dereference, `CChain::Next()`
is changed to take a reference instead of a pointer.
Call sites have been adapted.
@optout21
Copy link
Contributor Author

optout21 commented Feb 5, 2026

Rebased, following #34464 ; one commit got annihilated.

Copy link

@7zkm7b8gw9-web 7zkm7b8gw9-web left a comment

Choose a reason for hiding this comment

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

Yes

@DrahtBot
Copy link
Contributor

🐙 This pull request conflicts with the target branch and needs rebase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants