Skip to content

Latest commit

 

History

History
85 lines (67 loc) · 3.44 KB

File metadata and controls

85 lines (67 loc) · 3.44 KB

Threat model

malcom moves chain state between machines over an untrusted P2P network. The integrity of every artifact depends on understanding which checks prove what.

Trust boundary

The malcom snapshot fetch peer set is untrusted. A peer may withhold chunks, return garbage, or fabricate an entire snapshot covering a fake chain history. Any node ID can be generated for free; do not assume "the peer claimed to be X" means anything.

The application.db produced by malcom snapshot import is trusted only after malcom verify succeeds against a trusted RPC.

What per-chunk hashes prove

Every cosmos-sdk snapshot carries a Metadata blob with one SHA-256 per chunk. malcom snapshot fetch recomputes each chunk's hash and compares it against the peer's advertised value before writing the chunk to disk. A mismatch aborts the fetch.

This proves: the bytes on disk are byte-identical to what the peer's snapshot offer advertised.

This does not prove:

  • That the snapshot reflects the real chain state at that height.
  • That the peer is honest.
  • That the snapshot was generated by a node that was ever in consensus with the rest of the network.

A malicious peer can construct a self-consistent fake snapshot: a set of chunks whose hashes match its advertised Metadata, whose overall hash matches its advertised SnapshotsResponse.Hash, and whose payload encodes anything — modified balances, omitted transactions, fabricated validator sets. Every per-chunk check passes. The fetcher cannot tell the difference.

What malcom verify proves

malcom verify is the trust anchor for an imported snapshot. It:

  1. Reads CommitInfo from the imported application.db at the snapshot height (the same struct cosmos-sdk's BeginBlocker reads).
  2. Computes the consensus AppHash locally from that CommitInfo.
  3. Fetches the real AppHash for height+1 from an operator-supplied RPC (or set of RPCs), which means it comes from a block header that consensus already agreed on.
  4. Compares the two. A match means the imported state is bit-identical to what every honest validator agreed the state should be at that height.

This depends entirely on the RPC being a node the operator trusts. A compromised RPC plus a compromised snapshot peer plus matching forged AppHash would defeat verify. Mitigate by passing multiple independent RPCs to --rpc-list; verify takes the first one that responds with a usable AppHash but the diagnostic logs which one, so cross-check across runs.

Operational guidance

  • Always run malcom verify before using an imported snapshot in production. Skipping verify means trusting your peers, which is the wrong default.
  • Use multiple independent RPCs in the verify step. A single RPC is a single point of compromise.
  • Treat the malcom snapshot serve peer set as adversarial. Rate limits (ChunkRatePerPeer, GlobalRate) bound the damage a hostile peer can do; they don't make any peer trustworthy.

What malcom does NOT defend against

  • A consensus-level attack on the chain being snapshotted (51%, long-range, etc.). Those compromise the AppHash itself, so even verify can't help.
  • An attacker who controls both your snapshot peer and your verify RPC. The two-source design forces an attacker to compromise independent infrastructure; it doesn't make compromise impossible.
  • Side-channel attacks on the host (disk corruption beyond what fsync covers, RAM bitflips, etc.). Out of scope.