You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor(core,eth,ethstats,params): make fork choice independent of the TD index
Chaindata written before the TD index existed can leave the head
without a total difficulty entry. Every fork-choice, sync and
stalling check assumed the value was present, so such nodes either
panicked in the comparisons or stalled forever when insertion
demanded a parent TD that was missing.
Rather than rebuilding the index or treating the missing value as
zero everywhere, the decision layer now routes all fork-choice
comparisons through forkChoiceCmp: in the v2 region, where every
difficulty is 1, the comparison is exactly a height check; the v1
region keeps the heaviest-chain rule. A missing TD falls back to a
height comparison, and blocks without a computable parent TD are
stored without a TD entry instead of being rejected.
Wire fields and TD writes are otherwise unchanged, so mixed-version
nodes stay compatible. Legacy data serves a null totalDifficulty
over RPC and a zero TD in handshakes and block announcements, and
ethstats reports zero instead of an invalid JSON "<nil>" value.
Notes for reviewers and node operators:
- NewBlock announcements no longer spawn a synchronise probe while a
downloader cycle is already running; the running cycle and the
periodic syncer re-evaluate peers. This applies to TD-healthy nodes
as well.
- A legacy node whose advertised peer head is already known locally
and not strictly above the current head skips the sync cycle
entirely, since the height-based fork choice can never prefer such
a chain. Startup logs display zero rather than a "<nil>" TD.
- The v2 boundary now lives in params.XDPoSConfig.IsV2Block, the
single source of truth shared with block validation, avoiding
duplicated switch-block comparisons on fork-choice hot paths.
- InsertReceiptChain re-checks the canonical hash of the receipt
batch head under chainmu before advancing the snap marker, so a
head removed by a concurrent rewind cannot repoint the snap marker
above the rewind point.
- A fork-choice tie with unknown total difficulties keeps the
current chain deterministically instead of the anti-selfish-mining
coin flip, which is only applied when both TDs are known.
- Block tracer hooks receive a zero TD instead of a nil pointer on
legacy chaindata.
0 commit comments