erigontech / erigontech/erigon

Discrepancy analysis between consensus specs and Erigon (Caplin)

Open
#21,866 1 comment 0 reactions 1 assignee Claimed by @domiwei View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.