Improve block clock rendering and sync state - #803
Open
johnny9 wants to merge 5 commits into
Open
Conversation
johnny9
marked this pull request as ready for review
July 19, 2026 22:00
Extract the block clock timeline from ChainModel, keep its data current independently of presentation, and stop dial and QML animation work when the relevant view is inactive. Bound sync-progress estimation work and cover the model, dial lifecycle, page visibility, and QML behavior.
Stop treating verification progress as a completion signal. Keep the clock in its initial-sync presentation until the node is ready, Core has left IBD, header sync and presync are inactive, and the active chain has caught the best known header. Latch completion for the session so a normal header-first block announcement does not return the clock to IBD. While sync is pending, drive the dial from active header or block progress. Display Core's reported percentage, capping only near-complete estimates at 99.9%. Use the same completion state for the full clock, mini clock, and wallet tooltip. Fit the header presync label inside the dial, and accept an empty current-period block timeline as valid clock data. Cover stale-tip catch-up, genesis, late headers, normal new blocks, progress rendering, labels, empty histories, and tooltip state in NodeModel and QML tests.
johnny9
force-pushed
the
improve/block-clock
branch
from
July 30, 2026 18:08
a3d1291 to
df9cb11
Compare
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
This PR fixes how the block clock represents sync/catch-up state and how confirmation history renders in both the full and mini clocks.
ChainModeltoBlockClockModeland stop presentation work while the clock is not visible. Hidden pages or tabs—and hidden or minimized windows—do not schedule dial repaints or run dial, peer-indicator, or estimating animations. The backing model stays current with minute-aligned clock updates and an immediate refresh when a block arrives, so the clock renders the latest state when it becomes visible again.Visual evidence
Catch-up sync-state bug
The unfixed build briefly shows the normal red clock while the active chain is still rapidly catching up from a stale signet tip. The new sync-state latch keeps the UI in syncing state at 99.9% until both header and block catch-up are complete.
Screencast.from.2026-07-19.17-37-22.mp4
Confirmation segment rendering
Mini block clock gradient
The mini clock now uses the same direction as the full clock: older, higher-confirmation time is yellow, transitioning clockwise toward the newest, zero-confirmation time in red.
Motivation
verificationProgress > 0.999can report the normal clock too early. With a saved signet tip at height 313768, Core had already left IBD at 0.999830; once a peer announced height 313904, the UI showed a normal clock while 136 blocks rapidly caught up.The existing timeline also mixed model data with paint geometry, kept repaint requests, timers, and animations active while views were hidden, and lost confirmation transitions when rounded segments were too close to render separately.
Related issues
Fixes #227.
Fixes #743.
Fixes #785.
Related to #576.
Follow-up to #609.
Testing
bitcoin-core-app,bitcoinqml_unit_tests, andbitcoinqml_qmltests.QT_QPA_PLATFORM=offscreen QT_QUICK_BACKEND=software LIBGL_ALWAYS_SOFTWARE=1 ctest --test-dir build --output-on-failure(2/2 passed).git diff --check.BlockClockModelcoverage for minute alignment and block-triggered time refresh (BlockClockModelTests: 10/10 passed), and reran the QML suite (389/389 passed).