diff options
Diffstat (limited to 'src/wallet/scriptpubkeyman.cpp')
-rw-r--r-- | src/wallet/scriptpubkeyman.cpp | 99 |
1 files changed, 51 insertions, 48 deletions
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index 3eaaf3786c..b4315014cb 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -18,7 +18,7 @@ bool LegacyScriptPubKeyMan::GetNewDestination(const OutputType type, CTxDestinat // Generate a new key that is added to wallet CPubKey new_key; - if (!GetKeyFromPool(new_key)) { + if (!GetKeyFromPool(new_key, type)) { error = "Error: Keypool ran out, please call keypoolrefill first"; return false; } @@ -202,12 +202,11 @@ isminetype LegacyScriptPubKeyMan::IsMine(const CScript& script) const assert(false); } -bool CWallet::Unlock(const CKeyingMaterial& vMasterKeyIn, bool accept_no_keys) +bool LegacyScriptPubKeyMan::CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys) { { LOCK(cs_KeyStore); - if (!SetCrypted()) - return false; + assert(mapKeys.empty()); bool keyPass = mapCryptedKeys.empty(); // Always pass when there are no encrypted keys bool keyFail = false; @@ -217,7 +216,7 @@ bool CWallet::Unlock(const CKeyingMaterial& vMasterKeyIn, bool accept_no_keys) const CPubKey &vchPubKey = (*mi).second.first; const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second; CKey key; - if (!DecryptKey(vMasterKeyIn, vchCryptedSecret, vchPubKey, key)) + if (!DecryptKey(master_key, vchCryptedSecret, vchPubKey, key)) { keyFail = true; break; @@ -233,53 +232,55 @@ bool CWallet::Unlock(const CKeyingMaterial& vMasterKeyIn, bool accept_no_keys) } if (keyFail || (!keyPass && !accept_no_keys)) return false; - vMasterKey = vMasterKeyIn; fDecryptionThoroughlyChecked = true; } - NotifyStatusChanged(this); return true; } -bool LegacyScriptPubKeyMan::EncryptKeys(CKeyingMaterial& vMasterKeyIn) +bool LegacyScriptPubKeyMan::Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) { + AssertLockHeld(cs_wallet); LOCK(cs_KeyStore); - if (!mapCryptedKeys.empty() || IsCrypted()) + encrypted_batch = batch; + if (!mapCryptedKeys.empty()) { + encrypted_batch = nullptr; return false; + } - fUseCrypto = true; - for (const KeyMap::value_type& mKey : mapKeys) + KeyMap keys_to_encrypt; + keys_to_encrypt.swap(mapKeys); // Clear mapKeys so AddCryptedKeyInner will succeed. + for (const KeyMap::value_type& mKey : keys_to_encrypt) { const CKey &key = mKey.second; CPubKey vchPubKey = key.GetPubKey(); CKeyingMaterial vchSecret(key.begin(), key.end()); std::vector<unsigned char> vchCryptedSecret; - if (!EncryptSecret(vMasterKeyIn, vchSecret, vchPubKey.GetHash(), vchCryptedSecret)) + if (!EncryptSecret(master_key, vchSecret, vchPubKey.GetHash(), vchCryptedSecret)) { + encrypted_batch = nullptr; return false; - if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) + } + if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) { + encrypted_batch = nullptr; return false; + } } - mapKeys.clear(); + encrypted_batch = nullptr; return true; } -bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, int64_t& index, CKeyPool& keypool) +bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool) { + if (!CanGetAddresses(internal)) { + return false; + } + if (!ReserveKeyFromKeyPool(index, keypool, internal)) { return false; } + address = GetDestinationForKey(keypool.vchPubKey, type); return true; } -void LegacyScriptPubKeyMan::KeepDestination(int64_t index) -{ - KeepKey(index); -} - -void LegacyScriptPubKeyMan::ReturnDestination(int64_t index, bool internal, const CPubKey& pubkey) -{ - ReturnKey(index, internal, pubkey); -} - void LegacyScriptPubKeyMan::MarkUnusedAddresses(const CScript& script) { AssertLockHeld(cs_wallet); @@ -460,7 +461,7 @@ size_t LegacyScriptPubKeyMan::KeypoolCountExternalKeys() unsigned int LegacyScriptPubKeyMan::GetKeyPoolSize() const { AssertLockHeld(cs_wallet); - return setInternalKeyPool.size() + setExternalKeyPool.size(); + return setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size(); } int64_t LegacyScriptPubKeyMan::GetTimeFirstKey() const @@ -548,7 +549,7 @@ bool LegacyScriptPubKeyMan::AddKeyPubKeyWithDB(WalletBatch& batch, const CKey& s RemoveWatchOnly(script); } - if (!IsCrypted()) { + if (!m_storage.HasEncryptionKeys()) { return batch.WriteKey(pubkey, secret.GetPrivKey(), mapKeyMetadata[pubkey.GetID()]); @@ -589,7 +590,7 @@ void LegacyScriptPubKeyMan::LoadScriptMetadata(const CScriptID& script_id, const bool LegacyScriptPubKeyMan::AddKeyPubKeyInner(const CKey& key, const CPubKey &pubkey) { LOCK(cs_KeyStore); - if (!IsCrypted()) { + if (!m_storage.HasEncryptionKeys()) { return FillableSigningProvider::AddKeyPubKey(key, pubkey); } @@ -599,7 +600,7 @@ bool LegacyScriptPubKeyMan::AddKeyPubKeyInner(const CKey& key, const CPubKey &pu std::vector<unsigned char> vchCryptedSecret; CKeyingMaterial vchSecret(key.begin(), key.end()); - if (!EncryptSecret(vMasterKey, vchSecret, pubkey.GetHash(), vchCryptedSecret)) { + if (!EncryptSecret(m_storage.GetEncryptionKey(), vchSecret, pubkey.GetHash(), vchCryptedSecret)) { return false; } @@ -617,9 +618,7 @@ bool LegacyScriptPubKeyMan::LoadCryptedKey(const CPubKey &vchPubKey, const std:: bool LegacyScriptPubKeyMan::AddCryptedKeyInner(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { LOCK(cs_KeyStore); - if (!SetCrypted()) { - return false; - } + assert(mapKeys.empty()); mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret); ImplicitlyLearnRelatedKeyScripts(vchPubKey); @@ -746,7 +745,7 @@ void LegacyScriptPubKeyMan::SetHDChain(const CHDChain& chain, bool memonly) bool LegacyScriptPubKeyMan::HaveKey(const CKeyID &address) const { LOCK(cs_KeyStore); - if (!IsCrypted()) { + if (!m_storage.HasEncryptionKeys()) { return FillableSigningProvider::HaveKey(address); } return mapCryptedKeys.count(address) > 0; @@ -755,7 +754,7 @@ bool LegacyScriptPubKeyMan::HaveKey(const CKeyID &address) const bool LegacyScriptPubKeyMan::GetKey(const CKeyID &address, CKey& keyOut) const { LOCK(cs_KeyStore); - if (!IsCrypted()) { + if (!m_storage.HasEncryptionKeys()) { return FillableSigningProvider::GetKey(address, keyOut); } @@ -764,7 +763,7 @@ bool LegacyScriptPubKeyMan::GetKey(const CKeyID &address, CKey& keyOut) const { const CPubKey &vchPubKey = (*mi).second.first; const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second; - return DecryptKey(vMasterKey, vchCryptedSecret, vchPubKey, keyOut); + return DecryptKey(m_storage.GetEncryptionKey(), vchCryptedSecret, vchPubKey, keyOut); } return false; } @@ -802,7 +801,7 @@ bool LegacyScriptPubKeyMan::GetWatchPubKey(const CKeyID &address, CPubKey &pubke bool LegacyScriptPubKeyMan::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const { LOCK(cs_KeyStore); - if (!IsCrypted()) { + if (!m_storage.HasEncryptionKeys()) { if (!FillableSigningProvider::GetPubKey(address, vchPubKeyOut)) { return GetWatchPubKey(address, vchPubKeyOut); } @@ -1092,15 +1091,20 @@ void LegacyScriptPubKeyMan::AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const m_pool_key_to_index[pubkey.GetID()] = index; } -void LegacyScriptPubKeyMan::KeepKey(int64_t nIndex) +void LegacyScriptPubKeyMan::KeepDestination(int64_t nIndex, const OutputType& type) { // Remove from key pool WalletBatch batch(m_storage.GetDatabase()); batch.ErasePool(nIndex); + CPubKey pubkey; + bool have_pk = GetPubKey(m_index_to_reserved_key.at(nIndex), pubkey); + assert(have_pk); + LearnRelatedScripts(pubkey, type); + m_index_to_reserved_key.erase(nIndex); WalletLogPrintf("keypool keep %d\n", nIndex); } -void LegacyScriptPubKeyMan::ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey) +void LegacyScriptPubKeyMan::ReturnDestination(int64_t nIndex, bool fInternal, const CTxDestination&) { // Return to key pool { @@ -1112,13 +1116,15 @@ void LegacyScriptPubKeyMan::ReturnKey(int64_t nIndex, bool fInternal, const CPub } else { setExternalKeyPool.insert(nIndex); } - m_pool_key_to_index[pubkey.GetID()] = nIndex; + CKeyID& pubkey_id = m_index_to_reserved_key.at(nIndex); + m_pool_key_to_index[pubkey_id] = nIndex; + m_index_to_reserved_key.erase(nIndex); NotifyCanGetAddressesChanged(); } WalletLogPrintf("keypool return %d\n", nIndex); } -bool LegacyScriptPubKeyMan::GetKeyFromPool(CPubKey& result, bool internal) +bool LegacyScriptPubKeyMan::GetKeyFromPool(CPubKey& result, const OutputType type, bool internal) { if (!CanGetAddresses(internal)) { return false; @@ -1134,7 +1140,7 @@ bool LegacyScriptPubKeyMan::GetKeyFromPool(CPubKey& result, bool internal) result = GenerateNewKey(batch, internal); return true; } - KeepKey(nIndex); + KeepDestination(nIndex, type); result = keypool.vchPubKey; } return true; @@ -1179,6 +1185,8 @@ bool LegacyScriptPubKeyMan::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& key throw std::runtime_error(std::string(__func__) + ": keypool entry invalid"); } + assert(m_index_to_reserved_key.count(nIndex) == 0); + m_index_to_reserved_key[nIndex] = keypool.vchPubKey.GetID(); m_pool_key_to_index.erase(keypool.vchPubKey.GetID()); WalletLogPrintf("keypool reserve %d\n", nIndex); } @@ -1379,7 +1387,7 @@ bool LegacyScriptPubKeyMan::ImportScriptPubKeys(const std::set<CScript>& script_ std::set<CKeyID> LegacyScriptPubKeyMan::GetKeys() const { LOCK(cs_KeyStore); - if (!IsCrypted()) { + if (!m_storage.HasEncryptionKeys()) { return FillableSigningProvider::GetKeys(); } std::set<CKeyID> set_address; @@ -1393,13 +1401,8 @@ std::set<CKeyID> LegacyScriptPubKeyMan::GetKeys() const LegacyScriptPubKeyMan::LegacyScriptPubKeyMan(CWallet& wallet) : ScriptPubKeyMan(wallet), m_wallet(wallet), - cs_wallet(wallet.cs_wallet), - vMasterKey(wallet.vMasterKey), - fUseCrypto(wallet.fUseCrypto), - fDecryptionThoroughlyChecked(wallet.fDecryptionThoroughlyChecked) {} + cs_wallet(wallet.cs_wallet) {} -bool LegacyScriptPubKeyMan::SetCrypted() { return m_wallet.SetCrypted(); } -bool LegacyScriptPubKeyMan::IsCrypted() const { return m_wallet.IsCrypted(); } void LegacyScriptPubKeyMan::NotifyWatchonlyChanged(bool fHaveWatchOnly) const { return m_wallet.NotifyWatchonlyChanged(fHaveWatchOnly); } void LegacyScriptPubKeyMan::NotifyCanGetAddressesChanged() const { return m_wallet.NotifyCanGetAddressesChanged(); } template<typename... Params> void LegacyScriptPubKeyMan::WalletLogPrintf(const std::string& fmt, const Params&... parameters) const { return m_wallet.WalletLogPrintf(fmt, parameters...); } |