This is grabbed from #17565.
All laanwj's and ryanofsky's suggestions are implemented.
With this PR, the GUI does not freeze when a user runs:
$ ./src/qt/bitcoin-qt -reindex
utACK
Thanks you for working on this! Concept ACK
242 | @@ -243,7 +243,8 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, int heig 243 | clientmodel->cachedBestHeaderTime = blockTime; 244 | } 245 | // if we are in-sync or if we notify a header update, update the UI regardless of last update time 246 | - if (fHeader || !initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) { 247 | + // If the command line option -reindex is specified, the GUI update pace is throttled down.
In commit "gui: Throttle GUI update pace when -reindex" (56bf42516722c7f05391f5ca2a5c4709486057e4)
Comment is a little misleading because throttling doesn't happen just generally when -reindex is specified, it does stop when the reindex is over.
Would suggest changing to: "During initial sync, block notifications, and header notifications from reindexing are both throttled."
Done.
242 | @@ -243,7 +243,8 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, int heig 243 | clientmodel->cachedBestHeaderTime = blockTime; 244 | } 245 | // if we are in-sync or if we notify a header update, update the UI regardless of last update time 246 | - if (fHeader || !initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) { 247 | + // If the command line option -reindex is specified, the GUI update pace is throttled down. 248 | + if ((fHeader && !clientmodel->node().getReindex()) || !initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
In commit "gui: Throttle GUI update pace when -reindex" (56bf42516722c7f05391f5ca2a5c4709486057e4)
I think it would be best to put !initialSync condition first to be clear throttling only happens during initial sync.
Done.
Code review ACK 56bf42516722c7f05391f5ca2a5c4709486057e4. This is a good minimal fix. It would be also be nice to have followup cleanup that passes the reindexing state directly to the handleNotifyBlockTip/handleNotifyHeaderTip handlers, so the GUI doesn't need to call back into the node in the middle of handling an event from the node. This would also make the initial sync and reindexing conditions more consistent, and maybe more efficient if there are a lot of notifications backed up in the queue, because throttling could still happen when reindexing finished but notifications from reindexing were still being processed.
Co-authored-by: Barry Deeney <mxaddict@codedmaster.com>
Co-authored-by: Russell Yanofsky <russ@yanofsky.org>
Updated 56bf42516722c7f05391f5ca2a5c4709486057e4 -> c9fe61291e9b23f37cf66194c2dad28e4d4a8954 (pr18121.01 -> pr18121.02, compare). @ryanofsky Thank you for your review. All your comments have been addressed.
241 | @@ -242,8 +242,9 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, int heig 242 | clientmodel->cachedBestHeaderHeight = height; 243 | clientmodel->cachedBestHeaderTime = blockTime; 244 | } 245 | - // if we are in-sync or if we notify a header update, update the UI regardless of last update time 246 | - if (fHeader || !initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) { 247 | + 248 | + // During initial sync, block notifications, and header notifications from reindexing are both throttled.
I find this very confusing, and even if I look past the grammar error, probably outright wrong since header notifications are only throttled for reindex, not initial sync?
IIUC, fReindex==true implies initialSync==true: https://github.com/bitcoin/bitcoin/blob/2bdc476d4d23256d8396bb9051a511f540d87392/src/validation.cpp#L1281-L1282
Anyway, mind suggesting a better wording?
I find this very confusing, and even if I look past the grammar error, probably outright wrong since header notifications are only throttled for reindex, not initial sync?
This is pretty confusing, and I was probably trying to pack too much information in a short comment. There should be chances to clean this up in the future with followups from #18136 or #18121#pullrequestreview-357730284
Ideally the code would just be more direct and not need a comment stating what it does:
enum NotificationType { BLOCK_TIP_CHANGED, HEADER_TIP_CHANGED };
enum NotificationStatus { INIT_REINDEX, INIT_DOWNLOAD, POST_INIT };
void HandleNotification(NotificationType notification, NotificationStatus status) {
bool throttle = status == INIT_REINDEX || (status == INIT_DOWNLOAD && notification == BLOCK_TIP_CHANGED);
if (!throttle || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) ...
<!--e57a25ab6845829454e8d69fc972939a-->
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
<!--174a7506f384e20aa4161008e828411d-->
Reviewers, this pull request conflicts with the following ones:
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.
utACK c9fe61291e9b23f37cf66194c2dad28e4d4a8954