Skip to content

warp sync to finney mainnet never leaves block 0: "invalid commit in grandpa justification" #3112

Description

@JSONbored

Summary

--sync=warp against finney mainnet never leaves block 0. The node requests a warp proof beginning at genesis, peers serve it, and verification fails with:

Bad warp proof response: bad justification for header: invalid commit in grandpa justification

The node then applies a -536870912 reputation penalty, drops the peer, and repeats against the next one indefinitely. Status stays ⏩ Warping, Downloading finality proofs, 0.00 Mib forever, at any peer count.

Reproduced independently on two unrelated hosts in different datacentres and on different providers.

Reproduce

--base-path=/data
--chain=/home/subtensor/chainspecs/raw_spec_finney.json
--sync=warp
--rpc-external
--rpc-cors=all

Reproduces with a completely minimal flag set (above) and with a tuned one; not configuration-dependent.

Trace

With --log=sync=trace:

TRACE sync: New WarpProofRequest to 12D3KooWErnA…, begin hash: 0x2f05…6c03.
TRACE sync: Created `WarpProofRequest` to 12D3KooWErnA…,
      request: WarpProofRequest { begin: 0x2f0555cc76fc… }
DEBUG sync: Bad warp proof response: bad justification for header:
      invalid commit in grandpa justification
TRACE sync: PeerId("12D3KooWErnA…") dropped:
      ReputationChange { value: -536870912, reason: "Bad warp proof" }

begin is the finney genesis hash 0x2f0555cc76fc2840a25a6ea3b9637146806f1f44b090c175ffde2a7e5ab36c03.

A large fraction of peers additionally answer Request to peer … failed: Refused. — expected, since a warp-synced node has no justification history to serve from — but the peers that do serve a proof all fail verification identically.

Rejection counts by client version

Same host, same flags, DB wiped between runs:

image built bad warp proofs distinct peers penalised
ghcr.io/raofoundation/subtensor:latest (= v432) 2026-07-17 151 14
ghcr.io/opentensor/subtensor:latest 2026-06-29 40 13
ghcr.io/raofoundation/subtensor:main 2026-08-21 still fails, same error —

Suspected cause

node/src/service/grandpa_warp_sync.rs gives mainnet and testnet materially different treatment:

if genesis_hash == TESTNET_GENESIS {
    Config::TestnetCheckpoints(testnet_checkpoints())
} else if genesis_hash == FINNEY_GENESIS {
    Config::OneTimeInitialSetId(3)
}

Testnet gets a full Vec<AuthoritySetHardFork<Block>> checkpoint list — added recently in #3055, #3082, 08762343 fix(testnet): use historical GRANDPA signing sets, add2b31a fix(testnet): correct GRANDPA checkpoint transition.

Finney gets a single initial set-ID offset, applied only when set_id == 0, with no hard-fork checkpoints at all. If finney has any authority-set discontinuity past genesis, that path has nothing to reconcile it — which matches invalid commit in grandpa justification on a proof that begins at genesis.

The testnet fixes appear to address this exact class of failure; mainnet looks like it has not received the equivalent treatment. There is also no CLI escape hatch — the config is selected by hardcoded genesis hash, so an operator cannot supply finney checkpoints.

Ruled out

  • Wrong network. Our genesis is 0x2f0555cc76fc2840a25a6ea3b9637146806f1f44b090c175ffde2a7e5ab36c03, byte-identical to chain_getBlockHash(0) from entrypoint-finney.opentensor.ai. system_chain = Bittensor. Absolute chainspec path used, never --chain=finney.
  • Stalled finality. Finney is finalizing normally — finalized 8900556 vs best 8900558 at time of test.
  • Peering. Peers report bestNumber=8900412 (chain head). Reproduced at 40 peers.
  • Egress/firewall. Container-to-bootnode TCP verified from inside the Docker bridge.
  • Database backend. Identical behaviour with --database=paritydb and with RocksDB.
  • Our tuning. Reproduces on a minimal flag set.
  • --sync=fast. Advertised in --help but rejected at runtime with Service(Other("Unsupported sync mode")), so warp is the only practical option — full is a multi-week genesis sync.

Separate observation: litep2p

Also seen while narrowing this down, possibly worth its own issue:

  • On one host, --network-backend=litep2p (the default on :main) connected 0 peers indefinitely, while --network-backend=libp2p on the same host, same image, same config reached 30 peers in ~150s.
  • On the other host litep2p peered fine but produced 55 bad warp proofs where libp2p produced 0–3.

Impact

Warp is the documented way to stand up a lite node, and it is the only fast path — fast is unimplemented and full is a multi-week genesis sync. With warp broken on mainnet, there is no practical route to a new finney lite node, and no public snapshots exist.

Happy to supply full trace logs or test a patch.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions