Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Chain] Prune entire orphaned chains. #962

Merged
merged 1 commit into from
Jul 30, 2021

Conversation

Zannick
Copy link
Collaborator

@Zannick Zannick commented Jul 26, 2021

Problem

Pruned blocks sometimes cause other blocks in the index (mostly descendants of orphans) to have invalid parents, which may trip an assert pindexWalk->pprev (#692) on startup. Additionally, because block indexes don't own their own hash values, removing the index from mapBlockIndex where the hash is allocated may lead to a use-after-free corrupting the hash of a block written to disk (may be the cause of #930 (comment)).

Solution

Select pruning candidates in two rounds: first, based on height. Then, add all descendants of the blocks chosen in the first round.

For the memory issue, add a shared_ptr field to CBlockIndex that provides the hash value when the block is removed from mapBlockIndex. This will manage the memory of the hash for the lifetime of the object (which is forever anyway) and allows for efficient sharing and copying as usual (unique_ptr does not).

Testing

Via regtest. See #692 (comment)

If the index contains forks other than the active fork, then
removing one from an early part of the chain can cause startup to
assert `pindexWalk->pprev` on the remaining blocks in the fork which
no longer have parents in the index. (Issue Veil-Project#692)

This is made likely by the pruning process that only prunes orphans
based on height far enough from the best block.

Solution: After finding out which index entries are old enough to be
pruned, search the index for all entries that descend from any of those,
and add them to be pruned.

Additionally, CBlockIndex pointers are passed all over the codebase and
are never deleted, but their hash values are pointers to the
mapBlockIndex's keys. Normally this isn't a problem (unordered_map),
until the data is erased and the memory reused.
@codeofalltrades codeofalltrades added Tag: Chainstate Related to blockindexes and the state of the chain. Tag: Waiting For Code Review Waiting for code review from a core developer labels Jul 26, 2021
Copy link
Collaborator

@codeofalltrades codeofalltrades left a comment

Choose a reason for hiding this comment

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

ACK 2054946

@CaveSpectre11
Copy link
Collaborator

utACK 2054946

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Code Review: Passed Dev Status: Merged Issue is completely finished. Tag: Chainstate Related to blockindexes and the state of the chain.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants