Skip to content

Commit d4640d7

Browse files
Added argument to getbalance to include watchonly addresses and fixed errors in balance calculation.
1 parent d2692f6 commit d4640d7

File tree

4 files changed

+62
-24
lines changed

4 files changed

+62
-24
lines changed

src/rpcclient.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
4040
{ "listreceivedbyaccount", 0 },
4141
{ "listreceivedbyaccount", 1 },
4242
{ "getbalance", 1 },
43+
{ "getbalance", 2 },
4344
{ "getblockhash", 0 },
4445
{ "move", 2 },
4546
{ "move", 3 },

src/rpcwallet.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
557557
}
558558

559559

560-
int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth)
560+
int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth, const isminefilter& filter = MINE_SPENDABLE)
561561
{
562562
int64_t nBalance = 0;
563563

@@ -569,7 +569,7 @@ int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMi
569569
continue;
570570

571571
int64_t nReceived, nSent, nFee;
572-
wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee);
572+
wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee, filter);
573573

574574
if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
575575
nBalance += nReceived;
@@ -582,25 +582,26 @@ int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMi
582582
return nBalance;
583583
}
584584

585-
int64_t GetAccountBalance(const string& strAccount, int nMinDepth)
585+
int64_t GetAccountBalance(const string& strAccount, int nMinDepth, const isminefilter& filter = MINE_SPENDABLE)
586586
{
587587
CWalletDB walletdb(pwalletMain->strWalletFile);
588-
return GetAccountBalance(walletdb, strAccount, nMinDepth);
588+
return GetAccountBalance(walletdb, strAccount, nMinDepth, filter);
589589
}
590590

591591

592592
Value getbalance(const Array& params, bool fHelp)
593593
{
594-
if (fHelp || params.size() > 2)
594+
if (fHelp || params.size() > 3)
595595
throw runtime_error(
596-
"getbalance ( \"account\" minconf )\n"
596+
"getbalance ( \"account\" minconf includeWatchonly )\n"
597597
"\nIf account is not specified, returns the server's total available balance.\n"
598598
"If account is specified, returns the balance in the account.\n"
599599
"Note that the account \"\" is not the same as leaving the parameter out.\n"
600600
"The server total may be different to the balance in the default \"\" account.\n"
601601
"\nArguments:\n"
602602
"1. \"account\" (string, optional) The selected account, or \"*\" for entire wallet. It may be the default account using \"\".\n"
603603
"2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
604+
"3. includeWatchonly (bool, optional, default=false) Also include balance in watchonly addresses (see 'importaddress')\n"
604605
"\nResult:\n"
605606
"amount (numeric) The total amount in btc received for this account.\n"
606607
"\nExamples:\n"
@@ -620,8 +621,14 @@ Value getbalance(const Array& params, bool fHelp)
620621
return ValueFromAmount(pwalletMain->GetBalance());
621622

622623
int nMinDepth = 1;
624+
isminefilter filter = MINE_SPENDABLE;
623625
if (params.size() > 1)
626+
{
624627
nMinDepth = params[1].get_int();
628+
if(params.size() > 2)
629+
if(params[2].get_bool())
630+
filter = filter | MINE_WATCH_ONLY;
631+
}
625632

626633
if (params[0].get_str() == "*") {
627634
// Calculate total balance a different way from GetBalance()
@@ -638,7 +645,7 @@ Value getbalance(const Array& params, bool fHelp)
638645
string strSentAccount;
639646
list<pair<CTxDestination, int64_t> > listReceived;
640647
list<pair<CTxDestination, int64_t> > listSent;
641-
wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount);
648+
wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
642649
if (wtx.GetDepthInMainChain() >= nMinDepth)
643650
{
644651
BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listReceived)
@@ -653,7 +660,7 @@ Value getbalance(const Array& params, bool fHelp)
653660

654661
string strAccount = AccountFromValue(params[0]);
655662

656-
int64_t nBalance = GetAccountBalance(strAccount, nMinDepth);
663+
int64_t nBalance = GetAccountBalance(strAccount, nMinDepth, filter);
657664

658665
return ValueFromAmount(nBalance);
659666
}

src/wallet.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ isminetype CWallet::IsMine(const CTxIn &txin) const
711711
return MINE_NO;
712712
}
713713

714-
int64_t CWallet::GetDebit(const CTxIn &txin) const
714+
int64_t CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
715715
{
716716
{
717717
LOCK(cs_wallet);
@@ -720,7 +720,7 @@ int64_t CWallet::GetDebit(const CTxIn &txin) const
720720
{
721721
const CWalletTx& prev = (*mi).second;
722722
if (txin.prevout.n < prev.vout.size())
723-
if (IsMine(prev.vout[txin.prevout.n]))
723+
if (IsMine(prev.vout[txin.prevout.n]) & filter)
724724
return prev.vout[txin.prevout.n].nValue;
725725
}
726726
}
@@ -801,7 +801,7 @@ void CWalletTx::GetAmounts(list<pair<CTxDestination, int64_t> >& listReceived,
801801
strSentAccount = strFromAccount;
802802

803803
// Compute fee:
804-
int64_t nDebit = GetDebit();
804+
int64_t nDebit = GetDebit(filter);
805805
if (nDebit > 0) // debit>0 means we signed/sent this transaction
806806
{
807807
int64_t nValueOut = GetValueOut();
@@ -846,15 +846,15 @@ void CWalletTx::GetAmounts(list<pair<CTxDestination, int64_t> >& listReceived,
846846
}
847847

848848
void CWalletTx::GetAccountAmounts(const string& strAccount, int64_t& nReceived,
849-
int64_t& nSent, int64_t& nFee) const
849+
int64_t& nSent, int64_t& nFee, const isminefilter& filter) const
850850
{
851851
nReceived = nSent = nFee = 0;
852852

853853
int64_t allFee;
854854
string strSentAccount;
855855
list<pair<CTxDestination, int64_t> > listReceived;
856856
list<pair<CTxDestination, int64_t> > listSent;
857-
GetAmounts(listReceived, listSent, allFee, strSentAccount);
857+
GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
858858

859859
if (strAccount == strSentAccount)
860860
{

src/wallet.h

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -288,12 +288,12 @@ class CWallet : public CCryptoKeyStore, public CWalletInterface
288288
std::set<CTxDestination> GetAccountAddresses(std::string strAccount) const;
289289

290290
isminetype IsMine(const CTxIn& txin) const;
291-
int64_t GetDebit(const CTxIn& txin) const;
291+
int64_t GetDebit(const CTxIn& txin, const isminefilter& filter=(MINE_SPENDABLE|MINE_WATCH_ONLY)) const;
292292
isminetype IsMine(const CTxOut& txout) const
293293
{
294294
return ::IsMine(*this, txout.scriptPubKey);
295295
}
296-
int64_t GetCredit(const CTxOut& txout, const isminefilter& filter = (MINE_WATCH_ONLY | MINE_SPENDABLE)) const
296+
int64_t GetCredit(const CTxOut& txout, const isminefilter& filter=(MINE_WATCH_ONLY|MINE_SPENDABLE)) const
297297
{
298298
if (!MoneyRange(txout.nValue))
299299
throw std::runtime_error("CWallet::GetCredit() : value out of range");
@@ -324,12 +324,12 @@ class CWallet : public CCryptoKeyStore, public CWalletInterface
324324
return true;
325325
return false;
326326
}
327-
int64_t GetDebit(const CTransaction& tx) const
327+
int64_t GetDebit(const CTransaction& tx, const isminefilter& filter=(MINE_SPENDABLE|MINE_WATCH_ONLY)) const
328328
{
329329
int64_t nDebit = 0;
330330
BOOST_FOREACH(const CTxIn& txin, tx.vin)
331331
{
332-
nDebit += GetDebit(txin);
332+
nDebit += GetDebit(txin, filter);
333333
if (!MoneyRange(nDebit))
334334
throw std::runtime_error("CWallet::GetDebit() : value out of range");
335335
}
@@ -486,13 +486,17 @@ class CWalletTx : public CMerkleTx
486486
mutable bool fCreditCached;
487487
mutable bool fImmatureCreditCached;
488488
mutable bool fAvailableCreditCached;
489+
mutable bool fWatchDebitCached;
490+
mutable bool fWatchCreditCached;
489491
mutable bool fImmatureWatchCreditCached;
490492
mutable bool fAvailableWatchCreditCached;
491493
mutable bool fChangeCached;
492494
mutable int64_t nDebitCached;
493495
mutable int64_t nCreditCached;
494496
mutable int64_t nImmatureCreditCached;
495497
mutable int64_t nAvailableCreditCached;
498+
mutable int64_t nWatchDebitCached;
499+
mutable int64_t nWatchCreditCached;
496500
mutable int64_t nImmatureWatchCreditCached;
497501
mutable int64_t nAvailableWatchCreditCached;
498502
mutable int64_t nChangeCached;
@@ -531,13 +535,17 @@ class CWalletTx : public CMerkleTx
531535
fCreditCached = false;
532536
fImmatureCreditCached = false;
533537
fAvailableCreditCached = false;
538+
fWatchDebitCached = false;
539+
fWatchCreditCached = false;
534540
fImmatureWatchCreditCached = false;
535541
fAvailableWatchCreditCached = false;
536542
fChangeCached = false;
537543
nDebitCached = 0;
538544
nCreditCached = 0;
539545
nImmatureCreditCached = 0;
540546
nAvailableCreditCached = 0;
547+
nWatchDebitCached = 0;
548+
nWatchCreditCached = 0;
541549
nAvailableWatchCreditCached = 0;
542550
nImmatureWatchCreditCached = 0;
543551
nChangeCached = 0;
@@ -592,6 +600,8 @@ class CWalletTx : public CMerkleTx
592600
{
593601
fCreditCached = false;
594602
fAvailableCreditCached = false;
603+
fWatchDebitCached = false;
604+
fWatchCreditCached = false;
595605
fAvailableWatchCreditCached = false;
596606
fImmatureWatchCreditCached = false;
597607
fDebitCached = false;
@@ -604,15 +614,35 @@ class CWalletTx : public CMerkleTx
604614
MarkDirty();
605615
}
606616

607-
int64_t GetDebit() const
617+
int64_t GetDebit(const isminefilter& filter=(MINE_SPENDABLE|MINE_WATCH_ONLY)) const
608618
{
609619
if (vin.empty())
610620
return 0;
611-
if (fDebitCached)
612-
return nDebitCached;
613-
nDebitCached = pwallet->GetDebit(*this);
614-
fDebitCached = true;
615-
return nDebitCached;
621+
622+
int64_t debit = 0;
623+
if(filter & MINE_SPENDABLE)
624+
{
625+
if (fDebitCached)
626+
debit += nDebitCached;
627+
else
628+
{
629+
nDebitCached = pwallet->GetDebit(*this, MINE_SPENDABLE);
630+
fDebitCached = true;
631+
debit += nDebitCached;
632+
}
633+
}
634+
if(filter & MINE_WATCH_ONLY)
635+
{
636+
if(fWatchDebitCached)
637+
debit += nWatchDebitCached;
638+
else
639+
{
640+
nWatchDebitCached = pwallet->GetDebit(*this, MINE_WATCH_ONLY);
641+
fWatchDebitCached = true;
642+
debit += nWatchDebitCached;
643+
}
644+
}
645+
return debit;
616646
}
617647

618648
int64_t GetCredit(bool fUseCache=true) const
@@ -729,7 +759,7 @@ class CWalletTx : public CMerkleTx
729759
std::list<std::pair<CTxDestination, int64_t> >& listSent, int64_t& nFee, std::string& strSentAccount, const isminefilter& filter=(MINE_SPENDABLE|MINE_WATCH_ONLY)) const;
730760

731761
void GetAccountAmounts(const std::string& strAccount, int64_t& nReceived,
732-
int64_t& nSent, int64_t& nFee) const;
762+
int64_t& nSent, int64_t& nFee, const isminefilter& filter=(MINE_SPENDABLE|MINE_WATCH_ONLY)) const;
733763

734764
bool IsFromMe() const
735765
{

0 commit comments

Comments
 (0)