Branch data 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 : : class SigningProvider
# 19 : : {
# 20 : : public:
# 21 : 2361309 : virtual ~SigningProvider() {}
# 22 : 19 : virtual bool GetCScript(const CScriptID &scriptid, CScript& script) const { return false; }
# 23 : 0 : virtual bool HaveCScript(const CScriptID &scriptid) const { return false; }
# 24 : 4 : virtual bool GetPubKey(const CKeyID &address, CPubKey& pubkey) const { return false; }
# 25 : 31 : virtual bool GetKey(const CKeyID &address, CKey& key) const { return false; }
# 26 : 0 : virtual bool HaveKey(const CKeyID &address) const { return false; }
# 27 : 10227 : virtual bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const { return false; }
# 28 : : };
# 29 : :
# 30 : : extern const SigningProvider& DUMMY_SIGNING_PROVIDER;
# 31 : :
# 32 : : 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 : 2284 : 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 : : 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 : : 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 : 467 : 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
|