Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto 2 : // Copyright (c) 2009-2020 The Bitcoin Core developers 3 : // Distributed under the MIT software license, see the accompanying 4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 : 6 : #ifndef BITCOIN_SCRIPT_SIGNINGPROVIDER_H 7 : #define BITCOIN_SCRIPT_SIGNINGPROVIDER_H 8 : 9 : #include <key.h> 10 : #include <pubkey.h> 11 : #include <script/script.h> 12 : #include <script/standard.h> 13 : #include <sync.h> 14 : 15 : struct KeyOriginInfo; 16 : 17 : /** An interface to be implemented by keystores that support signing. */ 18 806423 : class SigningProvider 19 : { 20 : public: 21 787759 : virtual ~SigningProvider() {} 22 15 : virtual bool GetCScript(const CScriptID &scriptid, CScript& script) const { return false; } 23 0 : virtual bool HaveCScript(const CScriptID &scriptid) const { return false; } 24 6 : virtual bool GetPubKey(const CKeyID &address, CPubKey& pubkey) const { return false; } 25 14 : virtual bool GetKey(const CKeyID &address, CKey& key) const { return false; } 26 0 : virtual bool HaveKey(const CKeyID &address) const { return false; } 27 5440 : virtual bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const { return false; } 28 : }; 29 : 30 : extern const SigningProvider& DUMMY_SIGNING_PROVIDER; 31 : 32 1652 : class HidingSigningProvider : public SigningProvider 33 : { 34 : private: 35 : const bool m_hide_secret; 36 : const bool m_hide_origin; 37 : const SigningProvider* m_provider; 38 : 39 : public: 40 1652 : HidingSigningProvider(const SigningProvider* provider, bool hide_secret, bool hide_origin) : m_hide_secret(hide_secret), m_hide_origin(hide_origin), m_provider(provider) {} 41 : bool GetCScript(const CScriptID& scriptid, CScript& script) const override; 42 : bool GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const override; 43 : bool GetKey(const CKeyID& keyid, CKey& key) const override; 44 : bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override; 45 : }; 46 : 47 1183986 : struct FlatSigningProvider final : public SigningProvider 48 : { 49 : std::map<CScriptID, CScript> scripts; 50 : std::map<CKeyID, CPubKey> pubkeys; 51 : std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>> origins; 52 : std::map<CKeyID, CKey> keys; 53 : 54 : bool GetCScript(const CScriptID& scriptid, CScript& script) const override; 55 : bool GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const override; 56 : bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override; 57 : bool GetKey(const CKeyID& keyid, CKey& key) const override; 58 : }; 59 : 60 : FlatSigningProvider Merge(const FlatSigningProvider& a, const FlatSigningProvider& b); 61 : 62 : /** Fillable signing provider that keeps keys in an address->secret map */ 63 2696 : class FillableSigningProvider : public SigningProvider 64 : { 65 : protected: 66 : using KeyMap = std::map<CKeyID, CKey>; 67 : using ScriptMap = std::map<CScriptID, CScript>; 68 : 69 : /** 70 : * Map of key id to unencrypted private keys known by the signing provider. 71 : * Map may be empty if the provider has another source of keys, like an 72 : * encrypted store. 73 : */ 74 : KeyMap mapKeys GUARDED_BY(cs_KeyStore); 75 : 76 : /** 77 : * Map of script id to scripts known by the signing provider. 78 : * 79 : * This map originally just held P2SH redeemScripts, and was used by wallet 80 : * code to look up script ids referenced in "OP_HASH160 <script id> 81 : * OP_EQUAL" P2SH outputs. Later in 605e8473a7d it was extended to hold 82 : * P2WSH witnessScripts as well, and used to look up nested scripts 83 : * referenced in "OP_0 <script hash>" P2WSH outputs. Later in commits 84 : * f4691ab3a9d and 248f3a76a82, it was extended once again to hold segwit 85 : * "OP_0 <key or script hash>" scriptPubKeys, in order to give the wallet a 86 : * way to distinguish between segwit outputs that it generated addresses for 87 : * and wanted to receive payments from, and segwit outputs that it never 88 : * generated addresses for, but it could spend just because of having keys. 89 : * (Before segwit activation it was also important to not treat segwit 90 : * outputs to arbitrary wallet keys as payments, because these could be 91 : * spent by anyone without even needing to sign with the keys.) 92 : * 93 : * Some of the scripts stored in mapScripts are memory-only and 94 : * intentionally not saved to disk. Specifically, scripts added by 95 : * ImplicitlyLearnRelatedKeyScripts(pubkey) calls are not written to disk so 96 : * future wallet code can have flexibility to be more selective about what 97 : * transaction outputs it recognizes as payments, instead of having to treat 98 : * all outputs spending to keys it knows as payments. By contrast, 99 : * mapScripts entries added by AddCScript(script), 100 : * LearnRelatedScripts(pubkey, type), and LearnAllRelatedScripts(pubkey) 101 : * calls are saved because they are all intentionally used to receive 102 : * payments. 103 : * 104 : * The FillableSigningProvider::mapScripts script map should not be confused 105 : * with LegacyScriptPubKeyMan::setWatchOnly script set. The two collections 106 : * can hold the same scripts, but they serve different purposes. The 107 : * setWatchOnly script set is intended to expand the set of outputs the 108 : * wallet considers payments. Every output with a script it contains is 109 : * considered to belong to the wallet, regardless of whether the script is 110 : * solvable or signable. By contrast, the scripts in mapScripts are only 111 : * used for solving, and to restrict which outputs are considered payments 112 : * by the wallet. An output with a script in mapScripts, unlike 113 : * setWatchOnly, is not automatically considered to belong to the wallet if 114 : * it can't be solved and signed for. 115 : */ 116 : ScriptMap mapScripts GUARDED_BY(cs_KeyStore); 117 : 118 : void ImplicitlyLearnRelatedKeyScripts(const CPubKey& pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore); 119 : 120 : public: 121 : mutable RecursiveMutex cs_KeyStore; 122 : 123 : virtual bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey); 124 362 : virtual bool AddKey(const CKey &key) { return AddKeyPubKey(key, key.GetPubKey()); } 125 : virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const override; 126 : virtual bool HaveKey(const CKeyID &address) const override; 127 : virtual std::set<CKeyID> GetKeys() const; 128 : virtual bool GetKey(const CKeyID &address, CKey &keyOut) const override; 129 : virtual bool AddCScript(const CScript& redeemScript); 130 : virtual bool HaveCScript(const CScriptID &hash) const override; 131 : virtual std::set<CScriptID> GetCScripts() const; 132 : virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const override; 133 : }; 134 : 135 : /** Return the CKeyID of the key involved in a script (if there is a unique one). */ 136 : CKeyID GetKeyForDestination(const SigningProvider& store, const CTxDestination& dest); 137 : 138 : #endif // BITCOIN_SCRIPT_SIGNINGPROVIDER_H