Merge #7577: [Wallet] move "load wallet phase" to CWallet
15e6e13 [Wallet] optimize return value of InitLoadWallet() (Jonas Schnelli) fc7c60d [Wallet] move "load wallet phase" to CWallet (Jonas Schnelli)
This commit is contained in:
parent
8be396a3b8
commit
b3525b2e67
185
src/init.cpp
185
src/init.cpp
@ -1653,182 +1653,19 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
pwalletMain = NULL;
|
pwalletMain = NULL;
|
||||||
LogPrintf("Wallet disabled!\n");
|
LogPrintf("Wallet disabled!\n");
|
||||||
} else {
|
} else {
|
||||||
|
std::string warningString;
|
||||||
// needed to restore wallet transaction meta data after -zapwallettxes
|
std::string errorString;
|
||||||
std::vector<CWalletTx> vWtx;
|
pwalletMain = CWallet::InitLoadWallet(fDisableWallet, strWalletFile, warningString, errorString);
|
||||||
|
if (!warningString.empty())
|
||||||
if (GetBoolArg("-zapwallettxes", false)) {
|
InitWarning(warningString);
|
||||||
uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
|
if (!errorString.empty())
|
||||||
|
{
|
||||||
pwalletMain = new CWallet(strWalletFile);
|
LogPrintf("%s", errorString);
|
||||||
DBErrors nZapWalletRet = pwalletMain->ZapWalletTx(vWtx);
|
return InitError(errorString);
|
||||||
if (nZapWalletRet != DB_LOAD_OK) {
|
}
|
||||||
uiInterface.InitMessage(_("Error loading wallet.dat: Wallet corrupted"));
|
if (!pwalletMain)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete pwalletMain;
|
|
||||||
pwalletMain = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
uiInterface.InitMessage(_("Loading wallet..."));
|
|
||||||
|
|
||||||
nStart = GetTimeMillis();
|
|
||||||
bool fFirstRun = true;
|
|
||||||
pwalletMain = new CWallet(strWalletFile);
|
|
||||||
DBErrors nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun);
|
|
||||||
if (nLoadWalletRet != DB_LOAD_OK)
|
|
||||||
{
|
|
||||||
if (nLoadWalletRet == DB_CORRUPT)
|
|
||||||
strErrors << _("Error loading wallet.dat: Wallet corrupted") << "\n";
|
|
||||||
else if (nLoadWalletRet == DB_NONCRITICAL_ERROR)
|
|
||||||
{
|
|
||||||
InitWarning(_("Error reading wallet.dat! All keys read correctly, but transaction data"
|
|
||||||
" or address book entries might be missing or incorrect."));
|
|
||||||
}
|
|
||||||
else if (nLoadWalletRet == DB_TOO_NEW)
|
|
||||||
strErrors << strprintf(_("Error loading wallet.dat: Wallet requires newer version of %s"), _(PACKAGE_NAME)) << "\n";
|
|
||||||
else if (nLoadWalletRet == DB_NEED_REWRITE)
|
|
||||||
{
|
|
||||||
strErrors << strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)) << "\n";
|
|
||||||
LogPrintf("%s", strErrors.str());
|
|
||||||
return InitError(strErrors.str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
strErrors << _("Error loading wallet.dat") << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetBoolArg("-upgradewallet", fFirstRun))
|
|
||||||
{
|
|
||||||
int nMaxVersion = GetArg("-upgradewallet", 0);
|
|
||||||
if (nMaxVersion == 0) // the -upgradewallet without argument case
|
|
||||||
{
|
|
||||||
LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
|
|
||||||
nMaxVersion = CLIENT_VERSION;
|
|
||||||
pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
|
|
||||||
}
|
|
||||||
else
|
|
||||||
LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
|
|
||||||
if (nMaxVersion < pwalletMain->GetVersion())
|
|
||||||
strErrors << _("Cannot downgrade wallet") << "\n";
|
|
||||||
pwalletMain->SetMaxVersion(nMaxVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fFirstRun)
|
|
||||||
{
|
|
||||||
// Create new keyUser and set as default key
|
|
||||||
RandAddSeedPerfmon();
|
|
||||||
|
|
||||||
if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && !pwalletMain->IsHDEnabled()) {
|
|
||||||
if (GetArg("-mnemonicpassphrase", "").size() > 256)
|
|
||||||
return InitError(_("Mnemonic passphrase is too long, must be at most 256 characters"));
|
|
||||||
// generate a new master key
|
|
||||||
pwalletMain->GenerateNewHDChain();
|
|
||||||
|
|
||||||
// ensure this wallet.dat can only be opened by clients supporting HD
|
|
||||||
pwalletMain->SetMinVersion(FEATURE_HD);
|
|
||||||
}
|
|
||||||
|
|
||||||
CPubKey newDefaultKey;
|
|
||||||
if (pwalletMain->GetKeyFromPool(newDefaultKey, false)) {
|
|
||||||
pwalletMain->SetDefaultKey(newDefaultKey);
|
|
||||||
if (!pwalletMain->SetAddressBook(pwalletMain->vchDefaultKey.GetID(), "", "receive"))
|
|
||||||
strErrors << _("Cannot write default address") << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
pwalletMain->SetBestChain(chainActive.GetLocator());
|
|
||||||
|
|
||||||
// Try to create wallet backup right after new wallet was created
|
|
||||||
std::string strBackupWarning;
|
|
||||||
std::string strBackupError;
|
|
||||||
if(!AutoBackupWallet(pwalletMain, "", strBackupWarning, strBackupError)) {
|
|
||||||
if (!strBackupWarning.empty())
|
|
||||||
InitWarning(strBackupWarning);
|
|
||||||
if (!strBackupError.empty())
|
|
||||||
return InitError(strBackupError);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (mapArgs.count("-usehd")) {
|
|
||||||
bool useHD = GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET);
|
|
||||||
if (pwalletMain->IsHDEnabled() && !useHD)
|
|
||||||
return InitError(strprintf(_("Error loading %s: You can't disable HD on a already existing HD wallet"), strWalletFile));
|
|
||||||
if (!pwalletMain->IsHDEnabled() && useHD)
|
|
||||||
return InitError(strprintf(_("Error loading %s: You can't enable HD on a already existing non-HD wallet"), strWalletFile));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warn user every time he starts non-encrypted HD wallet
|
|
||||||
if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && !pwalletMain->IsLocked()) {
|
|
||||||
InitWarning(_("Make sure to encrypt your wallet and delete all non-encrypted backups after you verified that wallet works!"));
|
|
||||||
}
|
|
||||||
|
|
||||||
LogPrintf("%s", strErrors.str());
|
|
||||||
LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart);
|
|
||||||
|
|
||||||
RegisterValidationInterface(pwalletMain);
|
|
||||||
|
|
||||||
CBlockIndex *pindexRescan = chainActive.Tip();
|
|
||||||
if (GetBoolArg("-rescan", false))
|
|
||||||
pindexRescan = chainActive.Genesis();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CWalletDB walletdb(strWalletFile);
|
|
||||||
CBlockLocator locator;
|
|
||||||
if (walletdb.ReadBestBlock(locator))
|
|
||||||
pindexRescan = FindForkInGlobalIndex(chainActive, locator);
|
|
||||||
else
|
|
||||||
pindexRescan = chainActive.Genesis();
|
|
||||||
}
|
|
||||||
if (chainActive.Tip() && chainActive.Tip() != pindexRescan)
|
|
||||||
{
|
|
||||||
//We can't rescan beyond non-pruned blocks, stop and throw an error
|
|
||||||
//this might happen if a user uses a old wallet within a pruned node
|
|
||||||
// or if he ran -disablewallet for a longer time, then decided to re-enable
|
|
||||||
if (fPruneMode)
|
|
||||||
{
|
|
||||||
CBlockIndex *block = chainActive.Tip();
|
|
||||||
while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA) && block->pprev->nTx > 0 && pindexRescan != block)
|
|
||||||
block = block->pprev;
|
|
||||||
|
|
||||||
if (pindexRescan != block)
|
|
||||||
return InitError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)"));
|
|
||||||
}
|
|
||||||
|
|
||||||
uiInterface.InitMessage(_("Rescanning..."));
|
|
||||||
LogPrintf("Rescanning last %i blocks (from block %i)...\n", chainActive.Height() - pindexRescan->nHeight, pindexRescan->nHeight);
|
|
||||||
nStart = GetTimeMillis();
|
|
||||||
pwalletMain->ScanForWalletTransactions(pindexRescan, true);
|
|
||||||
LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart);
|
|
||||||
pwalletMain->SetBestChain(chainActive.GetLocator());
|
|
||||||
nWalletDBUpdated++;
|
|
||||||
|
|
||||||
// Restore wallet transaction metadata after -zapwallettxes=1
|
|
||||||
if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2")
|
|
||||||
{
|
|
||||||
CWalletDB walletdb(strWalletFile);
|
|
||||||
|
|
||||||
BOOST_FOREACH(const CWalletTx& wtxOld, vWtx)
|
|
||||||
{
|
|
||||||
uint256 hash = wtxOld.GetHash();
|
|
||||||
std::map<uint256, CWalletTx>::iterator mi = pwalletMain->mapWallet.find(hash);
|
|
||||||
if (mi != pwalletMain->mapWallet.end())
|
|
||||||
{
|
|
||||||
const CWalletTx* copyFrom = &wtxOld;
|
|
||||||
CWalletTx* copyTo = &mi->second;
|
|
||||||
copyTo->mapValue = copyFrom->mapValue;
|
|
||||||
copyTo->vOrderForm = copyFrom->vOrderForm;
|
|
||||||
copyTo->nTimeReceived = copyFrom->nTimeReceived;
|
|
||||||
copyTo->nTimeSmart = copyFrom->nTimeSmart;
|
|
||||||
copyTo->fFromMe = copyFrom->fFromMe;
|
|
||||||
copyTo->strFromAccount = copyFrom->strFromAccount;
|
|
||||||
copyTo->nOrderPos = copyFrom->nOrderPos;
|
|
||||||
copyTo->WriteToDisk(&walletdb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pwalletMain->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));
|
|
||||||
} // (!fDisableWallet)
|
|
||||||
#else // ENABLE_WALLET
|
#else // ENABLE_WALLET
|
||||||
LogPrintf("No wallet support compiled in!\n");
|
LogPrintf("No wallet support compiled in!\n");
|
||||||
#endif // !ENABLE_WALLET
|
#endif // !ENABLE_WALLET
|
||||||
|
@ -4391,6 +4391,197 @@ std::string CWallet::GetWalletHelpString(bool showDebug)
|
|||||||
return strUsage;
|
return strUsage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWalletFile, std::string& warningString, std::string& errorString)
|
||||||
|
{
|
||||||
|
// needed to restore wallet transaction meta data after -zapwallettxes
|
||||||
|
std::vector<CWalletTx> vWtx;
|
||||||
|
|
||||||
|
if (GetBoolArg("-zapwallettxes", false)) {
|
||||||
|
uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
|
||||||
|
|
||||||
|
CWallet *tempWallet = new CWallet(strWalletFile);
|
||||||
|
DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
|
||||||
|
if (nZapWalletRet != DB_LOAD_OK) {
|
||||||
|
errorString = _("Error loading wallet.dat: Wallet corrupted");
|
||||||
|
uiInterface.InitMessage(_("Error loading wallet.dat: Wallet corrupted"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete tempWallet;
|
||||||
|
tempWallet = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uiInterface.InitMessage(_("Loading wallet..."));
|
||||||
|
|
||||||
|
int64_t nStart = GetTimeMillis();
|
||||||
|
bool fFirstRun = true;
|
||||||
|
CWallet *walletInstance = new CWallet(strWalletFile);
|
||||||
|
DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
|
||||||
|
if (nLoadWalletRet != DB_LOAD_OK)
|
||||||
|
{
|
||||||
|
if (nLoadWalletRet == DB_CORRUPT)
|
||||||
|
errorString += _("Error loading wallet.dat: Wallet corrupted") + "\n";
|
||||||
|
else if (nLoadWalletRet == DB_NONCRITICAL_ERROR)
|
||||||
|
{
|
||||||
|
warningString += _("Error reading wallet.dat! All keys read correctly, but transaction data"
|
||||||
|
" or address book entries might be missing or incorrect.");
|
||||||
|
}
|
||||||
|
else if (nLoadWalletRet == DB_TOO_NEW)
|
||||||
|
errorString += strprintf(_("Error loading wallet.dat: Wallet requires newer version of %s"), _(PACKAGE_NAME)) + "\n";
|
||||||
|
else if (nLoadWalletRet == DB_NEED_REWRITE)
|
||||||
|
{
|
||||||
|
errorString += strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)) + "\n";
|
||||||
|
LogPrintf("%s", errorString);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
errorString += _("Error loading wallet.dat") + "\n";
|
||||||
|
|
||||||
|
if (!errorString.empty())
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetBoolArg("-upgradewallet", fFirstRun))
|
||||||
|
{
|
||||||
|
int nMaxVersion = GetArg("-upgradewallet", 0);
|
||||||
|
if (nMaxVersion == 0) // the -upgradewallet without argument case
|
||||||
|
{
|
||||||
|
LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
|
||||||
|
nMaxVersion = CLIENT_VERSION;
|
||||||
|
walletInstance->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
|
||||||
|
if (nMaxVersion < walletInstance->GetVersion())
|
||||||
|
{
|
||||||
|
errorString += _("Cannot downgrade wallet") + "\n";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
walletInstance->SetMaxVersion(nMaxVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fFirstRun)
|
||||||
|
{
|
||||||
|
// Create new keyUser and set as default key
|
||||||
|
RandAddSeedPerfmon();
|
||||||
|
|
||||||
|
if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && !pwalletMain->IsHDEnabled()) {
|
||||||
|
if (GetArg("-mnemonicpassphrase", "").size() > 256)
|
||||||
|
return InitError(_("Mnemonic passphrase is too long, must be at most 256 characters"));
|
||||||
|
// generate a new master key
|
||||||
|
pwalletMain->GenerateNewHDChain();
|
||||||
|
|
||||||
|
// ensure this wallet.dat can only be opened by clients supporting HD
|
||||||
|
pwalletMain->SetMinVersion(FEATURE_HD);
|
||||||
|
}
|
||||||
|
|
||||||
|
CPubKey newDefaultKey;
|
||||||
|
if (walletInstance->GetKeyFromPool(newDefaultKey, false)) {
|
||||||
|
walletInstance->SetDefaultKey(newDefaultKey);
|
||||||
|
if (!walletInstance->SetAddressBook(walletInstance->vchDefaultKey.GetID(), "", "receive"))
|
||||||
|
{
|
||||||
|
errorString += _("Cannot write default address") += "\n";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
walletInstance->SetBestChain(chainActive.GetLocator());
|
||||||
|
|
||||||
|
// Try to create wallet backup right after new wallet was created
|
||||||
|
std::string strBackupWarning;
|
||||||
|
std::string strBackupError;
|
||||||
|
if(!AutoBackupWallet(pwalletMain, "", strBackupWarning, strBackupError)) {
|
||||||
|
if (!strBackupWarning.empty())
|
||||||
|
InitWarning(strBackupWarning);
|
||||||
|
if (!strBackupError.empty())
|
||||||
|
return InitError(strBackupError);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (mapArgs.count("-usehd")) {
|
||||||
|
bool useHD = GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET);
|
||||||
|
if (pwalletMain->IsHDEnabled() && !useHD)
|
||||||
|
return InitError(strprintf(_("Error loading %s: You can't disable HD on a already existing HD wallet"), strWalletFile));
|
||||||
|
if (!pwalletMain->IsHDEnabled() && useHD)
|
||||||
|
return InitError(strprintf(_("Error loading %s: You can't enable HD on a already existing non-HD wallet"), strWalletFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warn user every time he starts non-encrypted HD wallet
|
||||||
|
if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && !pwalletMain->IsLocked()) {
|
||||||
|
InitWarning(_("Make sure to encrypt your wallet and delete all non-encrypted backups after you verified that wallet works!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart);
|
||||||
|
|
||||||
|
RegisterValidationInterface(walletInstance);
|
||||||
|
|
||||||
|
CBlockIndex *pindexRescan = chainActive.Tip();
|
||||||
|
if (GetBoolArg("-rescan", false))
|
||||||
|
pindexRescan = chainActive.Genesis();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CWalletDB walletdb(strWalletFile);
|
||||||
|
CBlockLocator locator;
|
||||||
|
if (walletdb.ReadBestBlock(locator))
|
||||||
|
pindexRescan = FindForkInGlobalIndex(chainActive, locator);
|
||||||
|
else
|
||||||
|
pindexRescan = chainActive.Genesis();
|
||||||
|
}
|
||||||
|
if (chainActive.Tip() && chainActive.Tip() != pindexRescan)
|
||||||
|
{
|
||||||
|
//We can't rescan beyond non-pruned blocks, stop and throw an error
|
||||||
|
//this might happen if a user uses a old wallet within a pruned node
|
||||||
|
// or if he ran -disablewallet for a longer time, then decided to re-enable
|
||||||
|
if (fPruneMode)
|
||||||
|
{
|
||||||
|
CBlockIndex *block = chainActive.Tip();
|
||||||
|
while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA) && block->pprev->nTx > 0 && pindexRescan != block)
|
||||||
|
block = block->pprev;
|
||||||
|
|
||||||
|
if (pindexRescan != block)
|
||||||
|
{
|
||||||
|
errorString = _("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uiInterface.InitMessage(_("Rescanning..."));
|
||||||
|
LogPrintf("Rescanning last %i blocks (from block %i)...\n", chainActive.Height() - pindexRescan->nHeight, pindexRescan->nHeight);
|
||||||
|
nStart = GetTimeMillis();
|
||||||
|
walletInstance->ScanForWalletTransactions(pindexRescan, true);
|
||||||
|
LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart);
|
||||||
|
walletInstance->SetBestChain(chainActive.GetLocator());
|
||||||
|
nWalletDBUpdated++;
|
||||||
|
|
||||||
|
// Restore wallet transaction metadata after -zapwallettxes=1
|
||||||
|
if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2")
|
||||||
|
{
|
||||||
|
CWalletDB walletdb(strWalletFile);
|
||||||
|
|
||||||
|
BOOST_FOREACH(const CWalletTx& wtxOld, vWtx)
|
||||||
|
{
|
||||||
|
uint256 hash = wtxOld.GetHash();
|
||||||
|
std::map<uint256, CWalletTx>::iterator mi = walletInstance->mapWallet.find(hash);
|
||||||
|
if (mi != walletInstance->mapWallet.end())
|
||||||
|
{
|
||||||
|
const CWalletTx* copyFrom = &wtxOld;
|
||||||
|
CWalletTx* copyTo = &mi->second;
|
||||||
|
copyTo->mapValue = copyFrom->mapValue;
|
||||||
|
copyTo->vOrderForm = copyFrom->vOrderForm;
|
||||||
|
copyTo->nTimeReceived = copyFrom->nTimeReceived;
|
||||||
|
copyTo->nTimeSmart = copyFrom->nTimeSmart;
|
||||||
|
copyTo->fFromMe = copyFrom->fFromMe;
|
||||||
|
copyTo->strFromAccount = copyFrom->strFromAccount;
|
||||||
|
copyTo->nOrderPos = copyFrom->nOrderPos;
|
||||||
|
copyTo->WriteToDisk(&walletdb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
walletInstance->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));
|
||||||
|
|
||||||
|
return walletInstance;
|
||||||
|
}
|
||||||
|
|
||||||
CKeyPool::CKeyPool()
|
CKeyPool::CKeyPool()
|
||||||
{
|
{
|
||||||
nTime = GetTime();
|
nTime = GetTime();
|
||||||
|
@ -1022,6 +1022,9 @@ public:
|
|||||||
/* Returns the wallets help message */
|
/* Returns the wallets help message */
|
||||||
static std::string GetWalletHelpString(bool showDebug);
|
static std::string GetWalletHelpString(bool showDebug);
|
||||||
|
|
||||||
|
/* initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */
|
||||||
|
static CWallet* InitLoadWallet(bool fDisableWallet, const std::string& strWalletFile, std::string& warningString, std::string& errorString);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HD Wallet Functions
|
* HD Wallet Functions
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user