Standard / EIP·EVM
EIP-3076 — Slashing Protection Interchange Format
Interface EIP defining a JSON file format for exporting and importing a validator's slashing-protection database between consensus clients. Standardizes signed-block and signed-attestation history so a validator can migrate between Lighthouse, Prysm, Teku, Nimbus, Lodestar without double-signing.
- 01migrating validators between CL clients
- 02moving validators between hardware/hosts
- 03staking-as-a-service operator handoffs
- 04DVT (Obol/SSV) operator changes
- 05disaster-recovery key restoration
- # All major consensus clients ship import/export commands:
- # lighthouse account validator slashing-protection {import,export}
- # prysmctl validator slashing-protection-history {import,export}
- # teku slashing-protection {import,export}
- # nimbus_beacon_node slashingdb {import,export}
- # lodestar validator slashing-protection {import,export}
Implement validator client tooling against the EIP-3076 JSON schema: a top-level `metadata` object (`interchange_format_version: '5'`, `genesis_validators_root`) and a `data` array of per-validator records each containing `pubkey`, `signed_blocks` (objects with `slot` and optional `signing_root`), and `signed_attestations` (objects with `source_epoch`, `target_epoch`, optional `signing_root`). On import, the client MUST refuse to sign any future block at slot ≤ max(seen slot) and any attestation whose source < max(source) or target ≤ max(target) — the surround/double-vote rules. Support both `complete` (full history) and `minimal` (only the highest slot/source/target per validator) modes; `minimal` is safe for simple migrations but loses fine-grained history. Always export from the SOURCE client while it is stopped, then import into the TARGET client before starting the validator — never run two clients with the same key, even briefly.
- ⚑Slashing-DB merge is NOT a union: you cannot simply concatenate two interchange files. If you have signed on machine A and machine B with overlapping windows, take the maximum slot per block, the maximum target per attestation, and the maximum source per attestation per pubkey — anything less risks a slashable surround vote.
- ⚑`genesis_validators_root` must match the target chain. Importing a mainnet interchange into a testnet client (or vice versa) silently corrupts protection. Validate the GVR before accepting the file.
- ⚑`minimal` mode is one-way: once you import a minimal record, you cannot later import a complete record for the same pubkey without the client refusing or downgrading — clients diverge here. Pick `complete` whenever possible.
- ⚑Run-once-only: never start the source client after exporting, and never start the target client before importing. Concurrent operation with the same key is the primary cause of real-world slashings during migrations.
- ⚑Some clients reject `signing_root: null` in strict mode; produce signing_root when known and treat absent signing_root as 'must check the slashing rule conservatively' (refuse to sign anything ≤ recorded slot/target).