Added argument to getbalance to include watchonly addresses and fixed errors in balance calculation.
This commit is contained in:
parent
d2692f6116
commit
d4640d7d8c
|
@ -40,6 +40,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||||
{ "listreceivedbyaccount", 0 },
|
{ "listreceivedbyaccount", 0 },
|
||||||
{ "listreceivedbyaccount", 1 },
|
{ "listreceivedbyaccount", 1 },
|
||||||
{ "getbalance", 1 },
|
{ "getbalance", 1 },
|
||||||
|
{ "getbalance", 2 },
|
||||||
{ "getblockhash", 0 },
|
{ "getblockhash", 0 },
|
||||||
{ "move", 2 },
|
{ "move", 2 },
|
||||||
{ "move", 3 },
|
{ "move", 3 },
|
||||||
|
|
|
@ -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;
|
int64_t nBalance = 0;
|
||||||
|
|
||||||
|
@ -569,7 +569,7 @@ int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMi
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int64_t nReceived, nSent, nFee;
|
int64_t nReceived, nSent, nFee;
|
||||||
wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee);
|
wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee, filter);
|
||||||
|
|
||||||
if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
|
if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
|
||||||
nBalance += nReceived;
|
nBalance += nReceived;
|
||||||
|
@ -582,18 +582,18 @@ int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMi
|
||||||
return nBalance;
|
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);
|
CWalletDB walletdb(pwalletMain->strWalletFile);
|
||||||
return GetAccountBalance(walletdb, strAccount, nMinDepth);
|
return GetAccountBalance(walletdb, strAccount, nMinDepth, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Value getbalance(const Array& params, bool fHelp)
|
Value getbalance(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() > 2)
|
if (fHelp || params.size() > 3)
|
||||||
throw runtime_error(
|
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"
|
"\nIf account is not specified, returns the server's total available balance.\n"
|
||||||
"If account is specified, returns the balance in the account.\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"
|
"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"
|
"\nArguments:\n"
|
||||||
"1. \"account\" (string, optional) The selected account, or \"*\" for entire wallet. It may be the default account using \"\".\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"
|
"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"
|
"\nResult:\n"
|
||||||
"amount (numeric) The total amount in btc received for this account.\n"
|
"amount (numeric) The total amount in btc received for this account.\n"
|
||||||
"\nExamples:\n"
|
"\nExamples:\n"
|
||||||
|
@ -620,8 +621,14 @@ Value getbalance(const Array& params, bool fHelp)
|
||||||
return ValueFromAmount(pwalletMain->GetBalance());
|
return ValueFromAmount(pwalletMain->GetBalance());
|
||||||
|
|
||||||
int nMinDepth = 1;
|
int nMinDepth = 1;
|
||||||
|
isminefilter filter = MINE_SPENDABLE;
|
||||||
if (params.size() > 1)
|
if (params.size() > 1)
|
||||||
|
{
|
||||||
nMinDepth = params[1].get_int();
|
nMinDepth = params[1].get_int();
|
||||||
|
if(params.size() > 2)
|
||||||
|
if(params[2].get_bool())
|
||||||
|
filter = filter | MINE_WATCH_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
if (params[0].get_str() == "*") {
|
if (params[0].get_str() == "*") {
|
||||||
// Calculate total balance a different way from GetBalance()
|
// Calculate total balance a different way from GetBalance()
|
||||||
|
@ -638,7 +645,7 @@ Value getbalance(const Array& params, bool fHelp)
|
||||||
string strSentAccount;
|
string strSentAccount;
|
||||||
list<pair<CTxDestination, int64_t> > listReceived;
|
list<pair<CTxDestination, int64_t> > listReceived;
|
||||||
list<pair<CTxDestination, int64_t> > listSent;
|
list<pair<CTxDestination, int64_t> > listSent;
|
||||||
wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount);
|
wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
|
||||||
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listReceived)
|
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]);
|
string strAccount = AccountFromValue(params[0]);
|
||||||
|
|
||||||
int64_t nBalance = GetAccountBalance(strAccount, nMinDepth);
|
int64_t nBalance = GetAccountBalance(strAccount, nMinDepth, filter);
|
||||||
|
|
||||||
return ValueFromAmount(nBalance);
|
return ValueFromAmount(nBalance);
|
||||||
}
|
}
|
||||||
|
|
|
@ -711,7 +711,7 @@ isminetype CWallet::IsMine(const CTxIn &txin) const
|
||||||
return MINE_NO;
|
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);
|
LOCK(cs_wallet);
|
||||||
|
@ -720,7 +720,7 @@ int64_t CWallet::GetDebit(const CTxIn &txin) const
|
||||||
{
|
{
|
||||||
const CWalletTx& prev = (*mi).second;
|
const CWalletTx& prev = (*mi).second;
|
||||||
if (txin.prevout.n < prev.vout.size())
|
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;
|
return prev.vout[txin.prevout.n].nValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -801,7 +801,7 @@ void CWalletTx::GetAmounts(list<pair<CTxDestination, int64_t> >& listReceived,
|
||||||
strSentAccount = strFromAccount;
|
strSentAccount = strFromAccount;
|
||||||
|
|
||||||
// Compute fee:
|
// Compute fee:
|
||||||
int64_t nDebit = GetDebit();
|
int64_t nDebit = GetDebit(filter);
|
||||||
if (nDebit > 0) // debit>0 means we signed/sent this transaction
|
if (nDebit > 0) // debit>0 means we signed/sent this transaction
|
||||||
{
|
{
|
||||||
int64_t nValueOut = GetValueOut();
|
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,
|
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;
|
nReceived = nSent = nFee = 0;
|
||||||
|
|
||||||
|
@ -854,7 +854,7 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64_t& nReceived,
|
||||||
string strSentAccount;
|
string strSentAccount;
|
||||||
list<pair<CTxDestination, int64_t> > listReceived;
|
list<pair<CTxDestination, int64_t> > listReceived;
|
||||||
list<pair<CTxDestination, int64_t> > listSent;
|
list<pair<CTxDestination, int64_t> > listSent;
|
||||||
GetAmounts(listReceived, listSent, allFee, strSentAccount);
|
GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
|
||||||
|
|
||||||
if (strAccount == strSentAccount)
|
if (strAccount == strSentAccount)
|
||||||
{
|
{
|
||||||
|
|
48
src/wallet.h
48
src/wallet.h
|
@ -288,12 +288,12 @@ public:
|
||||||
std::set<CTxDestination> GetAccountAddresses(std::string strAccount) const;
|
std::set<CTxDestination> GetAccountAddresses(std::string strAccount) const;
|
||||||
|
|
||||||
isminetype IsMine(const CTxIn& txin) 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
|
isminetype IsMine(const CTxOut& txout) const
|
||||||
{
|
{
|
||||||
return ::IsMine(*this, txout.scriptPubKey);
|
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))
|
if (!MoneyRange(txout.nValue))
|
||||||
throw std::runtime_error("CWallet::GetCredit() : value out of range");
|
throw std::runtime_error("CWallet::GetCredit() : value out of range");
|
||||||
|
@ -324,12 +324,12 @@ public:
|
||||||
return true;
|
return true;
|
||||||
return false;
|
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;
|
int64_t nDebit = 0;
|
||||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||||
{
|
{
|
||||||
nDebit += GetDebit(txin);
|
nDebit += GetDebit(txin, filter);
|
||||||
if (!MoneyRange(nDebit))
|
if (!MoneyRange(nDebit))
|
||||||
throw std::runtime_error("CWallet::GetDebit() : value out of range");
|
throw std::runtime_error("CWallet::GetDebit() : value out of range");
|
||||||
}
|
}
|
||||||
|
@ -486,6 +486,8 @@ public:
|
||||||
mutable bool fCreditCached;
|
mutable bool fCreditCached;
|
||||||
mutable bool fImmatureCreditCached;
|
mutable bool fImmatureCreditCached;
|
||||||
mutable bool fAvailableCreditCached;
|
mutable bool fAvailableCreditCached;
|
||||||
|
mutable bool fWatchDebitCached;
|
||||||
|
mutable bool fWatchCreditCached;
|
||||||
mutable bool fImmatureWatchCreditCached;
|
mutable bool fImmatureWatchCreditCached;
|
||||||
mutable bool fAvailableWatchCreditCached;
|
mutable bool fAvailableWatchCreditCached;
|
||||||
mutable bool fChangeCached;
|
mutable bool fChangeCached;
|
||||||
|
@ -493,6 +495,8 @@ public:
|
||||||
mutable int64_t nCreditCached;
|
mutable int64_t nCreditCached;
|
||||||
mutable int64_t nImmatureCreditCached;
|
mutable int64_t nImmatureCreditCached;
|
||||||
mutable int64_t nAvailableCreditCached;
|
mutable int64_t nAvailableCreditCached;
|
||||||
|
mutable int64_t nWatchDebitCached;
|
||||||
|
mutable int64_t nWatchCreditCached;
|
||||||
mutable int64_t nImmatureWatchCreditCached;
|
mutable int64_t nImmatureWatchCreditCached;
|
||||||
mutable int64_t nAvailableWatchCreditCached;
|
mutable int64_t nAvailableWatchCreditCached;
|
||||||
mutable int64_t nChangeCached;
|
mutable int64_t nChangeCached;
|
||||||
|
@ -531,6 +535,8 @@ public:
|
||||||
fCreditCached = false;
|
fCreditCached = false;
|
||||||
fImmatureCreditCached = false;
|
fImmatureCreditCached = false;
|
||||||
fAvailableCreditCached = false;
|
fAvailableCreditCached = false;
|
||||||
|
fWatchDebitCached = false;
|
||||||
|
fWatchCreditCached = false;
|
||||||
fImmatureWatchCreditCached = false;
|
fImmatureWatchCreditCached = false;
|
||||||
fAvailableWatchCreditCached = false;
|
fAvailableWatchCreditCached = false;
|
||||||
fChangeCached = false;
|
fChangeCached = false;
|
||||||
|
@ -538,6 +544,8 @@ public:
|
||||||
nCreditCached = 0;
|
nCreditCached = 0;
|
||||||
nImmatureCreditCached = 0;
|
nImmatureCreditCached = 0;
|
||||||
nAvailableCreditCached = 0;
|
nAvailableCreditCached = 0;
|
||||||
|
nWatchDebitCached = 0;
|
||||||
|
nWatchCreditCached = 0;
|
||||||
nAvailableWatchCreditCached = 0;
|
nAvailableWatchCreditCached = 0;
|
||||||
nImmatureWatchCreditCached = 0;
|
nImmatureWatchCreditCached = 0;
|
||||||
nChangeCached = 0;
|
nChangeCached = 0;
|
||||||
|
@ -592,6 +600,8 @@ public:
|
||||||
{
|
{
|
||||||
fCreditCached = false;
|
fCreditCached = false;
|
||||||
fAvailableCreditCached = false;
|
fAvailableCreditCached = false;
|
||||||
|
fWatchDebitCached = false;
|
||||||
|
fWatchCreditCached = false;
|
||||||
fAvailableWatchCreditCached = false;
|
fAvailableWatchCreditCached = false;
|
||||||
fImmatureWatchCreditCached = false;
|
fImmatureWatchCreditCached = false;
|
||||||
fDebitCached = false;
|
fDebitCached = false;
|
||||||
|
@ -604,15 +614,35 @@ public:
|
||||||
MarkDirty();
|
MarkDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t GetDebit() const
|
int64_t GetDebit(const isminefilter& filter=(MINE_SPENDABLE|MINE_WATCH_ONLY)) const
|
||||||
{
|
{
|
||||||
if (vin.empty())
|
if (vin.empty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
int64_t debit = 0;
|
||||||
|
if(filter & MINE_SPENDABLE)
|
||||||
|
{
|
||||||
if (fDebitCached)
|
if (fDebitCached)
|
||||||
return nDebitCached;
|
debit += nDebitCached;
|
||||||
nDebitCached = pwallet->GetDebit(*this);
|
else
|
||||||
|
{
|
||||||
|
nDebitCached = pwallet->GetDebit(*this, MINE_SPENDABLE);
|
||||||
fDebitCached = true;
|
fDebitCached = true;
|
||||||
return nDebitCached;
|
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
|
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;
|
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,
|
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
|
bool IsFromMe() const
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue