Reorg problem of the BlockRequestAllowed
approach
The previous approach in #24571 used BlockRequestAllowed
to determine if a peer is allowed to know about stale headers in a node's block index. BlockRequestAllowed
returns true if the block is on the main chain or if the block is younger (by time and PoW) than STALE_RELAY_AGE_LIMIT
(~ 1 month).
The idea was: If a peer sends us headers that build on top of an old stale block (according to the logic in BlockRequestAllowed
) we reject the new headers.
The problem with the one-month limit was that it would reject headers that connect to an old fork chain that is longer than 2000 (MAX_HEADERS_RESULTS
) blocks.
Consider the following block index:
If block x is older than one month we reject any headers that build on top of x and re-request the 2000 headers that connect to c. When we receive those 2000 headers, we request more headers and when those next headers arrive we reject them as they connect to an old chain. We then re-request the 2000 headers that connect to c once again. This continues on a loop until the peer is disconnected.