Monthly research note. Theme: Blockchain Protocols.
TL;DR
Light Clients: Trust Minimization Without Full Replication as an engineering constraint: write down assumptions, make invariants executable, and design operational recovery as part of correctness.
Most failures are boundary failures: parsing, persistence, concurrency, retries, and upgrades.
Key takeaways
- Upgrades must be compatibility-aware: mixed rulesets are a threat model.
- Finality guarantees are user security guarantees—document and enforce them.
- Topology attacks (eclipse/partition) change security outcomes; harden peer selection.
- Prefer protocols and APIs that make invalid states hard to express.
- Write assumptions down; treat them as interfaces.
Why this matters
- State growth is a security problem: it impacts decentralization and verification.
- Mempools are an attack surface: spam, pinning, and incentive manipulation.
- Finality guarantees are user security guarantees; ambiguity is a UX vulnerability.
- MEV turns protocol details into adversarial strategy.
Key questions
- Where do you enforce resource limits (gas, bandwidth, storage, signature checks)?
- What is the determinism story (byte-for-byte re-execution across platforms)?
- What is the reorg budget for applications and how do you communicate it?
- Which invariants need proofs (supply, balances, ordering, slashing)?
- How do upgrades change security assumptions (fork choice, state transition rules)?
- How do you defend against topology attacks (eclipse, partition, sybil)?
Assumptions
- Attackers can buy bandwidth and compute; they can also bribe and censor.
- Peers are untrusted; gossip can be manipulated for delay or isolation.
- Nodes are heterogeneous; determinism must survive platform differences.
- Users and apps rely on probabilistic finality until proven otherwise.
Non-goals
- Assuming honest majority without defining the adversary’s budget.
- Relying on client-side heuristics to paper over protocol ambiguity.
Negotiation and fallbacks are where security silently becomes optional—treat them as hostile.
Model & invariants
A ledger is a replicated state machine. Safety is uniqueness of finalized history:
Model the mempool as an adversarial scheduler: it chooses which work gets executed.
Explicitly model upgrade boundaries: old rules vs new rules during transition.
Make the “impossible state” observable: a metric or alert that fires when invariants drift.
Security properties
- Authenticity: actions are bound to identity and purpose.
- Evidence: critical actions emit verifiable audit events.
- Integrity: invalid transitions are rejected (and detectable).
- Least authority: privileges are scoped by purpose and time.
Failure modes
- Timeout ambiguity causing double-apply or partial state transitions.
- Mixed-version behavior that violates assumptions silently.
- Resource exhaustion (CPU/bandwidth/storage) turning into correctness failures.
- Observability gaps during incidents (missing evidence).
Caches tend to become sources of truth unless you can recompute and validate them.
Design sketch
flowchart TD
tx["Transaction"] --> mp["Mempool (admission + prioritization)"]
mp --> prop["Block Proposal"]
prop --> cons["Consensus / Finality"]
cons --> exec["Deterministic Execution"]
exec --> root["State Root Commitment"]Implementation notes
Determinism is a boundary: every nondeterministic input is an attack surface.
Acknowledge only after durability (or make “ack” explicitly best-effort).
// Deterministic execution is a security boundary.
pub trait Executor {
fn apply_block(&mut self, block: &[u8]) -> Result<(), String>;
fn state_root(&self) -> [u8; 32];
}
// Avoid nondeterminism: time, RNG, unordered maps, floating-point.Verification strategy
- Formal invariants for supply/balance conservation where appropriate.
- Cross-implementation tests when multiple clients exist.
- Fuzzing transaction decoding and state transition edge cases.
- Adversarial mempool tests: spam, pinning, worst-case signature patterns.
- Determinism tests across architectures (x86/ARM) and OSes.
Operational notes
- Keep execution resource limits explicit and enforced.
- Measure invalid tx rejection reasons and rates (spam signature).
- Protect peer tables against eclipse attempts (diversity, scoring, rotation).
- Monitor reorg depth and frequency; treat increases as incidents.
- Rehearse upgrades with mixed versions and rollback paths.
Attach explicit rollout/rollback triggers to changes that touch security or correctness.
What to monitor
- Authz failures and policy denials (unexpected spikes).
- Retry/timeout rates by endpoint and client cohort.
- Rollback events and the conditions that triggered them.
- Error budget burn + tail latency under load.
- Admission-control / rate-limit rejections (by reason).
Rollback plan
- Define an explicit rollback trigger (metrics + thresholds).
- Use canaries and staged rollout; stop early when signals degrade.
- Keep dual-write / dual-verify windows where appropriate.
- Prefer backward-compatible changes; avoid “flag day” upgrades.
- Preserve evidence (configs, artifacts, audit logs) to reconstruct what changed.
Evidence
- Designing Data-Intensive Applications (Kleppmann) (1) — The systems-engineering baseline for correctness, replication, and failure.
- Evidence: Replication and consistency tradeoffs as engineering constraints; use as reference when naming guarantees.
- Jepsen (2) — Fault injection and correctness testing for distributed systems.
- Evidence: Turn faults into test cases; prioritize partition and clock-skew scenarios that violate user-visible guarantees.
Open questions
- How do you communicate finality uncertainty to users without lying?
- Which invariants should be proven vs tested vs monitored?
- What is the worst-case work a single transaction can force?
- Where does your implementation accidentally depend on local wall-clock time?
Checklist
- Rollback plan rehearsed and automated.
- Assumptions listed and reviewed.
- Safety properties stated as invariants.
- Failure modes enumerated with mitigations.
- Telemetry captures correctness signals.
- Costs bounded (CPU/memory/bandwidth) under adversarial inputs.
Further reading
- EIP-1559 — Fee market mechanics and incentive surfaces.
- Bitcoin: A Peer-to-Peer Electronic Cash System — The original replicated-ledger model and threat assumptions.
- Ethereum Yellow Paper — A formal-ish specification for execution and state transitions.
- Designing Data-Intensive Applications (Kleppmann) — The systems-engineering baseline for correctness, replication, and failure.
- Site Reliability Engineering (Google) — Error budgets, incident response, and reliability as an engineering discipline.
- Jepsen — Fault injection and correctness testing for distributed systems.