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