I really wasn’t sure what the best solution is when I opened the issue and still am not, but these are my thoughts:
Yes, there are two reasons why we might not apply assumevalid during a reindex currently:
1.) The best header has not enough chainwork
2.) The assumevalid block is not in our block index
I could change this to always skip script checks during a reindex, but IIUC having a block on disk doesn’t mean that it was connected during the previous IBD.
I think the question is rather how well we can avoid to connect blocks skipping the script checks during the reindex that we would have fully validated in the original run if we hadn’t crashed. Assuming that the user provides the same -assumevalid
arg to the reindex run that they did in the original run I can see the following cases:
1.) The user provides an existing block (or nothing, so that the default hash from chainparams is used) that we just haven’t downloaded yet because it’s later in the best chain - if we don’t have it in our index we’d be justified to skip script checks - if we do have it in our index, no special rules are necessary for reindexing. I think that’s the most common case for users.
2.) The user provides -assumevalid=0
- we should respect that also in the reindex run and fully validate everything.
3.) The user provides a block hash with -assumevalid
that is non-existing / not in the best chain. I think that’s the critical case because here we would have fully validated everything in the original run, but won’t validate anything during the reindex. But arguably that’s not a common case / the user’s fault for providing this bad block, so maybe it can be tolerated?
Might be worth it to sync headers first then connect blocks even during reindex.
Yes, that’s the second option I thought of. I think we can’t just stop and wait for the headers to be downloaded - reindex should be able to finish without having a p2p connection, even if that means no assumevalid. But I was thinking of maybe just disabling the relevant LoadingBlocks()
guards in net_processing, so that we’d download headers in parallel to ActivateBestChain()
, and would change to use assumevalid after a few thousand blocks or so. That seem a bit messy (we’d still connect some blocks without assumevalid) and requires testing but might work well in practice?!