-
Notifications
You must be signed in to change notification settings - Fork 1.2k
refactor: optimize AsyncSign by using std::move for quorum parameter #6906
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?
refactor: optimize AsyncSign by using std::move for quorum parameter #6906
Conversation
|
WalkthroughThe PR changes quorum ownership and access semantics across llmq modules: many APIs that previously accepted CQuorumCPtr (pointer) now take CQuorum or CQuorumCPtr by value/non-const, and several call sites move quorum objects into async/thread lambdas. Implementations and callers were updated from pointer syntax ( Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (1)src/**/*.{cpp,h,cc,cxx,hpp}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🔇 Additional comments (5)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…o use CQuorum reference
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.
Actionable comments posted: 0
🧹 Nitpick comments (4)
src/llmq/signing.cpp (1)
676-689
: Quorum selection + local capture looks good; minor readability nit.The on-the-fly lambda returning CQuorumCPtr is fine and keeps scopes tight. Optional: make the type explicit (CQuorumCPtr quorum = …) for readability in this hot path.
src/llmq/quorums.h (1)
283-285
: API changes align with move/reference strategy; add nodiscard to prevent ignored results.
- RequestQuorumData(const CQuorum&, uint16_t, …) and Start*Thread signatures are coherent with the move into worker lambdas.
- Recommend marking RequestQuorumData as [[nodiscard]]; its boolean is actionable and ignoring it can hide request throttling/failures.
- bool RequestQuorumData(CNode* pfrom, CConnman& connman, const CQuorum& quorum, uint16_t nDataMask, + [[nodiscard]] bool RequestQuorumData(CNode* pfrom, CConnman& connman, const CQuorum& quorum, uint16_t nDataMask, const uint256& proTxHash = uint256()) const;Also consider [[nodiscard]] for CreateSigShare in signing_shares.h (it already returns std::optional).
Also applies to: 312-317, 314-317
src/llmq/quorums.cpp (1)
676-699
: Guard against modulo by zero on validMembers.size().nIndex % quorum.qc->validMembers.size() will UB if validMembers is empty (shouldn’t happen, but a defensive guard avoids rare crashes).
- return nIndex % quorum.qc->validMembers.size(); + const size_t nMembers = quorum.qc->validMembers.size(); + assert(nMembers != 0); + return nMembers ? (nIndex % nMembers) : 0;src/llmq/signing_shares.h (1)
436-440
: Interfaces now mix moved shared_ptr and const references; looks coherent.
- AsyncSign(CQuorumCPtr) by value enables caller std::move and avoids extra atomic ops.
- ForceReAnnouncement/SelectMemberForRecovery taking const CQuorum& is appropriate.
Optional: mark CreateSigShare(...) [[nodiscard]] to prevent silent drops of failures.- std::optional<CSigShare> CreateSigShare(const CQuorum& quorum, const uint256& id, const uint256& msgHash) const; + [[nodiscard]] std::optional<CSigShare> CreateSigShare(const CQuorum& quorum, const uint256& id, const uint256& msgHash) const;Also applies to: 439-440, 443-444
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/llmq/quorums.cpp
(10 hunks)src/llmq/quorums.h
(2 hunks)src/llmq/signing.cpp
(2 hunks)src/llmq/signing_shares.cpp
(11 hunks)src/llmq/signing_shares.h
(2 hunks)src/rpc/quorums.cpp
(8 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/**/*.{cpp,h,cc,cxx,hpp}
📄 CodeRabbit inference engine (CLAUDE.md)
src/**/*.{cpp,h,cc,cxx,hpp}
: Dash Core C++ codebase must be written in C++20 and require at least Clang 16 or GCC 11.1
Dash uses unordered_lru_cache for efficient caching with LRU eviction
Files:
src/llmq/signing_shares.h
src/llmq/signing.cpp
src/rpc/quorums.cpp
src/llmq/quorums.cpp
src/llmq/quorums.h
src/llmq/signing_shares.cpp
🧬 Code graph analysis (4)
src/llmq/signing_shares.h (1)
src/llmq/signing_shares.cpp (12)
AsyncSign
(1510-1514)AsyncSign
(1510-1510)CreateSigShare
(1540-1610)CreateSigShare
(1540-1540)ForceReAnnouncement
(1613-1637)ForceReAnnouncement
(1613-1613)HandleNewRecoveredSig
(1639-1644)HandleNewRecoveredSig
(1639-1639)SelectMemberForRecovery
(846-859)SelectMemberForRecovery
(846-846)TryRecoverSig
(764-844)TryRecoverSig
(764-765)
src/rpc/quorums.cpp (1)
src/llmq/quorums.h (1)
nDataMask
(102-102)
src/llmq/quorums.h (1)
src/llmq/quorums.cpp (8)
RequestQuorumData
(478-519)RequestQuorumData
(478-479)GetQuorumRecoveryStartOffset
(676-699)GetQuorumRecoveryStartOffset
(676-676)StartCachePopulatorThread
(886-914)StartCachePopulatorThread
(886-886)StartQuorumDataRecoveryThread
(916-1037)StartQuorumDataRecoveryThread
(916-917)
src/llmq/signing_shares.cpp (2)
src/llmq/signhash.cpp (1)
SignHash
(14-22)src/llmq/signhash.h (1)
SignHash
(24-46)
🪛 GitHub Actions: Clang Diff Format Check
src/llmq/signing_shares.h
[error] 1-1: Clang-format differences detected in src/llmq/signing_shares.h. Run the formatter to fix formatting mismatches.
src/rpc/quorums.cpp
[error] 1-1: Clang-format differences detected in src/rpc/quorums.cpp. Run the formatter to fix formatting mismatches.
src/llmq/quorums.cpp
[error] 1-1: Clang-format differences detected in src/llmq/quorums.cpp. Run the formatter to fix formatting mismatches.
src/llmq/signing_shares.cpp
[error] 1-1: Clang-format differences detected in src/llmq/signing_shares.cpp. Run the formatter to fix formatting mismatches.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: mac-build / Build source
- GitHub Check: arm-linux-build / Build source
- GitHub Check: linux64_sqlite-build / Build source
- GitHub Check: linux64_ubsan-build / Build source
- GitHub Check: linux64-build / Build source
- GitHub Check: linux64_fuzz-build / Build source
- GitHub Check: linux64_tsan-build / Build source
- GitHub Check: win64-build / Build source
- GitHub Check: linux64_nowallet-build / Build source
- GitHub Check: Lint / Run linters
🔇 Additional comments (10)
src/llmq/signing.cpp (1)
736-739
: Correct: avoid extra atomic ops by moving the shared_ptr into AsyncSign.Passing a dereferenced quorum to ForceReAnnouncement and then moving the shared_ptr into AsyncSign is the right order and avoids post-move use. Nice micro‑opt.
Please double‑check no future edits access “quorum” after Line 739; a quick grep will prevent accidental use‑after‑move regressions.
src/rpc/quorums.cpp (2)
182-233
: Consistent shift to reference semantics for CQuorum across RPC paths.
- BuildQuorumInfo now takes const CQuorum&; member access updates are correct.
- Callers dereference shared_ptrs appropriately: quorum_info, quorum_memberof, quorum_sign_helper, quorum_selectquorum, quorum_getdata.
All good and lifetime-safe since sources are CQuorumCPtr held locally.Given public RPC exposure, please smoke‑test:
- quorum info: with includeSkShare=false/true (if this node is a member).
- quorum sign … submit=false path (CreateSigShare).
- quorum getdata with both QUORUM_VERIFICATION_VECTOR and ENCRYPTED_CONTRIBUTIONS masks.
Also applies to: 268-269, 426-429, 476-477, 745-747, 833-833
1-1
: Verify formatting changes against CI results.The sandbox environment does not have clang-format available to verify the formatting diffs. While the file exists and a
.clang-format
configuration is present, I cannot execute the formatter to confirm the claimed violations. Please runclang-format-16 -i src/rpc/quorums.cpp
locally and review thegit diff
output, or check the CI results to confirm the exact formatting issues before applying fixes.src/llmq/quorums.cpp (3)
478-519
: RequestQuorumData refactor: parameter update is correct.Switching to const CQuorum& and building the request with the new nDataMask parameter looks good. Logging and request de‑dupe remain intact.
886-914
: Good use of move-capture for pQuorum into worker lambdas.Moving CQuorumCPtr into StartCachePopulatorThread/StartQuorumDataRecoveryThread tasks eliminates extra atomic ops and lifetime issues. Access is pointer‑stable in the closures.
Please sanity‑run a node with -watchquorums and ensure recovery logs (“Start/Requested/Processed/Done”) appear as expected on rotation.
Also applies to: 916-937, 1009-1011
1-1
: Run clang-format locally to fix formatting issues.Formatting issues were detected in src/llmq/quorums.cpp. Evidence of trailing whitespace was found during inspection. Since clang-format is unavailable in the verification environment, please run the formatter locally and verify the changes:
clang-format -i src/llmq/quorums.cpp git diff -- src/llmq/quorums.cppCommit the formatting changes to resolve the CI check.
src/llmq/signing_shares.cpp (3)
1510-1514
: AsyncSign path: correct move into queue; CreateSigShare callsite aligns with refactor.
- Moving CQuorumCPtr into pendingSigns avoids extra refcount traffic.
- Dereferencing for CreateSigShare is consistent with the new signature.
Also applies to: 1521-1537
1540-1610
: Refactor to const CQuorum& in signing logic is sound.Member access changes (params, qc, members) are correct; TryRecoverSig and ForceReAnnouncement build SignHash with dereferenced quorum consistently. Single‑node quorum handling remains intact.
Please verify recovery still triggers at threshold by:
- forcing a session to reach params.threshold and observing a recovered signature in logs.
Also applies to: 1613-1637, 760-767, 776-828, 801-810, 827-835
1-1
: Manual verification required for clang-format diffs.The clang-format tool is not available in the sandbox environment to verify the formatting issues. While manual inspection of src/llmq/signing_shares.cpp shows the copyright header and includes are clean (no trailing whitespace detected), I cannot confirm what clang-format diffs CI originally detected. Please run
clang-format -i src/llmq/signing_shares.cpp
locally and verify the file passes CI formatting checks.src/llmq/signing_shares.h (1)
1-1
: Unable to verify clang-format violations in the sandbox (clang-format tool not available). The file inspection shows proper Unix line endings and no visible trailing whitespace on the copyright header. However, without executing clang-format locally, the actual formatting violations cannot be confirmed.Please run
clang-format -i src/llmq/signing_shares.h
andgit diff -- src/llmq/signing_shares.h
locally to verify whether formatting changes are actually needed.
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.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
-
src/llmq/quorums.cpp
(11 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/**/*.{cpp,h,cc,cxx,hpp}
📄 CodeRabbit inference engine (CLAUDE.md)
src/**/*.{cpp,h,cc,cxx,hpp}
: Dash Core C++ codebase must be written in C++20 and require at least Clang 16 or GCC 11.1
Dash uses unordered_lru_cache for efficient caching with LRU eviction
Files:
src/llmq/quorums.cpp
🪛 GitHub Actions: Clang Diff Format Check
src/llmq/quorums.cpp
[error] 1-1: Clang format differences found. Command failed: git diff -U0 origin/develop --
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: mac-build / Build source
- GitHub Check: linux64_tsan-build / Build source
- GitHub Check: linux64_ubsan-build / Build source
- GitHub Check: linux64_fuzz-build / Build source
- GitHub Check: linux64-build / Build source
- GitHub Check: linux64_sqlite-build / Build source
- GitHub Check: arm-linux-build / Build source
- GitHub Check: linux64_nowallet-build / Build source
- GitHub Check: win64-build / Build source
- GitHub Check: Lint / Run linters
🔇 Additional comments (5)
src/llmq/quorums.cpp (5)
478-494
: Excellent refactor to eliminate unnecessary reference counting.Changing the parameter from
CQuorumCPtr
(shared pointer) toconst CQuorum&
(reference) is a good optimization since this function only reads from the quorum and doesn't need ownership semantics. This avoids atomic increment/decrement operations on the control block.
676-698
: Good refactor to use const reference.Similar to
RequestQuorumData
, this change eliminates unnecessary shared_ptr operations for a read-only function.
886-913
: LGTM! This achieves the move optimization for async tasks.The changes here correctly implement the optimization described in the PR:
- Taking
CQuorumCPtr
by value (line 886) enables the caller to move in- Capturing by move in the lambda (line 899) transfers ownership to the async task
- This avoids the atomic increment/decrement pair that would occur with const reference + copy
916-1037
: LGTM! Consistent move optimization for async recovery.The changes mirror the pattern in
StartCachePopulatorThread
:
- Pass-by-value parameter enables move semantics (line 916-917)
- Lambda move capture transfers ownership (line 927)
- Dereferences on lines 933 and 1009 are consistent with updated function signatures
The
&connman
capture by reference is safe since the worker pool is stopped in the destructor.
1-1
: Address clang-format issues.The pipeline is reporting clang-format differences. Please run the clang-format tool to fix formatting issues before merging.
f075a12
to
0716c7a
Compare
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.
utACK 0716c7a
Issue being fixed or feature implemented
Using std::move here should save on the magnitude of ~10-150 ns depending on how contended the underlying shared_ptr is. This move becomes basically free, with no atomics etc being touched. Currently, we pass a const ref in, then copy it, resulting in 2 unneeded atomic operations (++ for the copy, -- for the destroy of the one we could've just moved in.
What was done?
use std::move
Also; prefer just using the reference to CQuorum where possible, as opposed to the shared_ptr
How Has This Been Tested?
compiles
Breaking Changes
Please describe any breaking changes your code introduces
Checklist:
Go over all the following points, and put an
x
in all the boxes that apply.