Skip to content

Commit 54ac0f8

Browse files
committed
wallet: regression fix, getAvailableBalance skips selected coins
Only a GUI issue, for the "use available balance" button when the user manually select inputs on the send screen. The previous behavior for getAvailableBalance when the coin control has selected inputs was to return the sum of them. Instead, we are currently returning the wallet's available total balance minus the selected coins total amount. Reason: We missed to update the GetAvailableBalance function to include the coin control selected coins on bitcoin#25685. Context: Since bitcoin#25685 we skip the selected coins inside `AvailableCoins`, the reason is that there is no need to walk through the entire wallet's txes map just to get coins that could have gotten by just doing a simple mapWallet.find).
1 parent 8ae2808 commit 54ac0f8

File tree

6 files changed

+28
-13
lines changed

6 files changed

+28
-13
lines changed

src/bench/wallet_create_tx.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ static void WalletCreateTx(benchmark::Bench& bench, const OutputType output_type
102102
}
103103

104104
// Check available balance
105-
auto bal = wallet::GetAvailableBalance(wallet); // Cache
105+
auto bal = WITH_LOCK(wallet.cs_wallet, return wallet::AvailableCoins(wallet).GetTotalAmount()); // Cache
106106
assert(bal == 50 * COIN * (chain_size - COINBASE_MATURITY));
107107

108108
wallet::CCoinControl coin_control;
@@ -160,7 +160,7 @@ static void AvailableCoins(benchmark::Bench& bench, const std::vector<OutputType
160160
}
161161

162162
// Check available balance
163-
auto bal = wallet::GetAvailableBalance(wallet); // Cache
163+
auto bal = WITH_LOCK(wallet.cs_wallet, return wallet::AvailableCoins(wallet).GetTotalAmount()); // Cache
164164
assert(bal == 50 * COIN * (chain_size - COINBASE_MATURITY));
165165

166166
bench.epochIterations(2).run([&] {

src/qt/sendcoinsdialog.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,8 +781,13 @@ void SendCoinsDialog::useAvailableBalance(SendCoinsEntry* entry)
781781
// Include watch-only for wallets without private key
782782
m_coin_control->fAllowWatchOnly = model->wallet().privateKeysDisabled() && !model->wallet().hasExternalSigner();
783783

784+
// Same behavior as send: if we have selected coins, only obtain their available balance.
785+
// future, introduce a checkbox to customize this value.
786+
CCoinControl coin_control = *m_coin_control;
787+
coin_control.m_allow_other_inputs = !coin_control.HasSelected();
788+
784789
// Calculate available amount to send.
785-
CAmount amount = model->getAvailableBalance(m_coin_control.get());
790+
CAmount amount = model->getAvailableBalance(&coin_control);
786791
for (int i = 0; i < ui->entries->count(); ++i) {
787792
SendCoinsEntry* e = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
788793
if (e && !e->isHidden() && e != entry) {

src/wallet/interfaces.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <util/system.h>
1919
#include <util/translation.h>
2020
#include <util/ui_change_type.h>
21+
#include <wallet/coincontrol.h>
2122
#include <wallet/context.h>
2223
#include <wallet/feebumper.h>
2324
#include <wallet/fees.h>
@@ -402,7 +403,24 @@ class WalletImpl : public Wallet
402403
CAmount getBalance() override { return GetBalance(*m_wallet).m_mine_trusted; }
403404
CAmount getAvailableBalance(const CCoinControl& coin_control) override
404405
{
405-
return GetAvailableBalance(*m_wallet, &coin_control);
406+
LOCK(m_wallet->cs_wallet);
407+
CAmount total_amount = 0;
408+
// Fetch selected coins total amount
409+
if (coin_control.HasSelected()) {
410+
FastRandomContext rng{};
411+
CoinSelectionParams params(rng);
412+
// Note: for now, swallow any error.
413+
if (auto res = FetchSelectedInputs(*m_wallet, coin_control, params)) {
414+
total_amount += res->total_amount;
415+
}
416+
}
417+
418+
// And fetch the wallet available coins
419+
if (coin_control.m_allow_other_inputs) {
420+
total_amount += AvailableCoins(*m_wallet, &coin_control).GetTotalAmount();
421+
}
422+
423+
return total_amount;
406424
}
407425
isminetype txinIsMine(const CTxIn& txin) override
408426
{

src/wallet/spend.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -356,12 +356,6 @@ CoinsResult AvailableCoinsListUnspent(const CWallet& wallet, const CCoinControl*
356356
return AvailableCoins(wallet, coinControl, /*feerate=*/ std::nullopt, params);
357357
}
358358

359-
CAmount GetAvailableBalance(const CWallet& wallet, const CCoinControl* coinControl)
360-
{
361-
LOCK(wallet.cs_wallet);
362-
return AvailableCoins(wallet, coinControl).GetTotalAmount();
363-
}
364-
365359
const CTxOut& FindNonChangeParentOutput(const CWallet& wallet, const COutPoint& outpoint)
366360
{
367361
AssertLockHeld(wallet.cs_wallet);

src/wallet/spend.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,6 @@ CoinsResult AvailableCoins(const CWallet& wallet,
9494
*/
9595
CoinsResult AvailableCoinsListUnspent(const CWallet& wallet, const CCoinControl* coinControl = nullptr, CoinFilterParams params = {}) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
9696

97-
CAmount GetAvailableBalance(const CWallet& wallet, const CCoinControl* coinControl = nullptr);
98-
9997
/**
10098
* Find non-change parent output.
10199
*/

src/wallet/test/wallet_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ BOOST_FIXTURE_TEST_CASE(ListCoinsTest, ListCoinsTestingSetup)
581581
BOOST_CHECK_EQUAL(list.begin()->second.size(), 1U);
582582

583583
// Check initial balance from one mature coinbase transaction.
584-
BOOST_CHECK_EQUAL(50 * COIN, GetAvailableBalance(*wallet));
584+
BOOST_CHECK_EQUAL(50 * COIN, WITH_LOCK(wallet->cs_wallet, return AvailableCoins(*wallet).GetTotalAmount()));
585585

586586
// Add a transaction creating a change address, and confirm ListCoins still
587587
// returns the coin associated with the change address underneath the

0 commit comments

Comments
 (0)