6
6
#include " txmempool.h"
7
7
8
8
#include " clientversion.h"
9
- #include " main.h" // for COINBASE_MATURITY
9
+ #include " main.h"
10
10
#include " streams.h"
11
11
#include " util.h"
12
12
#include " utilmoneystr.h"
@@ -539,17 +539,22 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
539
539
540
540
uint64_t checkTotal = 0 ;
541
541
542
+ CCoinsViewCache mempoolDuplicate (const_cast <CCoinsViewCache*>(pcoins));
543
+
542
544
LOCK (cs);
545
+ list<const CTxMemPoolEntry*> waitingOnDependants;
543
546
for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin (); it != mapTx.end (); it++) {
544
547
unsigned int i = 0 ;
545
548
checkTotal += it->second .GetTxSize ();
546
549
const CTransaction& tx = it->second .GetTx ();
550
+ bool fDependsWait = false ;
547
551
BOOST_FOREACH (const CTxIn &txin, tx.vin ) {
548
552
// Check that every mempool transaction's inputs refer to available coins, or other mempool tx's.
549
553
std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find (txin.prevout .hash );
550
554
if (it2 != mapTx.end ()) {
551
555
const CTransaction& tx2 = it2->second .GetTx ();
552
556
assert (tx2.vout .size () > txin.prevout .n && !tx2.vout [txin.prevout .n ].IsNull ());
557
+ fDependsWait = true ;
553
558
} else {
554
559
const CCoins* coins = pcoins->AccessCoins (txin.prevout .hash );
555
560
assert (coins && coins->IsAvailable (txin.prevout .n ));
@@ -561,6 +566,29 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
561
566
assert (it3->second .n == i);
562
567
i++;
563
568
}
569
+ if (fDependsWait )
570
+ waitingOnDependants.push_back (&it->second );
571
+ else {
572
+ CValidationState state; CTxUndo undo;
573
+ assert (CheckInputs (tx, state, mempoolDuplicate, false , 0 , false , NULL ));
574
+ UpdateCoins (tx, state, mempoolDuplicate, undo, 1000000 );
575
+ }
576
+ }
577
+ unsigned int stepsSinceLastRemove = 0 ;
578
+ while (!waitingOnDependants.empty ()) {
579
+ const CTxMemPoolEntry* entry = waitingOnDependants.front ();
580
+ waitingOnDependants.pop_front ();
581
+ CValidationState state;
582
+ if (!mempoolDuplicate.HaveInputs (entry->GetTx ())) {
583
+ waitingOnDependants.push_back (entry);
584
+ stepsSinceLastRemove++;
585
+ assert (stepsSinceLastRemove < waitingOnDependants.size ());
586
+ } else {
587
+ assert (CheckInputs (entry->GetTx (), state, mempoolDuplicate, false , 0 , false , NULL ));
588
+ CTxUndo undo;
589
+ UpdateCoins (entry->GetTx (), state, mempoolDuplicate, undo, 1000000 );
590
+ stepsSinceLastRemove = 0 ;
591
+ }
564
592
}
565
593
for (std::map<COutPoint, CInPoint>::const_iterator it = mapNextTx.begin (); it != mapNextTx.end (); it++) {
566
594
uint256 hash = it->second .ptx ->GetHash ();
0 commit comments