Skip to content

Commit

Permalink
Added argument to getbalance to include watchonly addresses and fixed…
Browse files Browse the repository at this point in the history
… errors in balance calculation.

Conflicts:
	src/wallet.h

Rebased-from: d4640d7 bitcoin#4045
  • Loading branch information
sdkfjlsfjlskdfjlsdjflsjf authored and wtogami committed Sep 19, 2014
1 parent 7334b60 commit 72aa20b
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 24 deletions.
1 change: 1 addition & 0 deletions src/rpcclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "listreceivedbyaccount", 0 },
{ "listreceivedbyaccount", 1 },
{ "getbalance", 1 },
{ "getbalance", 2 },
{ "getblockhash", 0 },
{ "move", 2 },
{ "move", 3 },
Expand Down
23 changes: 15 additions & 8 deletions src/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
}


int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth)
int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth, const isminefilter& filter = MINE_SPENDABLE)
{
int64_t nBalance = 0;

Expand All @@ -564,7 +564,7 @@ int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMi
continue;

int64_t nReceived, nSent, nFee;
wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee);
wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee, filter);

if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
nBalance += nReceived;
Expand All @@ -577,25 +577,26 @@ int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMi
return nBalance;
}

int64_t GetAccountBalance(const string& strAccount, int nMinDepth)
int64_t GetAccountBalance(const string& strAccount, int nMinDepth, const isminefilter& filter = MINE_SPENDABLE)
{
CWalletDB walletdb(pwalletMain->strWalletFile);
return GetAccountBalance(walletdb, strAccount, nMinDepth);
return GetAccountBalance(walletdb, strAccount, nMinDepth, filter);
}


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

int nMinDepth = 1;
isminefilter filter = MINE_SPENDABLE;
if (params.size() > 1)
{
nMinDepth = params[1].get_int();
if(params.size() > 2)
if(params[2].get_bool())
filter = filter | MINE_WATCH_ONLY;
}

if (params[0].get_str() == "*") {
// Calculate total balance a different way from GetBalance()
Expand All @@ -633,7 +640,7 @@ Value getbalance(const Array& params, bool fHelp)
string strSentAccount;
list<pair<CTxDestination, int64_t> > listReceived;
list<pair<CTxDestination, int64_t> > listSent;
wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount);
wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
if (wtx.GetDepthInMainChain() >= nMinDepth)
{
BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listReceived)
Expand All @@ -648,7 +655,7 @@ Value getbalance(const Array& params, bool fHelp)

string strAccount = AccountFromValue(params[0]);

int64_t nBalance = GetAccountBalance(strAccount, nMinDepth);
int64_t nBalance = GetAccountBalance(strAccount, nMinDepth, filter);

return ValueFromAmount(nBalance);
}
Expand Down
10 changes: 5 additions & 5 deletions src/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ isminetype CWallet::IsMine(const CTxIn &txin) const
return MINE_NO;
}

int64_t CWallet::GetDebit(const CTxIn &txin) const
int64_t CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
{
{
LOCK(cs_wallet);
Expand All @@ -690,7 +690,7 @@ int64_t CWallet::GetDebit(const CTxIn &txin) const
{
const CWalletTx& prev = (*mi).second;
if (txin.prevout.n < prev.vout.size())
if (IsMine(prev.vout[txin.prevout.n]))
if (IsMine(prev.vout[txin.prevout.n]) & filter)
return prev.vout[txin.prevout.n].nValue;
}
}
Expand Down Expand Up @@ -771,7 +771,7 @@ void CWalletTx::GetAmounts(list<pair<CTxDestination, int64_t> >& listReceived,
strSentAccount = strFromAccount;

// Compute fee:
int64_t nDebit = GetDebit();
int64_t nDebit = GetDebit(filter);
if (nDebit > 0) // debit>0 means we signed/sent this transaction
{
int64_t nValueOut = GetValueOut();
Expand Down Expand Up @@ -816,15 +816,15 @@ void CWalletTx::GetAmounts(list<pair<CTxDestination, int64_t> >& listReceived,
}

void CWalletTx::GetAccountAmounts(const string& strAccount, int64_t& nReceived,
int64_t& nSent, int64_t& nFee) const
int64_t& nSent, int64_t& nFee, const isminefilter& filter) const
{
nReceived = nSent = nFee = 0;

int64_t allFee;
string strSentAccount;
list<pair<CTxDestination, int64_t> > listReceived;
list<pair<CTxDestination, int64_t> > listSent;
GetAmounts(listReceived, listSent, allFee, strSentAccount);
GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);

if (strAccount == strSentAccount)
{
Expand Down
52 changes: 41 additions & 11 deletions src/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,12 +285,12 @@ class CWallet : public CCryptoKeyStore, public CWalletInterface
std::set<CTxDestination> GetAccountAddresses(std::string strAccount) const;

isminetype IsMine(const CTxIn& txin) const;
int64_t GetDebit(const CTxIn& txin) const;
int64_t GetDebit(const CTxIn& txin, const isminefilter& filter=(MINE_SPENDABLE|MINE_WATCH_ONLY)) const;
isminetype IsMine(const CTxOut& txout) const
{
return ::IsMine(*this, txout.scriptPubKey);
}
int64_t GetCredit(const CTxOut& txout, const isminefilter& filter = (MINE_WATCH_ONLY | MINE_SPENDABLE)) const
int64_t GetCredit(const CTxOut& txout, const isminefilter& filter=(MINE_WATCH_ONLY|MINE_SPENDABLE)) const
{
if (!MoneyRange(txout.nValue))
throw std::runtime_error("CWallet::GetCredit() : value out of range");
Expand All @@ -314,12 +314,12 @@ class CWallet : public CCryptoKeyStore, public CWalletInterface
{
return (GetDebit(tx) > 0);
}
int64_t GetDebit(const CTransaction& tx) const
int64_t GetDebit(const CTransaction& tx, const isminefilter& filter=(MINE_SPENDABLE|MINE_WATCH_ONLY)) const
{
int64_t nDebit = 0;
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
nDebit += GetDebit(txin);
nDebit += GetDebit(txin, filter);
if (!MoneyRange(nDebit))
throw std::runtime_error("CWallet::GetDebit() : value out of range");
}
Expand Down Expand Up @@ -476,13 +476,17 @@ class CWalletTx : public CMerkleTx
mutable bool fCreditCached;
mutable bool fImmatureCreditCached;
mutable bool fAvailableCreditCached;
mutable bool fWatchDebitCached;
mutable bool fWatchCreditCached;
mutable bool fImmatureWatchCreditCached;
mutable bool fAvailableWatchCreditCached;
mutable bool fChangeCached;
mutable int64_t nDebitCached;
mutable int64_t nCreditCached;
mutable int64_t nImmatureCreditCached;
mutable int64_t nAvailableCreditCached;
mutable int64_t nWatchDebitCached;
mutable int64_t nWatchCreditCached;
mutable int64_t nImmatureWatchCreditCached;
mutable int64_t nAvailableWatchCreditCached;
mutable int64_t nChangeCached;
Expand Down Expand Up @@ -521,13 +525,17 @@ class CWalletTx : public CMerkleTx
fCreditCached = false;
fImmatureCreditCached = false;
fAvailableCreditCached = false;
fWatchDebitCached = false;
fWatchCreditCached = false;
fImmatureWatchCreditCached = false;
fAvailableWatchCreditCached = false;
fChangeCached = false;
nDebitCached = 0;
nCreditCached = 0;
nImmatureCreditCached = 0;
nAvailableCreditCached = 0;
nWatchDebitCached = 0;
nWatchCreditCached = 0;
nAvailableWatchCreditCached = 0;
nImmatureWatchCreditCached = 0;
nChangeCached = 0;
Expand Down Expand Up @@ -582,6 +590,8 @@ class CWalletTx : public CMerkleTx
{
fCreditCached = false;
fAvailableCreditCached = false;
fWatchDebitCached = false;
fWatchCreditCached = false;
fAvailableWatchCreditCached = false;
fImmatureWatchCreditCached = false;
fDebitCached = false;
Expand All @@ -594,15 +604,35 @@ class CWalletTx : public CMerkleTx
MarkDirty();
}

int64_t GetDebit() const
int64_t GetDebit(const isminefilter& filter=(MINE_SPENDABLE|MINE_WATCH_ONLY)) const
{
if (vin.empty())
return 0;
if (fDebitCached)
return nDebitCached;
nDebitCached = pwallet->GetDebit(*this);
fDebitCached = true;
return nDebitCached;

int64_t debit = 0;
if(filter & MINE_SPENDABLE)
{
if (fDebitCached)
debit += nDebitCached;
else
{
nDebitCached = pwallet->GetDebit(*this, MINE_SPENDABLE);
fDebitCached = true;
debit += nDebitCached;
}
}
if(filter & MINE_WATCH_ONLY)
{
if(fWatchDebitCached)
debit += nWatchDebitCached;
else
{
nWatchDebitCached = pwallet->GetDebit(*this, MINE_WATCH_ONLY);
fWatchDebitCached = true;
debit += nWatchDebitCached;
}
}
return debit;
}

int64_t GetCredit(bool fUseCache=true) const
Expand Down Expand Up @@ -719,7 +749,7 @@ class CWalletTx : public CMerkleTx
std::list<std::pair<CTxDestination, int64_t> >& listSent, int64_t& nFee, std::string& strSentAccount, const isminefilter& filter=(MINE_SPENDABLE|MINE_WATCH_ONLY)) const;

void GetAccountAmounts(const std::string& strAccount, int64_t& nReceived,
int64_t& nSent, int64_t& nFee) const;
int64_t& nSent, int64_t& nFee, const isminefilter& filter=(MINE_SPENDABLE|MINE_WATCH_ONLY)) const;

bool IsFromMe() const
{
Expand Down

0 comments on commit 72aa20b

Please sign in to comment.