You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix: missing shareman->RegisterRecoveryInterface() in ActiveContext::Start #7243
Without this, completed sig share sessions are only cleaned up via the 5-second Cleanup() interval instead of promptly via HandleNewRecoveredSig. The corresponding UnregisterRecoveryInterface() call in Stop() is also missing.
Impact
Delayed cleanup of completed sig share sessions (up to 5s instead of immediate)
Under CI load with frozen mocktime, this manifests as flaky test failures in feature_llmq_signing.py and interface_zmq_dash.py where InstantSend locks don't arrive within expected timeouts
Root Cause
The registration was likely dropped during the sig share refactoring that split share management into a separate shareman object. The cl_signer and is_signer registrations survived but shareman was missed.
Fix
// In ActiveContext::Start():
cl_signer->RegisterRecoveryInterface();
is_signer->RegisterRecoveryInterface();
+shareman->RegisterRecoveryInterface();
// In ActiveContext::Stop():
+shareman->UnregisterRecoveryInterface();
is_signer->UnregisterRecoveryInterface();
cl_signer->UnregisterRecoveryInterface();
Discovery
Found during CI triage of dash#7242 (wallet deprecation backport). The fix was originally committed as a80c46c438 on the backport branch but has been stripped out since it's unrelated to that PR's scope.
See also: dash#7233 (flaky LLMQ signing test fixes — related symptoms, different root cause).
Failing test:feature_llmq_signing.py --spork21 — timed out in wait_for_sigs after 60s (failed all 3 retry attempts)
feature_llmq_signing.py (without --spork21) also failed 2/3 attempts before passing
The PR only touches RPC/wallet code (src/rpc/*.cpp, src/wallet/rpc/*.cpp) and adds deprecatedrpc=create_bdb to test config — zero relation to LLMQ signing. Confirms this is the pre-existing flakiness described in this issue.
Good question. No, AddExtraHandler is not sufficient for this case — it only auto-registers CValidationInterface:
voidPeerManagerImpl::AddExtraHandler(std::unique_ptr<NetHandler>&& handler)
{
if (auto i = dynamic_cast<CValidationInterface*>(handler.get()); i != nullptr) {
RegisterValidationInterface(i);
}
m_handlers.emplace_back(std::move(handler));
}
RegisterRecoveryInterface() is a different registration path — it calls sigman.RegisterRecoveredSigsListener(this) to register as a CRecoveredSigsListener, not a CValidationInterface. AddExtraHandler has no knowledge of CRecoveredSigsListener or CSigningManager.
Additionally, shareman is owned by ActiveContext, not by PeerManager — it is not added via AddExtraHandler at all. (The NetSigning handler that is added via AddExtraHandler holds a raw pointer to shareman but only implements CValidationInterface itself.)
So the explicit RegisterRecoveryInterface() / UnregisterRecoveryInterface() calls in ActiveContext::Start() / Stop() are the right place for this — matching how cl_signer and is_signer are already registered there.
That said, extending AddExtraHandler with a similar dynamic_cast<CRecoveredSigsListener*> pattern could be a nice follow-up to make the registration more systematic, but it would need a reference to CSigningManager which PeerManager does not currently hold, and it would not cover ActiveContext-owned objects like shareman anyway.
Activity
thepastaclaw commentedon Mar 22, 2026
Additional CI failure from this root cause:
feature_llmq_signing.py --spork21— timed out inwait_for_sigsafter 60s (failed all 3 retry attempts)feature_llmq_signing.py(without --spork21) also failed 2/3 attempts before passingThe PR only touches RPC/wallet code (
src/rpc/*.cpp,src/wallet/rpc/*.cpp) and addsdeprecatedrpc=create_bdbto test config — zero relation to LLMQ signing. Confirms this is the pre-existing flakiness described in this issue.knst commentedon Mar 23, 2026
@thepastaclaw check this function:
is it sufficient?
thepastaclaw commentedon Mar 23, 2026
Good question. No,
AddExtraHandleris not sufficient for this case — it only auto-registersCValidationInterface:RegisterRecoveryInterface()is a different registration path — it callssigman.RegisterRecoveredSigsListener(this)to register as aCRecoveredSigsListener, not aCValidationInterface.AddExtraHandlerhas no knowledge ofCRecoveredSigsListenerorCSigningManager.Additionally,
sharemanis owned byActiveContext, not byPeerManager— it is not added viaAddExtraHandlerat all. (TheNetSigninghandler that is added viaAddExtraHandlerholds a raw pointer to shareman but only implementsCValidationInterfaceitself.)So the explicit
RegisterRecoveryInterface()/UnregisterRecoveryInterface()calls inActiveContext::Start()/Stop()are the right place for this — matching howcl_signerandis_signerare already registered there.That said, extending
AddExtraHandlerwith a similardynamic_cast<CRecoveredSigsListener*>pattern could be a nice follow-up to make the registration more systematic, but it would need a reference toCSigningManagerwhichPeerManagerdoes not currently hold, and it would not coverActiveContext-owned objects likesharemananyway.Merge #7244: fix: register shareman recovery interface in ActiveContext