-
Notifications
You must be signed in to change notification settings - Fork 1.2k
fix: purge pending recovered sigs in BanNode #7563
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1788,6 +1788,17 @@ void PeerManagerImpl::FinalizeNode(const CNode& node) { | |
| } | ||
| } // cs_main | ||
|
|
||
| if (m_llmq_ctx && misbehavior >= DISCOURAGEMENT_THRESHOLD) { | ||
| // Drop the not-yet-verified pending recovered sigs of a peer that crossed the | ||
| // discouragement threshold. NetSigning::BanNode purges eagerly (and always scores exactly | ||
| // DISCOURAGEMENT_THRESHOLD), but a QSIGREC processed concurrently with a ban issued from a | ||
| // verification worker thread can re-queue entries behind the purge. This runs strictly | ||
| // after the peer's last ProcessMessages call and node ids are never reused, so it is | ||
| // final. Peers that disconnect without misbehaving keep their queue and drain as before: | ||
| // their pending sigs may be the only copy we ever receive. | ||
| m_llmq_ctx->sigman->RemoveNode(nodeid); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When an ordinary peer sends a valid AGENTS.md reference: AGENTS.md:L169-L170 Useful? React with 👍 / 👎. |
||
| } | ||
|
|
||
| if (node.fSuccessfullyConnected && misbehavior == 0 && !node.IsBlockOnlyConn() && !node.IsInboundConn()) { | ||
| // Only change visible addrman state for full outbound peers. We don't | ||
| // call Connected() for feeler connections since they don't have | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔴 Blocking: Prevent recovered signatures from being requeued after the eager purge
RemoveNode() only erases entries present while it holds cs_pending; it does not prevent a later VerifyAndProcessRecoveredSig() call for the same NodeId from inserting another entry. ProcessPendingRecoveredSigs() invokes BanNode() on the recovered-signature worker while the message handler can already be processing another QSIGREC. If removal wins the lock first, that in-flight message queues a residual signature afterward. Masternode connections can admit additional messages because their SendMessages() pass—and therefore MaybeDiscourageAndDisconnect()—is limited to the 100 ms cadence in CConnman::ThreadMessageHandler(). With the periodic sweep removed, these residual entries must be drained and BLS-verified after the peer is disconnected, defeating the stated cleanup guarantee. Fence further admission for the NodeId or perform another purge at a durable peer-disconnection/finalization point.
source: ['codex']
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. Requeue after
RemoveNode— real race, not treating as blockingAgreed that
RemoveNodeis a one-shot erase undercs_pendingand does not fence laterVerifyAndProcessRecoveredSiginserts for the sameNodeId. Concurrent msg-thread admission after a worker-path ban can re-queue residual entries.Why I’m not expanding the PR for it:
MAX_PENDING_RECSIGS_PER_NODE/TOTAL).SendMessages/MaybeDiscourageAndDisconnect→ disconnect → no moreProcessMessages.PeerIsBannedsweep was not a durable fence either (m_should_discourageis ~100ms and false again after finalize), so restoring a periodic sweep would not honestly close this.CSigningManagerwould work but duplicates peer lifecycle state inside LLMQ; a proper fence belongs on disconnect/FinalizeNode(or similar) if we want that later, not as a second ban bit next to the queue.So the PR guarantee is intentional: drop what is already queued at ban time, eagerly. Residual post-ban admission is accepted residual under BanNode-only + caps, not a regression of unbounded backlog.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved in
249d088— Prevent recovered signatures from being requeued after the eager purge no longer present.Auto-resolved by the review system based on the latest commit diff. If you believe this was closed in error, reopen the thread.