This commit is contained in:
Gavin Andresen 2011-01-03 14:45:49 -05:00
commit 0ded557af6
3 changed files with 68 additions and 35 deletions

View File

@ -395,9 +395,12 @@ int CWalletTx::GetRequestCount() const
} }
void CWalletTx::GetAmounts(int64& nGenerated, list<pair<string, int64> >& listReceived, void CWalletTx::GetAmounts(int64& nGenerated, list<pair<string, int64> >& listReceived,
int64& nSent, int64& nFee, string& strSentAccount) const list<pair<string, int64> >& listSent, int64& nFee, string& strSentAccount) const
{ {
nGenerated = nSent = nFee = 0; nGenerated = nFee = 0;
listReceived.clear();
listSent.clear();
strSentAccount = strFromAccount;
if (IsCoinBase()) if (IsCoinBase())
{ {
@ -406,24 +409,38 @@ void CWalletTx::GetAmounts(int64& nGenerated, list<pair<string, int64> >& listRe
return; return;
} }
// Received. Standard client will never generate a send-to-multiple-recipients, // Compute fee:
// but non-standard clients might (so return a list of address/amount pairs)
foreach(const CTxOut& txout, vout)
{
vector<unsigned char> vchPubKey;
if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))
listReceived.push_back(make_pair(PubKeyToAddress(vchPubKey), txout.nValue));
}
// Sent
int64 nDebit = GetDebit(); int64 nDebit = GetDebit();
if (nDebit > 0) if (nDebit > 0) // debit>0 means we signed/sent this transaction
{ {
int64 nValueOut = GetValueOut(); int64 nValueOut = GetValueOut();
nFee = nDebit - nValueOut; nFee = nDebit - nValueOut;
nSent = nValueOut - GetChange();
strSentAccount = strFromAccount;
} }
// Sent/received. Standard client will never generate a send-to-multiple-recipients,
// but non-standard clients might (so return a list of address/amount pairs)
foreach(const CTxOut& txout, vout)
{
string address;
uint160 hash160;
vector<unsigned char> vchPubKey;
if (ExtractHash160(txout.scriptPubKey, hash160))
address = Hash160ToAddress(hash160);
else if (ExtractPubKey(txout.scriptPubKey, false, vchPubKey))
address = PubKeyToAddress(vchPubKey);
else
address = " unknown "; // some type of weird non-standard transaction?
if (nDebit > 0 && txout.IsChange())
continue;
if (nDebit > 0)
listSent.push_back(make_pair(address, txout.nValue));
if (txout.IsMine())
listReceived.push_back(make_pair(address, txout.nValue));
}
} }
void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived, void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived,
@ -431,17 +448,19 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, i
{ {
nGenerated = nReceived = nSent = nFee = 0; nGenerated = nReceived = nSent = nFee = 0;
int64 allGenerated, allSent, allFee; int64 allGenerated, allFee;
allGenerated = allSent = allFee = 0; allGenerated = allFee = 0;
string strSentAccount; string strSentAccount;
list<pair<string, int64> > listReceived; list<pair<string, int64> > listReceived;
GetAmounts(allGenerated, listReceived, allSent, allFee, strSentAccount); list<pair<string, int64> > listSent;
GetAmounts(allGenerated, listReceived, listSent, allFee, strSentAccount);
if (strAccount == "") if (strAccount == "")
nGenerated = allGenerated; nGenerated = allGenerated;
if (strAccount == strSentAccount) if (strAccount == strSentAccount)
{ {
nSent = allSent; foreach(const PAIRTYPE(string,int64)& s, listSent)
nSent += s.second;
nFee = allFee; nFee = allFee;
} }
CRITICAL_BLOCK(cs_mapAddressBook) CRITICAL_BLOCK(cs_mapAddressBook)

2
main.h
View File

@ -874,7 +874,7 @@ public:
} }
void GetAmounts(int64& nGenerated, list<pair<string /* address */, int64> >& listReceived, void GetAmounts(int64& nGenerated, list<pair<string /* address */, int64> >& listReceived,
int64& nSent, int64& nFee, string& strSentAccount) const; list<pair<string /* address */, int64> >& listSent, int64& nFee, string& strSentAccount) const;
void GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived, void GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived,
int64& nSent, int64& nFee) const; int64& nSent, int64& nFee) const;

32
rpc.cpp
View File

@ -859,10 +859,11 @@ Value listreceivedbyaccount(const Array& params, bool fHelp)
void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, Array& ret) void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, Array& ret)
{ {
int64 nGenerated, nSent, nFee; int64 nGenerated, nFee;
string strSentAccount; string strSentAccount;
list<pair<string, int64> > listReceived; list<pair<string, int64> > listReceived;
wtx.GetAmounts(nGenerated, listReceived, nSent, nFee, strSentAccount); list<pair<string, int64> > listSent;
wtx.GetAmounts(nGenerated, listReceived, listSent, nFee, strSentAccount);
bool fAllAccounts = (strAccount == string("*")); bool fAllAccounts = (strAccount == string("*"));
@ -878,32 +879,42 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
} }
// Sent // Sent
if ((nSent != 0 || nFee != 0) && (fAllAccounts || strAccount == strSentAccount)) if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
{
foreach(const PAIRTYPE(string, int64)& s, listSent)
{ {
Object entry; Object entry;
entry.push_back(Pair("account", strSentAccount)); entry.push_back(Pair("account", strSentAccount));
entry.push_back(Pair("address", s.first));
entry.push_back(Pair("category", "send")); entry.push_back(Pair("category", "send"));
entry.push_back(Pair("amount", ValueFromAmount(-nSent))); entry.push_back(Pair("amount", ValueFromAmount(-s.second)));
entry.push_back(Pair("fee", ValueFromAmount(-nFee))); entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
WalletTxToJSON(wtx, entry); WalletTxToJSON(wtx, entry);
ret.push_back(entry); ret.push_back(entry);
} }
}
// Received // Received
if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
CRITICAL_BLOCK(cs_mapAddressBook) CRITICAL_BLOCK(cs_mapAddressBook)
{ {
foreach(const PAIRTYPE(string, int64)& r, listReceived) foreach(const PAIRTYPE(string, int64)& r, listReceived)
if (mapAddressBook.count(r.first) && (fAllAccounts || mapAddressBook[r.first] == strAccount)) {
string account;
if (mapAddressBook.count(r.first))
account = mapAddressBook[r.first];
if (fAllAccounts || (account == strAccount))
{ {
Object entry; Object entry;
entry.push_back(Pair("account", mapAddressBook[r.first])); entry.push_back(Pair("account", account));
entry.push_back(Pair("address", r.first));
entry.push_back(Pair("category", "receive")); entry.push_back(Pair("category", "receive"));
entry.push_back(Pair("amount", ValueFromAmount(r.second))); entry.push_back(Pair("amount", ValueFromAmount(r.second)));
WalletTxToJSON(wtx, entry); WalletTxToJSON(wtx, entry);
ret.push_back(entry); ret.push_back(entry);
} }
} }
}
} }
@ -1007,11 +1018,14 @@ Value listaccounts(const Array& params, bool fHelp)
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{ {
const CWalletTx& wtx = (*it).second; const CWalletTx& wtx = (*it).second;
int64 nGenerated, nSent, nFee; int64 nGenerated, nFee;
string strSentAccount; string strSentAccount;
list<pair<string, int64> > listReceived; list<pair<string, int64> > listReceived;
wtx.GetAmounts(nGenerated, listReceived, nSent, nFee, strSentAccount); list<pair<string, int64> > listSent;
mapAccountBalances[strSentAccount] -= nSent+nFee; wtx.GetAmounts(nGenerated, listReceived, listSent, nFee, strSentAccount);
mapAccountBalances[strSentAccount] -= nFee;
foreach(const PAIRTYPE(string, int64)& s, listSent)
mapAccountBalances[strSentAccount] -= s.second;
if (wtx.GetDepthInMainChain() >= nMinDepth) if (wtx.GetDepthInMainChain() >= nMinDepth)
{ {
mapAccountBalances[""] += nGenerated; mapAccountBalances[""] += nGenerated;