Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
Show First 20 Lines • Show All 249 Lines • ▼ Show 20 Lines | if (!passphrase.empty() && | ||||
error = Untranslated( | error = Untranslated( | ||||
"Error: Wallet was encrypted but could not be unlocked"); | "Error: Wallet was encrypted but could not be unlocked"); | ||||
return WalletCreationStatus::ENCRYPTION_FAILED; | return WalletCreationStatus::ENCRYPTION_FAILED; | ||||
} | } | ||||
// Set a seed for the wallet | // Set a seed for the wallet | ||||
{ | { | ||||
LOCK(wallet->cs_wallet); | LOCK(wallet->cs_wallet); | ||||
if (wallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) { | |||||
wallet->SetupDescriptorScriptPubKeyMans(); | |||||
} else { | |||||
for (auto spk_man : wallet->GetActiveScriptPubKeyMans()) { | for (auto spk_man : wallet->GetActiveScriptPubKeyMans()) { | ||||
if (!spk_man->SetupGeneration()) { | if (!spk_man->SetupGeneration()) { | ||||
error = Untranslated("Unable to generate initial keys"); | error = | ||||
Untranslated("Unable to generate initial keys"); | |||||
return WalletCreationStatus::CREATION_FAILED; | return WalletCreationStatus::CREATION_FAILED; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | |||||
// Relock the wallet | // Relock the wallet | ||||
wallet->Lock(); | wallet->Lock(); | ||||
} | } | ||||
} | } | ||||
AddWallet(wallet); | AddWallet(wallet); | ||||
wallet->postInitProcess(); | wallet->postInitProcess(); | ||||
result = wallet; | result = wallet; | ||||
▲ Show 20 Lines • Show All 3,946 Lines • ▼ Show 20 Lines | if (fFirstRun) { | ||||
// Only create LegacyScriptPubKeyMan when not descriptor wallet | // Only create LegacyScriptPubKeyMan when not descriptor wallet | ||||
if (!walletInstance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) { | if (!walletInstance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) { | ||||
walletInstance->SetupLegacyScriptPubKeyMan(); | walletInstance->SetupLegacyScriptPubKeyMan(); | ||||
} | } | ||||
if (!(wallet_creation_flags & | if (!(wallet_creation_flags & | ||||
(WALLET_FLAG_DISABLE_PRIVATE_KEYS | WALLET_FLAG_BLANK_WALLET))) { | (WALLET_FLAG_DISABLE_PRIVATE_KEYS | WALLET_FLAG_BLANK_WALLET))) { | ||||
LOCK(walletInstance->cs_wallet); | LOCK(walletInstance->cs_wallet); | ||||
for (auto spk_man : walletInstance->GetActiveScriptPubKeyMans()) { | if (walletInstance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) { | ||||
walletInstance->SetupDescriptorScriptPubKeyMans(); | |||||
// SetupDescriptorScriptPubKeyMans already calls SetupGeneration | |||||
// for us so we don't need to call SetupGeneration separately | |||||
} else { | |||||
// Legacy wallets need SetupGeneration here. | |||||
for (auto spk_man : | |||||
walletInstance->GetActiveScriptPubKeyMans()) { | |||||
if (!spk_man->SetupGeneration()) { | if (!spk_man->SetupGeneration()) { | ||||
error = _("Unable to generate initial keys"); | error = _("Unable to generate initial keys"); | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | |||||
walletInstance->chainStateFlushed(chain.getTipLocator()); | 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 " | error = strprintf(_("Error loading %s: Private keys can only be " | ||||
"disabled during creation"), | "disabled during creation"), | ||||
walletFile); | walletFile); | ||||
return nullptr; | return nullptr; | ||||
▲ Show 20 Lines • Show All 613 Lines • ▼ Show 20 Lines | |||||
void CWallet::LoadDescriptorScriptPubKeyMan(uint256 id, | void CWallet::LoadDescriptorScriptPubKeyMan(uint256 id, | ||||
WalletDescriptor &desc) { | WalletDescriptor &desc) { | ||||
auto spk_manager = std::unique_ptr<ScriptPubKeyMan>( | auto spk_manager = std::unique_ptr<ScriptPubKeyMan>( | ||||
new DescriptorScriptPubKeyMan(*this, desc)); | new DescriptorScriptPubKeyMan(*this, desc)); | ||||
m_spk_managers[id] = std::move(spk_manager); | m_spk_managers[id] = std::move(spk_manager); | ||||
} | } | ||||
void CWallet::SetupDescriptorScriptPubKeyMans() { | |||||
AssertLockHeld(cs_wallet); | |||||
// Make a seed | |||||
CKey seed_key; | |||||
seed_key.MakeNewKey(true); | |||||
CPubKey seed = seed_key.GetPubKey(); | |||||
assert(seed_key.VerifyPubKey(seed)); | |||||
// Get the extended key | |||||
CExtKey master_key; | |||||
master_key.SetSeed(seed_key.begin(), seed_key.size()); | |||||
for (bool internal : {false, true}) { | |||||
for (OutputType t : OUTPUT_TYPES) { | |||||
auto spk_manager = | |||||
std::make_unique<DescriptorScriptPubKeyMan>(*this, t, internal); | |||||
if (IsCrypted()) { | |||||
if (IsLocked()) { | |||||
throw std::runtime_error( | |||||
std::string(__func__) + | |||||
": Wallet is locked, cannot setup new descriptors"); | |||||
} | |||||
if (!spk_manager->CheckDecryptionKey(vMasterKey) && | |||||
!spk_manager->Encrypt(vMasterKey, nullptr)) { | |||||
throw std::runtime_error( | |||||
std::string(__func__) + | |||||
": Could not encrypt new descriptors"); | |||||
} | |||||
} | |||||
spk_manager->SetupDescriptorGeneration(master_key); | |||||
uint256 id = spk_manager->GetID(); | |||||
m_spk_managers[id] = std::move(spk_manager); | |||||
SetActiveScriptPubKeyMan(id, t, internal); | |||||
} | |||||
} | |||||
} | |||||
void CWallet::SetActiveScriptPubKeyMan(uint256 id, OutputType type, | void CWallet::SetActiveScriptPubKeyMan(uint256 id, OutputType type, | ||||
bool internal, bool memonly) { | bool internal, bool memonly) { | ||||
auto &spk_mans = | auto &spk_mans = | ||||
internal ? m_internal_spk_managers : m_external_spk_managers; | internal ? m_internal_spk_managers : m_external_spk_managers; | ||||
auto spk_man = m_spk_managers.at(id).get(); | auto spk_man = m_spk_managers.at(id).get(); | ||||
spk_man->SetType(type, internal); | spk_man->SetType(type, internal); | ||||
spk_mans[type] = spk_man; | spk_mans[type] = spk_man; | ||||
Show All 11 Lines |