erigontech / erigontech/erigon
Discrepancy analysis between consensus specs and Erigon (Caplin)
- Dominant language
- Go
- Stars
- 3.6k
- Forks
- 1.5k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 455
Description
## Discrepancy analysis: consensus-specs vs Caplin
Function-by-function audit of Caplin against the Python spec, pinned at `consensus-specs` **v1.7.0-alpha.10**. Each `def` compared to its Go (arithmetic, check ordering, fork gates, SSZ layout). Cross-checked with a clean spec-test run (**8085 pass / 0 fail**).
**Verdict:** Caplin faithfully tracks the spec through Gloas. **Electra and Fulu are clean.** All findings are Gloas-only; none confirmed consensus-breaking.
| Fork | Result |
|---|---|
| Gloas | 1 worth fixing + 2 fork-choice notes |
| Fulu | cosmetic only |
| Electra | 0 discrepancies |
## Gloas — findings
**1. In-place mutation of shared `BuilderPendingPayment` (worth fixing).**
`operations.go:1208-1255` does `payment.Weight += val` on a pointer that state copies share (`VectorSSZ.CopyTo` copies the pointer). The 3 sibling Gloas payment mutators all use copy-on-write; this path is the exception. Not proven reachable in sequential processing, but a retained shallow copy could be corrupted. Fix: `p := *payment; p.Weight += val; payments.Set(i, &p)`.
**2. `payload_timeliness`/`payload_data_availability` fallback — proposer-side liveness.**
`payload_vote.go:142,167` return `false` when the payload isn't verified; spec returns `not timely`/`not available`. Only feeds `ShouldBuildOnFull` (block production), not head selection.
**3. `IsPayloadVerified` stricter than spec — likely deliberate.**
`forkchoice.go:780` means "EL validated"; spec means "envelope present". Affects FULL-child exposure under optimistic sync. A test pins this (`TestIsPayloadVerifiedStrictSemantics`) — flagging to confirm intent.
_Cosmetic: `get_ptc` hardcodes `MIN_SEED_LOOKAHEAD=1` (`cache_accessors.go:557`); stale "alpha7" comment (`epbs_payload.go:261`)._
## Fulu — cosmetic only
PeerDAS (custody, column mapping, subnet, inclusion-proof + KZG verify) and core consensus are faithful; KZG math delegated to `go-eth-kzg`.
- `verify_data_column_sidecar` omits the blob-limit reject; done at each call site instead (`p2p_utils.go:29-57`). Equivalent today; worth folding back so a future caller can't skip it.
## Electra — 0 discrepancies
Execution requests (EIP-6110/7002/7251), EIP-7549 attestation bits, pending-queue prefix semantics, churn/hysteresis, `upgrade_to_electra`, and SSZ layout all faithful.
---
_Scope: state transition + fork choice. Out of scope: validator/builder out-of-protocol duties, BLS/KZG library internals._
Contributor guide
Assessment
This issue has not been assessed yet.