zap: a VM that cannot answer is not a VM that said no

The six state-sync messages were reserved with payloads defined and no capability
bit, so a node could only learn whether a VM syncs by asking and reading the
reply. That conflates two different answers: a VM with no state-sync surface
cannot respond at all, and a VM that has one may still choose to replay. A node
repairing a damaged chain has to tell those apart — the first means look
elsewhere, the second means this VM decided.

CapStateSync is set at the handshake, where every other optional surface is
already discovered, so the distinction costs no round trip.

Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
2026-08-16 08:19:06 -07:00
co-authored by Hanzo Dev
parent 42ce072b1f
commit 324f613c3d
+11
View File
@@ -196,6 +196,17 @@ const (
// MsgSetQuasarFinalized / MsgQuasarHeight. Set by the C-Chain EVM; the node
// wires the consensus export-frontier observer only when this bit is set.
CapQuasarExport uint64 = 1 << 0
// CapStateSync: the VM can adopt a peer's state summary instead of replaying
// to it, and answers the six MsgStateSync*/MsgStateSummary* messages. Set by
// any VM implementing the syncable surface.
//
// The node needs this at the handshake because the alternative is asking and
// reading a refusal, and a VM that cannot answer at all is indistinguishable
// on the wire from one that answered "no". A node repairing a damaged chain
// must tell those apart: the first means find another way, the second means
// this VM chose to replay.
CapStateSync uint64 = 1 << 1
)
// Encode serializes InitializeResponse to the buffer