RewindBlockIndex() is a mechanism to allow nodes to be upgraded after segwit activation, while still keeping their chainstate/datadir in a consistent state. It works as follows:
- A pre-segwit (i.e. v0.13.0 or older) node is running.
- Segwit activates. The pre-segwit node remains sync'ed to the tip, but is not enforcing the new segwit rules.
- The user upgrades the node to a segwit-aware version (v0.13.1 or newer).
- On startup, in AppInitMain(), RewindBlockIndex() is called (https://github.com/bitcoin/bitcoin/blob/ade38b6ee8f91e441507c0ee7ffe6ca020748991/src/init.cpp#L1692). This walks the chain backwards from the tip, disconnecting and erasing blocks that from after segwit activation that weren't validated with segwit rules.
- those blocks are then redownloaded (with witness data) and validated with segwit rules.
This logic probably isn't required any more since:
- Segwit activated at height 481824, when the block chain was 130GB and the total number of txs was 250 million. Today, we're at height 661100, the blockchain is around 315GB and the total number of txs is around 600 million. Even if 20% of that added data is witness data (a high estimate), then around 150GB of transactions would need to be rewound to get back to segwit activation height. It'd probably be faster to simply validate from genesis, especially since we won't be validating any scripts before the assumevalid block. It's also unclear whether rewinding 150GB of transactions would even work. It's certainly never been tested.
- Bitcoin Core v0.13 is hardly used any more. https://luke.dashjr.org/programs/bitcoin/files/charts/software.html shows less than 50 nodes running it. The software was EOL on Aug 1st 2018. It's very unlikely that anyone is running 0.13 and will want to upgrade to 0.22.
Removing this dead code would allow the following:
- removal of the test_upgrade_after_activation test in p2p_segwit.py (https://github.com/bitcoin/bitcoin/blob/ade38b6ee8f91e441507c0ee7ffe6ca020748991/test/functional/p2p_segwit.py#L1942)
- in turn, that would allow us to drop support for
-segwitheight=-1, which is only supported for that test. - that would allow us to always set
NODE_WITNESSin our local services (https://github.com/bitcoin/bitcoin/blob/ade38b6ee8f91e441507c0ee7ffe6ca020748991/test/functional/p2p_segwit.py#L1942). The only reason we don't do that is to support-segwitheight=-1. - that in turn would allow us to drop all of the
GetLocalServices() & NODE_WITNESSchecks inside net_processing, since we local services would always includeNODE_WITNESS