strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>";
int64 nTime = wtx.GetTxTime();
- int64 nCredit = wtx.GetCredit();
- int64 nDebit = wtx.GetDebit();
+ int64 nCredit = wtx.GetCredit(MINE_ALL);
+ int64 nDebit = wtx.GetDebit(MINE_ALL);
int64 nNet = nCredit - nDebit;
strHTML += "<b>" + tr("Status") + ":</b> " + FormatTxStatus(wtx);
//
int64 nUnmatured = 0;
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
- nUnmatured += wallet->GetCredit(txout);
+ nUnmatured += wallet->GetCredit(txout, MINE_ALL);
strHTML += "<b>" + tr("Credit") + ":</b> ";
if (wtx.IsInMainChain())
strHTML += BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nUnmatured)+ " (" + tr("matures in %n more block(s)", "", wtx.GetBlocksToMaturity()) + ")";
//
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
if (wallet->IsMine(txin))
- strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -wallet->GetDebit(txin)) + "<br>";
+ strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -wallet->GetDebit(txin, MINE_ALL)) + "<br>";
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
if (wallet->IsMine(txout))
- strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, wallet->GetCredit(txout)) + "<br>";
+ strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, wallet->GetCredit(txout, MINE_ALL)) + "<br>";
}
}
strHTML += "<hr><br>" + tr("Debug information") + "<br><br>";
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
if(wallet->IsMine(txin))
- strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -wallet->GetDebit(txin)) + "<br>";
+ strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -wallet->GetDebit(txin, MINE_ALL)) + "<br>";
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
if(wallet->IsMine(txout))
- strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, wallet->GetCredit(txout)) + "<br>";
+ strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, wallet->GetCredit(txout, MINE_ALL)) + "<br>";
strHTML += "<br><b>" + tr("Transaction") + ":</b><br>";
strHTML += GUIUtil::HtmlEscape(wtx.ToString(), true);
QList<TransactionRecord> parts;
int64 nTime = wtx.GetTxTime();
int64 nCredit = wtx.GetCredit(true);
- int64 nDebit = wtx.GetDebit();
+ int64 nDebit = wtx.GetDebit(MINE_ALL);
int64 nNet = nCredit - nDebit;
uint256 hash = wtx.GetHash(), hashPrev = 0;
std::map<std::string, std::string> mapValue = wtx.mapValue;
// For generated transactions, determine maturity
if(type == TransactionRecord::Generated)
{
+/*
int64 nCredit = wtx.GetCredit(true);
if (nCredit == 0)
{
{
status.maturity = TransactionStatus::Mature;
}
+*/
+
+ if (wtx.GetBlocksToMaturity() > 0)
+ {
+ status.maturity = TransactionStatus::Immature;
+
+ if (wtx.IsInMainChain())
+ {
+ status.matures_in = wtx.GetBlocksToMaturity();
+
+ // Check if the block was requested by anyone
+ if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
+ status.maturity = TransactionStatus::MaturesWarning;
+ }
+ else
+ {
+ status.maturity = TransactionStatus::NotAccepted;
+ }
+ }
+ else
+ {
+ status.maturity = TransactionStatus::Mature;
+ }
}
}
qint64 WalletModel::getBalanceWatchOnly() const
{
- return wallet->GetBalanceWatchOnly();
+ return wallet->GetWatchOnlyBalance();
}
qint64 WalletModel::getUnconfirmedBalance() const
obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
- obj.push_back(Pair("unspendable", ValueFromAmount(pwalletMain->GetBalanceWatchOnly())));
+ obj.push_back(Pair("unspendable", ValueFromAmount(pwalletMain->GetWatchOnlyBalance())));
obj.push_back(Pair("newmint", ValueFromAmount(pwalletMain->GetNewMint())));
obj.push_back(Pair("stake", ValueFromAmount(pwalletMain->GetStake())));
obj.push_back(Pair("blocks", (int)nBestHeight));
}
-int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth)
+int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth, const isminefilter& filter)
{
int64 nBalance = 0;
continue;
int64 nGenerated, nReceived, nSent, nFee;
- wtx.GetAccountAmounts(strAccount, nGenerated, nReceived, nSent, nFee);
+ wtx.GetAccountAmounts(strAccount, nGenerated, nReceived, nSent, nFee, filter);
if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
nBalance += nReceived;
return nBalance;
}
-int64 GetAccountBalance(const string& strAccount, int nMinDepth)
+int64 GetAccountBalance(const string& strAccount, int nMinDepth, const isminefilter& filter)
{
CWalletDB walletdb(pwalletMain->strWalletFile);
- return GetAccountBalance(walletdb, strAccount, nMinDepth);
+ return GetAccountBalance(walletdb, strAccount, nMinDepth, filter);
}
{
if (fHelp || params.size() > 2)
throw runtime_error(
- "getbalance [account] [minconf=1]\n"
+ "getbalance [account] [minconf=1] [watchonly=0]\n"
"If [account] is not specified, returns the server's total available balance.\n"
- "If [account] is specified, returns the balance in the account.");
+ "If [account] is specified, returns the balance in the account.\n"
+ "if [includeWatchonly] is specified, include balance in watchonly addresses (see 'importaddress').");
if (params.size() == 0)
return ValueFromAmount(pwalletMain->GetBalance());
int nMinDepth = 1;
if (params.size() > 1)
nMinDepth = params[1].get_int();
+ isminefilter filter = MINE_SPENDABLE;
+ 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()
string strSentAccount;
list<pair<CTxDestination, int64> > listReceived;
list<pair<CTxDestination, int64> > listSent;
- wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
+ wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount, filter);
if (wtx.GetDepthInMainChain() >= nMinDepth)
{
BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listReceived)
string strAccount = AccountFromValue(params[0]);
- int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
+ int64 nBalance = GetAccountBalance(strAccount, nMinDepth, filter);
return ValueFromAmount(nBalance);
}
EnsureWalletIsUnlocked();
// Check funds
- int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
+ int64 nBalance = GetAccountBalance(strAccount, nMinDepth, MINE_SPENDABLE);
if (nAmount > nBalance)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
EnsureWalletIsUnlocked();
// Check funds
- int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
+ int64 nBalance = GetAccountBalance(strAccount, nMinDepth, MINE_SPENDABLE);
if (totalAmount > nBalance)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
if (!fCreated)
{
- int64 nTotal = pwalletMain->GetBalance(), nWatchOnly = pwalletMain->GetBalanceWatchOnly();
+ int64 nTotal = pwalletMain->GetBalance(), nWatchOnly = pwalletMain->GetWatchOnlyBalance();
if (totalAmount + nFeeRequired > nTotal - nWatchOnly)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
throw JSONRPCError(RPC_WALLET_ERROR, "Transaction creation failed");
entry.push_back(Pair("address", addr.ToString()));
}
-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, const isminefilter& filter)
{
int64 nGeneratedImmature, nGeneratedMature, nFee;
string strSentAccount;
list<pair<CTxDestination, int64> > listReceived;
list<pair<CTxDestination, int64> > listSent;
- wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
+ wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount, filter);
bool fAllAccounts = (strAccount == string("*"));
+ bool involvesWatchonly = wtx.IsFromMe(MINE_WATCH_ONLY);
// Generated blocks assigned to account ""
if ((nGeneratedMature+nGeneratedImmature) != 0 && (fAllAccounts || strAccount == ""))
{
Object entry;
entry.push_back(Pair("account", strSentAccount));
+ if(involvesWatchonly || (::IsMine(*pwalletMain, s.first) & MINE_WATCH_ONLY))
+ entry.push_back(Pair("involvesWatchonly", true));
MaybePushAddress(entry, s.first);
if (wtx.GetDepthInMainChain() < 0) {
{
Object entry;
entry.push_back(Pair("account", account));
+ if(involvesWatchonly || (::IsMine(*pwalletMain, r.first) & MINE_WATCH_ONLY))
+ entry.push_back(Pair("involvesWatchonly", true));
MaybePushAddress(entry, r.first);
if (wtx.IsCoinBase())
{
if (params.size() > 2)
nFrom = params[2].get_int();
+ isminefilter filter = MINE_SPENDABLE;
+ if(params.size() > 3)
+ if(params[3].get_bool())
+ filter = filter | MINE_WATCH_ONLY;
+
if (nCount < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
if (nFrom < 0)
{
CWalletTx *const pwtx = (*it).second.first;
if (pwtx != 0)
- ListTransactions(*pwtx, strAccount, 0, true, ret);
+ ListTransactions(*pwtx, strAccount, 0, true, ret, filter);
CAccountingEntry *const pacentry = (*it).second.second;
if (pacentry != 0)
AcentryToJSON(*pacentry, strAccount, ret);
if (params.size() > 0)
nMinDepth = params[0].get_int();
+ isminefilter includeWatchonly = MINE_SPENDABLE;
+ if(params.size() > 1)
+ if(params[1].get_bool())
+ includeWatchonly = includeWatchonly | MINE_WATCH_ONLY;
+
+
map<string, int64> mapAccountBalances;
BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& entry, pwalletMain->mapAddressBook) {
if (IsMine(*pwalletMain, entry.first)) // This address belongs to me
string strSentAccount;
list<pair<CTxDestination, int64> > listReceived;
list<pair<CTxDestination, int64> > listSent;
- wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
+ wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount, includeWatchonly);
mapAccountBalances[strSentAccount] -= nFee;
BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& s, listSent)
mapAccountBalances[strSentAccount] -= s.second;
CBlockIndex *pindex = NULL;
int target_confirms = 1;
+ isminefilter filter = MINE_SPENDABLE;
if (params.size() > 0)
{
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
}
+ if(params.size() > 2)
+ if(params[2].get_bool())
+ filter = filter | MINE_WATCH_ONLY;
+
int depth = pindex ? (1 + nBestHeight - pindex->nHeight) : -1;
Array transactions;
CWalletTx tx = (*it).second;
if (depth == -1 || tx.GetDepthInMainChain() < depth)
- ListTransactions(tx, "*", 0, true, transactions);
+ ListTransactions(tx, "*", 0, true, transactions, filter);
}
uint256 lastblock;
uint256 hash;
hash.SetHex(params[0].get_str());
+ isminefilter filter = MINE_SPENDABLE;
+ if(params.size() > 1)
+ if(params[1].get_bool())
+ filter = filter | MINE_WATCH_ONLY;
+
Object entry;
if (pwalletMain->mapWallet.count(hash))
TxToJSON(wtx, 0, entry);
- int64 nCredit = wtx.GetCredit();
- int64 nDebit = wtx.GetDebit();
+ int64 nCredit = wtx.GetCredit(filter);
+ int64 nDebit = wtx.GetDebit(filter);
int64 nNet = nCredit - nDebit;
- int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
+ int64 nFee = (wtx.IsFromMe(filter) ? wtx.GetValueOut() - nDebit : 0);
entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
- if (wtx.IsFromMe())
+ if (wtx.IsFromMe(filter))
entry.push_back(Pair("fee", ValueFromAmount(nFee)));
WalletTxToJSON(wtx, entry);
Array details;
- ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
+ ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details, filter);
entry.push_back(Pair("details", details));
}
else
MINE_NO = 0,
MINE_WATCH_ONLY = 1,
MINE_SPENDABLE = 2,
+ MINE_ALL = MINE_WATCH_ONLY | MINE_SPENDABLE
};
+typedef uint8_t isminefilter;
+
/** Signature hash types/flags */
enum
{
printf("WalletUpdateSpent: bad wtx %s\n", wtx.GetHash().ToString().c_str());
else if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n]))
{
- printf("WalletUpdateSpent found spent coin %snvc %s\n", FormatMoney(wtx.GetCredit(false)).c_str(), wtx.GetHash().ToString().c_str());
+ printf("WalletUpdateSpent found spent coin %snvc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
wtx.MarkSpent(txin.prevout.n);
wtx.WriteToDisk();
NotifyTransactionChanged(this, txin.prevout.hash, CT_UPDATED);
return MINE_NO;
}
-int64 CWallet::GetDebit(const CTxIn &txin) const
+int64 CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
{
{
LOCK(cs_wallet);
{
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;
}
}
}
void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, 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 isminefilter& filter) const
{
nGeneratedImmature = nGeneratedMature = nFee = 0;
listReceived.clear();
if (IsCoinBase() || IsCoinStake())
{
if (GetBlocksToMaturity() > 0)
- nGeneratedImmature = pwallet->GetCredit(*this);
+ nGeneratedImmature = pwallet->GetCredit(*this, filter);
else
- nGeneratedMature = GetCredit(false);
+ nGeneratedMature = GetCredit(filter);
return;
}
// Compute fee:
- int64 nDebit = GetDebit();
+ int64 nDebit = GetDebit(filter);
if (nDebit > 0) // debit>0 means we signed/sent this transaction
{
int64 nValueOut = GetValueOut();
// Sent/received.
BOOST_FOREACH(const CTxOut& txout, vout)
{
- bool fIsMine;
+ isminetype fIsMine = pwallet->IsMine(txout);
// Only need to handle txouts if AT LEAST one of these is true:
// 1) they debit from us (sent)
// 2) the output is to us (received)
// Don't report 'change' txouts
if (pwallet->IsChange(txout))
continue;
- fIsMine = pwallet->IsMine(txout);
}
- else if (!(fIsMine = pwallet->IsMine(txout)))
+ else if (!(fIsMine & filter))
continue;
// In either case, we need to get the destination address
listSent.push_back(make_pair(address, txout.nValue));
// If we are receiving the output, add it as a "received" entry
- if (fIsMine)
+ if (fIsMine & filter)
listReceived.push_back(make_pair(address, txout.nValue));
}
}
void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived,
- int64& nSent, int64& nFee) const
+ int64& nSent, int64& nFee, const isminefilter& filter) const
{
nGenerated = nReceived = nSent = nFee = 0;
string strSentAccount;
list<pair<CTxDestination, int64> > listReceived;
list<pair<CTxDestination, int64> > listSent;
- GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
+ GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount, filter);
if (strAccount == "")
nGenerated = allGeneratedMature;
}
if (fUpdated)
{
- printf("ReacceptWalletTransactions found spent coin %snvc %s\n", FormatMoney(wtx.GetCredit(false)).c_str(), wtx.GetHash().ToString().c_str());
+ printf("ReacceptWalletTransactions found spent coin %snvc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
wtx.MarkDirty();
wtx.WriteToDisk();
}
return nTotal;
}
-int64 CWallet::GetBalanceWatchOnly() const
+int64 CWallet::GetWatchOnlyBalance() const
{
int64 nTotal = 0;
{
{
const CWalletTx* pcoin = &(*it).second;
if (pcoin->IsTrusted())
- nTotal += pcoin->GetAvailableCreditWatchOnly();
+ nTotal += pcoin->GetAvailableWatchCredit();
}
}
{
const CWalletTx* pcoin = &(*it).second;
if (!pcoin->IsFinal() || !pcoin->IsTrusted())
- nTotal += pcoin->GetAvailableCredit(false);
+ nTotal += pcoin->GetAvailableCredit();
+ }
+ }
+ return nTotal;
+}
+
+int64 CWallet::GetUnconfirmedWatchOnlyBalance() const
+{
+ int64 nTotal = 0;
+ {
+ LOCK(cs_wallet);
+ for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ {
+ const CWalletTx* pcoin = &(*it).second;
+ if (!pcoin->IsFinal() || !pcoin->IsTrusted())
+ nTotal += pcoin->GetAvailableWatchCredit();
}
}
return nTotal;
LOCK(cs_wallet);
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{
- const CWalletTx& pcoin = (*it).second;
- if (pcoin.IsCoinBase() && pcoin.GetBlocksToMaturity() > 0 && pcoin.IsInMainChain())
- nTotal += GetCredit(pcoin);
+ const CWalletTx* pcoin = &(*it).second;
+ nTotal += pcoin->GetImmatureCredit();
+ }
+ }
+ return nTotal;
+}
+
+int64 CWallet::GetImmatureWatchOnlyBalance() const
+{
+ int64 nTotal = 0;
+ {
+ LOCK(cs_wallet);
+ for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ {
+ const CWalletTx* pcoin = &(*it).second;
+ nTotal += pcoin->GetImmatureWatchOnlyCredit();
}
}
return nTotal;
}
}
-// ppcoin: total coins staked (non-spendable until maturity)
int64 CWallet::GetStake() const
{
int64 nTotal = 0;
{
const CWalletTx* pcoin = &(*it).second;
if (pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
- nTotal += CWallet::GetCredit(*pcoin);
+ nTotal += CWallet::GetCredit(*pcoin, MINE_ALL);
+ }
+ return nTotal;
+}
+
+int64 CWallet::GetWatchOnlyStake() const
+{
+ int64 nTotal = 0;
+ LOCK(cs_wallet);
+ for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ {
+ const CWalletTx* pcoin = &(*it).second;
+ if (pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
+ nTotal += CWallet::GetCredit(*pcoin, MINE_WATCH_ONLY);
}
return nTotal;
}
{
const CWalletTx* pcoin = &(*it).second;
if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
- nTotal += CWallet::GetCredit(*pcoin);
+ nTotal += CWallet::GetCredit(*pcoin, MINE_ALL);
+ }
+ return nTotal;
+}
+
+int64 CWallet::GetWatchOnlyNewMint() const
+{
+ int64 nTotal = 0;
+ LOCK(cs_wallet);
+ for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ {
+ const CWalletTx* pcoin = &(*it).second;
+ if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
+ nTotal += CWallet::GetCredit(*pcoin, MINE_WATCH_ONLY);
}
return nTotal;
}
const CWalletTx *pcoin = output.tx;
- if (output.nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs))
+ if (output.nDepth < (pcoin->IsFromMe(MINE_ALL) ? nConfMine : nConfTheirs))
continue;
int i = output.i;
if (block.IsProofOfWork() && mapWallet.count(block.vtx[0].GetHash()))
{
CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
- printf(" mine: %d %d %"PRI64d"", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit(false));
+ printf(" mine: %d %d %"PRI64d"", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
}
if (block.IsProofOfStake() && mapWallet.count(block.vtx[1].GetHash()))
{
CWalletTx& wtx = mapWallet[block.vtx[1].GetHash()];
- printf(" stake: %d %d %"PRI64d"", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit(false));
+ printf(" stake: %d %d %"PRI64d"", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
}
}
continue;
int nDepth = pcoin->GetDepthInMainChain();
- if (nDepth < (pcoin->IsFromMe() ? 0 : 1))
+ if (nDepth < (pcoin->IsFromMe(MINE_ALL) ? 0 : 1))
continue;
for (unsigned int i = 0; i < pcoin->vout.size(); i++)
void ReacceptWalletTransactions();
void ResendWalletTransactions();
int64 GetBalance() const;
- int64 GetBalanceWatchOnly() const;
+ int64 GetWatchOnlyBalance() const;
int64 GetUnconfirmedBalance() const;
+ int64 GetUnconfirmedWatchOnlyBalance() const;
int64 GetImmatureBalance() const;
+ int64 GetImmatureWatchOnlyBalance() const;
int64 GetStake() const;
int64 GetNewMint() const;
+ int64 GetWatchOnlyStake() const;
+ int64 GetWatchOnlyNewMint() const;
bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, const CCoinControl *coinControl=NULL);
bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, const CCoinControl *coinControl=NULL);
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
std::map<CTxDestination, int64> GetAddressBalances();
isminetype IsMine(const CTxIn& txin) const;
- int64 GetDebit(const CTxIn& txin) const;
+ int64 GetDebit(const CTxIn& txin, const isminefilter& filter) const;
isminetype IsMine(const CTxOut& txout) const
{
return ::IsMine(*this, txout.scriptPubKey);
}
- int64 GetCredit(const CTxOut& txout) const
+ int64 GetCredit(const CTxOut& txout, const isminefilter& filter) const
{
if (!MoneyRange(txout.nValue))
throw std::runtime_error("CWallet::GetCredit() : value out of range");
- isminetype ismine = IsMine(txout);
- return (ismine != MINE_NO ? txout.nValue : 0);
- }
- int64 GetCreditWatchOnly(const CTxOut& txout) const
- {
- if (!MoneyRange(txout.nValue))
- throw std::runtime_error("CWallet::GetCreditWatchOnly() : value out of range");
- isminetype ismine = IsMine(txout);
- if (ismine != MINE_WATCH_ONLY)
- return 0;
- return (ismine != MINE_NO ? txout.nValue : 0);
+ return (IsMine(txout) & filter ? txout.nValue : 0);
}
bool IsChange(const CTxOut& txout) const;
int64 GetChange(const CTxOut& txout) const
}
bool IsFromMe(const CTransaction& tx) const
{
- return (GetDebit(tx) > 0);
+ return (GetDebit(tx, MINE_ALL) > 0);
}
- int64 GetDebit(const CTransaction& tx) const
+ int64 GetDebit(const CTransaction& tx, const isminefilter& filter) const
{
int64 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");
}
return nDebit;
}
- int64 GetCredit(const CTransaction& tx) const
- {
- int64 nCredit = 0;
- BOOST_FOREACH(const CTxOut& txout, tx.vout)
- {
- nCredit += GetCredit(txout);
- if (!MoneyRange(nCredit))
- throw std::runtime_error("CWallet::GetCredit() : value out of range");
- }
- return nCredit;
- }
- int64 GetCreditWatchOnly(const CTransaction& tx) const
+ int64 GetCredit(const CTransaction& tx, const isminefilter& filter) const
{
int64 nCredit = 0;
BOOST_FOREACH(const CTxOut& txout, tx.vout)
{
- nCredit += GetCreditWatchOnly(txout);
+ nCredit += GetCredit(txout, filter);
if (!MoneyRange(nCredit))
throw std::runtime_error("CWallet::GetCredit() : value out of range");
}
// memory only
mutable bool fDebitCached;
+ mutable bool fWatchDebitCached;
mutable bool fCreditCached;
- mutable bool fWatchOnlyCreditCached;
+ mutable bool fWatchCreditCached;
mutable bool fAvailableCreditCached;
- mutable bool fAvailableWatchOnlyCreditCached;
+ mutable bool fImmatureCreditCached;
+ mutable bool fImmatureWatchCreditCached;
+ mutable bool fAvailableWatchCreditCached;
mutable bool fChangeCached;
mutable int64 nDebitCached;
+ mutable int64 nWatchDebitCached;
mutable int64 nCreditCached;
- mutable int64 nWatchOnlyCreditCached;
+ mutable int64 nWatchCreditCached;
mutable int64 nAvailableCreditCached;
- mutable int64 nAvailableWatchOnlyCreditCached;
+ mutable int64 nImmatureCreditCached;
+ mutable int64 nImmatureWatchCreditCached;
+ mutable int64 nAvailableWatchCreditCached;
mutable int64 nChangeCached;
CWalletTx()
strFromAccount.clear();
vfSpent.clear();
fDebitCached = false;
+ fWatchDebitCached = false;
fCreditCached = false;
- fWatchOnlyCreditCached = false;
+ fWatchCreditCached = false;
fAvailableCreditCached = false;
- fAvailableWatchOnlyCreditCached = false;
+ fAvailableWatchCreditCached = false;
fChangeCached = false;
nDebitCached = 0;
+ nWatchDebitCached = 0;
nCreditCached = 0;
- nWatchOnlyCreditCached = 0;
+ nWatchCreditCached = 0;
nAvailableCreditCached = 0;
- nAvailableWatchOnlyCreditCached = 0;
+ nAvailableWatchCreditCached = 0;
nChangeCached = 0;
nOrderPos = -1;
}
{
vfSpent[i] = true;
fReturn = true;
- fAvailableCreditCached = fAvailableWatchOnlyCreditCached = false;
+ fAvailableCreditCached = fAvailableWatchCreditCached = false;
}
}
return fReturn;
void MarkDirty()
{
fCreditCached = false;
- fAvailableCreditCached = fAvailableWatchOnlyCreditCached = false;
- fDebitCached = false;
+ fAvailableCreditCached = fAvailableWatchCreditCached = false;
+ fDebitCached = fWatchDebitCached = false;
fChangeCached = false;
}
if (!vfSpent[nOut])
{
vfSpent[nOut] = true;
- fAvailableCreditCached = fAvailableWatchOnlyCreditCached = false;
+ fAvailableCreditCached = fAvailableWatchCreditCached = false;
}
}
if (vfSpent[nOut])
{
vfSpent[nOut] = false;
- fAvailableCreditCached = fAvailableWatchOnlyCreditCached = false;
+ fAvailableCreditCached = fAvailableWatchCreditCached = false;
}
}
return (!!vfSpent[nOut]);
}
- int64 GetDebit() const
+ int64 GetDebit(const isminefilter& filter) const
{
if (vin.empty())
return 0;
- if (fDebitCached)
- return nDebitCached;
- nDebitCached = pwallet->GetDebit(*this);
- fDebitCached = true;
- return nDebitCached;
+
+ int64 nDebit = 0;
+ if (filter & MINE_SPENDABLE)
+ {
+ if (fDebitCached)
+ nDebit += nDebitCached;
+ else
+ {
+ nDebitCached = pwallet->GetDebit(*this, MINE_SPENDABLE);
+ fDebitCached = true;
+ nDebit += nDebitCached;
+ }
+ }
+ if (filter & MINE_WATCH_ONLY)
+ {
+ if (fWatchDebitCached)
+ nDebit += nWatchDebitCached;
+ else
+ {
+ nWatchDebitCached = pwallet->GetDebit(*this, MINE_WATCH_ONLY);
+ fWatchDebitCached = true;
+ nDebit += nWatchDebitCached;
+ }
+ }
+
+ return nDebit;
}
int64 GetCredit(bool fUseCache=true) const
return nCreditCached;
}
- nCreditCached = pwallet->GetCredit(*this);
+ nCreditCached = pwallet->GetCredit(*this, MINE_ALL);
fCreditCached = true;
return nCreditCached;
}
+ int64 GetImmatureCredit(bool fUseCache=true) const
+ {
+ if ((IsCoinBase() || IsCoinStake()) && GetBlocksToMaturity() > 0 && IsInMainChain())
+ {
+ if (fUseCache && fImmatureCreditCached)
+ return nImmatureCreditCached;
+ nImmatureCreditCached = pwallet->GetCredit(*this, MINE_SPENDABLE);
+ fImmatureCreditCached = true;
+ return nImmatureCreditCached;
+ }
+
+ return 0;
+ }
+
+ int64 GetImmatureWatchOnlyCredit(bool fUseCache=true) const
+ {
+ if ((IsCoinBase() || IsCoinStake()) && GetBlocksToMaturity() > 0 && IsInMainChain())
+ {
+ if (fUseCache && fImmatureWatchCreditCached)
+ return nImmatureWatchCreditCached;
+ nImmatureWatchCreditCached = pwallet->GetCredit(*this, MINE_WATCH_ONLY);
+ fImmatureWatchCreditCached = true;
+ return nImmatureWatchCreditCached;
+ }
+
+ return 0;
+ }
+
+
int64 GetAvailableCredit(bool fUseCache=true) const
{
// Must wait until coinbase is safely deep enough in the chain before valuing it
if (!IsSpent(i))
{
const CTxOut &txout = vout[i];
- nCredit += pwallet->GetCredit(txout);
+ nCredit += pwallet->GetCredit(txout, MINE_SPENDABLE);
if (!MoneyRange(nCredit))
throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
}
return nCredit;
}
- int64 GetCreditWatchOnly(bool fUseCache=true) const
+ int64 GetAvailableWatchCredit(bool fUseCache=true) const
{
// Must wait until coinbase is safely deep enough in the chain before valuing it
if ((IsCoinBase() || IsCoinStake()) && GetBlocksToMaturity() > 0)
return 0;
- // GetBalance can assume transactions in mapWallet won't change
if (fUseCache) {
- if (fWatchOnlyCreditCached)
- return nWatchOnlyCreditCached;
- }
-
- nWatchOnlyCreditCached = pwallet->GetCreditWatchOnly(*this);
- fWatchOnlyCreditCached = true;
-
- return nWatchOnlyCreditCached;
- }
-
- int64 GetAvailableCreditWatchOnly(bool fUseCache=true) const
- {
- // Must wait until coinbase is safely deep enough in the chain before valuing it
- if ((IsCoinBase() || IsCoinStake()) && GetBlocksToMaturity() > 0)
- return 0;
-
- if (fUseCache) {
- if (fAvailableWatchOnlyCreditCached)
- return nAvailableWatchOnlyCreditCached;
+ if (fAvailableWatchCreditCached)
+ return nAvailableWatchCreditCached;
}
int64 nCredit = 0;
if (!IsSpent(i))
{
const CTxOut &txout = vout[i];
- nCredit += pwallet->GetCreditWatchOnly(txout);
+ nCredit += pwallet->GetCredit(txout, MINE_WATCH_ONLY);
if (!MoneyRange(nCredit))
- throw std::runtime_error("CWalletTx::GetAvailableCreditWatchOnly() : value out of range");
+ throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
}
}
- nAvailableWatchOnlyCreditCached = nCredit;
- fAvailableWatchOnlyCreditCached = true;
+ nAvailableWatchCreditCached = nCredit;
+ fAvailableWatchCreditCached = true;
return nCredit;
}
-
int64 GetChange() const
{
if (fChangeCached)
}
void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, 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 isminefilter& filter) const;
void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived,
- int64& nSent, int64& nFee) const;
+ int64& nSent, int64& nFee, const isminefilter& filter) const;
- bool IsFromMe() const
+ bool IsFromMe(const isminefilter& filter) const
{
- return (GetDebit() > 0);
+ return (GetDebit(filter) > 0);
}
bool IsTrusted() const
return false;
if (GetDepthInMainChain() >= 1)
return true;
- if (fConfChange || !IsFromMe()) // using wtx's cached debit
+ if (fConfChange || !IsFromMe(MINE_ALL)) // using wtx's cached debit
return false;
// If no confirmations but it's from us, we can still