As it says on the tin.
Avoid repeated lookups in mapOrphanTransactions and mapOrphanTransactionsByPrev #4873
pull laanwj wants to merge 1 commits into bitcoin:master from laanwj:2014_09_avoid_repeated_orphantx_lookup changing 1 files +13 −10-
laanwj commented at 3:39 PM on September 8, 2014: member
-
Avoid repeated lookups in mapOrphanTransactions and mapOrphanTransactionsByPrev 89d91f6aa7
-
BitcoinPullTester commented at 4:04 PM on September 8, 2014: none
Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/p4873_89d91f6aa74da5e3fb1bbd08ce20ab3b9d593abd/ for binaries and test log. This test script verifies pulls every time they are updated. It, however, dies sometimes and fails to test properly. If you are waiting on a test, please check timestamps to verify that the test.log is moving at http://jenkins.bluematt.me/pull-tester/current/ Contact BlueMatt on freenode if something looks broken.
-
gavinandresen commented at 4:36 PM on September 8, 2014: contributor
Tested ACK.
-
sipa commented at 9:32 PM on September 8, 2014: member
Untested ACK
-
gmaxwell commented at 11:14 PM on September 8, 2014: contributor
ACK.
- laanwj merged this on Sep 9, 2014
- laanwj closed this on Sep 9, 2014
- laanwj referenced this in commit 8bc0a0173e on Sep 9, 2014
- Diapolo referenced this in commit b11360b7b6 on Sep 9, 2014
-
gavinandresen commented at 3:47 PM on September 9, 2014: contributor
Bah: did some more testing today with MAX_ORPHAN_TRANSACTIONS = 4 and got a core dump.
I'm running with this fix; so far so good:
diff --git a/src/main.cpp b/src/main.cpp index 2e24eb9..10f9ba9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -498,6 +498,8 @@ void static EraseOrphanTx(uint256 hash) BOOST_FOREACH(const CTxIn& txin, it->second.vin) { map<uint256, set<uint256> >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.prevout.hash); + if (itPrev == mapOrphanTransactionsByPrev.end()) + continue; itPrev->second.erase(hash); if (itPrev->second.empty()) mapOrphanTransactionsByPrev.erase(itPrev); -
sipa commented at 3:51 PM on September 9, 2014: member
@gavinandresen Ugh, that's not good. That means the orphan pool is inconsistent.
-
laanwj commented at 3:53 PM on September 9, 2014: member
Good sanity check to add, but indeed in principle it shouldn't happen.
-
sipa commented at 4:02 PM on September 9, 2014: member
If we don't understand why the orphan pool is getting inconsistent, I think we should revert instead of patching it up (an assert would be fine, though).
-
laanwj commented at 4:09 PM on September 9, 2014: member
We have no reason to think that this is caused by this change. Before, this problem would not have been caught (or have resulted in a crash) because the record was created every time.
mapOrphanTransactionsByPrev[txin.prevout.hash].erase(hash);So all that @gavinandresen's patch would do is restore the old behavior. But indeed, that would ignore the inconsistency.
-
gavinandresen commented at 5:32 PM on September 9, 2014: contributor
Looking at this more closely, I'm confident my proposed fix is correct.
Scenario 1 that tickles the bug: Orphan transaction that spends two inputs of the same transaction. I think two orphan transactions that spend the same output of a parent transaction would also cause the crash.
The memory pool is consistent-- mapOrphanTransactions/mapOrphanTransactionsByPrev is just a big bag of transactions that can be inconsistent (may contain double-spends or invalid transactions), and that is OK, transactions are checked before moving from mapOrphanTransactions into the memory pool.
-
sipa commented at 6:11 PM on September 9, 2014: member
By inconsistent I just meant a discrepance between mapOrphanTransactions and mapOrphanTransactionsByPrev. But indeed, as they're identified by txid and not txid:index, a transaction spending two outputs from the same transactions does explain it. ACK on the change.
- wtogami referenced this in commit 8a9d840224 on Sep 10, 2014
- MarcoFalke locked this on Sep 8, 2021