Skip to content

[WIP] Fix payload poll reporting and unregistered fee recipient - #23340

Closed
lystopad with Copilot wants to merge 1 commit into
feature/lystopad/production-loggingfrom
copilot/cl-beacon-report-failing-payload-poll
Closed

[WIP] Fix payload poll reporting and unregistered fee recipient#23340
lystopad with Copilot wants to merge 1 commit into
feature/lystopad/production-loggingfrom
copilot/cl-beacon-report-failing-payload-poll

Conversation

Copilot AI commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Thanks for the feedback on #23274. I've created this new PR, which merges into #23274, to address your comment. I will work on the changes and keep this PR's description up to date as I make progress.

Original PR: #23274
Triggering comment (#23274 (comment)):

I have cut this PR back to what it was meant to be, and I owe an explanation rather than just a diff.

The claim in the previous revision was false. It said a failed production is recorded once at the boundary. Only four of eleven failure paths in the body goroutine carried their cause into executionErr; the other seven — invalid bundle, invalid peerdas bundle, invalid commitment length, invalid proof length, invalid blob length, the Gloas requests root, and the sync aggregate — still logged and returned, leaving executionErr nil. produceBeaconBody then returned the cause-less failed to produce execution payload, and the new boundary logged that on top. Two records for one failure, and the second one worse than the Failed to produce beacon body line it replaced, which at least carried localErr.

@copilot named two of those paths, I fixed exactly those two, and then wrote "every exit is covered once" here and in the PR body without checking the rest of the function. That was my mistake and I am sorry for the review time it cost.

So the error-propagation work is out of this PR. It was asked for and it is worth doing, but it is a change to how block production reports failure, not an observability change, and doing it properly means all eleven paths plus their tests. It will come as its own PR where it can be reviewed as that. This one is back to +58 −4 of production code, from +337 −34.

What is left is the two things the title promises:

  • the polling window reports once, when it is over, with the slot, the failure count and the first cause; silent when it recovers and when the caller went away, but still reporting failures that preceded the caller leaving, per @yperbasis's predicate;
  • the fee recipient warning, once per proposer, claimed atomically with ContainsOrAdd and bounded by an LRU.

Everything from the review rounds that belongs to this scope is kept: the slot key, the first-not-last error, the atomic claim, the bounded cache, and the log capture helper writing through a lock and filtering to block-production records.

Worth noting what this also removes: the select race @yperbasis found last round, where a cancelled caller and a closing window were both ready, existed only because of the propagation machinery. With reporting decided by whether any non-cancellation failure was seen, which arm the select takes no longer matters.

make lintci clean, go test -race green, and each new test verified to fail against the behaviour it replaces.

@lystopad

Copy link
Copy Markdown
Member

It was created by a misread of a citation

@lystopad lystopad closed this Aug 17, 2026
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