mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 20:03:34 -03:00
Merge bitcoin/bitcoin#20773: refactor: split CWallet::Create
489ebb7b34
wallet: make chain optional for CWallet::Create (Ivan Metlushko)d73ae93964
CWallet::Create move chain init message up into calling code (Ivan Metlushko)44c430ffac
refactor: Add CWallet:::AttachChain method (Russell Yanofsky)e2a47ce085
refactor: move first run detection to client code (Ivan Metlushko) Pull request description: This is a followup for https://github.com/bitcoin/bitcoin/pull/20365#discussion_r522265003 First part of a refactoring with overall goal to simplify `CWallet` and de-duplicate code with `wallettool` **Rationale**: split `CWallet::Create` and create `CWallet::AttachChain`. `CWallet::AttachChain` takes chain as first parameter on purpose. In future I suggest we can remove `chain` from `CWallet` constructor. The second commit is based on be164f9cf89b123f03b926aa980996919924ee64 from #15719 (thanks ryanofsky) cc ryanofsky achow101 ACKs for top commit: ryanofsky: Code review ACK489ebb7b34
. Only changes since last review were adding a const variable declaration, and implementing suggestion not to move feerate option checks to AttachChain. Thanks for updates and fast responses! Tree-SHA512: 00235abfe1b00874c56c449adcab8a36582424abb9ba27440bf750af8f3f217b68c11ca74eb30f78a2109ad1d9009315480effc78345e16a3074a1b5d8128721
This commit is contained in:
commit
d4c409cf09
11 changed files with 93 additions and 68 deletions
|
@ -22,8 +22,7 @@ static void WalletBalance(benchmark::Bench& bench, const bool set_dirty, const b
|
|||
CWallet wallet{test_setup->m_node.chain.get(), "", CreateMockWalletDatabase()};
|
||||
{
|
||||
wallet.SetupLegacyScriptPubKeyMan();
|
||||
bool first_run;
|
||||
if (wallet.LoadWallet(first_run) != DBErrors::LOAD_OK) assert(false);
|
||||
if (wallet.LoadWallet() != DBErrors::LOAD_OK) assert(false);
|
||||
}
|
||||
auto handler = test_setup->m_node.chain->handleNotifications({&wallet, [](CWallet*) {}});
|
||||
|
||||
|
|
|
@ -63,8 +63,7 @@ void TestAddAddressesToSendBook(interfaces::Node& node)
|
|||
node.setContext(&test.m_node);
|
||||
std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(node.context()->chain.get(), "", CreateMockWalletDatabase());
|
||||
wallet->SetupLegacyScriptPubKeyMan();
|
||||
bool firstRun;
|
||||
wallet->LoadWallet(firstRun);
|
||||
wallet->LoadWallet();
|
||||
|
||||
auto build_address = [&wallet]() {
|
||||
CKey key;
|
||||
|
|
|
@ -140,8 +140,7 @@ void TestGUI(interfaces::Node& node)
|
|||
}
|
||||
node.setContext(&test.m_node);
|
||||
std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(node.context()->chain.get(), "", CreateMockWalletDatabase());
|
||||
bool firstRun;
|
||||
wallet->LoadWallet(firstRun);
|
||||
wallet->LoadWallet();
|
||||
{
|
||||
auto spk_man = wallet->GetOrCreateLegacyScriptPubKeyMan();
|
||||
LOCK2(wallet->cs_wallet, spk_man->cs_KeyStore);
|
||||
|
|
|
@ -194,8 +194,7 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling
|
|||
std::shared_ptr<CWallet> wallet(new CWallet(nullptr /* chain */, name, std::move(database)), WalletToolReleaseWallet);
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
bool first_run = true;
|
||||
DBErrors load_wallet_ret = wallet->LoadWallet(first_run);
|
||||
DBErrors load_wallet_ret = wallet->LoadWallet();
|
||||
if (load_wallet_ret != DBErrors::LOAD_OK) {
|
||||
error = strprintf(_("Error creating %s"), name);
|
||||
return false;
|
||||
|
|
|
@ -105,7 +105,8 @@ bool LoadWallets(interfaces::Chain& chain)
|
|||
if (!database && status == DatabaseStatus::FAILED_NOT_FOUND) {
|
||||
continue;
|
||||
}
|
||||
std::shared_ptr<CWallet> pwallet = database ? CWallet::Create(chain, name, std::move(database), options.create_flags, error, warnings) : nullptr;
|
||||
chain.initMessage(_("Loading wallet...").translated);
|
||||
std::shared_ptr<CWallet> pwallet = database ? CWallet::Create(&chain, name, std::move(database), options.create_flags, error, warnings) : nullptr;
|
||||
if (!warnings.empty()) chain.initWarning(Join(warnings, Untranslated("\n")));
|
||||
if (!pwallet) {
|
||||
chain.initError(error);
|
||||
|
|
|
@ -297,8 +297,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
|
|||
empty_wallet();
|
||||
{
|
||||
std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(m_node.chain.get(), "", CreateMockWalletDatabase());
|
||||
bool firstRun;
|
||||
wallet->LoadWallet(firstRun);
|
||||
wallet->LoadWallet();
|
||||
wallet->SetupLegacyScriptPubKeyMan();
|
||||
LOCK(wallet->cs_wallet);
|
||||
add_coin(*wallet, 5 * CENT, 6 * 24, false, 0, true);
|
||||
|
|
|
@ -8,8 +8,7 @@ WalletTestingSetup::WalletTestingSetup(const std::string& chainName)
|
|||
: TestingSetup(chainName),
|
||||
m_wallet(m_node.chain.get(), "", CreateMockWalletDatabase())
|
||||
{
|
||||
bool fFirstRun;
|
||||
m_wallet.LoadWallet(fFirstRun);
|
||||
m_wallet.LoadWallet();
|
||||
m_chain_notifications_handler = m_node.chain->handleNotifications({ &m_wallet, [](CWallet*) {} });
|
||||
m_wallet_client->registerRpcs();
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ static_assert(WALLET_INCREMENTAL_RELAY_FEE >= DEFAULT_INCREMENTAL_RELAY_FEE, "wa
|
|||
|
||||
BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup)
|
||||
|
||||
static std::shared_ptr<CWallet> TestLoadWallet(interfaces::Chain& chain)
|
||||
static std::shared_ptr<CWallet> TestLoadWallet(interfaces::Chain* chain)
|
||||
{
|
||||
DatabaseOptions options;
|
||||
DatabaseStatus status;
|
||||
|
@ -46,7 +46,9 @@ static std::shared_ptr<CWallet> TestLoadWallet(interfaces::Chain& chain)
|
|||
std::vector<bilingual_str> warnings;
|
||||
auto database = MakeWalletDatabase("", options, status, error);
|
||||
auto wallet = CWallet::Create(chain, "", std::move(database), options.create_flags, error, warnings);
|
||||
wallet->postInitProcess();
|
||||
if (chain) {
|
||||
wallet->postInitProcess();
|
||||
}
|
||||
return wallet;
|
||||
}
|
||||
|
||||
|
@ -483,8 +485,7 @@ public:
|
|||
LOCK2(wallet->cs_wallet, ::cs_main);
|
||||
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
|
||||
}
|
||||
bool firstRun;
|
||||
wallet->LoadWallet(firstRun);
|
||||
wallet->LoadWallet();
|
||||
AddKey(*wallet, coinbaseKey);
|
||||
WalletRescanReserver reserver(*wallet);
|
||||
reserver.reserve();
|
||||
|
@ -690,7 +691,7 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
|
|||
{
|
||||
gArgs.ForceSetArg("-unsafesqlitesync", "1");
|
||||
// Create new wallet with known key and unload it.
|
||||
auto wallet = TestLoadWallet(*m_node.chain);
|
||||
auto wallet = TestLoadWallet(m_node.chain.get());
|
||||
CKey key;
|
||||
key.MakeNewKey(true);
|
||||
AddKey(*wallet, key);
|
||||
|
@ -730,7 +731,7 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
|
|||
|
||||
// Reload wallet and make sure new transactions are detected despite events
|
||||
// being blocked
|
||||
wallet = TestLoadWallet(*m_node.chain);
|
||||
wallet = TestLoadWallet(m_node.chain.get());
|
||||
BOOST_CHECK(rescan_completed);
|
||||
BOOST_CHECK_EQUAL(addtx_count, 2);
|
||||
{
|
||||
|
@ -770,7 +771,7 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
|
|||
ENTER_CRITICAL_SECTION(wallet->wallet()->cs_wallet);
|
||||
ENTER_CRITICAL_SECTION(cs_wallets);
|
||||
});
|
||||
wallet = TestLoadWallet(*m_node.chain);
|
||||
wallet = TestLoadWallet(m_node.chain.get());
|
||||
BOOST_CHECK_EQUAL(addtx_count, 4);
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
|
@ -782,10 +783,17 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
|
|||
TestUnloadWallet(std::move(wallet));
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(CreateWalletWithoutChain, BasicTestingSetup)
|
||||
{
|
||||
auto wallet = TestLoadWallet(nullptr);
|
||||
BOOST_CHECK(wallet);
|
||||
UnloadWallet(std::move(wallet));
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(ZapSelectTx, TestChain100Setup)
|
||||
{
|
||||
gArgs.ForceSetArg("-unsafesqlitesync", "1");
|
||||
auto wallet = TestLoadWallet(*m_node.chain);
|
||||
auto wallet = TestLoadWallet(m_node.chain.get());
|
||||
CKey key;
|
||||
key.MakeNewKey(true);
|
||||
AddKey(*wallet, key);
|
||||
|
|
|
@ -213,7 +213,8 @@ std::shared_ptr<CWallet> LoadWalletInternal(interfaces::Chain& chain, const std:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<CWallet> wallet = CWallet::Create(chain, name, std::move(database), options.create_flags, error, warnings);
|
||||
chain.initMessage(_("Loading wallet...").translated);
|
||||
std::shared_ptr<CWallet> wallet = CWallet::Create(&chain, name, std::move(database), options.create_flags, error, warnings);
|
||||
if (!wallet) {
|
||||
error = Untranslated("Wallet loading failed.") + Untranslated(" ") + error;
|
||||
status = DatabaseStatus::FAILED_LOAD;
|
||||
|
@ -292,7 +293,8 @@ std::shared_ptr<CWallet> CreateWallet(interfaces::Chain& chain, const std::strin
|
|||
}
|
||||
|
||||
// Make the wallet
|
||||
std::shared_ptr<CWallet> wallet = CWallet::Create(chain, name, std::move(database), wallet_creation_flags, error, warnings);
|
||||
chain.initMessage(_("Loading wallet...").translated);
|
||||
std::shared_ptr<CWallet> wallet = CWallet::Create(&chain, name, std::move(database), wallet_creation_flags, error, warnings);
|
||||
if (!wallet) {
|
||||
error = Untranslated("Wallet creation failed.") + Untranslated(" ") + error;
|
||||
status = DatabaseStatus::FAILED_CREATE;
|
||||
|
@ -3247,11 +3249,10 @@ void CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
|
|||
}
|
||||
}
|
||||
|
||||
DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
|
||||
DBErrors CWallet::LoadWallet()
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
|
||||
fFirstRunRet = false;
|
||||
DBErrors nLoadWalletRet = WalletBatch(GetDatabase()).LoadWallet(this);
|
||||
if (nLoadWalletRet == DBErrors::NEED_REWRITE)
|
||||
{
|
||||
|
@ -3263,9 +3264,7 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
|
|||
}
|
||||
}
|
||||
|
||||
// This wallet is in its first run if there are no ScriptPubKeyMans and it isn't blank or no privkeys
|
||||
fFirstRunRet = m_spk_managers.empty() && !IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && !IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET);
|
||||
if (fFirstRunRet) {
|
||||
if (m_spk_managers.empty()) {
|
||||
assert(m_external_spk_managers.empty());
|
||||
assert(m_internal_spk_managers.empty());
|
||||
}
|
||||
|
@ -3886,18 +3885,15 @@ std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, cons
|
|||
return MakeDatabase(wallet_path, options, status, error_string);
|
||||
}
|
||||
|
||||
std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain& chain, const std::string& name, std::unique_ptr<WalletDatabase> database, uint64_t wallet_creation_flags, bilingual_str& error, std::vector<bilingual_str>& warnings)
|
||||
std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain* chain, const std::string& name, std::unique_ptr<WalletDatabase> database, uint64_t wallet_creation_flags, bilingual_str& error, std::vector<bilingual_str>& warnings)
|
||||
{
|
||||
const std::string& walletFile = database->Filename();
|
||||
|
||||
chain.initMessage(_("Loading wallet…").translated);
|
||||
|
||||
int64_t nStart = GetTimeMillis();
|
||||
bool fFirstRun = true;
|
||||
// TODO: Can't use std::make_shared because we need a custom deleter but
|
||||
// should be possible to use std::allocate_shared.
|
||||
std::shared_ptr<CWallet> walletInstance(new CWallet(&chain, name, std::move(database)), ReleaseWallet);
|
||||
DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
|
||||
std::shared_ptr<CWallet> walletInstance(new CWallet(chain, name, std::move(database)), ReleaseWallet);
|
||||
DBErrors nLoadWalletRet = walletInstance->LoadWallet();
|
||||
if (nLoadWalletRet != DBErrors::LOAD_OK) {
|
||||
if (nLoadWalletRet == DBErrors::CORRUPT) {
|
||||
error = strprintf(_("Error loading %s: Wallet corrupted"), walletFile);
|
||||
|
@ -3924,6 +3920,10 @@ std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain& chain, const std::st
|
|||
}
|
||||
}
|
||||
|
||||
// This wallet is in its first run if there are no ScriptPubKeyMans and it isn't blank or no privkeys
|
||||
const bool fFirstRun = walletInstance->m_spk_managers.empty() &&
|
||||
!walletInstance->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) &&
|
||||
!walletInstance->IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET);
|
||||
if (fFirstRun)
|
||||
{
|
||||
// ensure this wallet.dat can only be opened by clients supporting HD with chain split and expects no default key
|
||||
|
@ -3952,7 +3952,9 @@ std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain& chain, const std::st
|
|||
}
|
||||
}
|
||||
|
||||
walletInstance->chainStateFlushed(chain.getTipLocator());
|
||||
if (chain) {
|
||||
walletInstance->chainStateFlushed(chain->getTipLocator());
|
||||
}
|
||||
} else if (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS) {
|
||||
// Make it impossible to disable private keys after creation
|
||||
error = strprintf(_("Error loading %s: Private keys can only be disabled during creation"), walletFile);
|
||||
|
@ -4049,9 +4051,9 @@ std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain& chain, const std::st
|
|||
_("This is the transaction fee you will pay if you send a transaction."));
|
||||
}
|
||||
walletInstance->m_pay_tx_fee = CFeeRate(nFeePerK, 1000);
|
||||
if (walletInstance->m_pay_tx_fee < chain.relayMinFee()) {
|
||||
if (chain && walletInstance->m_pay_tx_fee < chain->relayMinFee()) {
|
||||
error = strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
|
||||
gArgs.GetArg("-paytxfee", ""), chain.relayMinFee().ToString());
|
||||
gArgs.GetArg("-paytxfee", ""), chain->relayMinFee().ToString());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -4065,15 +4067,15 @@ std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain& chain, const std::st
|
|||
if (nMaxFee > HIGH_MAX_TX_FEE) {
|
||||
warnings.push_back(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction."));
|
||||
}
|
||||
if (CFeeRate(nMaxFee, 1000) < chain.relayMinFee()) {
|
||||
if (chain && CFeeRate(nMaxFee, 1000) < chain->relayMinFee()) {
|
||||
error = strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
|
||||
gArgs.GetArg("-maxtxfee", ""), chain.relayMinFee().ToString());
|
||||
gArgs.GetArg("-maxtxfee", ""), chain->relayMinFee().ToString());
|
||||
return nullptr;
|
||||
}
|
||||
walletInstance->m_default_max_tx_fee = nMaxFee;
|
||||
}
|
||||
|
||||
if (chain.relayMinFee().GetFeePerK() > HIGH_TX_FEE_PER_KB) {
|
||||
if (chain && chain->relayMinFee().GetFeePerK() > HIGH_TX_FEE_PER_KB) {
|
||||
warnings.push_back(AmountHighWarn("-minrelaytxfee") + Untranslated(" ") +
|
||||
_("The wallet will avoid paying less than the minimum relay fee."));
|
||||
}
|
||||
|
@ -4089,6 +4091,35 @@ std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain& chain, const std::st
|
|||
|
||||
LOCK(walletInstance->cs_wallet);
|
||||
|
||||
if (chain && !AttachChain(walletInstance, *chain, error, warnings)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
{
|
||||
LOCK(cs_wallets);
|
||||
for (auto& load_wallet : g_load_wallet_fns) {
|
||||
load_wallet(interfaces::MakeWallet(walletInstance));
|
||||
}
|
||||
}
|
||||
|
||||
walletInstance->SetBroadcastTransactions(gArgs.GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));
|
||||
|
||||
{
|
||||
walletInstance->WalletLogPrintf("setKeyPool.size() = %u\n", walletInstance->GetKeyPoolSize());
|
||||
walletInstance->WalletLogPrintf("mapWallet.size() = %u\n", walletInstance->mapWallet.size());
|
||||
walletInstance->WalletLogPrintf("m_address_book.size() = %u\n", walletInstance->m_address_book.size());
|
||||
}
|
||||
|
||||
return walletInstance;
|
||||
}
|
||||
|
||||
bool CWallet::AttachChain(const std::shared_ptr<CWallet>& walletInstance, interfaces::Chain& chain, bilingual_str& error, std::vector<bilingual_str>& warnings)
|
||||
{
|
||||
LOCK(walletInstance->cs_wallet);
|
||||
// allow setting the chain if it hasn't been set already but prevent changing it
|
||||
assert(!walletInstance->m_chain || walletInstance->m_chain == &chain);
|
||||
walletInstance->m_chain = &chain;
|
||||
|
||||
// Register wallet with validationinterface. It's done before rescan to avoid
|
||||
// missing block connections between end of rescan and validation subscribing.
|
||||
// Because of wallet lock being hold, block connection notifications are going to
|
||||
|
@ -4122,21 +4153,21 @@ std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain& chain, const std::st
|
|||
|
||||
if (tip_height && *tip_height != rescan_height)
|
||||
{
|
||||
// We can't rescan beyond non-pruned blocks, stop and throw an error.
|
||||
// This might happen if a user uses an old wallet within a pruned node
|
||||
// or if they ran -disablewallet for a longer time, then decided to re-enable
|
||||
if (chain.havePruned()) {
|
||||
// Exit early and print an error.
|
||||
// If a block is pruned after this check, we will load the wallet,
|
||||
// but fail the rescan with a generic error.
|
||||
int block_height = *tip_height;
|
||||
while (block_height > 0 && chain.haveBlockOnDisk(block_height - 1) && rescan_height != block_height) {
|
||||
--block_height;
|
||||
}
|
||||
|
||||
if (rescan_height != block_height) {
|
||||
// We can't rescan beyond non-pruned blocks, stop and throw an error.
|
||||
// This might happen if a user uses an old wallet within a pruned node
|
||||
// or if they ran -disablewallet for a longer time, then decided to re-enable
|
||||
// Exit early and print an error.
|
||||
// If a block is pruned after this check, we will load the wallet,
|
||||
// but fail the rescan with a generic error.
|
||||
error = _("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)");
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4158,29 +4189,14 @@ std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain& chain, const std::st
|
|||
WalletRescanReserver reserver(*walletInstance);
|
||||
if (!reserver.reserve() || (ScanResult::SUCCESS != walletInstance->ScanForWalletTransactions(chain.getBlockHash(rescan_height), rescan_height, {} /* max height */, reserver, true /* update */).status)) {
|
||||
error = _("Failed to rescan the wallet during initialization");
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
walletInstance->chainStateFlushed(chain.getTipLocator());
|
||||
walletInstance->GetDatabase().IncrementUpdateCounter();
|
||||
}
|
||||
|
||||
{
|
||||
LOCK(cs_wallets);
|
||||
for (auto& load_wallet : g_load_wallet_fns) {
|
||||
load_wallet(interfaces::MakeWallet(walletInstance));
|
||||
}
|
||||
}
|
||||
|
||||
walletInstance->SetBroadcastTransactions(gArgs.GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));
|
||||
|
||||
{
|
||||
walletInstance->WalletLogPrintf("setKeyPool.size() = %u\n", walletInstance->GetKeyPoolSize());
|
||||
walletInstance->WalletLogPrintf("mapWallet.size() = %u\n", walletInstance->mapWallet.size());
|
||||
walletInstance->WalletLogPrintf("m_address_book.size() = %u\n", walletInstance->m_address_book.size());
|
||||
}
|
||||
|
||||
return walletInstance;
|
||||
return true;
|
||||
}
|
||||
|
||||
const CAddressBookData* CWallet::FindAddressBookEntry(const CTxDestination& dest, bool allow_change) const
|
||||
|
|
|
@ -763,6 +763,13 @@ private:
|
|||
|
||||
bool CreateTransactionInternal(const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CAmount& nFeeRet, int& nChangePosInOut, bilingual_str& error, const CCoinControl& coin_control, FeeCalculation& fee_calc_out, bool sign);
|
||||
|
||||
/**
|
||||
* Catch wallet up to current chain, scanning new blocks, updating the best
|
||||
* block locator and m_last_block_processed, and registering for
|
||||
* notifications about new blocks and transactions.
|
||||
*/
|
||||
static bool AttachChain(const std::shared_ptr<CWallet>& wallet, interfaces::Chain& chain, bilingual_str& error, std::vector<bilingual_str>& warnings);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Main wallet lock.
|
||||
|
@ -1126,7 +1133,7 @@ public:
|
|||
CAmount GetChange(const CTransaction& tx) const;
|
||||
void chainStateFlushed(const CBlockLocator& loc) override;
|
||||
|
||||
DBErrors LoadWallet(bool& fFirstRunRet);
|
||||
DBErrors LoadWallet();
|
||||
DBErrors ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
|
||||
bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& purpose);
|
||||
|
@ -1202,7 +1209,7 @@ public:
|
|||
bool MarkReplaced(const uint256& originalHash, const uint256& newHash);
|
||||
|
||||
/* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */
|
||||
static std::shared_ptr<CWallet> Create(interfaces::Chain& chain, const std::string& name, std::unique_ptr<WalletDatabase> database, uint64_t wallet_creation_flags, bilingual_str& error, std::vector<bilingual_str>& warnings);
|
||||
static std::shared_ptr<CWallet> Create(interfaces::Chain* chain, const std::string& name, std::unique_ptr<WalletDatabase> database, uint64_t wallet_creation_flags, bilingual_str& error, std::vector<bilingual_str>& warnings);
|
||||
|
||||
/**
|
||||
* Wallet post-init setup
|
||||
|
|
|
@ -54,8 +54,7 @@ static std::shared_ptr<CWallet> MakeWallet(const std::string& name, const fs::pa
|
|||
std::shared_ptr<CWallet> wallet_instance{new CWallet(nullptr /* chain */, name, std::move(database)), WalletToolReleaseWallet};
|
||||
DBErrors load_wallet_ret;
|
||||
try {
|
||||
bool first_run;
|
||||
load_wallet_ret = wallet_instance->LoadWallet(first_run);
|
||||
load_wallet_ret = wallet_instance->LoadWallet();
|
||||
} catch (const std::runtime_error&) {
|
||||
tfm::format(std::cerr, "Error loading %s. Is wallet being used by another process?\n", name);
|
||||
return nullptr;
|
||||
|
|
Loading…
Reference in a new issue