Changeset View
Changeset View
Standalone View
Standalone View
src/txmempool.cpp
Show All 29 Lines | CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef &_tx, const Amount _nFee, | ||||
bool _spendsCoinbase, int64_t _sigOpsCount, | bool _spendsCoinbase, int64_t _sigOpsCount, | ||||
LockPoints lp) | LockPoints lp) | ||||
: tx(_tx), nFee(_nFee), nTxSize(tx->GetTotalSize()), | : tx(_tx), nFee(_nFee), nTxSize(tx->GetTotalSize()), | ||||
nUsageSize(RecursiveDynamicUsage(tx)), nTime(_nTime), | nUsageSize(RecursiveDynamicUsage(tx)), nTime(_nTime), | ||||
entryHeight(_entryHeight), spendsCoinbase(_spendsCoinbase), | entryHeight(_entryHeight), spendsCoinbase(_spendsCoinbase), | ||||
sigOpCount(_sigOpsCount), lockPoints(lp) { | sigOpCount(_sigOpsCount), lockPoints(lp) { | ||||
nCountWithDescendants = 1; | nCountWithDescendants = 1; | ||||
nSizeWithDescendants = GetTxSize(); | nSizeWithDescendants = GetTxSize(); | ||||
nSigOpCountWithDescendants = sigOpCount; | |||||
nModFeesWithDescendants = nFee; | nModFeesWithDescendants = nFee; | ||||
feeDelta = Amount::zero(); | feeDelta = Amount::zero(); | ||||
nCountWithAncestors = 1; | nCountWithAncestors = 1; | ||||
nSizeWithAncestors = GetTxSize(); | nSizeWithAncestors = GetTxSize(); | ||||
nModFeesWithAncestors = nFee; | nModFeesWithAncestors = nFee; | ||||
nSigOpCountWithAncestors = sigOpCount; | nSigOpCountWithAncestors = sigOpCount; | ||||
Show All 37 Lines | while (!stageEntries.empty()) { | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// setAllDescendants now contains all in-mempool descendants of updateIt. | // setAllDescendants now contains all in-mempool descendants of updateIt. | ||||
// Update and add to cached descendant map | // Update and add to cached descendant map | ||||
int64_t modifySize = 0; | int64_t modifySize = 0; | ||||
int64_t modifyCount = 0; | int64_t modifyCount = 0; | ||||
Amount modifyFee = Amount::zero(); | Amount modifyFee = Amount::zero(); | ||||
int64_t modifySigOpCount = 0; | |||||
for (txiter cit : setAllDescendants) { | for (txiter cit : setAllDescendants) { | ||||
if (!setExclude.count(cit->GetTx().GetId())) { | if (!setExclude.count(cit->GetTx().GetId())) { | ||||
modifySize += cit->GetTxSize(); | modifySize += cit->GetTxSize(); | ||||
modifyFee += cit->GetModifiedFee(); | modifyFee += cit->GetModifiedFee(); | ||||
modifyCount++; | modifyCount++; | ||||
modifySigOpCount += cit->GetSigOpCount(); | |||||
cachedDescendants[updateIt].insert(cit); | cachedDescendants[updateIt].insert(cit); | ||||
// Update ancestor state for each descendant | // Update ancestor state for each descendant | ||||
mapTx.modify(cit, | mapTx.modify(cit, | ||||
update_ancestor_state(updateIt->GetTxSize(), | update_ancestor_state(updateIt->GetTxSize(), | ||||
updateIt->GetModifiedFee(), 1, | updateIt->GetModifiedFee(), 1, | ||||
updateIt->GetSigOpCount())); | updateIt->GetSigOpCount())); | ||||
} | } | ||||
} | } | ||||
mapTx.modify(updateIt, | mapTx.modify(updateIt, | ||||
update_descendant_state(modifySize, modifyFee, modifyCount)); | update_descendant_state(modifySize, modifyFee, modifyCount, | ||||
modifySigOpCount)); | |||||
} | } | ||||
// txidsToUpdate is the set of transaction hashes from a disconnected block | // txidsToUpdate is the set of transaction hashes from a disconnected block | ||||
// which has been re-added to the mempool. For each entry, look for descendants | // which has been re-added to the mempool. For each entry, look for descendants | ||||
// that are outside txidsToUpdate, and add fee/size information for such | // that are outside txidsToUpdate, and add fee/size information for such | ||||
// descendants to the parent. For each such descendant, also update the ancestor | // descendants to the parent. For each such descendant, also update the ancestor | ||||
// state to include the parent. | // state to include the parent. | ||||
void CTxMemPool::UpdateTransactionsFromBlock( | void CTxMemPool::UpdateTransactionsFromBlock( | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | void CTxMemPool::UpdateAncestorsOf(bool add, txiter it, | ||||
setEntries &setAncestors) { | setEntries &setAncestors) { | ||||
setEntries parentIters = GetMemPoolParents(it); | setEntries parentIters = GetMemPoolParents(it); | ||||
// add or remove this tx as a child of each parent | // add or remove this tx as a child of each parent | ||||
for (txiter piter : parentIters) { | for (txiter piter : parentIters) { | ||||
UpdateChild(piter, it, add); | UpdateChild(piter, it, add); | ||||
} | } | ||||
const int64_t updateCount = (add ? 1 : -1); | const int64_t updateCount = (add ? 1 : -1); | ||||
const int64_t updateSize = updateCount * it->GetTxSize(); | const int64_t updateSize = updateCount * it->GetTxSize(); | ||||
const int64_t updateSigOpCount = updateCount * it->GetSigOpCount(); | |||||
const Amount updateFee = updateCount * it->GetModifiedFee(); | const Amount updateFee = updateCount * it->GetModifiedFee(); | ||||
for (txiter ancestorIt : setAncestors) { | for (txiter ancestorIt : setAncestors) { | ||||
mapTx.modify(ancestorIt, update_descendant_state(updateSize, updateFee, | mapTx.modify(ancestorIt, | ||||
updateCount)); | update_descendant_state(updateSize, updateFee, updateCount, | ||||
updateSigOpCount)); | |||||
} | } | ||||
} | } | ||||
void CTxMemPool::UpdateEntryForAncestors(txiter it, | void CTxMemPool::UpdateEntryForAncestors(txiter it, | ||||
const setEntries &setAncestors) { | const setEntries &setAncestors) { | ||||
int64_t updateCount = setAncestors.size(); | int64_t updateCount = setAncestors.size(); | ||||
int64_t updateSize = 0; | int64_t updateSize = 0; | ||||
int64_t updateSigOpsCount = 0; | int64_t updateSigOpsCount = 0; | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove, | ||||
// setMemPoolParents for each direct child of a transaction being removed). | // setMemPoolParents for each direct child of a transaction being removed). | ||||
for (txiter removeIt : entriesToRemove) { | for (txiter removeIt : entriesToRemove) { | ||||
UpdateChildrenForRemoval(removeIt); | UpdateChildrenForRemoval(removeIt); | ||||
} | } | ||||
} | } | ||||
void CTxMemPoolEntry::UpdateDescendantState(int64_t modifySize, | void CTxMemPoolEntry::UpdateDescendantState(int64_t modifySize, | ||||
Amount modifyFee, | Amount modifyFee, | ||||
int64_t modifyCount) { | int64_t modifyCount, | ||||
int64_t modifySigOpCount) { | |||||
nSizeWithDescendants += modifySize; | nSizeWithDescendants += modifySize; | ||||
assert(int64_t(nSizeWithDescendants) > 0); | assert(int64_t(nSizeWithDescendants) > 0); | ||||
nModFeesWithDescendants += modifyFee; | nModFeesWithDescendants += modifyFee; | ||||
nCountWithDescendants += modifyCount; | nCountWithDescendants += modifyCount; | ||||
assert(int64_t(nCountWithDescendants) > 0); | assert(int64_t(nCountWithDescendants) > 0); | ||||
nSigOpCountWithDescendants += modifySigOpCount; | |||||
assert(int64_t(nSigOpCountWithDescendants) >= 0); | |||||
} | } | ||||
void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, Amount modifyFee, | void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, Amount modifyFee, | ||||
int64_t modifyCount, | int64_t modifyCount, | ||||
int modifySigOps) { | int modifySigOps) { | ||||
nSizeWithAncestors += modifySize; | nSizeWithAncestors += modifySize; | ||||
assert(int64_t(nSizeWithAncestors) > 0); | assert(int64_t(nSizeWithAncestors) > 0); | ||||
nModFeesWithAncestors += modifyFee; | nModFeesWithAncestors += modifyFee; | ||||
▲ Show 20 Lines • Show All 383 Lines • ▼ Show 20 Lines | for (indexed_transaction_set::const_iterator it = mapTx.begin(); | ||||
assert(it->GetSizeWithAncestors() == nSizeCheck); | assert(it->GetSizeWithAncestors() == nSizeCheck); | ||||
assert(it->GetSigOpCountWithAncestors() == nSigOpCheck); | assert(it->GetSigOpCountWithAncestors() == nSigOpCheck); | ||||
assert(it->GetModFeesWithAncestors() == nFeesCheck); | assert(it->GetModFeesWithAncestors() == nFeesCheck); | ||||
// Check children against mapNextTx | // Check children against mapNextTx | ||||
CTxMemPool::setEntries setChildrenCheck; | CTxMemPool::setEntries setChildrenCheck; | ||||
auto iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetId(), 0)); | auto iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetId(), 0)); | ||||
uint64_t child_sizes = 0; | uint64_t child_sizes = 0; | ||||
int64_t child_sigop_counts = 0; | |||||
for (; iter != mapNextTx.end() && | for (; iter != mapNextTx.end() && | ||||
iter->first->GetTxId() == it->GetTx().GetId(); | iter->first->GetTxId() == it->GetTx().GetId(); | ||||
++iter) { | ++iter) { | ||||
txiter childit = mapTx.find(iter->second->GetId()); | txiter childit = mapTx.find(iter->second->GetId()); | ||||
// mapNextTx points to in-mempool transactions | // mapNextTx points to in-mempool transactions | ||||
assert(childit != mapTx.end()); | assert(childit != mapTx.end()); | ||||
if (setChildrenCheck.insert(childit).second) { | if (setChildrenCheck.insert(childit).second) { | ||||
child_sizes += childit->GetTxSize(); | child_sizes += childit->GetTxSize(); | ||||
child_sigop_counts += childit->GetSigOpCount(); | |||||
} | } | ||||
} | } | ||||
assert(setChildrenCheck == GetMemPoolChildren(it)); | assert(setChildrenCheck == GetMemPoolChildren(it)); | ||||
// 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() >= child_sizes + it->GetTxSize()); | assert(it->GetSizeWithDescendants() >= child_sizes + it->GetTxSize()); | ||||
assert(it->GetSigOpCountWithDescendants() >= | |||||
child_sigop_counts + it->GetSigOpCount()); | |||||
if (fDependsWait) { | if (fDependsWait) { | ||||
waitingOnDependants.push_back(&(*it)); | waitingOnDependants.push_back(&(*it)); | ||||
} else { | } else { | ||||
CheckInputsAndUpdateCoins(tx, mempoolDuplicate, spendheight); | CheckInputsAndUpdateCoins(tx, mempoolDuplicate, spendheight); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 149 Lines • ▼ Show 20 Lines | void CTxMemPool::PrioritiseTransaction(const TxId &txid, | ||||
// Now update all ancestors' modified fees with descendants | // Now update all ancestors' modified fees with descendants | ||||
setEntries setAncestors; | setEntries setAncestors; | ||||
uint64_t nNoLimit = std::numeric_limits<uint64_t>::max(); | uint64_t nNoLimit = std::numeric_limits<uint64_t>::max(); | ||||
std::string dummy; | std::string dummy; | ||||
CalculateMemPoolAncestors(*it, setAncestors, nNoLimit, nNoLimit, | CalculateMemPoolAncestors(*it, setAncestors, nNoLimit, nNoLimit, | ||||
nNoLimit, nNoLimit, dummy, false); | nNoLimit, nNoLimit, dummy, false); | ||||
for (txiter ancestorIt : setAncestors) { | for (txiter ancestorIt : setAncestors) { | ||||
mapTx.modify(ancestorIt, | mapTx.modify(ancestorIt, | ||||
update_descendant_state(0, nFeeDelta, 0)); | update_descendant_state(0, nFeeDelta, 0, 0)); | ||||
} | } | ||||
// Now update all descendants' modified fees with ancestors | // Now update all descendants' modified fees with ancestors | ||||
setEntries setDescendants; | setEntries setDescendants; | ||||
CalculateDescendants(it, setDescendants); | CalculateDescendants(it, setDescendants); | ||||
setDescendants.erase(it); | setDescendants.erase(it); | ||||
for (txiter descendantIt : setDescendants) { | for (txiter descendantIt : setDescendants) { | ||||
mapTx.modify(descendantIt, | mapTx.modify(descendantIt, | ||||
▲ Show 20 Lines • Show All 456 Lines • Show Last 20 Lines |