SSV Checkpoint Sync Trust Model #93
Replies: 8 comments 4 replies
|
Just want to say it is nice you gave an extra option besides B, which was the only solution I had in mind! |
|
I personally think candidate A is acceptable. So I think we should develop this solution first. Nevertheless, if due to other reasons we need to change the contract we can add option B (if we see demand for it). |
|
I agree Candidate A is probably the practical first version, especially if we want checkpoint sync without contract changes. I just think it would help to make the trust and recovery model a bit more explicit. One thing I’d like to clarify is what we mean by an issue arising. A checkpoint can have valid signatures and metadata but still be incomplete or semantically wrong. In that case, a client may not know there is a problem unless some check catches it, another checkpoint source disagrees, or someone independently audits the checkpoint. Historical replay can still be useful as an audit or recovery path once a checkpoint is questioned. But then we should describe it that way. If historical replay is reliable and practical enough for nodes to depend on, the motivation for checkpoint sync is weaker. If it is slow, expensive, rate limited, or operationally fragile, then it should not be the main safety argument for accepting trusted checkpoints. I would also be careful with archive nodes here. Current SSV replay uses historical Another limitation of Candidate A is that it keeps the current situation where nodes do not have a protocol commitment for the full public SSV network state at a given block. So two clients still cannot compare one compact value and know they reconstructed the same SSV state. Candidate B would solve that, but with the contract and gas costs already described. I would not rely on Portal Network unless someone can point to a maintained production path for the exact SSV historical logs we need. On Candidate B and demand, I think we should define concrete triggers: client teams not being comfortable with trusted signers, operators wanting untrusted checkpoint mirrors, conflicting or invalid checkpoint incidents, or a contract upgrade where the added gas cost is acceptable. So I’m fine with Candidate A first, but the SIP should describe it as trusted checkpoints plus optional checks and separate audit/recovery. If we need untrusted import time validation, that is what Candidate B is for. |
|
Operator perspective from 17 months on mainnet (op 1039, Lido x SSV Strong +1 for Candidate A as the immediate fix. I went through a long One practical question on the trusted side: would the publisher set be On concrete triggers for Candidate B: the one that would make me |
|
Since the metadata volume of the SSV network is now very large, with a massive number of validators and expectations of significant future growth, choosing Option B seems completely unreasonable. It poses a major challenge to contract storage and gas costs. I agree with using Option A, even as a long-term solution, but I recommend mandating verification via |
|
The context here is Candidate A from the SIP discussion (trusted checkpoints). The weakness A leaves open is completeness. A checkpoint can carry valid signatures and correct metadata and still be missing or wrong about part of the state, and the
|
|
It helps to split this into two things we'd actually run. The first is a CI test. We capture a fixed slice of real history into a file, with the expected roots written in. On every code change, both clients replay that file in CI and assert their roots match. That part is fully automated, comparison included, but it only covers the history baked into the file. The second is a cross-client replay run. We start each client at the first SSV block, process all of history, and have each one emit a record every N blocks. Generating those records is automatic. Comparing the two clients' records is a separate step, and that's the part that's manual unless we build a small diff tool for it. At each of those sampling points (every N blocks) each client emits three values: the block number, a hash of the logs it consumed up to that block, and the state root. The log hash is there because the comparison only means something if both clients read the same events, and RPC providers can differ in indexing, retention, or gaps. So we compare the log hash first. If the log hashes differ, that's a data-source problem, not a client bug. Only matching log hashes with differing state roots point to a real reconstruction divergence. One thing worth calling out about clients that are already running. A deployed client synced to the tip keeps only current state and has discarded the earlier history, so it can emit those three values only from its deploy point forward, not for blocks before it started. That's still useful in two ways. Any running client, on either implementation, can emit the same three values as it follows the chain, so we get an ongoing stream of roots over new history without a dedicated replay run. And it gives us the production check directly: when we produce a checkpoint at a given block, the running clients on each implementation emit their root at that block, and those have to agree before we accept it. So the replay run from the first SSV block is the one that catches a historical bug like #972, where (per #972) the two clients decoded an operator key differently. The root mismatch would have shown up right at that block. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
SSV Checkpoint Sync Trust Model
Status: working decision note before SIP text or contract code.
Author: Diego Marin Santos (@diegomrsantos)
Goal
A client should be able to start from finalized Ethereum block
B, download an SSV checkpoint snapshot, rebuild public SSV network state atB, and continue processing recent SSV events fromB + 1.The client should not need historical SSV logs from contract deployment.
Problem
Current SSV clients rebuild this state by replaying historical contract events. This means a new client needs old logs to sync.
A checkpoint snapshot removes that dependency, but the client still needs to know whether the snapshot is valid.
Today there is also no SSV contract value that represents the full public SSV network state at finalized block
B. That means clients do not have a compact protocol commitment they can compare against to check whether they reconstructed the same state forB.This document only decides how snapshot validity is established.
Design Choice
B.eth_callchecks for fields the contract can read.B?eth_callchecks.Both candidates can use the same
SnapshotV1format and the same deterministicsnapshotRoot.Candidate A: Trusted Checkpoints
Checkpoint publishers create
SnapshotV1at blockB, computesnapshotRoot, and sign the checkpoint metadata.A client verifies the configured signatures, imports the snapshot, then resumes event processing from
B + 1.This avoids old logs without changing the SSV contracts.
Candidate A can be hardened with
eth_callchecks at blockBagainst the client's Ethereum endpoint. These checks compare snapshot fields with contract views for data the contract can read directly, such as global values, operator records, specific validator existence checks, and selected cluster tuple checks. This can catch many invalid snapshots, including snapshots produced from incomplete or buggy event data.These checks are not a complete proof. They only cover what the contract can query at block
B; they do not prove that the snapshot includes every public SSV record.Advantages:
Limitations:
eth_callchecks reduce the risk of accepting an invalid snapshot but do not remove publisher trust;Candidate B: On-chain SSV State Root
The SSV contract stores a root for public SSV network state:
A client accepts a snapshot only if its recomputed
snapshotRootequals the contract root at finalized blockB.This avoids trusting the snapshot source for contents. The snapshot source can serve bad data, but the client rejects it if the root does not match.
It also gives clients one compact value for public SSV network state at block
B:ssvPublicStateRoot.Advantages:
B;Costs:
What these costs mean:
binary-merkle-treeor Nervos'ssparse-merkle-treein Rust, and Go Merkle libraries or go-ethereum trie code if they match the final root design.Candidate B does not replace Ethereum finality or weak subjectivity. It only lets the client check that the snapshot matches the SSV root stored at block
B, and lets implementations compare that root when they need to check whether they reconstructed the same public SSV state.Root Construction
The root construction is the main technical choice inside Candidate B. It defines how many public state records become one
ssvPublicStateRoot, and how that root changes when one record is added, updated, or removed.The safe family of choices is Merkle commitments based on hash functions. They are standard, auditable, and avoid RSA, pairing, and elliptic curve assumptions. That matters for a future migration to post quantum cryptography: the root would rely on hash security rather than factoring or discrete log assumptions.
Two Merkle designs are worth evaluating first:
O(log capacity)H(domain, owner, validatorPubkey).O(log keyspace), typically much deeperThe likely first prototype should be indexed Merkle trees with fixed capacity, because SSV state has natural domains such as operators, owners, clusters, and validators. That design only works if stable indices and capacity limits are acceptable. If index management becomes too complex or fragile, Sparse Merkle Tree is the conservative fallback.
The SIP should not choose a root construction by intuition. It needs a prototype that measures gas for the affected write paths and verifies that independent implementations compute the same root from the same snapshot.
Decision Criteria
Choose Candidate A if the goal is practical checkpoint sync and the protocol is comfortable trusting configured checkpoint publishers.
Choose Candidate B if the snapshot should be verifiable from an untrusted source by comparing it with a commitment in the SSV contract, or if SSV needs a compact state commitment for finalized block
B.The main decision is whether the extra security of Candidate B is worth those costs.
Open Questions
eth_callchecks, or on a state root maintained by the SSV contract?All reactions