ChainSafe / ChainSafe/lodestar
Find better way to prune PayloadEnvelopeInput
- Dominant language
- TypeScript
- Stars
- 1.4k
- Forks
- 483
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 150
Description

The current implementation of `pruneBelowParent` is inefficient and contains a logging bug:
1. **Efficiency**: It performs a full chain walk back to the finalized checkpoint (`getAllAncestorBlocks`) every slot. Since `SeenPayloadEnvelopeInput` is a small cache (typically ~2 entries), it is much more efficient to iterate over the cache entries and check if they are ancestors of the current head using `isDescendant`. This avoids creating large arrays and performing long walks every slot.
2. **Logging Bug**: The debug log at line 146 is inside the loop but outside the `if (input)` check. This will cause the node to emit a debug log for *every* block in the ancestor chain (potentially hundreds) every single slot, even if no entry was deleted. This can lead to log flooding and performance degradation.
3. **Consistency**: The suggested implementation follows the same logging pattern as `pruneFinalized`, providing a summary of deleted entries.
```typescript
pruneBelowParent(parentBlock: ProtoBlock): void {
let deletedCount = 0;
for (const input of this.payloadInputs.values()) {
if (input.slot < parentBlock.slot) {
// Check if the cached FULL variant is an ancestor of the current parent block
if (this.forkChoice.isDescendant(input.blockRootHex, PayloadStatus.FULL, parentBlock.blockRoot, parentBlock.payloadStatus)) {
this.evictPayloadInput(input);
deletedCount++;
}
}
}
if (deletedCount > 0) {
this.logger?.debug("SeenPayloadEnvelopeInput.pruneBelowParent deleted entries", {
parentSlot: parentBlock.slot,
parentRoot: parentBlock.blockRoot,
deletedCount,
});
}
}
```
_Originally posted by @gemini-code-assist[bot] in https://github.com/ChainSafe/lodestar/pull/9317#discussion_r3174428369_
Contributor guide
Research direction
Start at SeenPayloadEnvelopeInput.pruneBelowParent and inspect its current ancestor-walk and logging behavior, along with pruneFinalized for the referenced logging pattern. The change is done when pruning iterates over cached entries, avoids unnecessary chain walks, and emits a summary debug log only when entries are deleted.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- blockchain
- Issue type
- Refactor
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100