Early subscribe core signals in transaction table model #121

pull promag wants to merge 4 commits into bitcoin-core:master from promag:2020-10-missing-transaction-notifications changing 1 files +26 −24
  1. promag commented at 2:01 am on October 28, 2020: contributor

    This fixes the case where transaction notifications arrive between getWalletTxs and subscribeToCoreSignals. Basically notifications are queued until getWalletTxs and wallet rescan complete.

    This is also a requirement to call getWalletTxs in a background thread.

    Motivated by https://github.com/bitcoin/bitcoin/issues/20241.

  2. promag force-pushed on Oct 28, 2020
  3. promag commented at 6:22 pm on October 28, 2020: contributor
    Please ignore whitespaces when reviewing.
  4. promag force-pushed on Nov 1, 2020
  5. promag commented at 1:01 pm on November 1, 2020: contributor
    Rebased due to conflict with updated #120.
  6. promag requested review from ryanofsky on Nov 12, 2020
  7. promag requested review from hebasto on Nov 12, 2020
  8. promag requested review from jonasschnelli on Nov 12, 2020
  9. promag force-pushed on Nov 12, 2020
  10. promag force-pushed on Dec 2, 2020
  11. hebasto commented at 3:04 pm on December 16, 2020: member
    Concept ACK.
  12. hebasto commented at 5:15 pm on January 4, 2021: member

    This fixes the case where transaction notifications arrive between getWalletTxs and subscribeToCoreSignals.

    Yes, the current behavior is indeed buggy. It is easy to verify by patching TransactionTableModel ctor with a delay before subscribeToCoreSignals call.

  13. in src/qt/transactiontablemodel.cpp:99 in 5d7d36344c outdated
     94@@ -95,25 +95,27 @@ class TransactionTablePriv
     95      */
     96     QList<TransactionRecord> cachedWallet;
     97 
     98-    bool fQueueNotifications = false;
     99+    bool m_loaded = false;
    100+    int m_progress = 100;
    


    hebasto commented at 6:08 pm on January 4, 2021:
    It would be nice to add doxygen comments for new data members.

    hebasto commented at 6:10 pm on January 4, 2021:
    Why have an int when we are only interested in bool if progress < 100?

    promag commented at 12:11 pm on April 19, 2021:
    Added.

    promag commented at 12:11 pm on April 19, 2021:
    Changed.
  14. in src/qt/transactiontablemodel.cpp:109 in 5d7d36344c outdated
    108      */
    109     void refreshWallet(interfaces::Wallet& wallet)
    110     {
    111-        qDebug() << "TransactionTablePriv::refreshWallet";
    112-        cachedWallet.clear();
    113+        assert(cachedWallet.empty());
    


    hebasto commented at 6:14 pm on January 4, 2021:

    With new logic I’d prefer to assert(!m_loaded); or

    0        assert(cachedWallet.empty() && !m_loaded);
    

    promag commented at 11:55 am on April 19, 2021:
    Done.
  15. in src/qt/transactiontablemodel.cpp:109 in 5d7d36344c outdated
    106 
    107     /* Query entire wallet anew from core.
    108      */
    109     void refreshWallet(interfaces::Wallet& wallet)
    110     {
    111-        qDebug() << "TransactionTablePriv::refreshWallet";
    


    hebasto commented at 6:16 pm on January 4, 2021:
    Why dropped?

    promag commented at 10:24 am on January 27, 2021:
    What is the goal of this log? To know when refreshWallet is called? Seems one of those logs you add when developing, but now it’s useless. I’ll revert this change if you think otherwise. It’s unrelated to this PR but committed since I was touching nearby code.

    hebasto commented at 11:02 am on January 27, 2021:

    To know when refreshWallet is called?

    Rather to know that refreshWallet is called, for example for old wallets that were not synced for a long time, no?


    promag commented at 11:35 am on January 27, 2021:
    But it’s called unconditionally in TransactionTableModel constructor.

    hebasto commented at 11:40 am on January 27, 2021:

    But it’s called unconditionally in TransactionTableModel constructor.

    Right. But it is an implementation detail that (as we assume) is hidden from users.

    Anyway, feel free to ignore this concern and mark it as resolved :)


    promag commented at 11:51 am on April 19, 2021:

    But it is an implementation detail that (as we assume) is hidden from users.

    Right, so why log it? Following the same idea there are many things we could also log.

  16. hebasto changes_requested
  17. hebasto commented at 6:17 pm on January 4, 2021: member
    Approach ACK 5d7d36344c1241fb940766905265747492570446.
  18. ryanofsky approved
  19. ryanofsky commented at 6:01 pm on January 25, 2021: contributor

    Code review ACK 5d7d36344c1241fb940766905265747492570446. This looks good but is a pretty confusing change. I think it could be clearer split up into two commits: one pure refactoring commit replacing ShowProgress with DispatchNotifications, and another commit changing initialization order moving the subscribeToCoreSignals call before the refreshWallet call and adding the new DispatchNotifications call at the end of the refreshWallet implementation.

    I will say I don’t fully understand the motivation for the two refreshMethod related changes. They seem safe but I don’t know if they are actually changing behavior now or just setting something up for the future. If they were moved to standalone commit, purpose of the changes could be made more clear either in the commit description or code comments.

    In case it helps other reviewers, I found the refactoring changes replacing ShowProgress with DispatchNotifications easier to understand after ignoring whitespace and rereading a previous explanation of the code #120 (review).

    Hebasto’s suggestions also all seem reasonable and good. Basically a lot could be made clearer here, but this PR does seems fine to merge in its current form.

    This PR might be interesting to people dealing with large wallets that have a lot of transactions, since it seems like it could help move to loading transactions asynchronously without locking up the GUI.

  20. promag commented at 10:48 am on January 27, 2021: contributor
    Thanks for reviewing, I’ll improve readability.
  21. laanwj commented at 7:17 pm on January 27, 2021: member

    This is also a requirement to call getWalletTxs in a background thread.

    Concept ACK, thanks for working on that.

  22. hebasto approved
  23. hebasto commented at 0:56 am on March 24, 2021: member

    ACK 5d7d36344c1241fb940766905265747492570446, agree with #121#pullrequestreview-575666547

    this PR does seems fine to merge in its current form.

  24. hebasto added the label Bug on Mar 25, 2021
  25. promag force-pushed on Apr 19, 2021
  26. promag commented at 12:11 pm on April 19, 2021: contributor
    Rebased and addressed @hebasto review.
  27. hebasto added the label Wallet on Apr 19, 2021
  28. hebasto renamed this:
    qt: Early subscribe core signals in transaction table model
    Early subscribe core signals in transaction table model
    on Apr 19, 2021
  29. in src/qt/transactiontablemodel.cpp:99 in 8f16516785 outdated
     95@@ -96,25 +96,29 @@ class TransactionTablePriv
     96      */
     97     QList<TransactionRecord> cachedWallet;
     98 
     99-    bool fQueueNotifications = false;
    100+    /** True when model finishes loading all wallet transaction on start */
    


    jonatack commented at 4:30 pm on April 23, 2021:
    nit, s/transaction/transactions/

    promag commented at 11:20 pm on April 28, 2021:
    Fixed.
  30. in src/qt/transactiontablemodel.cpp:102 in 8f16516785 outdated
     95@@ -96,25 +96,29 @@ class TransactionTablePriv
     96      */
     97     QList<TransactionRecord> cachedWallet;
     98 
     99-    bool fQueueNotifications = false;
    100+    /** True when model finishes loading all wallet transaction on start */
    101+    bool m_loaded = false;
    102+    /** True when transactions are being notified, for instance when scanning */
    103+    int m_loading = false;
    


    jonatack commented at 4:33 pm on April 23, 2021:

    (maybe a leftover from an initial version?) this can work but unless I’m misreading m_loading will only be set to true or false (1 or 0)

    0    bool m_loading = false;
    

    promag commented at 11:19 pm on April 28, 2021:
    Fixed.
  31. jonatack commented at 4:55 pm on April 23, 2021: contributor
    Approach ACK modulo that it’s a fairly confusing change and separating into more commits may help here (as mentioned above).
  32. qt: Set flag after inital load on transaction table model 3bccd50ad2
  33. qt: Refactor ShowProgress to DispatchNotifications c6cbdf1a90
  34. qt: Early subscribe core signals in transaction table model 57785fb7f6
  35. qt: Refactor to remove unnecessary block in DispatchNotifications
    Review with --ignore-all-space
    cafef080a2
  36. promag force-pushed on Apr 28, 2021
  37. promag commented at 11:21 pm on April 28, 2021: contributor
    Ok, I’ve tried to split in decent commits.
  38. in src/qt/transactiontablemodel.cpp:120 in cafef080a2
    119                 if (TransactionRecord::showTransaction()) {
    120                     cachedWallet.append(TransactionRecord::decomposeTransaction(wtx));
    121                 }
    122             }
    123         }
    124+        m_loaded = true;
    


    jonatack commented at 5:55 pm on April 29, 2021:

    3bccd50ad2f38 nit, can drop extra brackets

     0diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
     1index 0175c88e7..8dc6d4c40 100644
     2--- a/src/qt/transactiontablemodel.cpp
     3+++ b/src/qt/transactiontablemodel.cpp
     4@@ -110,11 +110,9 @@ public:
     5     void refreshWallet(interfaces::Wallet& wallet)
     6     {
     7         assert(!m_loaded);
     8-        {
     9-            for (const auto& wtx : wallet.getWalletTxs()) {
    10-                if (TransactionRecord::showTransaction()) {
    11-                    cachedWallet.append(TransactionRecord::decomposeTransaction(wtx));
    12-                }
    13+        for (const auto& wtx : wallet.getWalletTxs()) {
    14+            if (TransactionRecord::showTransaction()) {
    15+                cachedWallet.append(TransactionRecord::decomposeTransaction(wtx));
    16             }
    17         }
    18         m_loaded = true;
    

    jonatack commented at 5:57 pm on April 29, 2021:
    (similar to the change in the last commit, git show cafef080a2e --ignore-all-space)
  39. in src/qt/transactiontablemodel.cpp:743 in cafef080a2
    743+    if (vQueueNotifications.size() > 10) { // prevent balloon spam, show maximum 10 balloons
    744+        bool invoked = QMetaObject::invokeMethod(parent, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true));
    745+        assert(invoked);
    746+    }
    747+    for (unsigned int i = 0; i < vQueueNotifications.size(); ++i)
    748     {
    


    jonatack commented at 6:21 pm on April 29, 2021:

    cafef080a2e59c2 nit, while removing the brackets in this commit could also

     0diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
     1index 0175c88e7..734605a47 100644
     2--- a/src/qt/transactiontablemodel.cpp
     3+++ b/src/qt/transactiontablemodel.cpp
     4@@ -739,8 +739,7 @@ void TransactionTablePriv::DispatchNotifications()
     5         bool invoked = QMetaObject::invokeMethod(parent, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true));
     6         assert(invoked);
     7     }
     8-    for (unsigned int i = 0; i < vQueueNotifications.size(); ++i)
     9-    {
    10+    for (unsigned int i = 0; i < vQueueNotifications.size(); ++i) {
    
  40. jonatack commented at 6:23 pm on April 29, 2021: contributor

    tACK cafef080a2e59c2bcae6baeee3c3c7e187e931ae

    happy to re-ACK for the above

  41. in src/qt/transactiontablemodel.cpp:101 in cafef080a2
     95@@ -96,25 +96,29 @@ class TransactionTablePriv
     96      */
     97     QList<TransactionRecord> cachedWallet;
     98 
     99-    bool fQueueNotifications = false;
    100+    /** True when model finishes loading all wallet transactions on start */
    101+    bool m_loaded = false;
    102+    /** True when transactions are being notified, for instance when scanning */
    


    hebasto commented at 6:33 pm on April 29, 2021:

    It could be just my bad English, but it seems should be “… are not being notified”, no?

    If I’m correct, maybe re-word the comment in positive one?

    Or maybe we think about different notifications: (a) from the node vs (b) to a user?


    promag commented at 12:55 pm on April 30, 2021:
    Right, I’ll rephrase.

    ryanofsky commented at 1:06 am on May 4, 2021:

    In commit “qt: Refactor ShowProgress to DispatchNotifications” (c6cbdf1a90a253fef0259b365a782bf88cd437f2)

    re: #121 (review)

    Right, I’ll rephrase.

    If you’re still planning to update this, my attempt at a comment would be: “This will be true when blocks in the chain are being scanned for new transactions, and transaction notification popups should be suppressed until the scan is done. It can be true even after m_loaded is true if a rescan has been triggered.” I think I would also call this m_delay_notifications instead of m_loading because it can be true when m_loaded is also true, but feel free to stick with whatever name you prefer.

  42. in src/qt/transactiontablemodel.cpp:106 in cafef080a2
    103+    bool m_loading = false;
    104     std::vector< TransactionNotification > vQueueNotifications;
    105 
    106     void NotifyTransactionChanged(const uint256 &hash, ChangeType status);
    107-    void ShowProgress(const std::string &title, int nProgress);
    108+    void DispatchNotifications();
    


    hebasto commented at 6:33 pm on April 29, 2021:
    A doxygen comment?
  43. in src/qt/transactiontablemodel.cpp:727 in cafef080a2
    722@@ -719,44 +723,42 @@ void TransactionTablePriv::NotifyTransactionChanged(const uint256 &hash, ChangeT
    723 
    724     TransactionNotification notification(hash, status, showTransaction);
    725 
    726-    if (fQueueNotifications)
    727+    if (!m_loaded || m_loading)
    728     {
    


    hebasto commented at 6:34 pm on April 29, 2021:

    style nit:

    0    if (!m_loaded || m_loading) {
    
  44. hebasto commented at 6:35 pm on April 29, 2021: member
    Thanks for splitting commits! Much easier to review.
  45. ryanofsky approved
  46. ryanofsky commented at 1:30 am on May 4, 2021: contributor

    Code review ACK cafef080a2e59c2bcae6baeee3c3c7e187e931ae. Only change since last review is splitting commits and replacing m_progress with m_loading.

    Thanks for the updates! I think this change is much easier to understand now.

    It would be good to clarify in the PR description what exactly is meant by “This fixes the case where transaction notifications arrive between getWalletTxs and subscribeToCoreSignals.” It’s not clear from the description what the old behavior was and what the new behavior is.

    IIUC, the problem was that notifications about new transactions discovered while the wallet was being loaded were dropped previously, and now they are shown?

  47. meshcollider commented at 4:45 am on May 25, 2021: contributor
    Code review ACK cafef080a2e59c2bcae6baeee3c3c7e187e931ae
  48. hebasto merged this on May 26, 2021
  49. hebasto closed this on May 26, 2021

  50. promag deleted the branch on May 26, 2021
  51. sidhujag referenced this in commit 8bd2ce346d on May 27, 2021
  52. gwillen referenced this in commit 2893856697 on Jun 1, 2022
  53. bitcoin-core locked this on Aug 16, 2022

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin-core/gui. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-10-23 00:20 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me