Commit 8a714d73 authored by coin-server's avatar coin-server

Merge branch 'state_corruption' into 'v1.0.1a-qt5'

improve wallet handling

See merge request ProjectMerge/merge!6
parents db0c4ed2 de75a287
......@@ -2513,7 +2513,7 @@ bool static ConnectTip(CValidationState& state, CBlockIndex* pindexNew, CBlock*
LogPrint("bench", " - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
// Write the chain state to disk, if necessary. Always write to disk if this is the first of a new file.
FlushStateMode flushMode = FLUSH_STATE_ALWAYS;
FlushStateMode flushMode = FLUSH_STATE_IF_NEEDED;
if (pindexNew->pprev && (pindexNew->GetBlockPos().nFile != pindexNew->pprev->GetBlockPos().nFile))
flushMode = FLUSH_STATE_ALWAYS;
if (!FlushStateToDisk(state, flushMode))
......
......@@ -52,7 +52,7 @@ bool fPayAtLeastCustomFee = false;
* Override with -mintxfee
*/
CFeeRate CWallet::minTxFee = CFeeRate(0);
int64_t nStartupTime = GetAdjustedTime();
int64_t nStartupTime = GetTime();
/** @defgroup mapWallet
*
......@@ -663,7 +663,9 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet)
if (fFromLoadWallet) {
mapWallet[hash] = wtxIn;
mapWallet[hash].BindWallet(this);
CWalletTx& wtx = mapWallet[hash];
wtx.BindWallet(this);
wtxOrdered.insert(make_pair(wtx.nOrderPos, TxPair(&wtx, (CAccountingEntry*)0)));
AddToSpends(hash);
} else {
LOCK(cs_wallet);
......@@ -673,52 +675,17 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet)
wtx.BindWallet(this);
bool fInsertedNew = ret.second;
if (fInsertedNew) {
wtx.nTimeReceived = GetAdjustedTime();
if (!wtx.nTimeReceived)
wtx.nTimeReceived = GetAdjustedTime();
wtx.nOrderPos = IncOrderPosNext();
wtx.nTimeSmart = wtx.nTimeReceived;
if (wtxIn.hashBlock != 0) {
if (mapBlockIndex.count(wtxIn.hashBlock)) {
int64_t latestNow = wtx.nTimeReceived;
int64_t latestEntry = 0;
{
// Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
int64_t latestTolerated = latestNow + 300;
std::list<CAccountingEntry> acentries;
TxItems txOrdered = OrderedTxItems(acentries);
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_t 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;
}
}
}
int64_t blocktime = mapBlockIndex[wtxIn.hashBlock]->GetBlockTime();
wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
} else
LogPrintf("AddToWallet() : found %s in block %s not in index\n",
wtxIn.GetHash().ToString(),
wtxIn.hashBlock.ToString());
}
wtxOrdered.insert(make_pair(wtx.nOrderPos, TxPair(&wtx, (CAccountingEntry*)0)));
wtx.nTimeSmart = ComputeTimeSmart(wtx);
AddToSpends(hash);
}
bool fUpdated = false;
if (!fInsertedNew) {
// Merge
if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock) {
wtx.hashBlock = wtxIn.hashBlock;
fUpdated = true;
......@@ -1178,7 +1145,7 @@ void CWallet::ReacceptWalletTransactions()
int nDepth = wtx.GetDepthInMainChain();
if (!wtx.IsCoinBase() && nDepth < 0) {
if (!wtx.IsCoinBase() && nDepth < 0 && !wtx.IsCoinStake()) {
// Try to add to memory pool
LOCK(mempool.cs);
wtx.AcceptToMemoryPool(false);
......@@ -3408,6 +3375,48 @@ void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t>& mapKeyBirth) const
mapKeyBirth[it->first] = it->second->GetBlockTime() - 7200; // block times can be 2h off
}
unsigned int CWallet::ComputeTimeSmart(const CWalletTx& wtx) const
{
unsigned int nTimeSmart = wtx.nTimeReceived;
if (wtx.hashBlock != 0) {
if (mapBlockIndex.count(wtx.hashBlock)) {
int64_t latestNow = wtx.nTimeReceived;
int64_t latestEntry = 0;
{
// Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
int64_t latestTolerated = latestNow + 300;
TxItems txOrdered = wtxOrdered;
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_t 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;
}
}
}
int64_t blocktime = mapBlockIndex[wtx.hashBlock]->GetBlockTime();
nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
} else
LogPrintf("AddToWallet() : found %s in block %s not in index\n",
wtx.GetHash().ToString(),
wtx.hashBlock.ToString());
}
return nTimeSmart;
}
bool CWallet::AddDestData(const CTxDestination& dest, const std::string& key, const std::string& value)
{
if (boost::get<CNoDestination>(&dest))
......
......@@ -419,6 +419,7 @@ public:
bool EncryptWallet(const SecureString& strWalletPassphrase);
void GetKeyBirthTimes(std::map<CKeyID, int64_t>& mapKeyBirth) const;
unsigned int ComputeTimeSmart(const CWalletTx& wtx) const;
/**
* Increment the next transaction order id
......@@ -428,6 +429,7 @@ public:
typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair;
typedef std::multimap<int64_t, TxPair> TxItems;
TxItems wtxOrdered;
/**
* Get the wallet's activity log
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment