Closed sdaftuar closed 8 years ago
Ok, I think this works now -- first commit changes the behavior of -checkblocks
to not stomp on pruning nodes. Hopefully the change to FindForkInGlobalIndex
is okay...
(Note: The last commit is https://github.com/bitcoin/bitcoin/pull/8076 )
Rebased (and got rid of unintended code move in init.cpp
that was in the prior version).
Rebase on top of merged #8076?
I cherry picked that commit from #8076 and rebased on sipa/segwit-master.
@sdaftuar Woops, I missed this is against segwit-master and not against upstream!
Including in next batch.
Turns out this is harder than I thought. This is not suitable for merging because there's a bug (see below), and after further thought I now wonder whether trying to fix all this is worth it.
I ran into two issues: first, after we were calling
RewindBlockIndex
, in init we'd then callVerifyDB
, which for a pruning node would fail because we just rewound back to the point where we have no more data, so trying to read the next earlier block from disk would fail.I tried to workaround this by moving the
VerifyDB
call to happen before we callRewindBlockIndex
, but then realized that this doesn't work, because eg if you were using checklevel=4, then the blocks that need to be rewound wouldn't in general passVerifyDB
(since we didn't download those blocks with the likely-needed witness data).Maybe one solution to this problem would be to somehow bypass calling
VerifyDB
in the particular case that you're a pruning node and we just rewound the chain? But that seems hacky. Any better ideas?The second issue I ran into had to do with wallet rescans taking place after
RewindBlockIndex
. I figured there should be no problem, because the wallet ought to be ahead of the tip, which should be fine. However, it turns out thatFindForkInGlobalIndex(chainActive, wallet-locator)
can return a blockindex that is earlier thanchainActive.Tip()
even if the wallet locator's tip is a successor of our tip. So I added a quick "fix" toFindForkInGlobalIndex
that would detect this situation. It's not clear to me if there might be side effects (eg performance side effects, or new behavior because the function now returns different values in some situations) worth worrying about.Also, I discovered that the node is in a pretty brittle state if it's a pruning node that is rewound this way... If you were to, say, bring the node down after the chain has been rewound and before new blocks are downloaded from peers, then on restart the node will die in
VerifyDB
. So at this point, I am wondering if we shouldn't perhaps just put a big warning in the release notes that pruning nodes should try to upgrade before activation in order to avoid redownloading the blockchain, along with graceful detection so that if the user fails to do so, they get a nicer error message?I can take a stab at that approach if you agree that it makes more sense.