diff --git a/src/keystore.h b/src/keystore.h --- a/src/keystore.h +++ b/src/keystore.h @@ -62,6 +62,8 @@ ScriptMap mapScripts; WatchOnlySet setWatchOnly; + void ImplicitlyLearnRelatedKeyScripts(const CPubKey &pubkey); + public: bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override; bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override; diff --git a/src/keystore.cpp b/src/keystore.cpp --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -13,6 +13,22 @@ 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, CPubKey &vchPubKeyOut) const { CKey key; @@ -32,6 +48,7 @@ bool CBasicKeyStore::AddKeyPubKey(const CKey &key, const CPubKey &pubkey) { LOCK(cs_KeyStore); mapKeys[pubkey.GetID()] = key; + ImplicitlyLearnRelatedKeyScripts(pubkey); return true; } @@ -121,6 +138,7 @@ CPubKey pubKey; if (ExtractPubKey(dest, pubKey)) { mapWatchKeys[pubKey.GetID()] = pubKey; + ImplicitlyLearnRelatedKeyScripts(pubKey); } return true; } @@ -132,6 +150,8 @@ if (ExtractPubKey(dest, pubKey)) { mapWatchKeys.erase(pubKey.GetID()); } + // Related CScripts are not removed; having superfluous scripts around is + // harmless (see comment in ImplicitlyLearnRelatedKeyScripts). return true; } diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -270,6 +270,7 @@ } mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret); + ImplicitlyLearnRelatedKeyScripts(vchPubKey); return true; }