aboutsummaryrefslogtreecommitdiff
path: root/src/wallet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet.cpp')
-rw-r--r--src/wallet.cpp76
1 files changed, 75 insertions, 1 deletions
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 821b8851a6..07a5047cef 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -291,6 +291,31 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
return true;
}
+CWallet::TxItems
+CWallet::OrderedTxItems(std::string strAccount)
+{
+ CWalletDB walletdb(strWalletFile);
+
+ // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap.
+ TxItems txOrdered;
+
+ // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry
+ // would make this much faster for applications that do this a lot.
+ for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ {
+ CWalletTx* wtx = &((*it).second);
+ txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
+ }
+ list<CAccountingEntry> acentries;
+ walletdb.ListAccountCreditDebit(strAccount, acentries);
+ BOOST_FOREACH(CAccountingEntry& entry, acentries)
+ {
+ txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry)));
+ }
+
+ return txOrdered;
+}
+
void CWallet::WalletUpdateSpent(const CTransaction &tx)
{
// Anytime a signature is successfully verified, it's proof the outpoint is spent.
@@ -336,7 +361,55 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
wtx.BindWallet(this);
bool fInsertedNew = ret.second;
if (fInsertedNew)
+ {
wtx.nTimeReceived = GetAdjustedTime();
+ wtx.nOrderPos = nOrderPosNext++;
+
+ wtx.nTimeSmart = wtx.nTimeReceived;
+ if (wtxIn.hashBlock != 0)
+ {
+ if (mapBlockIndex.count(wtxIn.hashBlock))
+ {
+ unsigned int latestNow = wtx.nTimeReceived;
+ unsigned int latestEntry = 0;
+ {
+ // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
+ int64 latestTolerated = latestNow + 300;
+ TxItems txOrdered = OrderedTxItems();
+ for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
+ {
+ CWalletTx *const pwtx = (*it).second.first;
+ if (pwtx == &wtx)
+ continue;
+ CAccountingEntry *const pacentry = (*it).second.second;
+ int64 nSmartTime;
+ if (pwtx)
+ {
+ nSmartTime = pwtx->nTimeSmart;
+ if (!nSmartTime)
+ nSmartTime = pwtx->nTimeReceived;
+ }
+ else
+ nSmartTime = pacentry->nTime;
+ if (nSmartTime <= latestTolerated)
+ {
+ latestEntry = nSmartTime;
+ if (nSmartTime > latestNow)
+ latestNow = nSmartTime;
+ break;
+ }
+ }
+ }
+
+ unsigned int& blocktime = mapBlockIndex[wtxIn.hashBlock]->nTime;
+ wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
+ }
+ else
+ printf("AddToWallet() : found %s in block %s not in index\n",
+ wtxIn.GetHash().ToString().substr(0,10).c_str(),
+ wtxIn.hashBlock.ToString().c_str());
+ }
+ }
bool fUpdated = false;
if (!fInsertedNew)
@@ -485,7 +558,8 @@ bool CWallet::IsChange(const CTxOut& txout) const
int64 CWalletTx::GetTxTime() const
{
- return nTimeReceived;
+ int64 n = nTimeSmart;
+ return n ? n : nTimeReceived;
}
int CWalletTx::GetRequestCount() const