Changeset View
Changeset View
Standalone View
Standalone View
src/keystore.cpp
// Copyright (c) 2009-2010 Satoshi Nakamoto | // Copyright (c) 2009-2010 Satoshi Nakamoto | ||||
// Copyright (c) 2009-2016 The Bitcoin Core developers | // Copyright (c) 2009-2016 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <keystore.h> | #include <keystore.h> | ||||
#include <key.h> | #include <key.h> | ||||
#include <pubkey.h> | #include <pubkey.h> | ||||
#include <util.h> | #include <util.h> | ||||
bool CKeyStore::AddKey(const CKey &key) { | bool CKeyStore::AddKey(const CKey &key) { | ||||
return AddKeyPubKey(key, key.GetPubKey()); | return AddKeyPubKey(key, key.GetPubKey()); | ||||
} | } | ||||
void CBasicKeyStore::ImplicitlyLearnRelatedKeyScripts(const CPubKey &pubkey) { | |||||
AssertLockHeld(cs_KeyStore); | |||||
CKeyID key_id = pubkey.GetID(); | |||||
// We must actually know about this key already. | |||||
assert(HaveKey(key_id) || mapWatchKeys.count(key_id)); | |||||
// This adds the redeemscripts necessary to detect alternative outputs using | |||||
// the same keys. Also note that having superfluous scripts in the keystore | |||||
// never hurts. They're only used to guide recursion in signing and IsMine | |||||
// logic - if a script is present but we can't do anything with it, it has | |||||
// no effect. "Implicitly" refers to fact that scripts are derived | |||||
// automatically from existing keys, and are present in memory, even without | |||||
// being explicitly loaded (e.g. from a file). | |||||
// Right now there are none so do nothing. | |||||
} | |||||
bool CBasicKeyStore::GetPubKey(const CKeyID &address, | bool CBasicKeyStore::GetPubKey(const CKeyID &address, | ||||
CPubKey &vchPubKeyOut) const { | CPubKey &vchPubKeyOut) const { | ||||
CKey key; | CKey key; | ||||
if (!GetKey(address, key)) { | if (!GetKey(address, key)) { | ||||
LOCK(cs_KeyStore); | LOCK(cs_KeyStore); | ||||
WatchKeyMap::const_iterator it = mapWatchKeys.find(address); | WatchKeyMap::const_iterator it = mapWatchKeys.find(address); | ||||
if (it != mapWatchKeys.end()) { | if (it != mapWatchKeys.end()) { | ||||
vchPubKeyOut = it->second; | vchPubKeyOut = it->second; | ||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
vchPubKeyOut = key.GetPubKey(); | vchPubKeyOut = key.GetPubKey(); | ||||
return true; | return true; | ||||
} | } | ||||
bool CBasicKeyStore::AddKeyPubKey(const CKey &key, const CPubKey &pubkey) { | bool CBasicKeyStore::AddKeyPubKey(const CKey &key, const CPubKey &pubkey) { | ||||
LOCK(cs_KeyStore); | LOCK(cs_KeyStore); | ||||
mapKeys[pubkey.GetID()] = key; | mapKeys[pubkey.GetID()] = key; | ||||
ImplicitlyLearnRelatedKeyScripts(pubkey); | |||||
return true; | return true; | ||||
} | } | ||||
bool CBasicKeyStore::HaveKey(const CKeyID &address) const { | bool CBasicKeyStore::HaveKey(const CKeyID &address) const { | ||||
LOCK(cs_KeyStore); | LOCK(cs_KeyStore); | ||||
return mapKeys.count(address) > 0; | return mapKeys.count(address) > 0; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
bool CBasicKeyStore::AddWatchOnly(const CScript &dest) { | bool CBasicKeyStore::AddWatchOnly(const CScript &dest) { | ||||
LOCK(cs_KeyStore); | LOCK(cs_KeyStore); | ||||
setWatchOnly.insert(dest); | setWatchOnly.insert(dest); | ||||
CPubKey pubKey; | CPubKey pubKey; | ||||
if (ExtractPubKey(dest, pubKey)) { | if (ExtractPubKey(dest, pubKey)) { | ||||
mapWatchKeys[pubKey.GetID()] = pubKey; | mapWatchKeys[pubKey.GetID()] = pubKey; | ||||
ImplicitlyLearnRelatedKeyScripts(pubKey); | |||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool CBasicKeyStore::RemoveWatchOnly(const CScript &dest) { | bool CBasicKeyStore::RemoveWatchOnly(const CScript &dest) { | ||||
LOCK(cs_KeyStore); | LOCK(cs_KeyStore); | ||||
setWatchOnly.erase(dest); | setWatchOnly.erase(dest); | ||||
CPubKey pubKey; | CPubKey pubKey; | ||||
if (ExtractPubKey(dest, pubKey)) { | if (ExtractPubKey(dest, pubKey)) { | ||||
mapWatchKeys.erase(pubKey.GetID()); | mapWatchKeys.erase(pubKey.GetID()); | ||||
} | } | ||||
// Related CScripts are not removed; having superfluous scripts around is | |||||
// harmless (see comment in ImplicitlyLearnRelatedKeyScripts). | |||||
return true; | return true; | ||||
} | } | ||||
bool CBasicKeyStore::HaveWatchOnly(const CScript &dest) const { | bool CBasicKeyStore::HaveWatchOnly(const CScript &dest) const { | ||||
LOCK(cs_KeyStore); | LOCK(cs_KeyStore); | ||||
return setWatchOnly.count(dest) > 0; | return setWatchOnly.count(dest) > 0; | ||||
} | } | ||||
Show All 13 Lines |