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

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

Draft
wants to merge 16 commits into
base: develop
Choose a base branch
from

Conversation

kwvg
Copy link
Collaborator

@kwvg kwvg commented Jan 11, 2025

Additional Information

  • Dependent on backport: merge bitcoin#15596, #25497, #17331, #22155 (wallet backports: part 1) #6517

  • bitcoin#19101 has been split into two due to it performing two refactors in one commit, the first half deals with utilizing interfaces and managers as defined in WalletContext (as opposed to either passing them in separately as arguments or accessing them through globals) and the second half deals with deglobalizing wallet variables like ::vpwallets and cs_wallets.

    • WalletContext still needs to be initialized with a constructor as it stores a const-ref std::unique_ptr of interfaces::CoinJoin::Loader. This requirement hasn't been done away with. Tests that don't have access to coinjoin_loader will still need to pass nullptr.

    • Bitcoin registers wallet RPCs through WalletClient::registerRpcs() (source), which a part of the ChainClient interface (source). They are enumerated (source) differently from non-wallet RPCs (source).

      Wallet RPCs aren't supposed to have knowledge of NodeContext and likewise non-wallet RPCs aren't supposed to have knowledge of WalletContext. So far, Bitcoin has reworked their RPCs to maintain this separation and upstream RPCs are a part of the libbitcoin_wallet library.

      This isn't the case for some Dash RPCs, many of which reside in libbitcoin_server, some of which fit into two categories.

      • Requires knowledge of both NodeContext and WalletContext

        • Knowledge of WalletContext wasn't mandatory before deglobalization as wallet information could be accessed through the global context courtesy of ::vpwallets and friends but now that it is, many RPCs need to be able to access WalletContext when otherwise they wouldn't need to.
        • Due to the mutual exclusivity mentioned above, RPCs that access WalletContext cannot access NodeContext as their RPC registration logic doesn't give them access to NodeContext (source, m_context here is WalletContext) but in order to give those RPCs WalletContext, we need to register them as wallet RPCs, which prevent us from accessing NodeContext.
        • This has been tentatively worked around by including a pointer to NodeContext in WalletContext (source) and modifying EnsureAnyNodeContext() to fetch from WalletContext if regular behavior doesn't yield a NodeContext (source).
      • Are RPCs that possess both wallet and non-wallet functionality (i.e. have "reduced" capabilities if wallet support isn't compiled in as opposed to being absent altogether).

        • To enable wallet functionality, the RPCs need to be registered as wallet RPCs. If wallet functionality is disabled, those RPCs are not registered. Simple enough, unless you have an RPC that can partially work if wallet functionality as disabled, as the lack of registration would mean those RPCs are entirely inaccessible.
        • This is also tentatively worked around by registering them as non-wallet RPCs in the cases where wallet RPCs aren't registered (i.e. if wallet support isn't compiled in or if wallet support is disabled at runtime).
          • Bitcoin doesn't use #ifndef ENABLE_WALLET for checking if support is absent, we're expected to use !g_wallet_init_interface.HasWalletSupport() (which will always evaluate false if support isn't compiled in, source, as the stub wallet would be utilized to initialize the global in those cases, source). This has been done in the PR.

          • A notable change in this PR is that a lot of behavior that would be enabled if support was compiled in but disabled at runtime would now be disabled if support was disabled at runtime as wallet_loader won't be initialized if runtime disablement occurs (source), which in turns means that anything that relies on wallet_loader wouldn't work either, such as coinjoin_loader.

            This means that we also need to register the RPC as a non-wallet RPC if support is compiled in but disabled at runtime (source).

    • To register RPCs as wallet RPCs, generally they're done through WalletClient::registerRpcs(), which iterates through GetWalletRPCCommands(). This is perfectly fine as both reside in libbitcoin_wallet. Unfortunately, our Dash RPCs reside in libbitcoin_server and registerRpcs() cannot be extended to enumerate through RPCs not included in its library.

      We cannot simply move the Dash RPCs either (at least in its current state) as they rely on non-wallet logic, so moving the source files for those RPCs into libbitcoin_wallet would pull more or less, all of libbitcoin_server along with it.

      • To tentatively get around this, a new method has been defined, WalletLoader::registerOtherRpcs(), which will accept any set of RPCs for registration (source) and we use it in RPC init logic (source).
    • Some usage of CoreContext had to be removed (source) as without those removals, the test suite would crash.

      Crash:
      dash@01fd4f6cfa52:/src/dash$ lldb ./src/test/test_dash
      (lldb) target create "./src/test/test_dash"
      Current executable set to '/src/dash/src/test/test_dash' (x86_64).
      (lldb) r -t wallet_tests
      Process 653232 launched: '/src/dash/src/test/test_dash' (x86_64)
      Running 17 test cases...
      unknown location(0): fatal error: in "wallet_tests/CreateTransactionTest": unknown type
      wallet/test/wallet_tests.cpp(1052): last checkpoint
      
      *** 1 failure is detected in the test module "Dash Core Test Suite"
      Process 653232 exited with status = 201 (0x000000c9)
      
  • The assertion introduced in bitcoin#22686 (source) has not been backported as this assertion is downgraded to an error in bitcoin#26611 and then further modified in bitcoin#26643 (source), portions of which are already included in dash#6517 (source).

  • bitcoin#23288 finished what e3687f7 (dash#6078) started and coinselection_tests has now been realigned with upstream.

    • Dash-specific tests in wallet_tests (as introduced in dash#3367) have not been moved over to descriptor wallets and are still based on legacy wallets (to this effect, the old AddKey logic has been retained as AddLegacyKey, source).

      • To prevent merge conflicts, Dash-specific tests have been moved to the end of the source file and demarcated by a comment (source).

Notable Changes

  • CoinJoinWalletManager::{Add,Remove}() will no longer call WalletInit::InitCoinJoinSettings() if not called through the interface (i.e. interfaces::CoinJoin::Loader::{Add,Remove}()). If not using the interface, those calls will need to be made manually.

    It is recommended to use the interface where possible.

  • NodeContext::coinjoin_loader will not be initialized at all if wallet support is disabled at runtime. (Earlier behavior allowed for initialization so long as wallet support was included at compile-time, now it must be enabled at runtime as well).

    • A similar behavior change is present for the WalletInit::AutoLockMasternodeCollaterals() (also moved out of ThreadImport()) during init but since if wallet support is disabled at runtime, there would be no collaterals to lock, this change isn't of concern.

Breaking Changes

  • The RPCs coinjoin, coinjoinsalt, getpoolinfo, gobject list-prepared, gobject prepare, gobject vote-alias, gobject vote-many, masternode outputs, protx update*, protx register* and protx revoke will no longer be available if wallet support is disabled at runtime. This is not a change in functionality as they were already inoperative with disabled wallets but is a change in reporting as they would not be available at all.

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)

kwvg added 8 commits January 11, 2025 02:13
We aren't adding the `assert` check as it's superceded by a "Fee
needed > fee paid" error that was already backported from c1a84f1
(bitcoin#26643).
This is done to avoid conflicts in an upcoming backport which assume the
tests are ordered as they are upstream. Validate with `git log -p -n1`
` --color-moved=dimmed_zebra`.
This is done to avoid conflicts arising from backports.
The PR is logically split in two for ease of review, this commit deals
with folding ArgsManager, interfaces::Chain and interfaces::CoinJoin
::Loader into WalletContext.
@kwvg kwvg added this to the 23 milestone Jan 11, 2025
This is required because we're going to get deglobalize wallet variables
in an upcoming commit, which requires us to hold `WalletContext` in
order to iterate through all wallets. So, we rely on the interface to
help us do that.

Also, let's fold in the `WalletInit::InitCoinJoinSettings` calls into
`interfaces::CoinJoin::Loader` for simplicity's sake.
kwvg added 7 commits January 13, 2025 00:50
In an upcoming commit, wallet variables will be deglobalized. This means
that RPCs that use wallet logic need to get ahold of WalletContext, which
only happens if they're registered as a wallet RPC (i.e. registered
through WalletLoader).

The downside of being registered as a wallet RPC is that you lose access
to NodeContext. For now, we will work around this by giving WalletContext
access to NodeContext and modify EnsureAnyNodeContext to pull it from
WalletContext.
This is the second half of the backport, which deals with deglobalizing
wallet-specific variables like vpwallets, cs_wallets and friends.
…wallet tests

Dash-specific tests have not been migrated to use descriptor wallets
and the old AddKey() logic has been retained as AddLegacyKey().

final_hex needed to be recalculated in psbt_updater_test as one of the
input scripts were an invalid-to-Dash address and its replacement
with a descriptor that doesn't correspond to the same script requires
recalculating the unsigned PSBT.

excludes:
- 9951628 (we don't support bech32 addresses)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant