ChainSafe / ChainSafe/lodestar
`addPayloadEnvelope` should be idempotent for API/gossip race
- Dominant language
- TypeScript
- Stars
- 1.4k
- Forks
- 483
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 156
Description
## Context
In `PayloadEnvelopeInput.addPayloadEnvelope()`, a second call throws `"Payload envelope already set"`. This is reachable from external input paths when API and gossip race:
1. API handler receives envelope, sleeps for slot boundary alignment
2. Gossip envelope arrives during the sleep, gets added first
3. API handler wakes up and calls `addPayloadEnvelope()` → throws → 500 error to the VC
This is relevant in multi-node or DVT setups where the proposer's envelope arrives via gossip before the API call completes (similar to https://github.com/ChainSafe/lodestar/pull/8849).
## Proposed fix
Make `addPayloadEnvelope()` idempotent — silently return (or log) if the envelope is already set, matching the dedup semantics of `shouldImport()`. At minimum, the API handler should catch this gracefully instead of returning a 500.
## References
- PR #8962 — `payloadEnvelopeInput.ts` ([review comment](https://github.com/ChainSafe/lodestar/pull/8962#discussion_r2965822312))
- Issue #8915 — parallel block + payload submission
- PR #8849 — similar race condition handling
/cc @nflaig @twoeths
Contributor guide
Research direction
Start in payloadEnvelopeInput.ts at PayloadEnvelopeInput.addPayloadEnvelope(), then read the API and gossip submission paths described in the issue and the related PR references. Verify that a second envelope from the race is handled without an exception or API 500, while existing deduplication behavior remains intact.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend, distributed-systems
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 62/100