Added argument to getbalance to include watchonly addresses and fixed errors in balance calculation.

This commit is contained in:
JaSK 2014-04-08 15:23:50 +02:00
parent d2692f6116
commit d4640d7d8c
4 changed files with 62 additions and 24 deletions

View File

@ -40,6 +40,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "listreceivedbyaccount", 0 },
{ "listreceivedbyaccount", 1 },
{ "getbalance", 1 },
{ "getbalance", 2 },
{ "getblockhash", 0 },
{ "move", 2 },
{ "move", 3 },

View File

@ -557,7 +557,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;
@ -569,7 +569,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;
@ -582,18 +582,18 @@ 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"
@ -601,6 +601,7 @@ Value getbalance(const Array& params, bool fHelp)
"\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"
@ -620,8 +621,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()
@ -638,7 +645,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)
@ -653,7 +660,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);
}

View File

@ -711,7 +711,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);
@ -720,7 +720,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;
}
}
@ -801,7 +801,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();
@ -846,7 +846,7 @@ 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;
@ -854,7 +854,7 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64_t& nReceived,
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)
{

View File

@ -288,12 +288,12 @@ public:
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");
@ -324,12 +324,12 @@ public:
return true;
return false;
}
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");
}
@ -486,6 +486,8 @@ public:
mutable bool fCreditCached;
mutable bool fImmatureCreditCached;
mutable bool fAvailableCreditCached;
mutable bool fWatchDebitCached;
mutable bool fWatchCreditCached;
mutable bool fImmatureWatchCreditCached;
mutable bool fAvailableWatchCreditCached;
mutable bool fChangeCached;
@ -493,6 +495,8 @@ public:
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;
@ -531,6 +535,8 @@ public:
fCreditCached = false;
fImmatureCreditCached = false;
fAvailableCreditCached = false;
fWatchDebitCached = false;
fWatchCreditCached = false;
fImmatureWatchCreditCached = false;
fAvailableWatchCreditCached = false;
fChangeCached = false;
@ -538,6 +544,8 @@ public:
nCreditCached = 0;
nImmatureCreditCached = 0;
nAvailableCreditCached = 0;
nWatchDebitCached = 0;
nWatchCreditCached = 0;
nAvailableWatchCreditCached = 0;
nImmatureWatchCreditCached = 0;
nChangeCached = 0;
@ -592,6 +600,8 @@ public:
{
fCreditCached = false;
fAvailableCreditCached = false;
fWatchDebitCached = false;
fWatchCreditCached = false;
fAvailableWatchCreditCached = false;
fImmatureWatchCreditCached = false;
fDebitCached = false;
@ -604,15 +614,35 @@ public:
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
@ -729,7 +759,7 @@ public:
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
{