fix: block assembly reset skips intermediate block finalization and handleReorg returns nil after fallback reset#545
Open
freemans13 wants to merge 1 commit intobsv-blockchain:mainfrom
Conversation
…andleReorg returns nil after fallback reset Fix two bugs in block assembly's reset logic: Bug 1: SubtreeProcessor.reset() only called finalizeBlockProcessing (and thus SetBlockProcessedAt) for the LAST moveForward block. Intermediate blocks never got processed_at set, meaning they were not recognized as fully processed. Fix: call finalizeBlockProcessing for each moveForward block individually in both the legacy sync and non-legacy paths. Bug 2: handleReorg() returned nil after fallback reset (triggered by invalid block or failed Reorg), allowing processNewBlockAnnouncement to overwrite the reset's setBestBlockHeader with a potentially stale value captured before the reset ran. Fix: return ErrBlockAssemblyReset after fallback reset, matching the large-reorg path which already returns this error. Includes unit tests proving both bugs and integration tests using full blockchain daemon with gRPC and real stores.
Contributor
|
🤖 Claude Code Review Status: Complete Two critical bug fixes in block assembly reset logic, both properly addressed with comprehensive tests: Bug 1 Fix (SubtreeProcessor.go): Fixed intermediate block finalization during reset
Bug 2 Fix (BlockAssembler.go): Fixed handleReorg return value after fallback reset
Test Coverage: Excellent
No issues found. The fixes are well-reasoned, properly implemented, and thoroughly tested. |
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.



Summary
Fix two bugs in block assembly's reset logic that cause intermediate blocks to be improperly processed during reorgs/resets:
SubtreeProcessor.reset()only calledfinalizeBlockProcessing()(and thusSetBlockProcessedAt) for the last moveForward block. Intermediate blocks never gotprocessed_atset, meaning they were not recognized as fully processed.handleReorg()returnednilafter fallback reset (triggered by invalid block or failed Reorg), allowingprocessNewBlockAnnouncementto overwrite the reset'ssetBestBlockHeaderwith a potentially stale value captured before the reset ran.Changes
Bug 1 Fix (
SubtreeProcessor.go)finalizeBlockProcessing(ctx, block)inside the per-block moveForward loop so each block getsSetBlockProcessedAtcalled individually.currentBlockHeader.Store()+updatePrecomputedMiningData()with per-blockfinalizeBlockProcessing()loop after concurrent coinbase processing.Bug 2 Fix (
BlockAssembler.go)reset()succeeds inhandleReorg(), returnerrors.NewBlockAssemblyResetError(...)instead ofnil. This matches the large-reorg path which already correctly returnsErrBlockAssemblyReset, preventingprocessNewBlockAnnouncementfrom overwriting the reset's state.Tests
reset_bug_test.go): Two tests that prove both bugs exist and pass after fixes.blockassembly_system_test.go): Two tests using full blockchain daemon (gRPC, real stores) that exercise the reset and reorg-with-invalid-block paths end-to-end.Testing
All tests pass with no regressions:
Related issue: https://github.com/orgs/bitcoin-sv/projects/5/views/6?pane=issue&itemId=161301562&issue=bitcoin-sv%7Cteranode%7C4507