Skip to content

Un-stale spec vs latest charon main; add Pluto#11

Open
OisinKyne wants to merge 2 commits into
mainfrom
oisin/fable
Open

Un-stale spec vs latest charon main; add Pluto#11
OisinKyne wants to merge 2 commits into
mainfrom
oisin/fable

Conversation

@OisinKyne

Copy link
Copy Markdown
Contributor

Why

This repo went stale after 2025-11-12 while charon accumulated 336 commits
(now at 2eb6798e, 2026-07-14). Its purpose is to formally specify the Obol
DV protocol so that Pluto (Nethermind's Rust implementation) can be assured
of perfect interop with Charon. This PR brings the spec back in line with
charon main for everything it already covers, and records the project's
interop framing.

What's in this PR

Corrections (spec did not match the wire)

  • Priority protocol ID: charon's wire string is charon/priority/2.0.0
    no leading slash (core/priority/prioritiser.go:39). The spec
    claimed /charon/priority/2.0.0. Fixed in helpers.py, priority.md,
    and tests, each with a warning that the missing slash is
    accidental-but-normative (pluto deliberately accommodates it; do not
    "correct" it unless charon versions the protocol).
  • MsgSync.nickname (field 6, charon #4105, in v1.9.5): added to the
    dkg_sync model, proto/dkg_sync.proto, and docs. Max 32 chars,
    informational only.

Behavior updates (charon changed since 2025-11-12)

  • Deterministic round deadlines (charon #4243, in v1.9.5): the
    DoubleEagerLinearRoundTimer now derives each round's first deadline from
    genesis_time + slot * slot_duration + duty_start_delay instead of the
    local wall clock, so round boundaries and leader election stay aligned
    across peers. Added get_duty_start_delay (attester: slot/3;
    aggregator/sync-contribution: 2·slot/3). Wall-clock fallback retained,
    matching charon.
  • QBFT hardening (charon #4557, in v1.11.0):
    • DECIDED-resend rate limit: at most one rebroadcast per source per
      strictly-increasing round, capped at 16 per source
      (MAX_DECIDED_RESENDS), preventing amplification DoS.
    • MAX_CONSENSUS_MSG_SIZE (32 MiB) wire read limit.
    • verify_msg_limits: justifications ≤ 2·nodes, values ≤
      2·(justifications+1), enforced before expensive verification.
    • Documented in consensus.md (timers, message limits, decided-resend).

Structure / framing

  • Renamed subspecs/bcastsubspecs/reliable_bcast (and tests dir) to
    stop the name colliding with charon's core/bcast (beacon-node broadcast,
    a different component). Wire protocol ID /charon/dkg/bcast/1.0.0
    unchanged; disambiguation note added to reliable-broadcast.md.
  • Pluto added: README gains an Implementations table (Charon = Go
    reference implementation; Pluto = Rust, Nethermind, targeting wire
    compatibility) and an explicit interop mission statement.
  • docs/index.md fixed: was still the un-edited "Lean Ethereum" page
    from the September fork; now describes the DV specs and both clients.
  • Charon version anchor: README states the spec tracks charon main, last
    validated against 2eb6798e, with a table flagging which behaviors landed
    after v1.7.1 (pluto's current pin) and why they remain wire-compatible.
  • Fixed a stray duplicated return True in qbft/protocol.py.

Tests

24 new tests (155 → 179, all passing; ruff + mypy clean):

  • Deterministic timer: deadline derivation, cross-node alignment, late-start
    behavior, doubling from deterministic deadline, wall-clock fallback,
    duty start delays.
  • DECIDED-resend rate limit: per-round, per-peer, cap, own-message cases.
  • verify_msg_limits bounds.
  • MsgSync.nickname validation.

Deliberately NOT changed

  • Cluster definition doc stays at v1.10 (agreed target for now; charon
    is on v1.11 — revisit when the target moves).
  • Pedersen DKG spec untouched; FROST (charon's default and pluto's near-term
    DKG target) is not yet spec'd — it is the top follow-up item.

Follow-up phases (see plans/spec-completion.md for detail)

  • Phase 2 (next commit/session): FROST DKG + /charon/dkg/node_sig +
    reshare flows; sigagg (threshold BLS aggregation); infosync (priority
    protocol's actual use, gates consensus-protocol selection); validatorapi
    conformance; scheduler/core-bcast prose specs.
  • Phase 3: spec-generated test vectors as the interop contract, consumed
    by Go (charon) and Rust (pluto) test suites; conformance CI here with a
    weekly charon@main staleness alarm; wire-level mixed-cluster harness with
    the spec as passive protocol oracle.
  • Agreed aspirations: adversarial/negative vectors, differential fuzzing
    of the three QBFT state machines, pluto link-back PR, spec versioning
    policy mapped to charon MAJOR.MINOR, proto-parity CI (buf breaking-change
    diff against charon's protos — would have caught the nickname miss).

Comment thread docs/dv-spec/consensus.md
Comment on lines +68 to +70
- The default strategy is the *eager double linear* timer: round `r` lasts
`r` seconds, and the first deadline of each round is computed
deterministically from the chain (`genesis_time + slot * slot_duration +

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Describe eager rounds as absolute deadlines

When round 1 expires at duty_start + 1s and round 2 begins, calculate_timeout(2) sets its deadline to duty_start + 2s, leaving roughly one second rather than making round 2 last two seconds. An implementation following “round r lasts r seconds” would use cumulative deadlines and diverge from Charon’s schedule, undermining the alignment this section requires.

Comment thread README.md
Comment on lines +31 to +32
| `MsgSync.nickname` field (DKG sync) | `v1.9.5` |
| Deterministic (genesis-derived) eager double linear round deadlines | `v1.9.5` |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Anchor these features to v1.9.0

For implementers comparing against v1.9.0–v1.9.4, these rows incorrectly imply both features are absent: Charon commits d33572f2 and 31ff2996 are ancestors of the v1.9.0 tag, whose source already contains both MsgSync.nickname and the genesis-derived timer. The same incorrect v1.9.5 attribution is repeated in plans/spec-completion.md.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants