Treat generation (mined) transactions less different from receive transactions

- Show address receiving the generation, and include it in the correct "account"
- Multiple entries in listtransactions output if the coinbase has multiple outputs to us
This commit is contained in:
Luke Dashjr 2012-06-02 02:33:28 +00:00
parent 1bcd3f26c0
commit e07c8e9123
5 changed files with 38 additions and 61 deletions

View file

@ -54,12 +54,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
CTxDestination address; CTxDestination address;
sub.idx = parts.size(); // sequence number sub.idx = parts.size(); // sequence number
sub.credit = txout.nValue; sub.credit = txout.nValue;
if (wtx.IsCoinBase()) if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
{
// Generated
sub.type = TransactionRecord::Generated;
}
else if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
{ {
// Received by Bitcoin Address // Received by Bitcoin Address
sub.type = TransactionRecord::RecvWithAddress; sub.type = TransactionRecord::RecvWithAddress;
@ -71,6 +66,11 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
sub.type = TransactionRecord::RecvFromOther; sub.type = TransactionRecord::RecvFromOther;
sub.address = mapValue["from"]; sub.address = mapValue["from"];
} }
if (wtx.IsCoinBase())
{
// Generated
sub.type = TransactionRecord::Generated;
}
parts.append(sub); parts.append(sub);
} }

View file

@ -392,11 +392,11 @@ QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, b
return QString::fromStdString(wtx->address); return QString::fromStdString(wtx->address);
case TransactionRecord::RecvWithAddress: case TransactionRecord::RecvWithAddress:
case TransactionRecord::SendToAddress: case TransactionRecord::SendToAddress:
case TransactionRecord::Generated:
return lookupAddress(wtx->address, tooltip); return lookupAddress(wtx->address, tooltip);
case TransactionRecord::SendToOther: case TransactionRecord::SendToOther:
return QString::fromStdString(wtx->address); return QString::fromStdString(wtx->address);
case TransactionRecord::SendToSelf: case TransactionRecord::SendToSelf:
case TransactionRecord::Generated:
default: default:
return tr("(n/a)"); return tr("(n/a)");
} }
@ -409,13 +409,13 @@ QVariant TransactionTableModel::addressColor(const TransactionRecord *wtx) const
{ {
case TransactionRecord::RecvWithAddress: case TransactionRecord::RecvWithAddress:
case TransactionRecord::SendToAddress: case TransactionRecord::SendToAddress:
case TransactionRecord::Generated:
{ {
QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(wtx->address)); QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(wtx->address));
if(label.isEmpty()) if(label.isEmpty())
return COLOR_BAREADDRESS; return COLOR_BAREADDRESS;
} break; } break;
case TransactionRecord::SendToSelf: case TransactionRecord::SendToSelf:
case TransactionRecord::Generated:
return COLOR_BAREADDRESS; return COLOR_BAREADDRESS;
default: default:
break; break;

View file

@ -34,6 +34,8 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
{ {
int confirms = wtx.GetDepthInMainChain(); int confirms = wtx.GetDepthInMainChain();
entry.push_back(Pair("confirmations", confirms)); entry.push_back(Pair("confirmations", confirms));
if (wtx.IsCoinBase())
entry.push_back(Pair("generated", true));
if (confirms) if (confirms)
{ {
entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex())); entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
@ -445,12 +447,12 @@ int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinD
if (!wtx.IsFinal()) if (!wtx.IsFinal())
continue; continue;
int64 nGenerated, nReceived, nSent, nFee; int64 nReceived, nSent, nFee;
wtx.GetAccountAmounts(strAccount, nGenerated, nReceived, nSent, nFee); wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee);
if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
nBalance += nReceived; nBalance += nReceived;
nBalance += nGenerated - nSent - nFee; nBalance -= nSent + nFee;
} }
// Tally internal accounting entries // Tally internal accounting entries
@ -492,12 +494,11 @@ Value getbalance(const Array& params, bool fHelp)
if (!wtx.IsFinal()) if (!wtx.IsFinal())
continue; continue;
int64 allGeneratedImmature, allGeneratedMature, allFee; int64 allFee;
allGeneratedImmature = allGeneratedMature = allFee = 0;
string strSentAccount; string strSentAccount;
list<pair<CTxDestination, int64> > listReceived; list<pair<CTxDestination, int64> > listReceived;
list<pair<CTxDestination, int64> > listSent; list<pair<CTxDestination, int64> > listSent;
wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount); wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount);
if (wtx.GetDepthInMainChain() >= nMinDepth) if (wtx.GetDepthInMainChain() >= nMinDepth)
{ {
BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listReceived) BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listReceived)
@ -506,7 +507,6 @@ Value getbalance(const Array& params, bool fHelp)
BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listSent) BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listSent)
nBalance -= r.second; nBalance -= r.second;
nBalance -= allFee; nBalance -= allFee;
nBalance += allGeneratedMature;
} }
return ValueFromAmount(nBalance); return ValueFromAmount(nBalance);
} }
@ -877,35 +877,15 @@ Value listreceivedbyaccount(const Array& params, bool fHelp)
void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret) void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret)
{ {
int64 nGeneratedImmature, nGeneratedMature, nFee; int64 nFee;
string strSentAccount; string strSentAccount;
list<pair<CTxDestination, int64> > listReceived; list<pair<CTxDestination, int64> > listReceived;
list<pair<CTxDestination, int64> > listSent; list<pair<CTxDestination, int64> > listSent;
wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount); wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount);
bool fAllAccounts = (strAccount == string("*")); bool fAllAccounts = (strAccount == string("*"));
// Generated blocks assigned to account ""
if ((nGeneratedMature+nGeneratedImmature) != 0 && (fAllAccounts || strAccount == ""))
{
Object entry;
entry.push_back(Pair("account", string("")));
if (nGeneratedImmature)
{
entry.push_back(Pair("category", wtx.GetDepthInMainChain() ? "immature" : "orphan"));
entry.push_back(Pair("amount", ValueFromAmount(nGeneratedImmature)));
}
else
{
entry.push_back(Pair("category", "generate"));
entry.push_back(Pair("amount", ValueFromAmount(nGeneratedMature)));
}
if (fLong)
WalletTxToJSON(wtx, entry);
ret.push_back(entry);
}
// Sent // Sent
if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount)) if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
{ {
@ -936,7 +916,17 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
Object entry; Object entry;
entry.push_back(Pair("account", account)); entry.push_back(Pair("account", account));
entry.push_back(Pair("address", CBitcoinAddress(r.first).ToString())); entry.push_back(Pair("address", CBitcoinAddress(r.first).ToString()));
entry.push_back(Pair("category", "receive")); if (wtx.IsCoinBase())
{
if (wtx.GetDepthInMainChain() < 1)
entry.push_back(Pair("category", "orphan"));
else if (wtx.GetBlocksToMaturity() > 0)
entry.push_back(Pair("category", "immature"));
else
entry.push_back(Pair("category", "generate"));
}
else
entry.push_back(Pair("category", "receive"));
entry.push_back(Pair("amount", ValueFromAmount(r.second))); entry.push_back(Pair("amount", ValueFromAmount(r.second)));
if (fLong) if (fLong)
WalletTxToJSON(wtx, entry); WalletTxToJSON(wtx, entry);
@ -1040,17 +1030,16 @@ Value listaccounts(const Array& params, bool fHelp)
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
{ {
const CWalletTx& wtx = (*it).second; const CWalletTx& wtx = (*it).second;
int64 nGeneratedImmature, nGeneratedMature, nFee; int64 nFee;
string strSentAccount; string strSentAccount;
list<pair<CTxDestination, int64> > listReceived; list<pair<CTxDestination, int64> > listReceived;
list<pair<CTxDestination, int64> > listSent; list<pair<CTxDestination, int64> > listSent;
wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount); wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount);
mapAccountBalances[strSentAccount] -= nFee; mapAccountBalances[strSentAccount] -= nFee;
BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& s, listSent) BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& s, listSent)
mapAccountBalances[strSentAccount] -= s.second; mapAccountBalances[strSentAccount] -= s.second;
if (wtx.GetDepthInMainChain() >= nMinDepth) if (wtx.GetDepthInMainChain() >= nMinDepth)
{ {
mapAccountBalances[""] += nGeneratedMature;
BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& r, listReceived) BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& r, listReceived)
if (pwalletMain->mapAddressBook.count(r.first)) if (pwalletMain->mapAddressBook.count(r.first))
mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second; mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;

View file

@ -601,23 +601,14 @@ int CWalletTx::GetRequestCount() const
return nRequests; return nRequests;
} }
void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<CTxDestination, int64> >& listReceived, void CWalletTx::GetAmounts(list<pair<CTxDestination, int64> >& listReceived,
list<pair<CTxDestination, int64> >& listSent, int64& nFee, string& strSentAccount) const list<pair<CTxDestination, int64> >& listSent, int64& nFee, string& strSentAccount) const
{ {
nGeneratedImmature = nGeneratedMature = nFee = 0; nFee = 0;
listReceived.clear(); listReceived.clear();
listSent.clear(); listSent.clear();
strSentAccount = strFromAccount; strSentAccount = strFromAccount;
if (IsCoinBase())
{
if (GetBlocksToMaturity() > 0)
nGeneratedImmature = pwallet->GetCredit(*this);
else
nGeneratedMature = GetCredit();
return;
}
// Compute fee: // Compute fee:
int64 nDebit = GetDebit(); int64 nDebit = GetDebit();
if (nDebit > 0) // debit>0 means we signed/sent this transaction if (nDebit > 0) // debit>0 means we signed/sent this transaction
@ -650,20 +641,17 @@ void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, l
} }
void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived, void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nReceived,
int64& nSent, int64& nFee) const int64& nSent, int64& nFee) const
{ {
nGenerated = nReceived = nSent = nFee = 0; nReceived = nSent = nFee = 0;
int64 allGeneratedImmature, allGeneratedMature, allFee; int64 allFee;
allGeneratedImmature = allGeneratedMature = allFee = 0;
string strSentAccount; string strSentAccount;
list<pair<CTxDestination, int64> > listReceived; list<pair<CTxDestination, int64> > listReceived;
list<pair<CTxDestination, int64> > listSent; list<pair<CTxDestination, int64> > listSent;
GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount); GetAmounts(listReceived, listSent, allFee, strSentAccount);
if (strAccount == "")
nGenerated = allGeneratedMature;
if (strAccount == strSentAccount) if (strAccount == strSentAccount)
{ {
BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& s, listSent) BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& s, listSent)

View file

@ -589,10 +589,10 @@ public:
return nChangeCached; return nChangeCached;
} }
void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list<std::pair<CTxDestination, int64> >& listReceived, void GetAmounts(std::list<std::pair<CTxDestination, int64> >& listReceived,
std::list<std::pair<CTxDestination, int64> >& listSent, int64& nFee, std::string& strSentAccount) const; std::list<std::pair<CTxDestination, int64> >& listSent, int64& nFee, std::string& strSentAccount) const;
void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived, void GetAccountAmounts(const std::string& strAccount, int64& nReceived,
int64& nSent, int64& nFee) const; int64& nSent, int64& nFee) const;
bool IsFromMe() const bool IsFromMe() const