LCOV - code coverage report
Current view: top level - src/script - signingprovider.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 134 135 99.3 %
Date: 2021-06-29 14:35:33 Functions: 24 24 100.0 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 39 40 97.5 %

           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                 :            : #include <script/keyorigin.h>
#       7                 :            : #include <script/signingprovider.h>
#       8                 :            : #include <script/standard.h>
#       9                 :            : 
#      10                 :            : #include <util/system.h>
#      11                 :            : 
#      12                 :            : const SigningProvider& DUMMY_SIGNING_PROVIDER = SigningProvider();
#      13                 :            : 
#      14                 :            : template<typename M, typename K, typename V>
#      15                 :            : bool LookupHelper(const M& map, const K& key, V& value)
#      16                 :     732354 : {
#      17                 :     732354 :     auto it = map.find(key);
#      18 [ +  + ][ +  + ]:     732354 :     if (it != map.end()) {
#         [ +  + ][ +  + ]
#      19                 :     691892 :         value = it->second;
#      20                 :     691892 :         return true;
#      21                 :     691892 :     }
#      22                 :      40462 :     return false;
#      23                 :      40462 : }
#      24                 :            : 
#      25                 :            : bool HidingSigningProvider::GetCScript(const CScriptID& scriptid, CScript& script) const
#      26                 :        685 : {
#      27                 :        685 :     return m_provider->GetCScript(scriptid, script);
#      28                 :        685 : }
#      29                 :            : 
#      30                 :            : bool HidingSigningProvider::GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const
#      31                 :       1113 : {
#      32                 :       1113 :     return m_provider->GetPubKey(keyid, pubkey);
#      33                 :       1113 : }
#      34                 :            : 
#      35                 :            : bool HidingSigningProvider::GetKey(const CKeyID& keyid, CKey& key) const
#      36                 :       1822 : {
#      37         [ +  + ]:       1822 :     if (m_hide_secret) return false;
#      38                 :        527 :     return m_provider->GetKey(keyid, key);
#      39                 :        527 : }
#      40                 :            : 
#      41                 :            : bool HidingSigningProvider::GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const
#      42                 :       1822 : {
#      43         [ +  + ]:       1822 :     if (m_hide_origin) return false;
#      44                 :       1511 :     return m_provider->GetKeyOrigin(keyid, info);
#      45                 :       1511 : }
#      46                 :            : 
#      47                 :      20732 : bool FlatSigningProvider::GetCScript(const CScriptID& scriptid, CScript& script) const { return LookupHelper(scripts, scriptid, script); }
#      48                 :     350235 : bool FlatSigningProvider::GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const { return LookupHelper(pubkeys, keyid, pubkey); }
#      49                 :            : bool FlatSigningProvider::GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const
#      50                 :     335708 : {
#      51                 :     335708 :     std::pair<CPubKey, KeyOriginInfo> out;
#      52                 :     335708 :     bool ret = LookupHelper(origins, keyid, out);
#      53         [ +  + ]:     335708 :     if (ret) info = std::move(out.second);
#      54                 :     335708 :     return ret;
#      55                 :     335708 : }
#      56                 :      25679 : bool FlatSigningProvider::GetKey(const CKeyID& keyid, CKey& key) const { return LookupHelper(keys, keyid, key); }
#      57                 :            : 
#      58                 :            : FlatSigningProvider Merge(const FlatSigningProvider& a, const FlatSigningProvider& b)
#      59                 :     563842 : {
#      60                 :     563842 :     FlatSigningProvider ret;
#      61                 :     563842 :     ret.scripts = a.scripts;
#      62                 :     563842 :     ret.scripts.insert(b.scripts.begin(), b.scripts.end());
#      63                 :     563842 :     ret.pubkeys = a.pubkeys;
#      64                 :     563842 :     ret.pubkeys.insert(b.pubkeys.begin(), b.pubkeys.end());
#      65                 :     563842 :     ret.keys = a.keys;
#      66                 :     563842 :     ret.keys.insert(b.keys.begin(), b.keys.end());
#      67                 :     563842 :     ret.origins = a.origins;
#      68                 :     563842 :     ret.origins.insert(b.origins.begin(), b.origins.end());
#      69                 :     563842 :     return ret;
#      70                 :     563842 : }
#      71                 :            : 
#      72                 :            : void FillableSigningProvider::ImplicitlyLearnRelatedKeyScripts(const CPubKey& pubkey)
#      73                 :      39447 : {
#      74                 :      39447 :     AssertLockHeld(cs_KeyStore);
#      75                 :      39447 :     CKeyID key_id = pubkey.GetID();
#      76                 :            :     // This adds the redeemscripts necessary to detect P2WPKH and P2SH-P2WPKH
#      77                 :            :     // outputs. Technically P2WPKH outputs don't have a redeemscript to be
#      78                 :            :     // spent. However, our current IsMine logic requires the corresponding
#      79                 :            :     // P2SH-P2WPKH redeemscript to be present in the wallet in order to accept
#      80                 :            :     // payment even to P2WPKH outputs.
#      81                 :            :     // Also note that having superfluous scripts in the keystore never hurts.
#      82                 :            :     // They're only used to guide recursion in signing and IsMine logic - if
#      83                 :            :     // a script is present but we can't do anything with it, it has no effect.
#      84                 :            :     // "Implicitly" refers to fact that scripts are derived automatically from
#      85                 :            :     // existing keys, and are present in memory, even without being explicitly
#      86                 :            :     // loaded (e.g. from a file).
#      87         [ +  + ]:      39447 :     if (pubkey.IsCompressed()) {
#      88                 :      37414 :         CScript script = GetScriptForDestination(WitnessV0KeyHash(key_id));
#      89                 :            :         // This does not use AddCScript, as it may be overridden.
#      90                 :      37414 :         CScriptID id(script);
#      91                 :      37414 :         mapScripts[id] = std::move(script);
#      92                 :      37414 :     }
#      93                 :      39447 : }
#      94                 :            : 
#      95                 :            : bool FillableSigningProvider::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
#      96                 :    1246979 : {
#      97                 :    1246979 :     CKey key;
#      98         [ +  + ]:    1246979 :     if (!GetKey(address, key)) {
#      99                 :      33960 :         return false;
#     100                 :      33960 :     }
#     101                 :    1213019 :     vchPubKeyOut = key.GetPubKey();
#     102                 :    1213019 :     return true;
#     103                 :    1213019 : }
#     104                 :            : 
#     105                 :            : bool FillableSigningProvider::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
#     106                 :      38170 : {
#     107                 :      38170 :     LOCK(cs_KeyStore);
#     108                 :      38170 :     mapKeys[pubkey.GetID()] = key;
#     109                 :      38170 :     ImplicitlyLearnRelatedKeyScripts(pubkey);
#     110                 :      38170 :     return true;
#     111                 :      38170 : }
#     112                 :            : 
#     113                 :            : bool FillableSigningProvider::HaveKey(const CKeyID &address) const
#     114                 :    1171676 : {
#     115                 :    1171676 :     LOCK(cs_KeyStore);
#     116                 :    1171676 :     return mapKeys.count(address) > 0;
#     117                 :    1171676 : }
#     118                 :            : 
#     119                 :            : std::set<CKeyID> FillableSigningProvider::GetKeys() const
#     120                 :          5 : {
#     121                 :          5 :     LOCK(cs_KeyStore);
#     122                 :          5 :     std::set<CKeyID> set_address;
#     123         [ +  + ]:        858 :     for (const auto& mi : mapKeys) {
#     124                 :        858 :         set_address.insert(mi.first);
#     125                 :        858 :     }
#     126                 :          5 :     return set_address;
#     127                 :          5 : }
#     128                 :            : 
#     129                 :            : bool FillableSigningProvider::GetKey(const CKeyID &address, CKey &keyOut) const
#     130                 :    1305240 : {
#     131                 :    1305240 :     LOCK(cs_KeyStore);
#     132                 :    1305240 :     KeyMap::const_iterator mi = mapKeys.find(address);
#     133         [ +  + ]:    1305240 :     if (mi != mapKeys.end()) {
#     134                 :    1271015 :         keyOut = mi->second;
#     135                 :    1271015 :         return true;
#     136                 :    1271015 :     }
#     137                 :      34225 :     return false;
#     138                 :      34225 : }
#     139                 :            : 
#     140                 :            : bool FillableSigningProvider::AddCScript(const CScript& redeemScript)
#     141                 :      24099 : {
#     142         [ -  + ]:      24099 :     if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
#     143                 :          0 :         return error("FillableSigningProvider::AddCScript(): redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE);
#     144                 :            : 
#     145                 :      24099 :     LOCK(cs_KeyStore);
#     146                 :      24099 :     mapScripts[CScriptID(redeemScript)] = redeemScript;
#     147                 :      24099 :     return true;
#     148                 :      24099 : }
#     149                 :            : 
#     150                 :            : bool FillableSigningProvider::HaveCScript(const CScriptID& hash) const
#     151                 :     808069 : {
#     152                 :     808069 :     LOCK(cs_KeyStore);
#     153                 :     808069 :     return mapScripts.count(hash) > 0;
#     154                 :     808069 : }
#     155                 :            : 
#     156                 :            : std::set<CScriptID> FillableSigningProvider::GetCScripts() const
#     157                 :          6 : {
#     158                 :          6 :     LOCK(cs_KeyStore);
#     159                 :          6 :     std::set<CScriptID> set_script;
#     160         [ +  + ]:       1252 :     for (const auto& mi : mapScripts) {
#     161                 :       1252 :         set_script.insert(mi.first);
#     162                 :       1252 :     }
#     163                 :          6 :     return set_script;
#     164                 :          6 : }
#     165                 :            : 
#     166                 :            : bool FillableSigningProvider::GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const
#     167                 :     156818 : {
#     168                 :     156818 :     LOCK(cs_KeyStore);
#     169                 :     156818 :     ScriptMap::const_iterator mi = mapScripts.find(hash);
#     170         [ +  + ]:     156818 :     if (mi != mapScripts.end())
#     171                 :      43445 :     {
#     172                 :      43445 :         redeemScriptOut = (*mi).second;
#     173                 :      43445 :         return true;
#     174                 :      43445 :     }
#     175                 :     113373 :     return false;
#     176                 :     113373 : }
#     177                 :            : 
#     178                 :            : CKeyID GetKeyForDestination(const SigningProvider& store, const CTxDestination& dest)
#     179                 :       1452 : {
#     180                 :            :     // Only supports destinations which map to single public keys, i.e. P2PKH,
#     181                 :            :     // P2WPKH, and P2SH-P2WPKH.
#     182         [ +  + ]:       1452 :     if (auto id = std::get_if<PKHash>(&dest)) {
#     183                 :        378 :         return ToKeyID(*id);
#     184                 :        378 :     }
#     185         [ +  + ]:       1074 :     if (auto witness_id = std::get_if<WitnessV0KeyHash>(&dest)) {
#     186                 :        654 :         return ToKeyID(*witness_id);
#     187                 :        654 :     }
#     188         [ +  + ]:        420 :     if (auto script_hash = std::get_if<ScriptHash>(&dest)) {
#     189                 :        377 :         CScript script;
#     190                 :        377 :         CScriptID script_id(*script_hash);
#     191                 :        377 :         CTxDestination inner_dest;
#     192 [ +  + ][ +  + ]:        377 :         if (store.GetCScript(script_id, script) && ExtractDestination(script, inner_dest)) {
#     193         [ +  + ]:        322 :             if (auto inner_witness_id = std::get_if<WitnessV0KeyHash>(&inner_dest)) {
#     194                 :        287 :                 return ToKeyID(*inner_witness_id);
#     195                 :        287 :             }
#     196                 :        133 :         }
#     197                 :        377 :     }
#     198                 :        133 :     return CKeyID();
#     199                 :        133 : }

Generated by: LCOV version 1.14