diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -45,6 +45,7 @@ Amount totalFee = Amount::zero(); size_t totalSize = CTransaction(parentOfAll).GetTotalSize(); + int64_t totalSigOpCount = 0; // Generate 100 transactions for (size_t totalTransactions = 0; totalTransactions < 100; @@ -120,6 +121,7 @@ // Calculate overall values totalFee += randFee; totalSize += CTransaction(tx).GetTotalSize(); + totalSigOpCount += randSigOpCount; CTxMemPoolEntry parentEntry = *testPool.mapTx.find(parentOfAllId); CTxMemPoolEntry latestEntry = *testPool.mapTx.find(curId); @@ -140,6 +142,8 @@ testPool.mapTx.size()); BOOST_CHECK_EQUAL(parentEntry.GetSizeWithDescendants(), totalSize); BOOST_CHECK_EQUAL(parentEntry.GetModFeesWithDescendants(), totalFee); + BOOST_CHECK_EQUAL(parentEntry.GetSigOpCountWithDescendants(), + totalSigOpCount); } } diff --git a/src/txmempool.h b/src/txmempool.h --- a/src/txmempool.h +++ b/src/txmempool.h @@ -94,9 +94,10 @@ uint64_t nCountWithDescendants; //!< ... and size uint64_t nSizeWithDescendants; - //!< ... and total fees (all including us) Amount nModFeesWithDescendants; + //!< ... and sigop count + int64_t nSigOpCountWithDescendants; // Analogous statistics for ancestor transactions uint64_t nCountWithAncestors; @@ -123,7 +124,7 @@ // Adjusts the descendant state. void UpdateDescendantState(int64_t modifySize, Amount modifyFee, - int64_t modifyCount); + int64_t modifyCount, int64_t modifySigOpCount); // Adjusts the ancestor state void UpdateAncestorState(int64_t modifySize, Amount modifyFee, int64_t modifyCount, int modifySigOps); @@ -136,6 +137,9 @@ uint64_t GetCountWithDescendants() const { return nCountWithDescendants; } uint64_t GetSizeWithDescendants() const { return nSizeWithDescendants; } Amount GetModFeesWithDescendants() const { return nModFeesWithDescendants; } + int64_t GetSigOpCountWithDescendants() const { + return nSigOpCountWithDescendants; + } bool GetSpendsCoinbase() const { return spendsCoinbase; } @@ -153,18 +157,20 @@ // Helpers for modifying CTxMemPool::mapTx, which is a boost multi_index. struct update_descendant_state { update_descendant_state(int64_t _modifySize, Amount _modifyFee, - int64_t _modifyCount) + int64_t _modifyCount, int64_t _modifySigOpCount) : modifySize(_modifySize), modifyFee(_modifyFee), - modifyCount(_modifyCount) {} + modifyCount(_modifyCount), modifySigOpCount(_modifySigOpCount) {} void operator()(CTxMemPoolEntry &e) { - e.UpdateDescendantState(modifySize, modifyFee, modifyCount); + e.UpdateDescendantState(modifySize, modifyFee, modifyCount, + modifySigOpCount); } private: int64_t modifySize; Amount modifyFee; int64_t modifyCount; + int64_t modifySigOpCount; }; struct update_ancestor_state { diff --git a/src/txmempool.cpp b/src/txmempool.cpp --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -37,6 +37,7 @@ nCountWithDescendants = 1; nSizeWithDescendants = GetTxSize(); + nSigOpCountWithDescendants = sigOpCount; nModFeesWithDescendants = nFee; feeDelta = Amount::zero(); @@ -90,11 +91,13 @@ int64_t modifySize = 0; int64_t modifyCount = 0; Amount modifyFee = Amount::zero(); + int64_t modifySigOpCount = 0; for (txiter cit : setAllDescendants) { if (!setExclude.count(cit->GetTx().GetId())) { modifySize += cit->GetTxSize(); modifyFee += cit->GetModifiedFee(); modifyCount++; + modifySigOpCount += cit->GetSigOpCount(); cachedDescendants[updateIt].insert(cit); // Update ancestor state for each descendant mapTx.modify(cit, @@ -104,7 +107,8 @@ } } 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 @@ -250,10 +254,12 @@ } const int64_t updateCount = (add ? 1 : -1); const int64_t updateSize = updateCount * it->GetTxSize(); + const int64_t updateSigOpCount = updateCount * it->GetSigOpCount(); const Amount updateFee = updateCount * it->GetModifiedFee(); for (txiter ancestorIt : setAncestors) { - mapTx.modify(ancestorIt, update_descendant_state(updateSize, updateFee, - updateCount)); + mapTx.modify(ancestorIt, + update_descendant_state(updateSize, updateFee, updateCount, + updateSigOpCount)); } } @@ -342,12 +348,15 @@ void CTxMemPoolEntry::UpdateDescendantState(int64_t modifySize, Amount modifyFee, - int64_t modifyCount) { + int64_t modifyCount, + int64_t modifySigOpCount) { nSizeWithDescendants += modifySize; assert(int64_t(nSizeWithDescendants) > 0); nModFeesWithDescendants += modifyFee; nCountWithDescendants += modifyCount; assert(int64_t(nCountWithDescendants) > 0); + nSigOpCountWithDescendants += modifySigOpCount; + assert(int64_t(nSigOpCountWithDescendants) >= 0); } void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, Amount modifyFee, @@ -747,6 +756,7 @@ CTxMemPool::setEntries setChildrenCheck; auto iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetId(), 0)); uint64_t child_sizes = 0; + int64_t child_sigop_counts = 0; for (; iter != mapNextTx.end() && iter->first->GetTxId() == it->GetTx().GetId(); ++iter) { @@ -755,6 +765,7 @@ assert(childit != mapTx.end()); if (setChildrenCheck.insert(childit).second) { child_sizes += childit->GetTxSize(); + child_sigop_counts += childit->GetSigOpCount(); } } assert(setChildrenCheck == GetMemPoolChildren(it)); @@ -762,6 +773,8 @@ // children. Just a sanity check, not definitive that this calc is // correct... assert(it->GetSizeWithDescendants() >= child_sizes + it->GetTxSize()); + assert(it->GetSigOpCountWithDescendants() >= + child_sigop_counts + it->GetSigOpCount()); if (fDependsWait) { waitingOnDependants.push_back(&(*it)); @@ -927,7 +940,7 @@ nNoLimit, nNoLimit, dummy, false); for (txiter ancestorIt : setAncestors) { mapTx.modify(ancestorIt, - update_descendant_state(0, nFeeDelta, 0)); + update_descendant_state(0, nFeeDelta, 0, 0)); } // Now update all descendants' modified fees with ancestors