return true;
}
+bool AddToWalletIfFromMe(const CTransaction& tx, const CBlock* pblock)
+{
+ if (tx.IsFromMe() || mapWallet.count(tx.GetHash()))
+ {
+ CWalletTx wtx(tx);
+ // Get merkle branch if transaction was found in a block
+ if (pblock)
+ wtx.SetMerkleBranch(pblock);
+ return AddToWallet(wtx);
+ }
+ return true;
+}
+
bool EraseFromWallet(uint256 hash)
{
CRITICAL_BLOCK(cs_mapWallet)
if (IsCoinBase())
{
- if (GetBlocksToMaturity() == 0)
+ if (GetDepthInMainChain() >= COINBASE_MATURITY)
nGenerated = GetCredit();
return;
}
return false;
}
+int ScanForWalletTransactions(CBlockIndex* pindexStart)
+{
+ int ret = 0;
+
+ CBlockIndex* pindex = pindexStart;
+ CRITICAL_BLOCK(cs_mapWallet)
+ {
+ while (pindex)
+ {
+ CBlock block;
+ block.ReadFromDisk(pindex, true);
+ foreach(CTransaction& tx, block.vtx)
+ {
+ uint256 hash = tx.GetHash();
+ if (mapWallet.count(hash)) continue;
+ AddToWalletIfMine(tx, &block);
+ if (mapWallet.count(hash))
+ {
+ ++ret;
+ printf("Added missing RECEIVE %s\n", hash.ToString().c_str());
+ continue;
+ }
+ AddToWalletIfFromMe(tx, &block);
+ if (mapWallet.count(hash))
+ {
+ ++ret;
+ printf("Added missing SEND %s\n", hash.ToString().c_str());
+ continue;
+ }
+ }
+ pindex = pindex->pnext;
+ }
+ }
+ return ret;
+}
+
void ReacceptWalletTransactions()
{
CTxDB txdb("r");
- CRITICAL_BLOCK(cs_mapWallet)
+ bool fRepeat = true;
+ while (fRepeat) CRITICAL_BLOCK(cs_mapWallet)
{
+ fRepeat = false;
+ vector<CDiskTxPos> vMissingTx;
foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
{
CWalletTx& wtx = item.second;
{
if (!txindex.vSpent[i].IsNull() && wtx.vout[i].IsMine())
{
- printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
wtx.fSpent = true;
- wtx.WriteToDisk();
- break;
+ vMissingTx.push_back(txindex.vSpent[i]);
}
}
+ if (wtx.fSpent)
+ {
+ printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
+ wtx.WriteToDisk();
+ }
}
}
else
wtx.AcceptWalletTransaction(txdb, false);
}
}
+ if (!vMissingTx.empty())
+ {
+ // TODO: optimize this to scan just part of the block chain?
+ if (ScanForWalletTransactions(pindexGenesisBlock))
+ fRepeat = true; // Found missing transactions: re-do Reaccept.
+ }
}
}
return true;
}
-
-
bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
{
printf("REORGANIZE\n");
if (params.size() == 0)
return ((double)GetBalance() / (double)COIN);
+ if (params[0].get_str() == "*") {
+ // Calculate total balance a different way from GetBalance()
+ // (GetBalance() sums up all unspent TxOuts)
+ // getbalance and getbalance '*' should always return the same number.
+ int64 nBalance = 0;
+ for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ {
+ const CWalletTx& wtx = (*it).second;
+ int64 allGenerated, allFee;
+ allGenerated = allFee = 0;
+ string strSentAccount;
+ list<pair<string, int64> > listReceived;
+ list<pair<string, int64> > listSent;
+ wtx.GetAmounts(allGenerated, listReceived, listSent, allFee, strSentAccount);
+ foreach(const PAIRTYPE(string,int64)& r, listReceived)
+ nBalance += r.second;
+ foreach(const PAIRTYPE(string,int64)& r, listSent)
+ nBalance -= r.second;
+ nBalance -= allFee;
+ nBalance += allGenerated;
+ }
+ return (double)nBalance / (double)COIN;
+ }
+
string strAccount = AccountFromValue(params[0]);
int nMinDepth = 1;
if (params.size() > 1)