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.
Summary
--sync=warpagainst finney mainnet never leaves block 0. The node requests a warp proof beginning at genesis, peers serve it, and verification fails with:The node then applies a
-536870912reputation penalty, drops the peer, and repeats against the next one indefinitely. Status stays⏩ Warping, Downloading finality proofs, 0.00 Mibforever, at any peer count.Reproduced independently on two unrelated hosts in different datacentres and on different providers.
Reproduce
Reproduces with a completely minimal flag set (above) and with a tuned one; not configuration-dependent.
Trace
With
--log=sync=trace:beginis the finney genesis hash0x2f0555cc76fc2840a25a6ea3b9637146806f1f44b090c175ffde2a7e5ab36c03.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:
ghcr.io/raofoundation/subtensor:latest(=v432)ghcr.io/opentensor/subtensor:latestghcr.io/raofoundation/subtensor:mainSuspected cause
node/src/service/grandpa_warp_sync.rsgives mainnet and testnet materially different treatment: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 matchesinvalid commit in grandpa justificationon 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
0x2f0555cc76fc2840a25a6ea3b9637146806f1f44b090c175ffde2a7e5ab36c03, byte-identical tochain_getBlockHash(0)fromentrypoint-finney.opentensor.ai.system_chain=Bittensor. Absolute chainspec path used, never--chain=finney.8900556vs best8900558at time of test.bestNumber=8900412(chain head). Reproduced at 40 peers.--database=paritydband with RocksDB.--sync=fast. Advertised in--helpbut rejected at runtime withService(Other("Unsupported sync mode")), so warp is the only practical option —fullis a multi-week genesis sync.Separate observation: litep2p
Also seen while narrowing this down, possibly worth its own issue:
--network-backend=litep2p(the default on:main) connected 0 peers indefinitely, while--network-backend=libp2pon the same host, same image, same config reached 30 peers in ~150s.Impact
Warp is the documented way to stand up a lite node, and it is the only fast path —
fastis unimplemented andfullis 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.