consensus: Add (*MidState).forEachRevertedElementLeaf #187
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When iterating over the elements in a
MidState
, we need to be careful with regard to contract revisions. When applying a block, we want to report the latest revision; but when reverting, we want to report the earliest. Unfortunately, this asymmetry was overlooked, leading to a rather pernicious bug: when a block containing a revision is reverted, the Merkle tree is still contains the revision, not the original contract.It's pernicious because A) reorgs are fairly uncommon, and B) the reorg has to contain a revision, and also C) redundancy in the DB code means that the invalid hashes may be overwritten by valid ones, masking the problem. That's likely why we only discovered this bug after adding a sanity check that validates every block supplement. Sure, our consensus tests are a bit lacking when it comes to file contracts -- I don't think there are any involving both a revision and a reorg! -- but the nature of this bug makes me wonder if it would have eluded detection anyway.
If you've been running a
core
node long enough to observe a reorg, there's a decent chance your Merkle tree is (very slightly) wrong. This can probably be fixed by updating and then manually reverting and re-applying a lot of blocks... but resyncing from genesis is the best way to be sure your state is ok. 🙃