Skip to content

fix(beacon-node): apply tsgo cast + add slot to merged-in #9479 test emit#9492

Merged
nflaig merged 1 commit into
ChainSafe:te/fix_block_input_sync_metrics_logsfrom
lodekeeper:fix/tsgo-emitter-cast-9479-test
Jun 9, 2026
Merged

fix(beacon-node): apply tsgo cast + add slot to merged-in #9479 test emit#9492
nflaig merged 1 commit into
ChainSafe:te/fix_block_input_sync_metrics_logsfrom
lodekeeper:fix/tsgo-emitter-cast-9479-test

Conversation

@lodekeeper

Copy link
Copy Markdown
Contributor

Summary

The base-branch update brought in #9479's new test ("defers envelope validation until the block is in fork choice when payload input is seeded from the block body") which uses the same let emitter!: ChainEventEmitter + destructuring-assignment + sibling closure capture pattern that #9491 already mitigated in the original failing test below. Same TS2769 fires at the new test's emit site:

test/unit/sync/unknownBlock.test.ts(1027,20): error TS2769: No overload matches this call.
  Argument of type 'ChainEvent.unknownEnvelopeBlockRoot' is not assignable to parameter of type 'unique symbol'.

Also, #9479's emit predates this PR's addition of slot: Slot to the ChainEvent.unknownEnvelopeBlockRoot event signature, so the emit data is missing the required slot field after the merge.

Fix

Same minimal cast workaround as #9491 plus the required slot: 0 field:

-      emitter.emit(ChainEvent.unknownEnvelopeBlockRoot, {
+      // tsgo overload-resolution miss when emit is reached through a closure that captures emitter
+      // first; cast re-anchors the StrictEventEmitter overload for ChainEvent keys (see #9491).
+      (emitter as ChainEventEmitter).emit(ChainEvent.unknownEnvelopeBlockRoot, {
         rootHex: blockRootHex,
+        slot: 0,
         peer,
         source: BlockInputSource.gossip,
       });

Single-site change. The 5 other emitter.emit(ChainEvent.unknownEnvelopeBlockRoot, ...) sites in the file remain unchanged because they aren't reached through a sibling closure capture; the cast at the sibling test's emit (introduced in #9491, currently at line 1126) also remains as-is and continues to typecheck cleanly with the expanded EventType union from #9439.

Test plan

  • CI: Type Checks (24) passes (no TS2769 on unknownBlock.test.ts).
  • CI: the new defers envelope validation until the block is in fork choice when payload input is seeded from the block body test still passes — emit semantics unchanged.

🤖 Generated with Claude Code

 test emit

The merge of unstable into the PR branch brought in ChainSafe#9479's new test
"defers envelope validation until the block is in fork choice when payload
input is seeded from the block body". That test reproduces the same
`let emitter!: ChainEventEmitter` + destructuring-assignment + sibling
closure capture pattern that ChainSafe#9491 already mitigated in the sibling test
below, so the same tsgo TS2769 fires at the new test's emit site:

  test/unit/sync/unknownBlock.test.ts(1027,20): error TS2769:
  No overload matches this call.
  Argument of type 'ChainEvent.unknownEnvelopeBlockRoot' is not assignable
  to parameter of type 'unique symbol'.

Also, ChainSafe#9479's emit predates this PR's addition of `slot: Slot` to the
`ChainEvent.unknownEnvelopeBlockRoot` event signature, so the emit data
is missing the required `slot` field after the merge.

Apply the same minimal fix:
- Cast emitter at the failing site: `(emitter as ChainEventEmitter).emit(...)`.
- Add `slot: 0` to the emit data.

🤖 Generated with AI assistance
@lodekeeper lodekeeper requested a review from a team as a code owner June 9, 2026 13:37

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request updates a unit test in unknownBlock.test.ts by casting emitter to ChainEventEmitter to resolve a TypeScript overload-resolution issue and adding a slot property to the emitted event payload. The reviewer suggested fixing a typo in the added comment (tsgo to tsc) and replacing the hardcoded slot: 0 with block.message.slot for better accuracy and robustness.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +1027 to 1034
// tsgo overload-resolution miss when emit is reached through a closure that captures emitter
// first; cast re-anchors the StrictEventEmitter overload for ChainEvent keys (see #9491).
(emitter as ChainEventEmitter).emit(ChainEvent.unknownEnvelopeBlockRoot, {
rootHex: blockRootHex,
slot: 0,
peer,
source: BlockInputSource.gossip,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

There is a typo in the comment (tsgo instead of tsc). Additionally, instead of hardcoding slot: 0, it is more accurate and robust to use block.message.slot to match the slot of the block and envelope created in the test fixture.

Suggested change
// tsgo overload-resolution miss when emit is reached through a closure that captures emitter
// first; cast re-anchors the StrictEventEmitter overload for ChainEvent keys (see #9491).
(emitter as ChainEventEmitter).emit(ChainEvent.unknownEnvelopeBlockRoot, {
rootHex: blockRootHex,
slot: 0,
peer,
source: BlockInputSource.gossip,
});
// tsc overload-resolution miss when emit is reached through a closure that captures emitter
// first; cast re-anchors the StrictEventEmitter overload for ChainEvent keys (see #9491).
(emitter as ChainEventEmitter).emit(ChainEvent.unknownEnvelopeBlockRoot, {
rootHex: blockRootHex,
slot: block.message.slot,
peer,
source: BlockInputSource.gossip,
});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Declining both suggestions, but flagging the reasoning:

  1. tsgo vs tsctsgo is correct, not a typo. This repo uses @typescript/native-preview via "check-types": "tsgo" in packages/beacon-node/package.json:94, with @typescript/native-preview: 7.0.0-dev.20260303.1 pinned in the root package.json. The overload-resolution behavior that motivates this cast is specifically tsgo's — tsc doesn't reject this site.

  2. slot: 0 vs block.message.slot — kept slot: 0 for consistency with every other emitter.emit(ChainEvent.unknownEnvelopeBlockRoot, ...) site in this file (unknownBlock.test.ts:762, :836, :926, :1131). The field is a logging/prune hint per the emitter.ts comment (// slot is the message slot, not necessarily the envelope's slot, but useful as a logging/prune hint), not a correctness-load-bearing value in these tests, and switching just this one site would diverge from the established pattern. Happy to update all sites to block.message.slot in a follow-up if you'd rather have semantic accuracy across the board.

@lodekeeper

Copy link
Copy Markdown
Contributor Author

Re Gemini's two suggestions on the inline thread: declined both with reasoning in discussion_r3381092996. tldr: tsgo is correct (this repo uses @typescript/native-preview via "check-types": "tsgo", the overload-resolution behavior is tsgo-specific), and slot: 0 matches the established convention across every other emitter.emit(ChainEvent.unknownEnvelopeBlockRoot, ...) site in this test file. Noted on the consumer-version sunset.

@nflaig nflaig merged commit fec0c36 into ChainSafe:te/fix_block_input_sync_metrics_logs Jun 9, 2026
16 checks passed
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