Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/scriptpubkeyman.cpp
Show First 20 Lines • Show All 142 Lines • ▼ Show 20 Lines | switch (IsMineInner(*this, script, IsMineSigVersion::TOP)) { | ||||
case IsMineResult::WATCH_ONLY: | case IsMineResult::WATCH_ONLY: | ||||
return ISMINE_WATCH_ONLY; | return ISMINE_WATCH_ONLY; | ||||
case IsMineResult::SPENDABLE: | case IsMineResult::SPENDABLE: | ||||
return ISMINE_SPENDABLE; | return ISMINE_SPENDABLE; | ||||
} | } | ||||
assert(false); | 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); | LOCK(cs_KeyStore); | ||||
if (!SetCrypted()) { | assert(mapKeys.empty()); | ||||
return false; | |||||
} | |||||
// Always pass when there are no encrypted keys | // Always pass when there are no encrypted keys | ||||
bool keyPass = mapCryptedKeys.empty(); | bool keyPass = mapCryptedKeys.empty(); | ||||
bool keyFail = false; | bool keyFail = false; | ||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin(); | CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin(); | ||||
for (; mi != mapCryptedKeys.end(); ++mi) { | for (; mi != mapCryptedKeys.end(); ++mi) { | ||||
const CPubKey &vchPubKey = (*mi).second.first; | const CPubKey &vchPubKey = (*mi).second.first; | ||||
const std::vector<uint8_t> &vchCryptedSecret = (*mi).second.second; | const std::vector<uint8_t> &vchCryptedSecret = (*mi).second.second; | ||||
CKey key; | CKey key; | ||||
if (!DecryptKey(vMasterKeyIn, vchCryptedSecret, vchPubKey, key)) { | if (!DecryptKey(master_key, vchCryptedSecret, vchPubKey, key)) { | ||||
keyFail = true; | keyFail = true; | ||||
break; | break; | ||||
} | } | ||||
keyPass = true; | keyPass = true; | ||||
if (fDecryptionThoroughlyChecked) { | if (fDecryptionThoroughlyChecked) { | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if (keyPass && keyFail) { | if (keyPass && keyFail) { | ||||
LogPrintf("The wallet is probably corrupted: Some keys decrypt but " | LogPrintf("The wallet is probably corrupted: Some keys decrypt but " | ||||
"not all.\n"); | "not all.\n"); | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
"Error unlocking wallet: some keys decrypt but not all. Your " | "Error unlocking wallet: some keys decrypt but not all. Your " | ||||
"wallet file may be corrupt."); | "wallet file may be corrupt."); | ||||
} | } | ||||
if (keyFail || (!keyPass && !accept_no_keys)) { | if (keyFail || (!keyPass && !accept_no_keys)) { | ||||
return false; | return false; | ||||
} | } | ||||
vMasterKey = vMasterKeyIn; | |||||
fDecryptionThoroughlyChecked = true; | fDecryptionThoroughlyChecked = true; | ||||
} | } | ||||
NotifyStatusChanged(this); | |||||
return true; | return true; | ||||
} | } | ||||
bool LegacyScriptPubKeyMan::EncryptKeys(CKeyingMaterial &vMasterKeyIn) { | bool LegacyScriptPubKeyMan::Encrypt(const CKeyingMaterial &master_key, | ||||
WalletBatch *batch) { | |||||
AssertLockHeld(cs_wallet); | |||||
LOCK(cs_KeyStore); | LOCK(cs_KeyStore); | ||||
if (!mapCryptedKeys.empty() || IsCrypted()) { | encrypted_batch = batch; | ||||
if (!mapCryptedKeys.empty()) { | |||||
encrypted_batch = nullptr; | |||||
return false; | return false; | ||||
} | } | ||||
fUseCrypto = true; | KeyMap keys_to_encrypt; | ||||
for (const KeyMap::value_type &mKey : mapKeys) { | // Clear mapKeys so AddCryptedKeyInner will succeed. | ||||
keys_to_encrypt.swap(mapKeys); | |||||
for (const KeyMap::value_type &mKey : keys_to_encrypt) { | |||||
const CKey &key = mKey.second; | const CKey &key = mKey.second; | ||||
CPubKey vchPubKey = key.GetPubKey(); | CPubKey vchPubKey = key.GetPubKey(); | ||||
CKeyingMaterial vchSecret(key.begin(), key.end()); | CKeyingMaterial vchSecret(key.begin(), key.end()); | ||||
std::vector<uint8_t> vchCryptedSecret; | std::vector<uint8_t> vchCryptedSecret; | ||||
if (!EncryptSecret(vMasterKeyIn, vchSecret, vchPubKey.GetHash(), | if (!EncryptSecret(master_key, vchSecret, vchPubKey.GetHash(), | ||||
vchCryptedSecret)) { | vchCryptedSecret)) { | ||||
encrypted_batch = nullptr; | |||||
return false; | return false; | ||||
} | } | ||||
if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) { | if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) { | ||||
encrypted_batch = nullptr; | |||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
mapKeys.clear(); | encrypted_batch = nullptr; | ||||
return true; | return true; | ||||
} | } | ||||
bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, | bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, | ||||
bool internal, | bool internal, | ||||
CTxDestination &address, | CTxDestination &address, | ||||
int64_t &index, | int64_t &index, | ||||
CKeyPool &keypool) { | CKeyPool &keypool) { | ||||
▲ Show 20 Lines • Show All 280 Lines • ▼ Show 20 Lines | if (HaveWatchOnly(script)) { | ||||
RemoveWatchOnly(script); | RemoveWatchOnly(script); | ||||
} | } | ||||
script = GetScriptForRawPubKey(pubkey); | script = GetScriptForRawPubKey(pubkey); | ||||
if (HaveWatchOnly(script)) { | if (HaveWatchOnly(script)) { | ||||
RemoveWatchOnly(script); | RemoveWatchOnly(script); | ||||
} | } | ||||
if (!IsCrypted()) { | if (!m_storage.HasEncryptionKeys()) { | ||||
return batch.WriteKey(pubkey, secret.GetPrivKey(), | return batch.WriteKey(pubkey, secret.GetPrivKey(), | ||||
mapKeyMetadata[pubkey.GetID()]); | mapKeyMetadata[pubkey.GetID()]); | ||||
} | } | ||||
m_storage.UnsetBlankWalletFlag(batch); | m_storage.UnsetBlankWalletFlag(batch); | ||||
return true; | return true; | ||||
} | } | ||||
bool LegacyScriptPubKeyMan::LoadCScript(const CScript &redeemScript) { | bool LegacyScriptPubKeyMan::LoadCScript(const CScript &redeemScript) { | ||||
Show All 28 Lines | void LegacyScriptPubKeyMan::LoadScriptMetadata(const CScriptID &script_id, | ||||
AssertLockHeld(cs_wallet); | AssertLockHeld(cs_wallet); | ||||
UpdateTimeFirstKey(meta.nCreateTime); | UpdateTimeFirstKey(meta.nCreateTime); | ||||
m_script_metadata[script_id] = meta; | m_script_metadata[script_id] = meta; | ||||
} | } | ||||
bool LegacyScriptPubKeyMan::AddKeyPubKeyInner(const CKey &key, | bool LegacyScriptPubKeyMan::AddKeyPubKeyInner(const CKey &key, | ||||
const CPubKey &pubkey) { | const CPubKey &pubkey) { | ||||
LOCK(cs_KeyStore); | LOCK(cs_KeyStore); | ||||
if (!IsCrypted()) { | if (!m_storage.HasEncryptionKeys()) { | ||||
return FillableSigningProvider::AddKeyPubKey(key, pubkey); | return FillableSigningProvider::AddKeyPubKey(key, pubkey); | ||||
} | } | ||||
if (m_storage.IsLocked()) { | if (m_storage.IsLocked()) { | ||||
return false; | return false; | ||||
} | } | ||||
std::vector<uint8_t> vchCryptedSecret; | std::vector<uint8_t> vchCryptedSecret; | ||||
CKeyingMaterial vchSecret(key.begin(), key.end()); | CKeyingMaterial vchSecret(key.begin(), key.end()); | ||||
if (!EncryptSecret(vMasterKey, vchSecret, pubkey.GetHash(), | if (!EncryptSecret(m_storage.GetEncryptionKey(), vchSecret, | ||||
vchCryptedSecret)) { | pubkey.GetHash(), vchCryptedSecret)) { | ||||
return false; | return false; | ||||
} | } | ||||
if (!AddCryptedKey(pubkey, vchCryptedSecret)) { | if (!AddCryptedKey(pubkey, vchCryptedSecret)) { | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool LegacyScriptPubKeyMan::LoadCryptedKey( | bool LegacyScriptPubKeyMan::LoadCryptedKey( | ||||
const CPubKey &vchPubKey, const std::vector<uint8_t> &vchCryptedSecret) { | const CPubKey &vchPubKey, const std::vector<uint8_t> &vchCryptedSecret) { | ||||
return AddCryptedKeyInner(vchPubKey, vchCryptedSecret); | return AddCryptedKeyInner(vchPubKey, vchCryptedSecret); | ||||
} | } | ||||
bool LegacyScriptPubKeyMan::AddCryptedKeyInner( | bool LegacyScriptPubKeyMan::AddCryptedKeyInner( | ||||
const CPubKey &vchPubKey, const std::vector<uint8_t> &vchCryptedSecret) { | const CPubKey &vchPubKey, const std::vector<uint8_t> &vchCryptedSecret) { | ||||
LOCK(cs_KeyStore); | LOCK(cs_KeyStore); | ||||
if (!SetCrypted()) { | assert(mapKeys.empty()); | ||||
return false; | |||||
} | |||||
mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret); | mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret); | ||||
return true; | return true; | ||||
} | } | ||||
bool LegacyScriptPubKeyMan::AddCryptedKey( | bool LegacyScriptPubKeyMan::AddCryptedKey( | ||||
const CPubKey &vchPubKey, const std::vector<uint8_t> &vchCryptedSecret) { | const CPubKey &vchPubKey, const std::vector<uint8_t> &vchCryptedSecret) { | ||||
if (!AddCryptedKeyInner(vchPubKey, vchCryptedSecret)) { | if (!AddCryptedKeyInner(vchPubKey, vchCryptedSecret)) { | ||||
▲ Show 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | if (!memonly && !WalletBatch(m_storage.GetDatabase()).WriteHDChain(chain)) { | ||||
": writing chain failed"); | ": writing chain failed"); | ||||
} | } | ||||
hdChain = chain; | hdChain = chain; | ||||
} | } | ||||
bool LegacyScriptPubKeyMan::HaveKey(const CKeyID &address) const { | bool LegacyScriptPubKeyMan::HaveKey(const CKeyID &address) const { | ||||
LOCK(cs_KeyStore); | LOCK(cs_KeyStore); | ||||
if (!IsCrypted()) { | if (!m_storage.HasEncryptionKeys()) { | ||||
return FillableSigningProvider::HaveKey(address); | return FillableSigningProvider::HaveKey(address); | ||||
} | } | ||||
return mapCryptedKeys.count(address) > 0; | return mapCryptedKeys.count(address) > 0; | ||||
} | } | ||||
bool LegacyScriptPubKeyMan::GetKey(const CKeyID &address, CKey &keyOut) const { | bool LegacyScriptPubKeyMan::GetKey(const CKeyID &address, CKey &keyOut) const { | ||||
LOCK(cs_KeyStore); | LOCK(cs_KeyStore); | ||||
if (!IsCrypted()) { | if (!m_storage.HasEncryptionKeys()) { | ||||
return FillableSigningProvider::GetKey(address, keyOut); | return FillableSigningProvider::GetKey(address, keyOut); | ||||
} | } | ||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address); | CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address); | ||||
if (mi != mapCryptedKeys.end()) { | if (mi != mapCryptedKeys.end()) { | ||||
const CPubKey &vchPubKey = (*mi).second.first; | const CPubKey &vchPubKey = (*mi).second.first; | ||||
const std::vector<uint8_t> &vchCryptedSecret = (*mi).second.second; | const std::vector<uint8_t> &vchCryptedSecret = (*mi).second.second; | ||||
return DecryptKey(vMasterKey, vchCryptedSecret, vchPubKey, keyOut); | return DecryptKey(m_storage.GetEncryptionKey(), vchCryptedSecret, | ||||
vchPubKey, keyOut); | |||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
bool LegacyScriptPubKeyMan::GetKeyOrigin(const CKeyID &keyID, | bool LegacyScriptPubKeyMan::GetKeyOrigin(const CKeyID &keyID, | ||||
KeyOriginInfo &info) const { | KeyOriginInfo &info) const { | ||||
CKeyMetadata meta; | CKeyMetadata meta; | ||||
{ | { | ||||
Show All 23 Lines | if (it != mapWatchKeys.end()) { | ||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
bool LegacyScriptPubKeyMan::GetPubKey(const CKeyID &address, | bool LegacyScriptPubKeyMan::GetPubKey(const CKeyID &address, | ||||
CPubKey &vchPubKeyOut) const { | CPubKey &vchPubKeyOut) const { | ||||
LOCK(cs_KeyStore); | LOCK(cs_KeyStore); | ||||
if (!IsCrypted()) { | if (!m_storage.HasEncryptionKeys()) { | ||||
if (!FillableSigningProvider::GetPubKey(address, vchPubKeyOut)) { | if (!FillableSigningProvider::GetPubKey(address, vchPubKeyOut)) { | ||||
return GetWatchPubKey(address, vchPubKeyOut); | return GetWatchPubKey(address, vchPubKeyOut); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address); | CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address); | ||||
if (mi != mapCryptedKeys.end()) { | if (mi != mapCryptedKeys.end()) { | ||||
▲ Show 20 Lines • Show All 632 Lines • ▼ Show 20 Lines | for (const CScript &script : script_pub_keys) { | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
std::set<CKeyID> LegacyScriptPubKeyMan::GetKeys() const { | std::set<CKeyID> LegacyScriptPubKeyMan::GetKeys() const { | ||||
LOCK(cs_KeyStore); | LOCK(cs_KeyStore); | ||||
if (!IsCrypted()) { | if (!m_storage.HasEncryptionKeys()) { | ||||
return FillableSigningProvider::GetKeys(); | return FillableSigningProvider::GetKeys(); | ||||
} | } | ||||
std::set<CKeyID> set_address; | std::set<CKeyID> set_address; | ||||
for (const auto &mi : mapCryptedKeys) { | for (const auto &mi : mapCryptedKeys) { | ||||
set_address.insert(mi.first); | set_address.insert(mi.first); | ||||
} | } | ||||
return set_address; | return set_address; | ||||
} | } | ||||
// Temporary CWallet accessors and aliases. | // Temporary CWallet accessors and aliases. | ||||
LegacyScriptPubKeyMan::LegacyScriptPubKeyMan(CWallet &wallet) | LegacyScriptPubKeyMan::LegacyScriptPubKeyMan(CWallet &wallet) | ||||
: ScriptPubKeyMan(wallet), m_wallet(wallet), cs_wallet(wallet.cs_wallet), | : ScriptPubKeyMan(wallet), m_wallet(wallet), cs_wallet(wallet.cs_wallet) {} | ||||
vMasterKey(wallet.vMasterKey), fUseCrypto(wallet.fUseCrypto), | |||||
fDecryptionThoroughlyChecked(wallet.fDecryptionThoroughlyChecked) {} | |||||
bool LegacyScriptPubKeyMan::SetCrypted() { | |||||
return m_wallet.SetCrypted(); | |||||
} | |||||
bool LegacyScriptPubKeyMan::IsCrypted() const { | |||||
return m_wallet.IsCrypted(); | |||||
} | |||||
void LegacyScriptPubKeyMan::NotifyWatchonlyChanged(bool fHaveWatchOnly) const { | void LegacyScriptPubKeyMan::NotifyWatchonlyChanged(bool fHaveWatchOnly) const { | ||||
return m_wallet.NotifyWatchonlyChanged(fHaveWatchOnly); | return m_wallet.NotifyWatchonlyChanged(fHaveWatchOnly); | ||||
} | } | ||||
void LegacyScriptPubKeyMan::NotifyCanGetAddressesChanged() const { | void LegacyScriptPubKeyMan::NotifyCanGetAddressesChanged() const { | ||||
return m_wallet.NotifyCanGetAddressesChanged(); | return m_wallet.NotifyCanGetAddressesChanged(); | ||||
} | } | ||||
template <typename... Params> | template <typename... Params> | ||||
void LegacyScriptPubKeyMan::WalletLogPrintf( | void LegacyScriptPubKeyMan::WalletLogPrintf( | ||||
const std::string &fmt, const Params &... parameters) const { | const std::string &fmt, const Params &... parameters) const { | ||||
return m_wallet.WalletLogPrintf(fmt, parameters...); | return m_wallet.WalletLogPrintf(fmt, parameters...); | ||||
} | } |