wallet: make chain optional for CWallet::Create

pull/826/head
Ivan Metlushko 4 years ago
parent d73ae93964
commit 489ebb7b34

@ -106,7 +106,7 @@ bool LoadWallets(interfaces::Chain& chain)
continue; continue;
} }
chain.initMessage(_("Loading wallet...").translated); chain.initMessage(_("Loading wallet...").translated);
std::shared_ptr<CWallet> pwallet = database ? CWallet::Create(chain, name, std::move(database), options.create_flags, error, warnings) : nullptr; 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 (!warnings.empty()) chain.initWarning(Join(warnings, Untranslated("\n")));
if (!pwallet) { if (!pwallet) {
chain.initError(error); chain.initError(error);

@ -38,7 +38,7 @@ static_assert(WALLET_INCREMENTAL_RELAY_FEE >= DEFAULT_INCREMENTAL_RELAY_FEE, "wa
BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup) 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; DatabaseOptions options;
DatabaseStatus status; DatabaseStatus status;
@ -46,7 +46,9 @@ static std::shared_ptr<CWallet> TestLoadWallet(interfaces::Chain& chain)
std::vector<bilingual_str> warnings; std::vector<bilingual_str> warnings;
auto database = MakeWalletDatabase("", options, status, error); auto database = MakeWalletDatabase("", options, status, error);
auto wallet = CWallet::Create(chain, "", std::move(database), options.create_flags, error, warnings); auto wallet = CWallet::Create(chain, "", std::move(database), options.create_flags, error, warnings);
wallet->postInitProcess(); if (chain) {
wallet->postInitProcess();
}
return wallet; return wallet;
} }
@ -689,7 +691,7 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
{ {
gArgs.ForceSetArg("-unsafesqlitesync", "1"); gArgs.ForceSetArg("-unsafesqlitesync", "1");
// Create new wallet with known key and unload it. // Create new wallet with known key and unload it.
auto wallet = TestLoadWallet(*m_node.chain); auto wallet = TestLoadWallet(m_node.chain.get());
CKey key; CKey key;
key.MakeNewKey(true); key.MakeNewKey(true);
AddKey(*wallet, key); AddKey(*wallet, key);
@ -729,7 +731,7 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
// Reload wallet and make sure new transactions are detected despite events // Reload wallet and make sure new transactions are detected despite events
// being blocked // being blocked
wallet = TestLoadWallet(*m_node.chain); wallet = TestLoadWallet(m_node.chain.get());
BOOST_CHECK(rescan_completed); BOOST_CHECK(rescan_completed);
BOOST_CHECK_EQUAL(addtx_count, 2); BOOST_CHECK_EQUAL(addtx_count, 2);
{ {
@ -769,7 +771,7 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
ENTER_CRITICAL_SECTION(wallet->wallet()->cs_wallet); ENTER_CRITICAL_SECTION(wallet->wallet()->cs_wallet);
ENTER_CRITICAL_SECTION(cs_wallets); ENTER_CRITICAL_SECTION(cs_wallets);
}); });
wallet = TestLoadWallet(*m_node.chain); wallet = TestLoadWallet(m_node.chain.get());
BOOST_CHECK_EQUAL(addtx_count, 4); BOOST_CHECK_EQUAL(addtx_count, 4);
{ {
LOCK(wallet->cs_wallet); LOCK(wallet->cs_wallet);
@ -781,10 +783,17 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
TestUnloadWallet(std::move(wallet)); 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) BOOST_FIXTURE_TEST_CASE(ZapSelectTx, TestChain100Setup)
{ {
gArgs.ForceSetArg("-unsafesqlitesync", "1"); gArgs.ForceSetArg("-unsafesqlitesync", "1");
auto wallet = TestLoadWallet(*m_node.chain); auto wallet = TestLoadWallet(m_node.chain.get());
CKey key; CKey key;
key.MakeNewKey(true); key.MakeNewKey(true);
AddKey(*wallet, key); AddKey(*wallet, key);

@ -214,7 +214,7 @@ std::shared_ptr<CWallet> LoadWalletInternal(interfaces::Chain& chain, const std:
} }
chain.initMessage(_("Loading wallet...").translated); chain.initMessage(_("Loading wallet...").translated);
std::shared_ptr<CWallet> wallet = CWallet::Create(chain, name, std::move(database), options.create_flags, error, warnings); std::shared_ptr<CWallet> wallet = CWallet::Create(&chain, name, std::move(database), options.create_flags, error, warnings);
if (!wallet) { if (!wallet) {
error = Untranslated("Wallet loading failed.") + Untranslated(" ") + error; error = Untranslated("Wallet loading failed.") + Untranslated(" ") + error;
status = DatabaseStatus::FAILED_LOAD; status = DatabaseStatus::FAILED_LOAD;
@ -294,7 +294,7 @@ std::shared_ptr<CWallet> CreateWallet(interfaces::Chain& chain, const std::strin
// Make the wallet // Make the wallet
chain.initMessage(_("Loading wallet...").translated); chain.initMessage(_("Loading wallet...").translated);
std::shared_ptr<CWallet> wallet = CWallet::Create(chain, name, std::move(database), wallet_creation_flags, error, warnings); std::shared_ptr<CWallet> wallet = CWallet::Create(&chain, name, std::move(database), wallet_creation_flags, error, warnings);
if (!wallet) { if (!wallet) {
error = Untranslated("Wallet creation failed.") + Untranslated(" ") + error; error = Untranslated("Wallet creation failed.") + Untranslated(" ") + error;
status = DatabaseStatus::FAILED_CREATE; status = DatabaseStatus::FAILED_CREATE;
@ -3885,14 +3885,14 @@ std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, cons
return MakeDatabase(wallet_path, options, status, error_string); 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(); const std::string& walletFile = database->Filename();
int64_t nStart = GetTimeMillis(); int64_t nStart = GetTimeMillis();
// TODO: Can't use std::make_shared because we need a custom deleter but // TODO: Can't use std::make_shared because we need a custom deleter but
// should be possible to use std::allocate_shared. // should be possible to use std::allocate_shared.
std::shared_ptr<CWallet> walletInstance(new CWallet(&chain, name, std::move(database)), ReleaseWallet); std::shared_ptr<CWallet> walletInstance(new CWallet(chain, name, std::move(database)), ReleaseWallet);
DBErrors nLoadWalletRet = walletInstance->LoadWallet(); DBErrors nLoadWalletRet = walletInstance->LoadWallet();
if (nLoadWalletRet != DBErrors::LOAD_OK) { if (nLoadWalletRet != DBErrors::LOAD_OK) {
if (nLoadWalletRet == DBErrors::CORRUPT) { if (nLoadWalletRet == DBErrors::CORRUPT) {
@ -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) { } else if (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS) {
// Make it impossible to disable private keys after creation // Make it impossible to disable private keys after creation
error = strprintf(_("Error loading %s: Private keys can only be disabled during creation"), walletFile); 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.")); _("This is the transaction fee you will pay if you send a transaction."));
} }
walletInstance->m_pay_tx_fee = CFeeRate(nFeePerK, 1000); 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)"), 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; return nullptr;
} }
} }
@ -4065,15 +4067,15 @@ std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain& chain, const std::st
if (nMaxFee > HIGH_MAX_TX_FEE) { if (nMaxFee > HIGH_MAX_TX_FEE) {
warnings.push_back(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); 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)"), 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; return nullptr;
} }
walletInstance->m_default_max_tx_fee = nMaxFee; 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(" ") + warnings.push_back(AmountHighWarn("-minrelaytxfee") + Untranslated(" ") +
_("The wallet will avoid paying less than the minimum relay fee.")); _("The wallet will avoid paying less than the minimum relay fee."));
} }
@ -4089,7 +4091,7 @@ std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain& chain, const std::st
LOCK(walletInstance->cs_wallet); LOCK(walletInstance->cs_wallet);
if (!AttachChain(walletInstance, chain, error, warnings)) { if (chain && !AttachChain(walletInstance, *chain, error, warnings)) {
return nullptr; return nullptr;
} }

@ -1209,7 +1209,7 @@ public:
bool MarkReplaced(const uint256& originalHash, const uint256& newHash); 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 */ /* 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 * Wallet post-init setup

Loading…
Cancel
Save