LCOV - code coverage report
Current view: top level - src/script - signingprovider.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 11 13 84.6 %
Date: 2020-09-26 01:30:44 Functions: 24 29 82.8 %

          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

Generated by: LCOV version 1.15