-
Notifications
You must be signed in to change notification settings - Fork 1.2k
backport: bitcoin#25933, bitcoin-core/gui#598, partial #26699 #7602
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
87e5be4
01c5701
2c5fa19
b8c7d4a
5b34dab
5df7df4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -63,6 +63,9 @@ WalletModel::WalletModel(std::unique_ptr<interfaces::Wallet> wallet, ClientModel | |||||||||||||||||
| connect(optionsModel, &OptionsModel::dustProtectionChanged, this, &WalletModel::lockExistingDustOutputs); | ||||||||||||||||||
| // Lock existing dust on startup if dust protection is enabled | ||||||||||||||||||
| lockExistingDustOutputs(); | ||||||||||||||||||
| // CoinJoin balances are calculated only while CoinJoin is enabled, | ||||||||||||||||||
| // so the cached balance must be recalculated when it is toggled | ||||||||||||||||||
| connect(optionsModel, &OptionsModel::showCoinJoinChanged, this, [this] { fForceCheckBalanceChanged = true; }); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
@@ -73,6 +76,10 @@ WalletModel::~WalletModel() | |||||||||||||||||
|
|
||||||||||||||||||
| void WalletModel::startPollBalance() | ||||||||||||||||||
| { | ||||||||||||||||||
| // Update the cached balance right away, so every view can make use of it, | ||||||||||||||||||
| // so them don't need to waste resources recalculating it. | ||||||||||||||||||
| pollBalanceChanged(); | ||||||||||||||||||
|
|
||||||||||||||||||
| // This timer will be fired repeatedly to update the balance | ||||||||||||||||||
| // Since the QTimer::timeout is a private signal, it cannot be used | ||||||||||||||||||
| // in the GUIUtil::ExceptionSafeConnect directly. | ||||||||||||||||||
|
|
@@ -137,18 +144,29 @@ void WalletModel::pollBalanceChanged() | |||||||||||||||||
|
|
||||||||||||||||||
| void WalletModel::checkBalanceChanged(const interfaces::WalletBalances& new_balances) | ||||||||||||||||||
| { | ||||||||||||||||||
| if(new_balances.balanceChanged(m_cached_balances)) { | ||||||||||||||||||
| if (new_balances.balanceChanged(m_cached_balances)) { | ||||||||||||||||||
| m_cached_balances = new_balances; | ||||||||||||||||||
| Q_EMIT balanceChanged(new_balances); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| interfaces::WalletBalances WalletModel::getCachedBalance() const | ||||||||||||||||||
| { | ||||||||||||||||||
| return m_cached_balances; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| void WalletModel::updateTransaction() | ||||||||||||||||||
| { | ||||||||||||||||||
| // Balance and number of transactions might have changed | ||||||||||||||||||
| fForceCheckBalanceChanged = true; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| void WalletModel::updateLockedCoins() | ||||||||||||||||||
| { | ||||||||||||||||||
| // Locked share of the balance changed | ||||||||||||||||||
| fForceCheckBalanceChanged = true; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| void WalletModel::lockExistingDustOutputs() | ||||||||||||||||||
| { | ||||||||||||||||||
| if (!optionsModel) return; | ||||||||||||||||||
|
|
@@ -258,7 +276,9 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact | |||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| CAmount nBalance = m_wallet->getAvailableBalance(coinControl); | ||||||||||||||||||
| // If no coin was manually selected, use the cached balance | ||||||||||||||||||
| // Future: can merge this call with 'createTransaction'. | ||||||||||||||||||
| CAmount nBalance = getAvailableBalance(&coinControl); | ||||||||||||||||||
|
|
||||||||||||||||||
| if(total > nBalance) | ||||||||||||||||||
| { | ||||||||||||||||||
|
|
@@ -513,6 +533,12 @@ static void NotifyCanGetAddressesChanged(WalletModel* walletmodel) | |||||||||||||||||
| assert(invoked); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| static void NotifyLockedCoinsChanged(WalletModel* walletmodel) | ||||||||||||||||||
| { | ||||||||||||||||||
| bool invoked = QMetaObject::invokeMethod(walletmodel, "updateLockedCoins", Qt::QueuedConnection); | ||||||||||||||||||
| assert(invoked); | ||||||||||||||||||
|
Comment on lines
+536
to
+539
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win Use
As per coding guidelines, use Proposed fix- assert(invoked);
+ Assume(invoked);📝 Committable suggestion
Suggested change
🤖 Prompt for AI AgentsSource: Coding guidelines There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The replacement is correct under the project's assertion policy because a failed queued invocation leaves execution defined and does not threaten memory safety or persisted state. One clarification: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
🐇💭 ✏️ Learnings added
🧠 Learnings usedYou are interacting with an AI system.
knst marked this conversation as resolved.
|
||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| void WalletModel::subscribeToCoreSignals() | ||||||||||||||||||
| { | ||||||||||||||||||
| // Connect signals to wallet | ||||||||||||||||||
|
|
@@ -525,6 +551,7 @@ void WalletModel::subscribeToCoreSignals() | |||||||||||||||||
| m_handler_show_progress = m_wallet->handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2)); | ||||||||||||||||||
| m_handler_watch_only_changed = m_wallet->handleWatchOnlyChanged(std::bind(NotifyWatchonlyChanged, this, std::placeholders::_1)); | ||||||||||||||||||
| m_handler_can_get_addrs_changed = m_wallet->handleCanGetAddressesChanged(std::bind(NotifyCanGetAddressesChanged, this)); | ||||||||||||||||||
| m_handler_locked_coins_changed = m_wallet->handleLockedCoinsChanged(std::bind(NotifyLockedCoinsChanged, this)); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| void WalletModel::unsubscribeFromCoreSignals() | ||||||||||||||||||
|
|
@@ -539,6 +566,7 @@ void WalletModel::unsubscribeFromCoreSignals() | |||||||||||||||||
| m_handler_show_progress->disconnect(); | ||||||||||||||||||
| m_handler_watch_only_changed->disconnect(); | ||||||||||||||||||
| m_handler_can_get_addrs_changed->disconnect(); | ||||||||||||||||||
| m_handler_locked_coins_changed->disconnect(); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| // WalletModel::UnlockContext implementation | ||||||||||||||||||
|
|
@@ -633,3 +661,24 @@ uint256 WalletModel::getLastBlockProcessed() const | |||||||||||||||||
| { | ||||||||||||||||||
| return m_client_model ? m_client_model->getBestBlockHash() : uint256{}; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| CAmount WalletModel::getAvailableBalance(const CCoinControl* control) | ||||||||||||||||||
| { | ||||||||||||||||||
| // No selected coins, return the cached balance | ||||||||||||||||||
| if (!control || !control->HasSelected()) { | ||||||||||||||||||
| const interfaces::WalletBalances& balances = getCachedBalance(); | ||||||||||||||||||
| if (control && control->IsUsingCoinJoin()) { | ||||||||||||||||||
| return balances.anonymized_balance; | ||||||||||||||||||
|
Comment on lines
+670
to
+671
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When CoinJoin is disabled during the initial balance poll, Useful? React with 👍 / 👎.
Comment on lines
+670
to
+671
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Blocking: Refresh the balance cache when CoinJoin is enabled When CoinJoin is disabled, source: ['codex'] There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Resolved in this update — Refresh the balance cache when CoinJoin is enabled no longer present. Auto-resolved by the review system based on the latest commit diff. If you believe this was closed in error, reopen the thread. |
||||||||||||||||||
| } | ||||||||||||||||||
| // Coin selection cannot spend locked coins, so keep the locked share out | ||||||||||||||||||
| CAmount available_balance = balances.balance - balances.locked_balance; | ||||||||||||||||||
| // if wallet private keys are disabled, this is a watch-only wallet | ||||||||||||||||||
| // so, let's include the watch-only balance. | ||||||||||||||||||
| if (balances.have_watch_only && m_wallet->privateKeysDisabled()) { | ||||||||||||||||||
| available_balance += balances.watch_only_balance - balances.locked_watch_only_balance; | ||||||||||||||||||
| } | ||||||||||||||||||
| return available_balance; | ||||||||||||||||||
| } | ||||||||||||||||||
| // Fetch balance from the wallet, taking into account the selected coins | ||||||||||||||||||
| return wallet().getAvailableBalance(*control); | ||||||||||||||||||
| } | ||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.