consensus/bor, miner: fix stale pending state for non-validator nodes#2183
consensus/bor, miner: fix stale pending state for non-validator nodes#2183
Conversation
Nodes whose signer is configured but not in the active validator set (e.g. after a validator rotation) returned "insufficient funds for transfer" on eth_estimateGas and other RPC calls against the "pending" block. The root cause was that Prepare() returned UnauthorizedSignerError when the signer was not in the validator set, which caused prepareWork() to fail on every block. Since commit() was never called, the pending snapshot was never refreshed, and its underlying pathdb trie layers were eventually garbage-collected — making all state reads return zero. Fix Prepare() to not fail for unauthorized signers. Instead, default the succession number to 0 and let the block building pipeline continue normally. Seal() already independently rejects blocks from unauthorized signers, so no invalid blocks can be produced. This ensures the pending snapshot is refreshed on every chain head, keeping RPC queries functional regardless of whether the node is actively producing blocks. Also remove a redundant second call to GetSignerSuccessionNumber in the Giugliano waitOnPrepare block, reusing the succession value already computed earlier in Prepare().
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.
Tip: disable this comment in your organization's Code Review settings.
|
Code reviewFound 2 issues while checking for bugs and CLAUDE.md compliance. |
Codecov Report❌ Patch coverage is
❌ Your patch check has failed because the patch coverage (45.45%) is below the target coverage (90.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## develop #2183 +/- ##
========================================
Coverage 51.93% 51.93%
========================================
Files 884 884
Lines 155446 155447 +1
========================================
+ Hits 80731 80736 +5
+ Misses 69509 69501 -8
- Partials 5206 5210 +4
... and 15 files with indirect coverage changes
🚀 New features to boost your workflow:
|



Description
Nodes whose signer is configured but not in the active validator set (e.g. after a validator rotation) returned "insufficient funds for transfer" on eth_estimateGas and other RPC calls against the "pending" block. The root cause was that Prepare() returned UnauthorizedSignerError when the signer was not in the validator set, which caused prepareWork() to fail on every block. Since commit() was never called, the pending snapshot was never refreshed, and its underlying pathdb trie layers were eventually garbage-collected — making all state reads return zero.
Fix Prepare() to not fail for unauthorized signers. Instead, default the succession number to 0 and let the block building pipeline continue normally. Seal() already independently rejects blocks from unauthorized signers, so no invalid blocks can be produced. This ensures the pending snapshot is refreshed on every chain head, keeping RPC queries functional regardless of whether the node is actively producing blocks.
Also remove a redundant second call to GetSignerSuccessionNumber in the Giugliano waitOnPrepare block, reusing the succession value already computed earlier in Prepare().
Changes
Breaking changes
Please complete this section if any breaking changes have been made, otherwise delete it
Nodes audience
In case this PR includes changes that must be applied only to a subset of nodes, please specify how you handled it (e.g. by adding a flag with a default value...)
Checklist
Cross repository changes
Testing
Manual tests
Please complete this section with the steps you performed if you ran manual tests for this functionality, otherwise delete it
Additional comments
Please post additional comments in this section if you have them, otherwise delete it