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
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -401,10 +401,13 @@ BITCOIN_CORE_H = \
wallet/hdchain.h \
wallet/ismine.h \
wallet/load.h \
wallet/receive.h \
wallet/rpcwallet.h \
wallet/salvage.h \
wallet/scriptpubkeyman.h \
wallet/spend.h \
wallet/sqlite.h \
wallet/transaction.h \
wallet/wallet.h \
wallet/walletdb.h \
wallet/wallettool.h \
Expand Down Expand Up @@ -596,9 +599,12 @@ libbitcoin_wallet_a_SOURCES = \
wallet/hdchain.cpp \
wallet/interfaces.cpp \
wallet/load.cpp \
wallet/receive.cpp \
wallet/rpcdump.cpp \
wallet/rpcwallet.cpp \
wallet/scriptpubkeyman.cpp \
wallet/spend.cpp \
wallet/transaction.cpp \
wallet/wallet.cpp \
wallet/walletdb.cpp \
wallet/walletutil.cpp \
Expand Down
3 changes: 3 additions & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ BITCOIN_TESTS += \
wallet/test/bip39_tests.cpp \
wallet/test/coinjoin_tests.cpp \
wallet/test/psbt_wallet_tests.cpp \
wallet/test/spend_tests.cpp \
wallet/test/wallet_tests.cpp \
wallet/test/walletdb_tests.cpp \
wallet/test/wallet_crypto_tests.cpp \
Expand All @@ -213,6 +214,8 @@ endif


BITCOIN_TEST_SUITE += \
wallet/test/util.cpp \
wallet/test/util.h \
wallet/test/wallet_test_fixture.cpp \
wallet/test/wallet_test_fixture.h \
wallet/test/init_test_fixture.cpp \
Expand Down
11 changes: 4 additions & 7 deletions src/bench/coin_selection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ static void CoinSelection(benchmark::Bench& bench)
NodeContext node;
auto chain = interfaces::MakeChain(node);
CWallet wallet(chain.get(), /*coinjoin_loader=*/ nullptr, "", CreateDummyWalletDatabase());
wallet.SetupLegacyScriptPubKeyMan();
std::vector<std::unique_ptr<CWalletTx>> wtxs;
LOCK(wallet.cs_wallet);

Expand All @@ -48,15 +47,14 @@ static void CoinSelection(benchmark::Bench& bench)
coins.emplace_back(wtx.get(), 0 /* iIn */, 6 * 24 /* nDepthIn */, true /* spendable */, true /* solvable */, true /* safe */);
}
const CoinEligibilityFilter filter_standard(1, 6, 0);
const CoinSelectionParams coin_selection_params(/* use_bnb= */ true, /* change_output_size= */ 34,
const CoinSelectionParams coin_selection_params(/* change_output_size= */ 34,
/* change_spend_size= */ 148, /* effective_feerate= */ CFeeRate(0),
/* long_term_feerate= */ CFeeRate(0), /* discard_feerate= */ CFeeRate(0),
/* tx_no_inputs_size= */ 0, /* avoid_partial= */ false);
/* tx_noinputs_size= */ 0, /* avoid_partial= */ false);
bench.run([&] {
std::set<CInputCoin> setCoinsRet;
CAmount nValueRet;
bool bnb_used;
bool success = wallet.SelectCoinsMinConf(1003 * COIN, filter_standard, coins, setCoinsRet, nValueRet, coin_selection_params, bnb_used);
bool success = wallet.AttemptSelection(1003 * COIN, filter_standard, coins, setCoinsRet, nValueRet, coin_selection_params);
assert(success);
assert(nValueRet == 1003 * COIN);
assert(setCoinsRet.size() == 2);
Expand Down Expand Up @@ -94,12 +92,11 @@ static void BnBExhaustion(benchmark::Bench& bench)
std::vector<OutputGroup> utxo_pool;
CoinSet selection;
CAmount value_ret = 0;
CAmount not_input_fees = 0;

bench.run([&] {
// Benchmark
CAmount target = make_hard_case(17, utxo_pool);
SelectCoinsBnB(utxo_pool, target, 0, selection, value_ret, not_input_fees); // Should exhaust
SelectCoinsBnB(utxo_pool, target, 0, selection, value_ret); // Should exhaust

// Cleanup
utxo_pool.clear();
Expand Down
16 changes: 8 additions & 8 deletions src/bench/wallet_balance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,21 @@

#include <optional>

static void WalletBalance(benchmark::Bench& bench, const bool set_dirty, const bool add_watchonly, const bool add_mine, const uint32_t epoch_iters)
static void WalletBalance(benchmark::Bench& bench, const bool set_dirty, const bool add_mine, const uint32_t epoch_iters)
{
const auto test_setup = MakeNoLogFileContext<const TestingSetup>();
const auto& ADDRESS_WATCHONLY = ADDRESS_B58T_UNSPENDABLE;

CWallet wallet{test_setup->m_node.chain.get(), test_setup->m_node.coinjoin_loader.get(), "", CreateMockWalletDatabase()};
{
wallet.SetupLegacyScriptPubKeyMan();
LOCK(wallet.cs_wallet);
wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
wallet.SetupDescriptorScriptPubKeyMans();
if (wallet.LoadWallet() != DBErrors::LOAD_OK) assert(false);
}
auto handler = test_setup->m_node.chain->handleNotifications({&wallet, [](CWallet*) {}});

const std::optional<std::string> address_mine{add_mine ? std::optional<std::string>{getnewaddress(wallet)} : std::nullopt};
if (add_watchonly) importaddress(wallet, ADDRESS_WATCHONLY);

for (int i = 0; i < 100; ++i) {
generatetoaddress(test_setup->m_node, address_mine.value_or(ADDRESS_WATCHONLY));
Expand All @@ -40,14 +41,13 @@ static void WalletBalance(benchmark::Bench& bench, const bool set_dirty, const b
if (set_dirty) wallet.MarkDirty();
bal = wallet.GetBalance();
if (add_mine) assert(bal.m_mine_trusted > 0);
if (add_watchonly) assert(bal.m_watchonly_trusted > 0);
});
}

static void WalletBalanceDirty(benchmark::Bench& bench) { WalletBalance(bench, /* set_dirty */ true, /* add_watchonly */ true, /* add_mine */ true, 2500); }
static void WalletBalanceClean(benchmark::Bench& bench) {WalletBalance(bench, /* set_dirty */ false, /* add_watchonly */ true, /* add_mine */ true, 8000); }
static void WalletBalanceMine(benchmark::Bench& bench) { WalletBalance(bench, /* set_dirty */ false, /* add_watchonly */ false, /* add_mine */ true, 16000); }
static void WalletBalanceWatch(benchmark::Bench& bench) { WalletBalance(bench, /* set_dirty */ false, /* add_watchonly */ true, /* add_mine */ false, 8000); }
static void WalletBalanceDirty(benchmark::Bench& bench) { WalletBalance(bench, /* set_dirty */ true, /* add_mine */ true, 2500); }
static void WalletBalanceClean(benchmark::Bench& bench) {WalletBalance(bench, /* set_dirty */ false, /* add_mine */ true, 8000); }
static void WalletBalanceMine(benchmark::Bench& bench) { WalletBalance(bench, /* set_dirty */ false, /* add_mine */ true, 16000); }
static void WalletBalanceWatch(benchmark::Bench& bench) { WalletBalance(bench, /* set_dirty */ false, /* add_mine */ false, 8000); }

BENCHMARK(WalletBalanceDirty);
BENCHMARK(WalletBalanceClean);
Expand Down
2 changes: 1 addition & 1 deletion src/bitcoin-cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,7 @@ static void GetWalletBalances(UniValue& result)
}

/**
* GetProgressBar contructs a progress bar with 5% intervals.
* GetProgressBar constructs a progress bar with 5% intervals.
*
* @param[in] progress The proportion of the progress bar to be filled between 0 and 1.
* @param[out] progress_bar String representation of the progress bar.
Expand Down
20 changes: 7 additions & 13 deletions src/coinjoin/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1914,14 +1914,11 @@ void CCoinJoinClientManager::GetJsonInfo(UniValue& obj) const

void CoinJoinWalletManager::Add(const std::shared_ptr<CWallet>& wallet)
{
{
LOCK(cs_wallet_manager_map);
m_wallet_manager_map.try_emplace(wallet->GetName(),
std::make_unique<CCoinJoinClientManager>(wallet, *this, m_dmnman, m_mn_metaman,
m_mn_sync, m_isman, m_queueman,
m_is_masternode));
}
g_wallet_init_interface.InitCoinJoinSettings(*this);
LOCK(cs_wallet_manager_map);
m_wallet_manager_map.try_emplace(wallet->GetName(),
std::make_unique<CCoinJoinClientManager>(wallet, *this, m_dmnman, m_mn_metaman,
m_mn_sync, m_isman, m_queueman,
m_is_masternode));
}

void CoinJoinWalletManager::DoMaintenance(CConnman& connman)
Expand All @@ -1933,11 +1930,8 @@ void CoinJoinWalletManager::DoMaintenance(CConnman& connman)
}

void CoinJoinWalletManager::Remove(const std::string& name) {
{
LOCK(cs_wallet_manager_map);
m_wallet_manager_map.erase(name);
}
g_wallet_init_interface.InitCoinJoinSettings(*this);
LOCK(cs_wallet_manager_map);
m_wallet_manager_map.erase(name);
}

void CoinJoinWalletManager::Flush(const std::string& name)
Expand Down
23 changes: 19 additions & 4 deletions src/coinjoin/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <coinjoin/client.h>
#include <wallet/wallet.h>
#include <walletinitinterface.h>

#include <memory>
#include <string>
Expand Down Expand Up @@ -62,15 +63,25 @@ class CoinJoinClientImpl : public interfaces::CoinJoin::Client
class CoinJoinLoaderImpl : public interfaces::CoinJoin::Loader
{
CoinJoinWalletManager& m_walletman;
interfaces::WalletLoader& m_wallet_loader;

public:
explicit CoinJoinLoaderImpl(CoinJoinWalletManager& walletman)
: m_walletman(walletman) {}
explicit CoinJoinLoaderImpl(CoinJoinWalletManager& walletman, interfaces::WalletLoader& wallet_loader) :
m_walletman{walletman},
m_wallet_loader{wallet_loader}
{
g_wallet_init_interface.InitCoinJoinSettings(m_wallet_loader, m_walletman);
}

void AddWallet(const std::shared_ptr<CWallet>& wallet) override { m_walletman.Add(wallet); }
void AddWallet(const std::shared_ptr<CWallet>& wallet) override
{
m_walletman.Add(wallet);
g_wallet_init_interface.InitCoinJoinSettings(m_wallet_loader, m_walletman);
}
void RemoveWallet(const std::string& name) override
{
m_walletman.Remove(name);
g_wallet_init_interface.InitCoinJoinSettings(m_wallet_loader, m_walletman);
}
void FlushWallet(const std::string& name) override
{
Expand All @@ -91,5 +102,9 @@ class CoinJoinLoaderImpl : public interfaces::CoinJoin::Loader
} // namespace coinjoin

namespace interfaces {
std::unique_ptr<CoinJoin::Loader> MakeCoinJoinLoader(CoinJoinWalletManager& walletman) { return std::make_unique<coinjoin::CoinJoinLoaderImpl>(walletman); }
std::unique_ptr<CoinJoin::Loader> MakeCoinJoinLoader(CoinJoinWalletManager& walletman,
interfaces::WalletLoader& wallet_loader)
{
return std::make_unique<coinjoin::CoinJoinLoaderImpl>(walletman, wallet_loader);
}
} // namespace interfaces
6 changes: 4 additions & 2 deletions src/dummywallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace interfaces {
class Chain;
class Handler;
class Wallet;
class WalletLoader;
}

class DummyWalletInit : public WalletInitInterface {
Expand All @@ -23,15 +24,16 @@ class DummyWalletInit : public WalletInitInterface {
void Construct(NodeContext& node) const override {LogPrintf("No wallet support compiled in!\n");}

// Dash Specific WalletInitInterface InitCoinJoinSettings
void AutoLockMasternodeCollaterals() const override {}
void InitCoinJoinSettings(const CoinJoinWalletManager& cjwalletman) const override {}
void AutoLockMasternodeCollaterals(interfaces::WalletLoader& wallet_loader) const override {}
void InitCoinJoinSettings(interfaces::WalletLoader& wallet_loader, const CoinJoinWalletManager& cjwalletman) const override {}
bool InitAutoBackup() const override {return true;}
};

void DummyWalletInit::AddWalletOptions(ArgsManager& argsman) const
{
argsman.AddHiddenArgs({
"-avoidpartialspends",
"-consolidatefeerate=<amt>",
"-createwalletbackups=<n>",
"-disablewallet",
"-instantsendnotify=<cmd>",
Expand Down
30 changes: 27 additions & 3 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@
#include <httpserver.h>
#include <httprpc.h>
#include <init/common.h>
#include <interfaces/chain.h>
#include <index/blockfilterindex.h>
#include <index/coinstatsindex.h>
#include <index/txindex.h>
#include <interfaces/chain.h>
#include <interfaces/node.h>
#include <interfaces/wallet.h>
#include <mapport.h>
#include <node/miner.h>
#include <net.h>
Expand Down Expand Up @@ -1512,6 +1513,23 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
for (const auto& client : node.chain_clients) {
client->registerRpcs();
}
#ifdef ENABLE_WALLET
// Register non-core wallet-only RPC commands. These are commands that
// aren't a part of the wallet library but heavily rely on wallet logic.
// TODO: Move them to chain client interfaces so they can be called
// with registerRpcs()
if (!args.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
for (const auto& commands : {
GetWalletCoinJoinRPCCommands(),
GetWalletEvoRPCCommands(),
GetWalletGovernanceRPCCommands(),
GetWalletMasternodeRPCCommands(),
}) {
node.wallet_loader->registerOtherRpcs(commands);
}
}
#endif // ENABLE_WALLET

#if ENABLE_ZMQ
RegisterZMQRPCCommands(tableRPC);
#endif
Expand Down Expand Up @@ -2028,8 +2046,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
!ignores_incoming_txs);

#ifdef ENABLE_WALLET
node.coinjoin_loader = interfaces::MakeCoinJoinLoader(*node.cj_ctx->walletman);
g_wallet_init_interface.InitCoinJoinSettings(*node.cj_ctx->walletman);
if (!args.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
node.coinjoin_loader = interfaces::MakeCoinJoinLoader(*node.cj_ctx->walletman, *node.wallet_loader);
}
#endif // ENABLE_WALLET

// ********************************************************* Step 7d: Setup other Dash services
Expand Down Expand Up @@ -2206,6 +2225,11 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
chainman.m_load_block = std::thread(&util::TraceThread, "loadblk", [=, &args, &chainman, &node] {
ThreadImport(chainman, *node.dmnman, *g_ds_notification_interface, vImportFiles, node.mn_activeman.get(), args);
});
#ifdef ENABLE_WALLET
if (!args.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
g_wallet_init_interface.AutoLockMasternodeCollaterals(*node.wallet_loader);
}
#endif // ENABLE_WALLET

// Wait for genesis block to be processed
{
Expand Down
5 changes: 4 additions & 1 deletion src/interfaces/coinjoin.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

class CoinJoinWalletManager;
class CWallet;
namespace interfaces {
class WalletLoader;
}

namespace interfaces {
namespace CoinJoin {
Expand Down Expand Up @@ -42,7 +45,7 @@ class Loader
};
} // namespace CoinJoin

std::unique_ptr<CoinJoin::Loader> MakeCoinJoinLoader(CoinJoinWalletManager& walletman);
std::unique_ptr<CoinJoin::Loader> MakeCoinJoinLoader(CoinJoinWalletManager& walletman, interfaces::WalletLoader& wallet_loader);

} // namespace interfaces

Expand Down
Loading
Loading