Previously DisconnectBlock() would fail when undoing such transactions because it assumed all transactions will add at least one output to the UTXO set.
Be warned that I haven't tested this very well; I may be missing something.
Previously DisconnectBlock() would fail when undoing such transactions because it assumed all transactions will add at least one output to the UTXO set.
Be warned that I haven't tested this very well; I may be missing something.
I believe the issue and the solution is correct, but this patch seems over-complicated. I'll look at it later today.
As we do not have any releases with the pruning code enabled, this is not urgent.
I think it's slightly urgent as my analysis was that this issue is fork forming, and people do mine on git code. (The conclusion I reached while investigating this was that it would cause reorgs to fail, though I haven't attempted a test)
Previously DisconnectBlock() would fail when undoing such transactions
because it assumed all transactions will add at least one output to the
UTXO set.
1755 | - fClean = fClean && error("DisconnectBlock() : outputs still spent? database corrupted"); 1756 | - view.SetCoins(hash, CCoins()); 1757 | + // Remember that if every output of a transaction is unspendable the 1758 | + // correct state for the UTXO set to be in is always to not have the 1759 | + // transaction indexed at all. 1760 | + if (!tx.AllOutputsUnspendable()) {
Can you replace this by tx.IsPruned(), and see if things still work?
Ugh, this is a CTransaction, not a CCoins of course. Never mind.
FWIW I dunno I really need to add that function to CTransaction itself; this seems like the only case where it would ever be used.
1756 | - view.SetCoins(hash, CCoins()); 1757 | + // Remember that if every output of a transaction is unspendable the 1758 | + // correct state for the UTXO set to be in is always to not have the 1759 | + // transaction indexed at all. 1760 | + if (!tx.AllOutputsUnspendable()) { 1761 | + if (!view.HaveCoins(hash) & !tx.AllOutputsUnspendable()) {
No need to call AllOutputsUnspendable twice, I think? (also, use && instead of &).
Ooops!
Yeah, that patch was a bit rushed...
Alternative with less code changes: move outsBlock construction to before the test, and then use outsBlock.IsPruned() instead of the loop to check whether all outputs are unspendable.
Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/cbea442e6d8fb2b447e14fd8a527d670f76b1e68 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.
@petertodd Sure, but it avoids adding the extra loop for detecting the all-prunable case (and the duplicate work that is associated with it)
Seems this is urgent, I had to reindex now 2 times on my mainnet wallet using current master and 5 times my testnet wallet.
@petertodd I sent a simpler pullreq (#3163) that should accomplish the same. Care to test it?
A checklevel 2 is not really a workaround here, since we still can't disconnect the block if it ends up orphaned.