Skip to content
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

refactor: polish CoinJoin interface, use WalletLoader in Dash wallet initialization code, introduce new RPC coinjoin status #6594

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from

Conversation

kwvg
Copy link
Collaborator

@kwvg kwvg commented Feb 23, 2025

Motivation

Since bitcoin#22219 (introduced in dash#6568), the workarounds implemented for allowing the backport of bitcoin#19101 (a part of dash#6529) no longer work. A major reason for this is the initialization order assumed in dash#6529 is no longer holds true, requiring a rework of CoinJoin interfaces. This pull request aims to do that.

Additional Information

  • Dependency for backport: merge bitcoin#21207, #22008, #22686, #22742, #19101, #22183, #22009, #22938, #23288, #24592 (wallet backports: part 2) #6529

  • To allow for dropping walletman() from CoinJoin::Loader, both CoinJoin::Loader and CoinJoin::Client (accessible through CoinJoin::Loader::GetClient()) need to account for all potential usage.

    To that end, CoinJoin::Client::get{JsonInfo, SessionStatuses}() have been implemented.

    • Though some invocations of CCoinJoinClientSession functions cannot (or rather, should not) be available through the interface (like DoAutomaticDenominating()).

    • To take care of one such invocation (in coinjoin start, source), it has been removed altogether. coinjoin start will now behave like the "Start CoinJoin" button in Dash Qt and won't try to get ahead of the scheduler and start denomination.

      • The loss of status information in fail cases due to this, has been made up for with a new RPC, coinjoin status, that will report status information during any active mix session (as opposed to earlier behavior where such information was only made available when starting a mix session through coinjoin start and encountering a fail state).
  • CoinJoin::Loader and WalletLoader rely on each other as

    • CoinJoin::Loader::{Add,Remove}Wallet() needs to be able to run WalletInitInterface::InitCoinJoinSettings(), which in turn needs to be able enumerate through all available wallets (source), currently doing so through the global wallet context but eventually through WalletLoader when said globals are no longer available (post-bitcoin#19101)

    • WalletLoader needs CoinJoin::Loader to load (source) and restore (source) wallets as CWallet needs access to CoinJoin::Loader in order to call CoinJoin::Loader::{Add,Remove}Wallet() (source, source)

    This interdependent relationship has currently been floating along by passing a const ref of the smart pointer (source), which makes for cumbersome but workable code but in combination with bitcoin#22219, it breaks bitcoin#19101 as it forces us to definitively initialize both WalletLoader and CoinJoin::Loader before we get to initialize CoinJoin logic.

    To work around this, instead of requiring a fully initialized CoinJoinWalletManager to create a CoinJoin::Loader, we instead take NodeContext and defer resolving CoinJoinWalletManager to when interface calls are made.

  • By moving the initialization of the CoinJoin loader from AppInitMain() to WalletInit::Construct(), the linker was unhappy with trying to emit bench_dash (see error below). This was remedied by linking libbitcoin_wallet with libtest_util.

    Linker error:
      AR       libbitcoin_server.a
      CXXLD    dashd
      CXXLD    test/test_dash
      CXXLD    bench/bench_dash
      CXXLD    qt/dash-qt
      CXXLD    qt/test/test_dash-qt
    /usr/bin/ld: libtest_util.a(libtest_util_a-setup_common.o): in function `DashPostChainstateSetup(NodeContext&)':
    /src/dash/src/test/util/setup_common.cpp:127:(.text+0x1a8e): undefined reference to `interfaces::MakeCoinJoinLoader(NodeContext&)'
    collect2: error: ld returned 1 exit status
    make[2]: *** [Makefile:7354: bench/bench_dash] Error 1
    make[2]: *** Waiting for unfinished jobs....
    make[2]: Leaving directory '/src/dash/src'
    make[1]: *** [Makefile:20648: all-recursive] Error 1
    make[1]: Leaving directory '/src/dash/src'
    make: *** [Makefile:797: all-recursive] Error 1
    
  • bitcoin#22219 removes a WalletInit::Construct() call from setup_common.cpp (source), which is necessary since WalletInit::Construct() now relies on node.init (source).

    This isn't so much a problem for tests that use WalletTestingSetup or InitWalletDirTestingSetup but creates problems for tests based on TestChain100Setup (source, source), which is a specialization of TestingSetup that in turn, used to initialize coinjoin_loader (source) but since initialization has been moved to WalletInit::Construct() in line with Init::makeWalletLoader(), it is not done automatically anymore.

    To work around this, WalletInit::Construct()-like code has been introduced to initialize both coinjoin_loader and wallet_loader (source).

Breaking Changes

  • coinjoin start will no longer report errors from mix sessions. To see the status of mix sessions, a new RPC, coinjoin status, is available in its place.

Checklist

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation
  • I have assigned this pull request to a milestone (for repository code-owners and collaborators only)

Copy link

coderabbitai bot commented Feb 23, 2025

Walkthrough

The changes update various components related to CoinJoin and wallet functionality. A new RPC command, coinjoin status, is introduced while the behavior of coinjoin start is modified to defer error reporting to the status command. Client methods in the CoinJoin module have been refactored to return a vector of strings rather than a concatenated bilingual string, with extra functionalities added for JSON information retrieval and session status querying. The initialization of CoinJoin and wallet loaders has been restructured to use a node context instead of a direct wallet manager dependency, reflected in updated method signatures across multiple modules. Additionally, build configuration has been adjusted conditionally to include wallet libraries, and test setup routines have been revised by removing redundant post-chainstate setup functions and updating dependency injections for wallet and CoinJoin loaders.

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a 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 (10)
src/coinjoin/interfaces.cpp (3)

1-1: Please fix the Clang format issues.

The pipeline indicates Clang format differences. Kindly run clang-format or the appropriate code formatting step to resolve style discrepancies before merging.

🧰 Tools
🪛 GitHub Actions: Clang Diff Format Check

[error] 1-1: Clang format differences found. Please run 'clang-format' to fix formatting issues.


8-15: Include order and spacing look fine, but formatting might need re-check.

These new headers seem necessary for the added functionality. However, please ensure that final formatting matches Clang’s style requirements (see pipeline failures).


91-96: Constructor logic is valid.

Setting CCoinJoinClientOptions::SetEnabled(false) ensures mixing is off until wallets are added. Consider adding a short comment clarifying the rationale behind this initialization step.

src/wallet/init.cpp (2)

1-1: Please fix the Clang format issues.

As noted in the pipeline logs, formatting discrepancies need resolution before merging.


207-229: CoinJoin settings initialization logic is sound.

Enabling CoinJoin based on wallet presence, then selectively starting or stopping mixing depending on locking state, is coherent. Consider adding more descriptive logging if some wallets are locked while others start mixing.

src/rpc/coinjoin.cpp (1)

1-1: Resolve Clang format differences.

Kindly run the formatter tool before merging these changes.

🧰 Tools
🪛 GitHub Actions: Clang Diff Format Check

[error] 1-1: Clang format differences found. Please run 'clang-format' to fix formatting issues.

src/test/util/setup_common.cpp (1)

320-329: Caution with mixing raw pointers and smart pointers.

Storing wallet_loader.get() separately while also moving the unique_ptr into m_node.chain_clients can be safe, but the destructor must carefully manage the destruction order. It's currently handled, but consider more robust ownership patterns if usage expands.

src/interfaces/init.cpp (1)

15-16: Remove extra semicolon and clarify method stubs.

Returning empty pointers is valid as a placeholder, but consider providing actual implementations or confirming it's part of a future plan. Also remove the trailing semicolon to follow consistent code style.

-std::unique_ptr<CoinJoin::Loader> Init::makeCoinJoinLoader() { return {}; };
+std::unique_ptr<CoinJoin::Loader> Init::makeCoinJoinLoader() { return {}; }
src/interfaces/init.h (1)

35-36: Improved initialization design.

The separation of makeCoinJoinLoader and updated makeWalletLoader signature reflects a better separation of concerns:

  1. CoinJoin loader creation is now independent
  2. Wallet loader receives a reference instead of managing ownership of the CoinJoin loader

This design change improves modularity and reduces coupling between wallet and CoinJoin components.

src/coinjoin/client.h (1)

330-330: Improved status reporting design.

The change from bilingual_str to std::vector<std::string> is a good improvement:

  1. Better separation of concerns (separates data from presentation)
  2. More flexible for handling multiple status messages
  3. Aligns with the new coinjoin status RPC command requirements

This change makes the status reporting more modular and easier to extend.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5c1a627 and 038619d.

📒 Files selected for processing (29)
  • doc/release-notes-6594.md (1 hunks)
  • src/Makefile.test_util.include (1 hunks)
  • src/coinjoin/client.cpp (3 hunks)
  • src/coinjoin/client.h (1 hunks)
  • src/coinjoin/interfaces.cpp (3 hunks)
  • src/dummywallet.cpp (3 hunks)
  • src/init.cpp (1 hunks)
  • src/init/bitcoin-node.cpp (2 hunks)
  • src/init/bitcoind.cpp (2 hunks)
  • src/interfaces/coinjoin.h (3 hunks)
  • src/interfaces/init.cpp (2 hunks)
  • src/interfaces/init.h (2 hunks)
  • src/interfaces/wallet.h (2 hunks)
  • src/node/blockstorage.cpp (0 hunks)
  • src/qt/test/addressbooktests.cpp (0 hunks)
  • src/qt/test/wallettests.cpp (0 hunks)
  • src/rpc/coinjoin.cpp (8 hunks)
  • src/test/util/setup_common.cpp (3 hunks)
  • src/test/util/setup_common.h (0 hunks)
  • src/test/validation_chainstatemanager_tests.cpp (0 hunks)
  • src/wallet/context.cpp (1 hunks)
  • src/wallet/context.h (1 hunks)
  • src/wallet/init.cpp (3 hunks)
  • src/wallet/interfaces.cpp (5 hunks)
  • src/wallet/rpcwallet.cpp (3 hunks)
  • src/wallet/test/init_test_fixture.cpp (1 hunks)
  • src/wallet/test/wallet_test_fixture.cpp (1 hunks)
  • src/wallet/test/wallet_test_fixture.h (2 hunks)
  • src/walletinitinterface.h (2 hunks)
💤 Files with no reviewable changes (5)
  • src/node/blockstorage.cpp
  • src/qt/test/wallettests.cpp
  • src/qt/test/addressbooktests.cpp
  • src/test/util/setup_common.h
  • src/test/validation_chainstatemanager_tests.cpp
✅ Files skipped from review due to trivial changes (2)
  • doc/release-notes-6594.md
  • src/wallet/rpcwallet.cpp
🧰 Additional context used
🪛 GitHub Actions: Clang Diff Format Check
src/rpc/coinjoin.cpp

[error] 1-1: Clang format differences found. Please run 'clang-format' to fix formatting issues.

src/coinjoin/interfaces.cpp

[error] 1-1: Clang format differences found. Please run 'clang-format' to fix formatting issues.

⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: mac-build / Build source
  • GitHub Check: linux64_multiprocess-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: linux64_fuzz-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: arm-linux-build / Build source
🔇 Additional comments (54)
src/coinjoin/interfaces.cpp (10)

47-50: New method looks good.

The getJsonInfo() method simply delegates to m_clientman.GetJsonInfo(obj). No immediate issues found.


55-58: Session statuses retrieval is straightforward.

Returning a std::vector<std::string> from the underlying manager is clear and efficient.


98-102: Wallet addition triggers CoinJoin settings initialization.

Invoking g_wallet_init_interface.InitCoinJoinSettings(*this, wallet_loader()) for each wallet is consistent with the new design. No immediate issues found.


105-106: RemoveWallet is consistent with AddWallet.

Re-invoking InitCoinJoinSettings after removal is logical here. No further concerns.


110-110: FlushWallet call is straightforward.

Simple pass-through to walletman().Flush(name). No issues found.


114-114: Client creation via manager is valid.

Returns a CoinJoinClientImpl if the manager is found, otherwise nullptr. This pattern is safe.


118-119: Storing a NodeContext reference is acceptable.

Exposes node context for loader interactions. This is consistent with the new design.


125-125: Factory function aligns with interface changes.

MakeCoinJoinLoader(NodeContext& node) is good for constructing the new loader with node context references.


79-83:

❓ Verification inconclusive

Double Assert call may hide null-pointer risk.

return *Assert(Assert(m_node.cj_ctx)->walletman); could cause a crash if m_node.cj_ctx or walletman is null.

If any instantiation appears before the CoinJoin context is initialized, this might lead to null dereferences.


🏁 Script executed:

#!/bin/bash
# Check all instantiations of CoinJoinLoaderImpl to ensure m_node.cj_ctx is properly set
ast-grep --pattern $'new CoinJoinLoaderImpl($_)' 

Length of output: 215


I'll generate an additional verification script that restricts the search to C++ source files (i.e. *.cpp and *.h) to avoid interference from non-code files. This should help us determine whether any instantiations of CoinJoinLoaderImpl occur before the CoinJoin context is set:

Could you please run this script and share the output? This will help us determine if there’s a potential null-pointer issue related to m_node.cj_ctx or its walletman member.


🏁 Script executed:

#!/bin/bash
# Re-verify instantiations of CoinJoinLoaderImpl in C++ source files only
rg --glob '*.cpp' --glob '*.h' "new[[:space:]]+CoinJoinLoaderImpl\\(" .

Length of output: 72


Action: Review double asserts in walletman() for potential hidden null-pointer risks.

Our additional automated searches targeting CoinJoinLoaderImpl did not reveal any usage patterns that could lead to premature access of an uninitialized CoinJoin context. However, the nested use of Assert in

return *Assert(Assert(m_node.cj_ctx)->walletman);

still obscures which pointer might be null if a failure occurs. Please:

  • Verify that m_node.cj_ctx is always properly initialized before any call to walletman().
  • Consider separating the assertions or adding detailed logging to clearly indicate whether it’s m_node.cj_ctx or its walletman member that is null, to improve future debugging.
  • Revisit related code sections to confirm that the initialization order is consistently maintained.

85-88:

❓ Verification inconclusive

Confirm the non-null wallet_loader pointer.

Similarly, return *Assert(m_node.wallet_loader); can crash if wallet_loader is uninitialized. Verify that all call sites guarantee a valid pointer before usage.


🏁 Script executed:

#!/bin/bash
# Ensure node.wallet_loader is always set prior to CoinJoinLoaderImpl usage
ast-grep --pattern $'node.wallet_loader = $_'

Length of output: 212


Below is a revised verification script that excludes the JSON files (like those under src/univalue/) causing the encoding errors. This script will search for assignments to m_node.wallet_loader in C++ files and help us confirm whether the wallet loader pointer is always set before use:

Please run the above script and share its output. Based on the results, we can conclusively verify that all call sites ensure a valid pointer before using wallet_loader(). Until that output is confirmed, manual verification remains necessary.



🏁 Script executed:

[run_scripts]
#!/bin/bash
# Exclude problematic JSON files and search for C++ assignments to m_node.wallet_loader
rg --glob '!src/univalue/*' "m_node\.wallet_loader\s*=" -tcpp

Length of output: 331


Review Action Required: Validate Initialization of wallet_loader Pointer

The current implementation in src/coinjoin/interfaces.cpp:

interfaces::WalletLoader& wallet_loader()
{
    return *Assert(m_node.wallet_loader);
}

assumes that m_node.wallet_loader is always non-null. However, our search uncovered two assignment patterns in test code:

  • In src/test/util/setup_common.cpp, there is an assignment where m_node.wallet_loader is set to a valid pointer with:
    m_node.wallet_loader = wallet_loader.get();
  • In the same file, there is also an assignment where it’s explicitly set to nullptr:
    m_node.wallet_loader = nullptr;

Action Items:

  • Production Usage: Verify that all production call sites guarantee that m_node.wallet_loader is initialized (non-null) before calling wallet_loader(). This will prevent a potential crash when dereferencing a null pointer.
  • Test Code Consideration: Confirm that setting m_node.wallet_loader to nullptr in tests is intentional and that those code paths do not inadvertently invoke the wallet_loader() method. If they do, add appropriate safeguards or modify the test to avoid triggering the assertion.

Please manually verify these scenarios to ensure the design meets the required safety guarantees.


src/wallet/init.cpp (4)

9-9: New include is appropriate.

#include <interfaces/coinjoin.h> is needed to define the added functionality. Looks good.


50-51: Updated method signatures match the new interfaces.

Accepting interfaces::WalletLoader and interfaces::CoinJoin::Loader brings wallet and CoinJoin logic together cleanly.


192-193: Construct method now properly initializes loaders.

Assigning node.coinjoin_loader then creating a wallet loader with it is consistent and resolves previous initialization order issues.


199-204: AutoLockMasternodeCollaterals is straightforward.

Iterating over all wallets and calling autoLockMasternodeCollaterals() is correct. Consider logging or handling potential lock failures if needed.

src/rpc/coinjoin.cpp (9)

48-48: New "status" command documented.

The help text is updated to list the new "status" command. Good addition.


88-89: Reset flow uses safe client acquisition.

Using CHECK_NONFATAL ensures the loader exists and the client is valid, then resetPool() is called. No major issues identified.


128-134: Start mixing refactor.

The code checks if the wallet is unlocked, then starts mixing. Updated error messages are clear and consistent.


139-174: New coinjoin_status command is well-structured.

Ensures a valid wallet, checks if mixing is enabled, throws an error if not mixing, and returns session statuses in an array. This approach is user-friendly.


200-210: Stop mixing logic is consistent.

Confirms mixing is running before calling stopMixing(). Appropriately throws if there's no ongoing session.


274-275: Salt generation or override checks.

Guards against changing salt while mixing to avoid conflicts. Implementation is correct.


376-377: Salt set logic parallels generate.

Again checks for an active mix session before overwriting the salt. Consistency is maintained.


471-472: Client retrieval for getcoinjoininfo.

CHECK_NONFATAL(node.coinjoin_loader)->GetClient(...) is used safely, returning a client to gather additional JSON info.


500-500: Registers new "coinjoin_status" RPC command.

Completes the setup for the new status method, enabling it to be called by end users.

src/test/util/setup_common.cpp (3)

66-66: Header inclusion looks correct.

This newly added #include <interfaces/wallet.h> is appropriate for the subsequent wallet-related logic.


316-319: Ensure reference lifetime is valid.

Passing references of m_node members to CJContext is fine as long as their lifetimes are guaranteed to exceed the context's usage. Please verify that no concurrency or teardown sequence can invalidate these references prematurely.


339-347: Destruction order is consistent.

Resetting chain clients before clearing the raw pointer references ensures a proper teardown flow. This prevents dangling pointers and is safely managed.

src/wallet/context.cpp (1)

7-7: Confirm old constructor references are removed.

This default constructor replaces the previous constructor with a coinjoin_loader parameter. Verify that all call sites expecting the old constructor are updated accordingly.

src/interfaces/init.cpp (1)

6-6: Header inclusion is consistent.

Including <interfaces/coinjoin.h> is necessary to define and return the CoinJoin::Loader objects in subsequent methods.

src/wallet/test/wallet_test_fixture.cpp (1)

11-13: LGTM! The initialization order and ownership semantics are correct.

The changes properly integrate the CoinJoin loader into the wallet testing setup:

  1. m_coinjoin_loader is initialized first
  2. m_wallet_loader uses the CoinJoin loader after null check
  3. m_wallet uses the CoinJoin loader directly
src/wallet/test/wallet_test_fixture.h (1)

11-11: LGTM! The header changes maintain proper dependencies and RAII.

The changes correctly:

  1. Add the necessary include for CoinJoin interfaces
  2. Declare the CoinJoin loader member with proper ownership semantics
  3. Maintain correct declaration order for dependent members

Also applies to: 25-25

src/wallet/context.h (1)

31-31:

✅ Verification successful

Verify ownership management of the CoinJoin loader.

The change from a unique_ptr reference to a raw pointer aligns with the struct's purpose as a collection of state pointers. However, please ensure that:

  1. The lifetime of the CoinJoin loader is properly managed elsewhere
  2. The loader is not null when used

Let's verify the ownership management:

Also applies to: 36-36


🏁 Script executed:

#!/bin/bash
# Search for CoinJoin loader ownership management
rg -A 5 "MakeCoinJoinLoader|coinjoin_loader.*=|coinjoin_loader.*std::unique_ptr"

Length of output: 18547


Ownership management verified for CoinJoin loader.

The search results confirm that the CoinJoin loader is constructed via MakeCoinJoinLoader (returning a std::unique_ptr) and then consistently passed as a raw pointer throughout the codebase (e.g., in wallet initialization and RPC calls). This pattern aligns with the design of the context struct as a collection of non-owning state pointers, and null checks (e.g., in RPC functions) ensure safe usage.

  • The raw pointer is assigned from a unique pointer managed elsewhere.
  • Usage across wallets and tests consistently checks for null, ensuring proper lifetime management.

No further action is needed regarding ownership management.

src/walletinitinterface.h (1)

10-15:

❓ Verification inconclusive

Verify that all implementations are updated for the interface changes.

The interface changes improve modularity by explicitly passing loaders. However, please ensure that all implementations of WalletInitInterface are updated to match the new method signatures:

  1. AutoLockMasternodeCollaterals(interfaces::WalletLoader&)
  2. InitCoinJoinSettings(interfaces::CoinJoin::Loader&, interfaces::WalletLoader&)

Let's verify the implementations:

Also applies to: 29-30


🏁 Script executed:

#!/bin/bash
# Search for WalletInitInterface implementations
ast-grep --pattern 'class $_ : public WalletInitInterface {
  $$$
}'

Length of output: 70


Action Required: Verify Implementations Updated for New Interface Methods

The new forward declarations and updated method signatures for AutoLockMasternodeCollaterals(interfaces::WalletLoader&) and InitCoinJoinSettings(interfaces::CoinJoin::Loader&, interfaces::WalletLoader&) improve modularity by clearly defining loader dependencies. However, the automated AST-grep search did not return any matching implementations for classes inheriting from WalletInitInterface. This absence of output means we couldn’t conclusively verify that all implementations have been updated.

Before finalizing, please ensure or manually verify that all concrete classes implementing WalletInitInterface are updated accordingly. For further confirmation, you might consider running additional searches, for example:

#!/bin/bash
echo "Searching for WalletInitInterface implementations using rg"
rg 'class .*: public WalletInitInterface' -n

echo "Searching for AutoLockMasternodeCollaterals implementations"
rg 'AutoLockMasternodeCollaterals\(' -n

echo "Searching for InitCoinJoinSettings implementations"
rg 'InitCoinJoinSettings\(' -n

Once you confirm that the updated method signatures are correctly implemented across the codebase, please update the PR accordingly.

src/Makefile.test_util.include (1)

46-48: LGTM! Good practice for conditional linking.

The conditional inclusion of the wallet library ensures test utilities are only linked with wallet code when wallet functionality is enabled, improving modularity and build efficiency.

src/init/bitcoind.cpp (3)

6-6: LGTM! Required include for CoinJoin interface.

The addition of interfaces/coinjoin.h aligns with the new CoinJoin functionality.


28-31: LGTM! Clean implementation of CoinJoin loader factory.

The new method provides a clean way to create CoinJoin loaders using the node context.


32-35: LGTM! Improved safety with reference parameters.

The modified signature using references instead of pointers:

  • Prevents null pointer dereference
  • Makes ownership semantics clearer
src/interfaces/coinjoin.h (3)

10-15: LGTM! Required includes and forward declarations.

Clean addition of necessary includes and forward declarations for new functionality.


27-28: LGTM! New methods support improved status reporting.

The new methods enhance the Client interface:

  • getJsonInfo provides structured data for RPC responses
  • getSessionStatuses returns individual session statuses, improving flexibility over concatenated strings

49-49: LGTM! Improved loader initialization.

The signature change to use NodeContext instead of CoinJoinWalletManager aligns with the PR's goal of removing direct wallet manager dependency.

src/wallet/test/init_test_fixture.cpp (1)

17-18: LGTM! Proper initialization order and null checks.

The changes:

  • Initialize coinjoin loader before wallet loader
  • Use Assert for pointer validation
  • Follow the new dependency structure
src/interfaces/init.h (1)

18-20: LGTM! Clean namespace declaration.

The CoinJoin namespace is properly declared with clear scope.

src/init/bitcoin-node.cpp (2)

33-36: LGTM! Clean implementation of CoinJoin loader creation.

The implementation properly forwards the node context to create the CoinJoin loader.


37-40: LGTM! Proper error handling in makeWalletLoader.

Good use of Assert to validate node args before passing to wallet loader.

src/dummywallet.cpp (2)

32-33: LGTM! Proper dummy implementations.

Empty implementations correctly maintained for non-wallet build.


89-92: LGTM! Appropriate error handling.

Proper error message when wallet functions are called in non-wallet build.

src/interfaces/wallet.h (2)

89-90: LGTM: New virtual method for locking masternode collaterals.

The new pure virtual method autoLockMasternodeCollaterals() provides a clear interface for locking masternode collaterals. The method is appropriately placed in the wallet interface.


450-450:

✅ Verification successful

Verify the impact of the signature change.

The function signature has been changed from using a unique_ptr to a reference for coinjoin_loader, and the parameter order has been modified. This could affect existing callers.

Let's verify all callers of this function are updated:


🏁 Script executed:

#!/bin/bash
# Search for calls to MakeWalletLoader
rg "MakeWalletLoader\(" --type cpp

Length of output: 1125


Signature Consistency Confirmed – All Callers Updated

After verifying the call sites using the shell script output, all invocations of MakeWalletLoader now pass parameters in the new order—chain, followed by args, then coinjoin_loader. In cases where coinjoin_loader is stored as a pointer (e.g., in test files), the caller correctly dereferences it; other callers pass an object directly. No outdated call or ordering issue was detected.

src/wallet/interfaces.cpp (4)

150-150: LGTM: Simple delegation to wallet implementation.

The implementation correctly delegates to the wallet's AutoLockMasternodeCollaterals method.


557-562: LGTM: Updated constructor to use reference.

The constructor has been updated to use a reference for coinjoin_loader and store it in the context, which aligns with the interface changes.


578-578: LGTM: Updated method calls to use reference.

The methods have been updated to use the reference member coinjoin_loader consistently.

Also applies to: 593-593, 600-600, 605-605


642-644: LGTM: Updated factory function implementation.

The MakeWalletLoader implementation has been updated to match the new signature.

src/coinjoin/client.cpp (2)

353-365: LGTM: Improved status reporting.

The GetStatuses() method now returns a vector of strings instead of concatenating them into a single bilingual string. This provides more flexibility in handling individual status messages.


917-923: LGTM: Simplified wallet manager methods.

The Add and Remove methods have been simplified by removing unnecessary initialization calls.

Also applies to: 934-936

src/init.cpp (1)

2205-2209: LGTM! The wallet initialization code has been updated to use WalletLoader.

The code correctly checks if wallet is enabled before attempting to auto-lock masternode collaterals using the new WalletLoader interface, which aligns with the PR's objective of refactoring wallet initialization code.

@kwvg kwvg marked this pull request as ready for review February 23, 2025 18:01
Copy link

@coderabbitai coderabbitai bot left a 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

🔭 Outside diff range comments (1)
src/coinjoin/interfaces.cpp (1)

1-127: ⚠️ Potential issue

Fix clang-format issues.

The pipeline reports formatting differences.

Please run clang-format to fix the formatting issues.

🧰 Tools
🪛 GitHub Actions: Clang Diff Format Check

[error] 1-1: Clang format differences found. Please run 'clang-format' to fix formatting issues.

🧹 Nitpick comments (3)
src/coinjoin/interfaces.cpp (1)

91-96: Consider adding error handling for wallet manager initialization.

The constructor initializes CoinJoin settings but doesn't handle potential failures in wallet manager initialization.

Consider adding error handling:

 explicit CoinJoinLoaderImpl(NodeContext& node) :
     m_node(node)
 {
+    if (!m_node.cj_ctx || !m_node.cj_ctx->walletman) {
+        throw std::runtime_error("CoinJoin wallet manager not initialized");
+    }
     // Enablement will be re-evaluated when a wallet is added or removed
     CCoinJoinClientOptions::SetEnabled(false);
 }
src/wallet/init.cpp (1)

207-229: Consider adding error logging for CoinJoin initialization failures.

The method handles wallet locking states but doesn't log initialization failures.

Consider adding error logging:

 void WalletInit::InitCoinJoinSettings(interfaces::CoinJoin::Loader& coinjoin_loader, interfaces::WalletLoader& wallet_loader) const
 {
     const auto& wallets{wallet_loader.getWallets()};
     CCoinJoinClientOptions::SetEnabled(!wallets.empty() ? gArgs.GetBoolArg("-enablecoinjoin", true) : false);
     if (!CCoinJoinClientOptions::IsEnabled()) {
+        LogPrintf("CoinJoin: disabled\n");
         return;
     }
     bool fAutoStart = gArgs.GetBoolArg("-coinjoinautostart", DEFAULT_COINJOIN_AUTOSTART);
     for (auto& wallet : wallets) {
         auto manager = Assert(coinjoin_loader.GetClient(wallet->getWalletName()));
+        if (!manager) {
+            LogPrintf("CoinJoin: failed to initialize client for wallet %s\n", wallet->getWalletName());
+            continue;
+        }
         if (wallet->isLocked(/*fForMixing=*/false)) {
+            LogPrintf("CoinJoin: stopping mixing for locked wallet %s\n", wallet->getWalletName());
             manager->stopMixing();
         } else if (fAutoStart) {
+            LogPrintf("CoinJoin: starting mixing for wallet %s\n", wallet->getWalletName());
             manager->startMixing();
         }
     }
src/rpc/coinjoin.cpp (1)

88-89: Consider enhancing error handling in client manager access.

While the use of CHECK_NONFATAL for null checks is consistent, consider adding more descriptive error messages to help with debugging. For example:

-auto cj_clientman = CHECK_NONFATAL(node.coinjoin_loader)->GetClient(wallet->GetName());
-CHECK_NONFATAL(cj_clientman);
+auto cj_clientman = CHECK_NONFATAL(node.coinjoin_loader, "CoinJoin loader not initialized")->GetClient(wallet->GetName());
+CHECK_NONFATAL(cj_clientman, strprintf("Failed to get CoinJoin client for wallet %s", wallet->GetName()));

Also applies to: 128-129, 164-165, 204-210, 471-472

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 038619d and 685e74c.

📒 Files selected for processing (29)
  • doc/release-notes-6594.md (1 hunks)
  • src/Makefile.test_util.include (1 hunks)
  • src/coinjoin/client.cpp (3 hunks)
  • src/coinjoin/client.h (1 hunks)
  • src/coinjoin/interfaces.cpp (3 hunks)
  • src/dummywallet.cpp (3 hunks)
  • src/init.cpp (1 hunks)
  • src/init/bitcoin-node.cpp (2 hunks)
  • src/init/bitcoind.cpp (2 hunks)
  • src/interfaces/coinjoin.h (3 hunks)
  • src/interfaces/init.cpp (2 hunks)
  • src/interfaces/init.h (2 hunks)
  • src/interfaces/wallet.h (2 hunks)
  • src/node/blockstorage.cpp (0 hunks)
  • src/qt/test/addressbooktests.cpp (0 hunks)
  • src/qt/test/wallettests.cpp (0 hunks)
  • src/rpc/coinjoin.cpp (8 hunks)
  • src/test/util/setup_common.cpp (3 hunks)
  • src/test/util/setup_common.h (0 hunks)
  • src/test/validation_chainstatemanager_tests.cpp (0 hunks)
  • src/wallet/context.cpp (1 hunks)
  • src/wallet/context.h (1 hunks)
  • src/wallet/init.cpp (3 hunks)
  • src/wallet/interfaces.cpp (5 hunks)
  • src/wallet/rpcwallet.cpp (3 hunks)
  • src/wallet/test/init_test_fixture.cpp (1 hunks)
  • src/wallet/test/wallet_test_fixture.cpp (1 hunks)
  • src/wallet/test/wallet_test_fixture.h (2 hunks)
  • src/walletinitinterface.h (2 hunks)
💤 Files with no reviewable changes (5)
  • src/test/util/setup_common.h
  • src/test/validation_chainstatemanager_tests.cpp
  • src/qt/test/addressbooktests.cpp
  • src/node/blockstorage.cpp
  • src/qt/test/wallettests.cpp
🚧 Files skipped from review as they are similar to previous changes (12)
  • doc/release-notes-6594.md
  • src/Makefile.test_util.include
  • src/wallet/test/wallet_test_fixture.h
  • src/coinjoin/client.h
  • src/wallet/context.cpp
  • src/walletinitinterface.h
  • src/wallet/test/init_test_fixture.cpp
  • src/interfaces/init.h
  • src/dummywallet.cpp
  • src/wallet/test/wallet_test_fixture.cpp
  • src/wallet/rpcwallet.cpp
  • src/wallet/interfaces.cpp
🧰 Additional context used
🪛 GitHub Actions: Clang Diff Format Check
src/coinjoin/interfaces.cpp

[error] 1-1: Clang format differences found. Please run 'clang-format' to fix formatting issues.

src/rpc/coinjoin.cpp

[error] 1-1: Clang format differences found. Please run 'clang-format' to fix formatting issues.

🔇 Additional comments (30)
src/test/util/setup_common.cpp (4)

66-66: LGTM!

The addition of interfaces/wallet.h is necessary for the new wallet loader functionality.


316-318: LGTM!

The CoinJoin context initialization is properly structured with all required dependencies, aligning with the PR's goal of refactoring the CoinJoin interface.


320-329: LGTM!

The initialization sequence is well-structured:

  1. Proper conditional compilation with ENABLE_WALLET
  2. Correct initialization order: CoinJoin loader before wallet loader
  3. Appropriate integration with chain clients

339-348: LGTM!

The cleanup sequence follows best practices:

  1. Proper conditional compilation with ENABLE_WALLET
  2. Correct cleanup order: reverse of initialization
  3. Complete resource cleanup
src/interfaces/init.cpp (2)

6-6: LGTM!

The include directive for interfaces/coinjoin.h is correctly added to support the new CoinJoin functionality.


15-16: LGTM!

The changes correctly introduce the new makeCoinJoinLoader method and update the makeWalletLoader signature to use references instead of unique pointers, improving ownership semantics.

src/wallet/context.h (2)

31-31: LGTM!

The change to use a raw pointer with nullptr initialization aligns with the struct's purpose as a collection of state pointers and improves safety by not requiring a loader at construction time.


36-36: LGTM!

The default constructor is appropriate here as it allows for deferred initialization of the CoinJoin loader, which aligns with the PR objectives.

src/init/bitcoind.cpp (2)

6-6: LGTM!

The include directives for interfaces/coinjoin.h and util/check.h are correctly added to support the new functionality and assertions.

Also applies to: 12-12


29-36: LGTM!

The implementation correctly:

  • Creates the CoinJoin loader using the node context
  • Updates the wallet loader signature to use references
  • Ensures m_node.args is not null using Assert
src/interfaces/coinjoin.h (3)

10-15: LGTM!

The includes and forward declarations are correctly added and ordered to support the new functionality.


27-28: LGTM!

The new virtual methods getJsonInfo and getSessionStatuses enhance the interface by providing structured access to CoinJoin information, which aligns with the PR objectives.


49-49: LGTM!

The updated signature of MakeCoinJoinLoader correctly uses NodeContext instead of CoinJoinWalletManager, aligning with the refactoring goals to remove the wallet manager dependency.

src/init/bitcoin-node.cpp (3)

6-6: LGTM! Required includes added.

The new includes support the CoinJoin loader functionality and assertion utilities.

Also applies to: 13-13


34-37: LGTM! Well-structured CoinJoin loader creation.

The new makeCoinJoinLoader method follows the established pattern of other loader creation methods in the class.


38-41: LGTM! Improved parameter passing for wallet loader.

The change from unique_ptr to reference parameter improves ownership semantics, as the loader's lifetime is managed elsewhere.

src/coinjoin/interfaces.cpp (4)

8-11: LGTM! Required includes added.

The new includes support node context integration and CoinJoin options.


47-50: LGTM! New JSON info retrieval method.

The method provides a clean interface for getting JSON-formatted client information.


55-58: LGTM! New session status retrieval method.

The method returns a vector of strings, which is more flexible than a concatenated string.


79-89: LGTM! Well-structured helper methods.

The private helper methods walletman() and wallet_loader() improve code organization and error handling through assertions.

src/interfaces/wallet.h (2)

89-91: LGTM! New virtual method for masternode collateral management.

The pure virtual method enforces implementation in derived classes.


450-450: LGTM! Improved parameter ordering in MakeWalletLoader.

The signature change improves readability by grouping related parameters and using references appropriately.

src/wallet/init.cpp (2)

192-193: LGTM! Proper initialization order.

The CoinJoin loader is correctly initialized before the wallet loader.


199-205: LGTM! Improved masternode collateral management.

The method now uses the wallet loader interface to access wallets, improving encapsulation.

src/rpc/coinjoin.cpp (3)

48-48: LGTM! Command registration is properly updated.

The help message and command table are correctly updated to include the new coinjoin status command.

Also applies to: 500-500


139-174: LGTM! The new coinjoin_status implementation is well-structured.

The implementation includes proper validation, error handling, and follows the RPC interface pattern consistently. The status messages are returned as an array, which provides better flexibility for clients.


128-133: LGTM! The simplified coinjoin_start response is appropriate.

The change to return a simple "Mixing requested" message aligns with the PR objectives, as error reporting is now handled by the new coinjoin status command.

src/coinjoin/client.cpp (2)

353-365: LGTM! The GetStatuses refactor improves data structure.

The change from bilingual_str to std::vector<std::string> provides better flexibility and structure for status reporting. The use of uniform initialization for fWaitForBlock follows modern C++ practices.


917-923: LGTM! Client manager initialization is simplified.

The removal of g_wallet_init_interface.InitCoinJoinSettings and the updated initialization pattern simplify the code while maintaining functionality.

Also applies to: 934-936

src/init.cpp (1)

2205-2209:

❓ Verification inconclusive

Verify the wallet loader initialization.

The code correctly checks for the wallet being enabled before auto-locking masternode collaterals. However, since this is part of a larger refactor of wallet initialization code, ensure that wallet_loader is properly initialized at this point.

Run the following script to verify the initialization order:


🏁 Script executed:

#!/bin/bash
# Description: Check if wallet_loader is initialized before use

# Search for wallet_loader initialization
ast-grep --pattern $'node.wallet_loader = $_'

# Search for any potential null checks on wallet_loader
ast-grep --pattern $'if (node.wallet_loader) {
  $$$
}'

Length of output: 269


Below is a revised review comment. Since the initial script produced no conclusive output (and even reported issues reading a couple of JSON files), please re-run a more targeted search to confirm that node.wallet_loader is indeed initialized before its use in this block. In the meantime, manually verify the initialization order in src/init.cpp.

Manual Verification Required: Check Wallet Loader Initialization

  • The code at lines 2205–2209 correctly checks that the wallet is enabled before auto-locking masternode collaterals.
  • However, the recent search did not confirm whether node.wallet_loader is initialized before its use.
  • Please verify that node.wallet_loader is assigned (e.g. via an assignment like node.wallet_loader = …) prior to calling AutoLockMasternodeCollaterals().
  • It may be prudent to add an explicit null check or safeguard if there’s any risk of wallet_loader being uninitialized.

For additional clarification, you can run this targeted script:

#!/bin/bash
# Check for wallet_loader assignment and null checks specifically in src/init.cpp

echo "Searching for wallet_loader assignment in src/init.cpp"
rg -n "node\.wallet_loader\s*=" src/init.cpp

echo "Searching for wallet_loader null check in src/init.cpp"
rg -n "if\s*\(node\.wallet_loader\)" src/init.cpp

Please verify the initialization manually and adjust as needed.

@UdjinM6 UdjinM6 added the RPC Some notable changes to RPC params/behaviour/descriptions label Feb 23, 2025
@UdjinM6
Copy link

UdjinM6 commented Feb 24, 2025

Seems to be working with no issues. Consider adding some of ai bot suggestions maybe? pls see 71659ff

@kwvg kwvg requested review from UdjinM6 and removed request for UdjinM6 February 24, 2025 21:09
kwvg added 12 commits February 24, 2025 21:26
This helps us get rid of having to report it through `coinjoin start`.

Additionally, we won't try to jump ahead of the scheduler by starting
denomination routines ourselves, let the scheduler run its course.
This matters because we don't plan on exposing that capability through
the interface as we are migrating to the interface in the next commit.
`interfaces::CoinJoin::Loader` relies on `interfaces::WalletLoader` and
vice-versa. Currently this isn't explicitly enumerated due to the global
wallet state but when that goes away, we will need to defer access to one
of them to break the tie.

Let's do that now.
The previous commit removes the invocation of `MakeCoinJoinLoader` from
`init.cpp`. For some reason this makes the linker unhappy when working
with `bench_dash`. Fix it by adding the wallet library to `test_util`.

```
/usr/bin/ld: libtest_util.a(libtest_util_a-setup_common.o): in function `DashPostChainstateSetup(NodeContext&)':
/src/dash/src/test/util/setup_common.cpp:127:(.text+0x1a8e): undefined reference to `interfaces::MakeCoinJoinLoader(NodeContext&)'
collect2: error: ld returned 1 exit status
```
We now initialize the CoinJoin loader before initializing the wallet
loader thanks to deferred access to `CoinJoinWalletManager`, so we no
longer need the smart pointer ref workaround.
`validation_chainstatemanager_tests` can work without `CJContext`, we
can safely reincorporate it into `TestingSetup`.
@kwvg kwvg requested a review from PastaPastaPasta February 24, 2025 21:27
Copy link

@coderabbitai coderabbitai bot left a 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 (8)
src/interfaces/init.cpp (1)

16-16: Consider documenting ownership semantics.

The change from const std::unique_ptr<CoinJoin::Loader>& to CoinJoin::Loader& suggests a shift in ownership model. Consider adding a comment to clarify that the caller retains ownership of the loader.

src/rpc/coinjoin.cpp (3)

88-89: Consider adding error handling for GetClient result.

While CHECK_NONFATAL is used, consider adding explicit error handling to provide a more informative error message to the user.

-    auto cj_clientman = CHECK_NONFATAL(node.coinjoin_loader)->GetClient(wallet->GetName());
-    CHECK_NONFATAL(cj_clientman)->resetPool();
+    auto cj_loader = CHECK_NONFATAL(node.coinjoin_loader);
+    if (!cj_loader) {
+        throw JSONRPCError(RPC_INTERNAL_ERROR, "CoinJoin loader not available");
+    }
+    auto cj_clientman = cj_loader->GetClient(wallet->GetName());
+    if (!cj_clientman) {
+        throw JSONRPCError(RPC_INTERNAL_ERROR, strprintf("Failed to get CoinJoin client for wallet '%s'", wallet->GetName()));
+    }
+    cj_clientman->resetPool();

128-134: Improve error handling and return message.

The return message is now less informative. Consider providing more context about the mixing status.

-    return "Mixing requested";
+    return strprintf("Mixing requested for wallet '%s'. Use 'coinjoin status' to check mixing progress.", wallet->GetName());

202-209: Consider adding error handling for GetClient result.

Similar to earlier feedback, consider adding explicit error handling for the client manager retrieval.

-    auto cj_clientman = node.coinjoin_loader->GetClient(wallet->GetName());
+    auto cj_loader = CHECK_NONFATAL(node.coinjoin_loader);
+    if (!cj_loader) {
+        throw JSONRPCError(RPC_INTERNAL_ERROR, "CoinJoin loader not available");
+    }
+    auto cj_clientman = cj_loader->GetClient(wallet->GetName());
+    if (!cj_clientman) {
+        throw JSONRPCError(RPC_INTERNAL_ERROR, strprintf("Failed to get CoinJoin client for wallet '%s'", wallet->GetName()));
+    }
src/wallet/init.cpp (1)

199-204: Consider adding error handling for empty wallet list.

The method could benefit from early validation of the wallet list.

 void WalletInit::AutoLockMasternodeCollaterals(interfaces::WalletLoader& wallet_loader) const
 {
     // we can't do this before DIP3 is fully initialized
+    const auto& wallets = wallet_loader.getWallets();
+    if (wallets.empty()) {
+        return;
+    }
-    for (const auto& wallet : wallet_loader.getWallets()) {
+    for (const auto& wallet : wallets) {
         wallet->autoLockMasternodeCollaterals();
     }
 }
src/coinjoin/interfaces.cpp (1)

80-83: Consider adding thread safety for wallet manager access.

The helper methods should consider thread safety when accessing shared resources.

 private:
+    mutable std::mutex m_mutex;
+
     CoinJoinWalletManager& walletman()
     {
+        std::lock_guard<std::mutex> lock(m_mutex);
         return *Assert(Assert(m_node.cj_ctx)->walletman);
     }

     interfaces::WalletLoader& wallet_loader()
     {
+        std::lock_guard<std::mutex> lock(m_mutex);
         return *Assert(m_node.wallet_loader);
     }

Also applies to: 85-88

src/dummywallet.cpp (2)

84-87: Consider improving error message.

The error message could be more specific about the build configuration.

-    throw std::logic_error("Wallet function called in non-wallet build.");
+    throw std::logic_error("CoinJoin loader requested in build without wallet support (compiled with -DENABLE_WALLET=0).");

94-97: Consider improving error message.

Similar to above, the error message could be more specific.

-    throw std::logic_error("Wallet function called in non-wallet build.");
+    throw std::logic_error("Wallet loader requested in build without wallet support (compiled with -DENABLE_WALLET=0).");
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 80463f0 and 68cec8d.

📒 Files selected for processing (30)
  • doc/release-notes-6594.md (1 hunks)
  • src/Makefile.test_util.include (1 hunks)
  • src/coinjoin/client.cpp (3 hunks)
  • src/coinjoin/client.h (1 hunks)
  • src/coinjoin/interfaces.cpp (3 hunks)
  • src/dummywallet.cpp (3 hunks)
  • src/init.cpp (1 hunks)
  • src/init/bitcoin-node.cpp (2 hunks)
  • src/init/bitcoind.cpp (2 hunks)
  • src/interfaces/coinjoin.h (3 hunks)
  • src/interfaces/init.cpp (2 hunks)
  • src/interfaces/init.h (2 hunks)
  • src/interfaces/wallet.h (2 hunks)
  • src/node/blockstorage.cpp (0 hunks)
  • src/qt/test/addressbooktests.cpp (0 hunks)
  • src/qt/test/wallettests.cpp (0 hunks)
  • src/rpc/coinjoin.cpp (8 hunks)
  • src/test/util/setup_common.cpp (3 hunks)
  • src/test/util/setup_common.h (0 hunks)
  • src/test/validation_chainstatemanager_tests.cpp (0 hunks)
  • src/wallet/context.cpp (1 hunks)
  • src/wallet/context.h (1 hunks)
  • src/wallet/init.cpp (3 hunks)
  • src/wallet/interfaces.cpp (5 hunks)
  • src/wallet/rpcwallet.cpp (3 hunks)
  • src/wallet/test/init_test_fixture.cpp (1 hunks)
  • src/wallet/test/wallet_test_fixture.cpp (1 hunks)
  • src/wallet/test/wallet_test_fixture.h (2 hunks)
  • src/walletinitinterface.h (2 hunks)
  • test/functional/rpc_coinjoin.py (2 hunks)
💤 Files with no reviewable changes (5)
  • src/node/blockstorage.cpp
  • src/qt/test/wallettests.cpp
  • src/test/validation_chainstatemanager_tests.cpp
  • src/test/util/setup_common.h
  • src/qt/test/addressbooktests.cpp
🚧 Files skipped from review as they are similar to previous changes (12)
  • src/wallet/test/wallet_test_fixture.h
  • src/wallet/context.cpp
  • src/Makefile.test_util.include
  • src/wallet/test/wallet_test_fixture.cpp
  • src/coinjoin/client.h
  • doc/release-notes-6594.md
  • src/interfaces/init.h
  • src/walletinitinterface.h
  • src/wallet/test/init_test_fixture.cpp
  • src/interfaces/wallet.h
  • src/wallet/rpcwallet.cpp
  • src/interfaces/coinjoin.h
🧰 Additional context used
🪛 GitHub Actions: Clang Diff Format Check
src/coinjoin/interfaces.cpp

[error] 1-1: Clang format differences found. Please run 'clang-format' to fix formatting issues.

src/rpc/coinjoin.cpp

[error] 1-1: Clang format differences found. Please run 'clang-format' to fix formatting issues.

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: predict_conflicts
  • GitHub Check: arm-linux-gnueabihf / Build depends
  • GitHub Check: x86_64-apple-darwin / Build depends
  • GitHub Check: x86_64-pc-linux-gnu_multiprocess / Build depends
🔇 Additional comments (23)
test/functional/rpc_coinjoin.py (1)

69-70: LGTM! Good test coverage for the new coinjoin status RPC command.

The test cases appropriately verify both success and error scenarios for the new status command:

  1. Verifies that status can be queried while mixing is active
  2. Verifies that status request fails when no mix session is running

Also applies to: 79-80

src/interfaces/init.cpp (1)

6-6: LGTM! Good addition of CoinJoin loader interface.

The new makeCoinJoinLoader() method and its header inclusion align with the PR's objective of refactoring CoinJoin initialization.

Also applies to: 15-15

src/test/util/setup_common.cpp (3)

316-318: LGTM! Well-structured CoinJoin context initialization.

The initialization parameters are comprehensive and in a logical order.


320-329: LGTM! Good wallet initialization with proper dependency handling.

The code correctly:

  1. Creates the CoinJoin loader first
  2. Creates the wallet loader with proper dependencies
  3. Stores the loader in both direct and chain client references

339-348: LGTM! Proper cleanup of resources in reverse order.

The cleanup sequence correctly:

  1. Resets chain clients
  2. Clears the wallet loader reference
  3. Resets the CoinJoin loader
  4. Resets the CoinJoin context
src/init.cpp (1)

2205-2209:

❓ Verification inconclusive

Verify the wallet initialization changes.

The wallet initialization code looks correct, but let's verify that:

  1. The AutoLockMasternodeCollaterals call is properly handled when wallet is disabled
  2. The WalletLoader is properly initialized before this point

🏁 Script executed:

#!/bin/bash
# Check if WalletLoader is initialized before use
ast-grep --pattern $'node.wallet_loader = $_'

# Check if AutoLockMasternodeCollaterals handles disabled wallet case
ast-grep --pattern $'AutoLockMasternodeCollaterals($_)'

Length of output: 435


Action Required: Verify WalletLoader Initialization

The wallet initialization logic appears to be correctly guarded by the ENABLE_WALLET directive and the -disablewallet flag. However, our automated search for the initialization of node.wallet_loader and the call to AutoLockMasternodeCollaterals did not produce conclusive output (likely due to non-code UTF-8 files in the repository). Please manually verify that:

  • node.wallet_loader is reliably initialized prior to its use in this code segment.
  • AutoLockMasternodeCollaterals behaves as expected when the wallet is disabled and that its integration with WalletLoader is correct.
src/coinjoin/client.cpp (1)

353-365: LGTM! The changes improve code clarity and maintainability.

The changes to GetStatuses() method are well-structured:

  1. Return type changed from bilingual_str to std::vector<std::string> to return individual status strings.
  2. Using uniform initialization syntax for fWaitForBlock.
  3. Properly initializing the return vector.
src/init/bitcoin-node.cpp (1)

34-41: LGTM! The changes improve code organization and ownership semantics.

The changes are well-structured:

  1. New makeCoinJoinLoader() method properly separates concerns.
  2. Updated makeWalletLoader() signature improves ownership semantics by using references.
src/init/bitcoind.cpp (1)

29-36: LGTM! The changes maintain consistency with bitcoin-node.cpp.

The changes mirror those in bitcoin-node.cpp:

  1. New makeCoinJoinLoader() method properly separates concerns.
  2. Updated makeWalletLoader() signature improves ownership semantics by using references.
src/wallet/context.h (2)

36-36: LGTM! Default constructor addition improves usability.

The addition of a default constructor allows for more flexible initialization of WalletContext instances.


31-31:

✅ Verification successful

Verify null pointer checks for coinjoin_loader.

The change from const reference to raw pointer simplifies ownership semantics, but ensure that all usages of coinjoin_loader include proper null pointer checks to prevent potential crashes.

Run the following script to check for null pointer checks:


🏁 Script executed:

#!/bin/bash
# Description: Check for null pointer checks on coinjoin_loader
# Search for direct usage without null checks
rg "coinjoin_loader->" -A 2

# Search for null checks before usage
rg "if.*coinjoin_loader.*\)" -A 2

Length of output: 2017


Review Verified: Null Pointer Checks for coinjoin_loader Are Adequate

The search results confirm that all usages of coinjoin_loader are safely guarded with null checks. Specifically:

  • In src/rpc/coinjoin.cpp, usage occurs only after verifying node.coinjoin_loader != nullptr.
  • In src/wallet/wallet.cpp, the pointer is used within if (coinjoin_loader) conditions.
  • The test file src/wallet/test/wallet_tests.cpp also checks for the pointer before usage.

No further action is required.

src/rpc/coinjoin.cpp (2)

47-48: LGTM! Documentation updated for new command.

The help message has been updated to include the new status command.


138-173: LGTM! Well-structured new RPC command.

The new coinjoin status command is well-implemented with:

  • Clear documentation
  • Proper parameter validation
  • Consistent error handling
  • Structured return format
src/wallet/init.cpp (2)

192-195: LGTM! Proper initialization order and resource management.

The initialization sequence is correct:

  1. Create CoinJoin loader
  2. Create wallet loader with chain and CoinJoin loader
  3. Store wallet loader in node context
  4. Add to chain clients for lifecycle management

207-231: LGTM! Well-structured CoinJoin initialization.

The initialization logic is well-organized with:

  • Early validation of wallet list
  • Proper error handling
  • Clear logging
  • Consistent method naming
src/coinjoin/interfaces.cpp (3)

47-50: LGTM! Clean implementation of JSON info retrieval.

The method correctly delegates to the client manager.


55-58: LGTM! Clean implementation of session status retrieval.

The method correctly returns the vector of status strings.


91-96: LGTM! Clean initialization with proper documentation.

The constructor correctly:

  • Takes NodeContext reference
  • Initializes member variables
  • Sets initial CoinJoin state
  • Documents the enablement behavior
src/dummywallet.cpp (1)

32-33: LGTM! Clean interface implementation.

The dummy implementations correctly maintain the interface contract while doing nothing in a wallet-disabled build.

src/wallet/interfaces.cpp (4)

150-150: LGTM!

The new method autoLockMasternodeCollaterals() provides a clean interface to the underlying wallet functionality.


557-562: LGTM!

Good change to use references instead of pointers for coinjoin_loader. This enforces that a valid loader must be provided and cannot be null.


578-578: LGTM!

The updates to use references instead of pointers in these methods are consistent with the constructor changes and maintain the same safety guarantees.

Also applies to: 593-593, 600-600, 605-605


642-644: LGTM!

The MakeWalletLoader function signature has been correctly updated to match the constructor changes.

Copy link

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 68cec8d

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RPC Some notable changes to RPC params/behaviour/descriptions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants