Skip to content

Commit fa57411

Browse files
author
MarcoFalke
committed
wallet: Get all balances in one call
1 parent daef20f commit fa57411

File tree

5 files changed

+48
-92
lines changed

5 files changed

+48
-92
lines changed

src/interfaces/wallet.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -358,15 +358,16 @@ class WalletImpl : public Wallet
358358
}
359359
WalletBalances getBalances() override
360360
{
361+
const auto bal = m_wallet->GetBalance();
361362
WalletBalances result;
362-
result.balance = m_wallet->GetBalance();
363-
result.unconfirmed_balance = m_wallet->GetUnconfirmedBalance();
364-
result.immature_balance = m_wallet->GetImmatureBalance();
363+
result.balance = bal.m_mine_trusted;
364+
result.unconfirmed_balance = bal.m_mine_untrusted_pending;
365+
result.immature_balance = bal.m_mine_immature;
365366
result.have_watch_only = m_wallet->HaveWatchOnly();
366367
if (result.have_watch_only) {
367-
result.watch_only_balance = m_wallet->GetBalance(ISMINE_WATCH_ONLY);
368-
result.unconfirmed_watch_only_balance = m_wallet->GetUnconfirmedWatchOnlyBalance();
369-
result.immature_watch_only_balance = m_wallet->GetImmatureWatchOnlyBalance();
368+
result.watch_only_balance = bal.m_watchonly_trusted;
369+
result.unconfirmed_watch_only_balance = bal.m_watchonly_untrusted_pending;
370+
result.immature_watch_only_balance = bal.m_watchonly_immature;
370371
}
371372
return result;
372373
}
@@ -382,7 +383,7 @@ class WalletImpl : public Wallet
382383
num_blocks = locked_chain->getHeight().get_value_or(-1);
383384
return true;
384385
}
385-
CAmount getBalance() override { return m_wallet->GetBalance(); }
386+
CAmount getBalance() override { return m_wallet->GetBalance().m_mine_trusted; }
386387
CAmount getAvailableBalance(const CCoinControl& coin_control) override
387388
{
388389
return m_wallet->GetAvailableBalance(&coin_control);

src/wallet/rpcwallet.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ static UniValue setlabel(const JSONRPCRequest& request)
308308

309309
static CTransactionRef SendMoney(interfaces::Chain::Lock& locked_chain, CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, const CCoinControl& coin_control, mapValue_t mapValue)
310310
{
311-
CAmount curBalance = pwallet->GetBalance();
311+
CAmount curBalance = pwallet->GetBalance().m_mine_trusted;
312312

313313
// Check amount
314314
if (nValue <= 0)
@@ -761,12 +761,14 @@ static UniValue getbalance(const JSONRPCRequest& request)
761761
min_depth = request.params[1].get_int();
762762
}
763763

764-
isminefilter filter = ISMINE_SPENDABLE;
764+
bool include_watchonly = false;
765765
if (!request.params[2].isNull() && request.params[2].get_bool()) {
766-
filter = filter | ISMINE_WATCH_ONLY;
766+
include_watchonly = true;
767767
}
768768

769-
return ValueFromAmount(pwallet->GetBalance(filter, min_depth));
769+
const auto bal = pwallet->GetBalance(min_depth);
770+
771+
return ValueFromAmount(bal.m_mine_trusted + (include_watchonly ? bal.m_watchonly_trusted : 0));
770772
}
771773

772774
static UniValue getunconfirmedbalance(const JSONRPCRequest &request)
@@ -794,7 +796,7 @@ static UniValue getunconfirmedbalance(const JSONRPCRequest &request)
794796
auto locked_chain = pwallet->chain().lock();
795797
LOCK(pwallet->cs_wallet);
796798

797-
return ValueFromAmount(pwallet->GetUnconfirmedBalance());
799+
return ValueFromAmount(pwallet->GetBalance().m_mine_untrusted_pending);
798800
}
799801

800802

@@ -2416,11 +2418,12 @@ static UniValue getwalletinfo(const JSONRPCRequest& request)
24162418
UniValue obj(UniValue::VOBJ);
24172419

24182420
size_t kpExternalSize = pwallet->KeypoolCountExternalKeys();
2421+
const auto bal = pwallet->GetBalance();
24192422
obj.pushKV("walletname", pwallet->GetName());
24202423
obj.pushKV("walletversion", pwallet->GetVersion());
2421-
obj.pushKV("balance", ValueFromAmount(pwallet->GetBalance()));
2422-
obj.pushKV("unconfirmed_balance", ValueFromAmount(pwallet->GetUnconfirmedBalance()));
2423-
obj.pushKV("immature_balance", ValueFromAmount(pwallet->GetImmatureBalance()));
2424+
obj.pushKV("balance", ValueFromAmount(bal.m_mine_trusted));
2425+
obj.pushKV("unconfirmed_balance", ValueFromAmount(bal.m_mine_untrusted_pending));
2426+
obj.pushKV("immature_balance", ValueFromAmount(bal.m_mine_immature));
24242427
obj.pushKV("txcount", (int)pwallet->mapWallet.size());
24252428
obj.pushKV("keypoololdest", pwallet->GetOldestKeyPoolTime());
24262429
obj.pushKV("keypoolsize", (int64_t)kpExternalSize);

src/wallet/test/wallet_tests.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
5858
BOOST_CHECK(result.last_failed_block.IsNull());
5959
BOOST_CHECK(result.last_scanned_block.IsNull());
6060
BOOST_CHECK(!result.last_scanned_height);
61-
BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 0);
61+
BOOST_CHECK_EQUAL(wallet.GetBalance().m_mine_immature, 0);
6262
}
6363

6464
// Verify ScanForWalletTransactions picks up transactions in both the old
@@ -73,7 +73,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
7373
BOOST_CHECK(result.last_failed_block.IsNull());
7474
BOOST_CHECK_EQUAL(result.last_scanned_block, newTip->GetBlockHash());
7575
BOOST_CHECK_EQUAL(*result.last_scanned_height, newTip->nHeight);
76-
BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 100 * COIN);
76+
BOOST_CHECK_EQUAL(wallet.GetBalance().m_mine_immature, 100 * COIN);
7777
}
7878

7979
// Prune the older block file.
@@ -92,7 +92,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
9292
BOOST_CHECK_EQUAL(result.last_failed_block, oldTip->GetBlockHash());
9393
BOOST_CHECK_EQUAL(result.last_scanned_block, newTip->GetBlockHash());
9494
BOOST_CHECK_EQUAL(*result.last_scanned_height, newTip->nHeight);
95-
BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 50 * COIN);
95+
BOOST_CHECK_EQUAL(wallet.GetBalance().m_mine_immature, 50 * COIN);
9696
}
9797

9898
// Prune the remaining block file.
@@ -110,7 +110,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
110110
BOOST_CHECK_EQUAL(result.last_failed_block, newTip->GetBlockHash());
111111
BOOST_CHECK(result.last_scanned_block.IsNull());
112112
BOOST_CHECK(!result.last_scanned_height);
113-
BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 0);
113+
BOOST_CHECK_EQUAL(wallet.GetBalance().m_mine_immature, 0);
114114
}
115115
}
116116

src/wallet/wallet.cpp

Lines changed: 16 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2154,84 +2154,32 @@ void CWallet::ResendWalletTransactions(interfaces::Chain::Lock& locked_chain, in
21542154
*/
21552155

21562156

2157-
CAmount CWallet::GetBalance(const isminefilter& filter, const int min_depth) const
2157+
CWallet::Balance CWallet::GetBalance(const int min_depth) const
21582158
{
2159-
CAmount nTotal = 0;
2159+
Balance ret;
21602160
{
21612161
auto locked_chain = chain().lock();
21622162
LOCK(cs_wallet);
21632163
for (const auto& entry : mapWallet)
21642164
{
21652165
const CWalletTx& wtx = entry.second;
2166-
if (wtx.IsTrusted(*locked_chain) && wtx.GetDepthInMainChain(*locked_chain) >= min_depth) {
2167-
nTotal += wtx.GetAvailableCredit(*locked_chain, true, filter);
2166+
const bool is_trusted{wtx.IsTrusted(*locked_chain)};
2167+
const int tx_depth{wtx.GetDepthInMainChain(*locked_chain)};
2168+
const CAmount tx_credit_mine{wtx.GetAvailableCredit(*locked_chain, /* fUseCache */ true, ISMINE_SPENDABLE)};
2169+
const CAmount tx_credit_watchonly{wtx.GetAvailableCredit(*locked_chain, /* fUseCache */ true, ISMINE_WATCH_ONLY)};
2170+
if (is_trusted && tx_depth >= min_depth) {
2171+
ret.m_mine_trusted += tx_credit_mine;
2172+
ret.m_watchonly_trusted += tx_credit_watchonly;
21682173
}
2174+
if (!is_trusted && tx_depth == 0 && wtx.InMempool()) {
2175+
ret.m_mine_untrusted_pending += tx_credit_mine;
2176+
ret.m_watchonly_untrusted_pending += tx_credit_watchonly;
2177+
}
2178+
ret.m_mine_immature += wtx.GetImmatureCredit(*locked_chain);
2179+
ret.m_watchonly_immature += wtx.GetImmatureWatchOnlyCredit(*locked_chain);
21692180
}
21702181
}
2171-
2172-
return nTotal;
2173-
}
2174-
2175-
CAmount CWallet::GetUnconfirmedBalance() const
2176-
{
2177-
CAmount nTotal = 0;
2178-
{
2179-
auto locked_chain = chain().lock();
2180-
LOCK(cs_wallet);
2181-
for (const auto& entry : mapWallet)
2182-
{
2183-
const CWalletTx& wtx = entry.second;
2184-
if (!wtx.IsTrusted(*locked_chain) && wtx.GetDepthInMainChain(*locked_chain) == 0 && wtx.InMempool())
2185-
nTotal += wtx.GetAvailableCredit(*locked_chain);
2186-
}
2187-
}
2188-
return nTotal;
2189-
}
2190-
2191-
CAmount CWallet::GetImmatureBalance() const
2192-
{
2193-
CAmount nTotal = 0;
2194-
{
2195-
auto locked_chain = chain().lock();
2196-
LOCK(cs_wallet);
2197-
for (const auto& entry : mapWallet)
2198-
{
2199-
const CWalletTx& wtx = entry.second;
2200-
nTotal += wtx.GetImmatureCredit(*locked_chain);
2201-
}
2202-
}
2203-
return nTotal;
2204-
}
2205-
2206-
CAmount CWallet::GetUnconfirmedWatchOnlyBalance() const
2207-
{
2208-
CAmount nTotal = 0;
2209-
{
2210-
auto locked_chain = chain().lock();
2211-
LOCK(cs_wallet);
2212-
for (const auto& entry : mapWallet)
2213-
{
2214-
const CWalletTx& wtx = entry.second;
2215-
if (!wtx.IsTrusted(*locked_chain) && wtx.GetDepthInMainChain(*locked_chain) == 0 && wtx.InMempool())
2216-
nTotal += wtx.GetAvailableCredit(*locked_chain, true, ISMINE_WATCH_ONLY);
2217-
}
2218-
}
2219-
return nTotal;
2220-
}
2221-
2222-
CAmount CWallet::GetImmatureWatchOnlyBalance() const
2223-
{
2224-
CAmount nTotal = 0;
2225-
{
2226-
auto locked_chain = chain().lock();
2227-
LOCK(cs_wallet);
2228-
for (const auto& entry : mapWallet)
2229-
{
2230-
const CWalletTx& wtx = entry.second;
2231-
nTotal += wtx.GetImmatureWatchOnlyCredit(*locked_chain);
2232-
}
2233-
}
2234-
return nTotal;
2182+
return ret;
22352183
}
22362184

22372185
CAmount CWallet::GetAvailableBalance(const CCoinControl* coinControl) const

src/wallet/wallet.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -947,11 +947,15 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
947947
void TransactionRemovedFromMempool(const CTransactionRef &ptx) override;
948948
void ReacceptWalletTransactions(interfaces::Chain::Lock& locked_chain) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
949949
void ResendWalletTransactions(interfaces::Chain::Lock& locked_chain, int64_t nBestBlockTime) override;
950-
CAmount GetBalance(const isminefilter& filter=ISMINE_SPENDABLE, const int min_depth=0) const;
951-
CAmount GetUnconfirmedBalance() const;
952-
CAmount GetImmatureBalance() const;
953-
CAmount GetUnconfirmedWatchOnlyBalance() const;
954-
CAmount GetImmatureWatchOnlyBalance() const;
950+
struct Balance {
951+
CAmount m_mine_trusted{0}; //!< Trusted, at depth=GetBalance.min_depth or more
952+
CAmount m_mine_untrusted_pending{0}; //!< Untrusted, but in mempool (pending)
953+
CAmount m_mine_immature{0}; //!< Immature coinbases in the main chain
954+
CAmount m_watchonly_trusted{0};
955+
CAmount m_watchonly_untrusted_pending{0};
956+
CAmount m_watchonly_immature{0};
957+
};
958+
Balance GetBalance(int min_depth = 0) const;
955959
CAmount GetAvailableBalance(const CCoinControl* coinControl = nullptr) const;
956960

957961
OutputType TransactionChangeType(OutputType change_type, const std::vector<CRecipient>& vecSend);

0 commit comments

Comments
 (0)