Changeset View
Changeset View
Standalone View
Standalone View
src/txmempool.cpp
Show First 20 Lines • Show All 675 Lines • ▼ Show 20 Lines | void CTxMemPool::_clear() { | ||||
++nTransactionsUpdated; | ++nTransactionsUpdated; | ||||
} | } | ||||
void CTxMemPool::clear() { | void CTxMemPool::clear() { | ||||
LOCK(cs); | LOCK(cs); | ||||
_clear(); | _clear(); | ||||
} | } | ||||
static void CheckInputsAndUpdateCoins(const CTransaction &tx, | |||||
CCoinsViewCache &mempoolDuplicate, | |||||
const int64_t spendheight) { | |||||
CValidationState state; | |||||
Amount txfee = Amount::zero(); | |||||
bool fCheckResult = | |||||
tx.IsCoinBase() || Consensus::CheckTxInputs(tx, state, mempoolDuplicate, | |||||
spendheight, txfee); | |||||
assert(fCheckResult); | |||||
UpdateCoins(mempoolDuplicate, tx, 1000000); | |||||
} | |||||
void CTxMemPool::check(const CCoinsViewCache *pcoins) const { | void CTxMemPool::check(const CCoinsViewCache *pcoins) const { | ||||
LOCK(cs); | LOCK(cs); | ||||
if (nCheckFrequency == 0) { | if (nCheckFrequency == 0) { | ||||
return; | return; | ||||
} | } | ||||
if (GetRand(std::numeric_limits<uint32_t>::max()) >= nCheckFrequency) { | if (GetRand(std::numeric_limits<uint32_t>::max()) >= nCheckFrequency) { | ||||
return; | return; | ||||
} | } | ||||
LogPrint(BCLog::MEMPOOL, | LogPrint(BCLog::MEMPOOL, | ||||
"Checking mempool with %u transactions and %u inputs\n", | "Checking mempool with %u transactions and %u inputs\n", | ||||
(unsigned int)mapTx.size(), (unsigned int)mapNextTx.size()); | (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size()); | ||||
uint64_t checkTotal = 0; | uint64_t checkTotal = 0; | ||||
uint64_t innerUsage = 0; | uint64_t innerUsage = 0; | ||||
CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache *>(pcoins)); | CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache *>(pcoins)); | ||||
const int64_t nSpendHeight = GetSpendHeight(mempoolDuplicate); | const int64_t spendheight = GetSpendHeight(mempoolDuplicate); | ||||
std::list<const CTxMemPoolEntry *> waitingOnDependants; | std::list<const CTxMemPoolEntry *> waitingOnDependants; | ||||
for (indexed_transaction_set::const_iterator it = mapTx.begin(); | for (indexed_transaction_set::const_iterator it = mapTx.begin(); | ||||
it != mapTx.end(); it++) { | it != mapTx.end(); it++) { | ||||
unsigned int i = 0; | unsigned int i = 0; | ||||
checkTotal += it->GetTxSize(); | checkTotal += it->GetTxSize(); | ||||
innerUsage += it->DynamicMemoryUsage(); | innerUsage += it->DynamicMemoryUsage(); | ||||
const CTransaction &tx = it->GetTx(); | const CTransaction &tx = it->GetTx(); | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | for (indexed_transaction_set::const_iterator it = mapTx.begin(); | ||||
// Also check to make sure size is greater than sum with immediate | // Also check to make sure size is greater than sum with immediate | ||||
// children. Just a sanity check, not definitive that this calc is | // children. Just a sanity check, not definitive that this calc is | ||||
// correct... | // correct... | ||||
assert(it->GetSizeWithDescendants() >= childSizes + it->GetTxSize()); | assert(it->GetSizeWithDescendants() >= childSizes + it->GetTxSize()); | ||||
if (fDependsWait) { | if (fDependsWait) { | ||||
waitingOnDependants.push_back(&(*it)); | waitingOnDependants.push_back(&(*it)); | ||||
} else { | } else { | ||||
CValidationState state; | CheckInputsAndUpdateCoins(tx, mempoolDuplicate, spendheight); | ||||
bool fCheckResult = tx.IsCoinBase() || | |||||
Consensus::CheckTxInputs( | |||||
tx, state, mempoolDuplicate, nSpendHeight); | |||||
assert(fCheckResult); | |||||
UpdateCoins(mempoolDuplicate, tx, 1000000); | |||||
} | } | ||||
} | } | ||||
unsigned int stepsSinceLastRemove = 0; | unsigned int stepsSinceLastRemove = 0; | ||||
while (!waitingOnDependants.empty()) { | while (!waitingOnDependants.empty()) { | ||||
const CTxMemPoolEntry *entry = waitingOnDependants.front(); | const CTxMemPoolEntry *entry = waitingOnDependants.front(); | ||||
waitingOnDependants.pop_front(); | waitingOnDependants.pop_front(); | ||||
CValidationState state; | CValidationState state; | ||||
if (!mempoolDuplicate.HaveInputs(entry->GetTx())) { | if (!mempoolDuplicate.HaveInputs(entry->GetTx())) { | ||||
waitingOnDependants.push_back(entry); | waitingOnDependants.push_back(entry); | ||||
stepsSinceLastRemove++; | stepsSinceLastRemove++; | ||||
assert(stepsSinceLastRemove < waitingOnDependants.size()); | assert(stepsSinceLastRemove < waitingOnDependants.size()); | ||||
} else { | } else { | ||||
bool fCheckResult = | CheckInputsAndUpdateCoins(entry->GetTx(), mempoolDuplicate, | ||||
entry->GetTx().IsCoinBase() || | spendheight); | ||||
Consensus::CheckTxInputs(entry->GetTx(), state, | |||||
mempoolDuplicate, nSpendHeight); | |||||
assert(fCheckResult); | |||||
UpdateCoins(mempoolDuplicate, entry->GetTx(), 1000000); | |||||
stepsSinceLastRemove = 0; | stepsSinceLastRemove = 0; | ||||
} | } | ||||
} | } | ||||
for (auto it = mapNextTx.cbegin(); it != mapNextTx.cend(); it++) { | for (auto it = mapNextTx.cbegin(); it != mapNextTx.cend(); it++) { | ||||
uint256 txid = it->second->GetId(); | uint256 txid = it->second->GetId(); | ||||
indexed_transaction_set::const_iterator it2 = mapTx.find(txid); | indexed_transaction_set::const_iterator it2 = mapTx.find(txid); | ||||
const CTransaction &tx = it2->GetTx(); | const CTransaction &tx = it2->GetTx(); | ||||
▲ Show 20 Lines • Show All 580 Lines • Show Last 20 Lines |