LCOV - code coverage report
Current view: top level - src/script - signingprovider.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 154 155 99.4 %
Date: 2022-04-21 14:51:19 Functions: 27 27 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: 50 54 92.6 %

           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                 :            : #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                 :     812806 : {
#      17                 :     812806 :     auto it = map.find(key);
#      18 [ +  + ][ +  + ]:     812806 :     if (it != map.end()) {
#         [ +  + ][ +  + ]
#                 [ +  + ]
#      19                 :     703547 :         value = it->second;
#      20                 :     703547 :         return true;
#      21                 :     703547 :     }
#      22                 :     109259 :     return false;
#      23                 :     812806 : }
#      24                 :            : 
#      25                 :            : bool HidingSigningProvider::GetCScript(const CScriptID& scriptid, CScript& script) const
#      26                 :       2182 : {
#      27                 :       2182 :     return m_provider->GetCScript(scriptid, script);
#      28                 :       2182 : }
#      29                 :            : 
#      30                 :            : bool HidingSigningProvider::GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const
#      31                 :       1777 : {
#      32                 :       1777 :     return m_provider->GetPubKey(keyid, pubkey);
#      33                 :       1777 : }
#      34                 :            : 
#      35                 :            : bool HidingSigningProvider::GetKey(const CKeyID& keyid, CKey& key) const
#      36                 :      24641 : {
#      37         [ +  + ]:      24641 :     if (m_hide_secret) return false;
#      38                 :      10623 :     return m_provider->GetKey(keyid, key);
#      39                 :      24641 : }
#      40                 :            : 
#      41                 :            : bool HidingSigningProvider::GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const
#      42                 :       4558 : {
#      43         [ +  + ]:       4558 :     if (m_hide_origin) return false;
#      44                 :       3891 :     return m_provider->GetKeyOrigin(keyid, info);
#      45                 :       4558 : }
#      46                 :            : 
#      47                 :            : bool HidingSigningProvider::GetTaprootSpendData(const XOnlyPubKey& output_key, TaprootSpendData& spenddata) const
#      48                 :       1846 : {
#      49                 :       1846 :     return m_provider->GetTaprootSpendData(output_key, spenddata);
#      50                 :       1846 : }
#      51                 :            : 
#      52                 :      27078 : bool FlatSigningProvider::GetCScript(const CScriptID& scriptid, CScript& script) const { return LookupHelper(scripts, scriptid, script); }
#      53                 :     350817 : bool FlatSigningProvider::GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const { return LookupHelper(pubkeys, keyid, pubkey); }
#      54                 :            : bool FlatSigningProvider::GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const
#      55                 :     342721 : {
#      56                 :     342721 :     std::pair<CPubKey, KeyOriginInfo> out;
#      57                 :     342721 :     bool ret = LookupHelper(origins, keyid, out);
#      58         [ +  + ]:     342721 :     if (ret) info = std::move(out.second);
#      59                 :     342721 :     return ret;
#      60                 :     342721 : }
#      61                 :      86348 : bool FlatSigningProvider::GetKey(const CKeyID& keyid, CKey& key) const { return LookupHelper(keys, keyid, key); }
#      62                 :            : bool FlatSigningProvider::GetTaprootSpendData(const XOnlyPubKey& output_key, TaprootSpendData& spenddata) const
#      63                 :       5842 : {
#      64                 :       5842 :     return LookupHelper(tr_spenddata, output_key, spenddata);
#      65                 :       5842 : }
#      66                 :            : 
#      67                 :            : FlatSigningProvider Merge(const FlatSigningProvider& a, const FlatSigningProvider& b)
#      68                 :     708329 : {
#      69                 :     708329 :     FlatSigningProvider ret;
#      70                 :     708329 :     ret.scripts = a.scripts;
#      71                 :     708329 :     ret.scripts.insert(b.scripts.begin(), b.scripts.end());
#      72                 :     708329 :     ret.pubkeys = a.pubkeys;
#      73                 :     708329 :     ret.pubkeys.insert(b.pubkeys.begin(), b.pubkeys.end());
#      74                 :     708329 :     ret.keys = a.keys;
#      75                 :     708329 :     ret.keys.insert(b.keys.begin(), b.keys.end());
#      76                 :     708329 :     ret.origins = a.origins;
#      77                 :     708329 :     ret.origins.insert(b.origins.begin(), b.origins.end());
#      78                 :     708329 :     ret.tr_spenddata = a.tr_spenddata;
#      79         [ +  + ]:     708329 :     for (const auto& [output_key, spenddata] : b.tr_spenddata) {
#      80                 :        468 :         ret.tr_spenddata[output_key].Merge(spenddata);
#      81                 :        468 :     }
#      82                 :     708329 :     return ret;
#      83                 :     708329 : }
#      84                 :            : 
#      85                 :            : void FillableSigningProvider::ImplicitlyLearnRelatedKeyScripts(const CPubKey& pubkey)
#      86                 :      33602 : {
#      87                 :      33602 :     AssertLockHeld(cs_KeyStore);
#      88                 :      33602 :     CKeyID key_id = pubkey.GetID();
#      89                 :            :     // This adds the redeemscripts necessary to detect P2WPKH and P2SH-P2WPKH
#      90                 :            :     // outputs. Technically P2WPKH outputs don't have a redeemscript to be
#      91                 :            :     // spent. However, our current IsMine logic requires the corresponding
#      92                 :            :     // P2SH-P2WPKH redeemscript to be present in the wallet in order to accept
#      93                 :            :     // payment even to P2WPKH outputs.
#      94                 :            :     // Also note that having superfluous scripts in the keystore never hurts.
#      95                 :            :     // They're only used to guide recursion in signing and IsMine logic - if
#      96                 :            :     // a script is present but we can't do anything with it, it has no effect.
#      97                 :            :     // "Implicitly" refers to fact that scripts are derived automatically from
#      98                 :            :     // existing keys, and are present in memory, even without being explicitly
#      99                 :            :     // loaded (e.g. from a file).
#     100         [ +  + ]:      33602 :     if (pubkey.IsCompressed()) {
#     101                 :      33572 :         CScript script = GetScriptForDestination(WitnessV0KeyHash(key_id));
#     102                 :            :         // This does not use AddCScript, as it may be overridden.
#     103                 :      33572 :         CScriptID id(script);
#     104                 :      33572 :         mapScripts[id] = std::move(script);
#     105                 :      33572 :     }
#     106                 :      33602 : }
#     107                 :            : 
#     108                 :            : bool FillableSigningProvider::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
#     109                 :    1074664 : {
#     110                 :    1074664 :     CKey key;
#     111         [ +  + ]:    1074664 :     if (!GetKey(address, key)) {
#     112                 :      37645 :         return false;
#     113                 :      37645 :     }
#     114                 :    1037019 :     vchPubKeyOut = key.GetPubKey();
#     115                 :    1037019 :     return true;
#     116                 :    1074664 : }
#     117                 :            : 
#     118                 :            : bool FillableSigningProvider::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
#     119                 :      32023 : {
#     120                 :      32023 :     LOCK(cs_KeyStore);
#     121                 :      32023 :     mapKeys[pubkey.GetID()] = key;
#     122                 :      32023 :     ImplicitlyLearnRelatedKeyScripts(pubkey);
#     123                 :      32023 :     return true;
#     124                 :      32023 : }
#     125                 :            : 
#     126                 :            : bool FillableSigningProvider::HaveKey(const CKeyID &address) const
#     127                 :    1012480 : {
#     128                 :    1012480 :     LOCK(cs_KeyStore);
#     129                 :    1012480 :     return mapKeys.count(address) > 0;
#     130                 :    1012480 : }
#     131                 :            : 
#     132                 :            : std::set<CKeyID> FillableSigningProvider::GetKeys() const
#     133                 :          6 : {
#     134                 :          6 :     LOCK(cs_KeyStore);
#     135                 :          6 :     std::set<CKeyID> set_address;
#     136         [ +  + ]:       1043 :     for (const auto& mi : mapKeys) {
#     137                 :       1043 :         set_address.insert(mi.first);
#     138                 :       1043 :     }
#     139                 :          6 :     return set_address;
#     140                 :          6 : }
#     141                 :            : 
#     142                 :            : bool FillableSigningProvider::GetKey(const CKeyID &address, CKey &keyOut) const
#     143                 :    1123691 : {
#     144                 :    1123691 :     LOCK(cs_KeyStore);
#     145                 :    1123691 :     KeyMap::const_iterator mi = mapKeys.find(address);
#     146         [ +  + ]:    1123691 :     if (mi != mapKeys.end()) {
#     147                 :    1085889 :         keyOut = mi->second;
#     148                 :    1085889 :         return true;
#     149                 :    1085889 :     }
#     150                 :      37802 :     return false;
#     151                 :    1123691 : }
#     152                 :            : 
#     153                 :            : bool FillableSigningProvider::AddCScript(const CScript& redeemScript)
#     154                 :      23899 : {
#     155         [ -  + ]:      23899 :     if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
#     156                 :          0 :         return error("FillableSigningProvider::AddCScript(): redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE);
#     157                 :            : 
#     158                 :      23899 :     LOCK(cs_KeyStore);
#     159                 :      23899 :     mapScripts[CScriptID(redeemScript)] = redeemScript;
#     160                 :      23899 :     return true;
#     161                 :      23899 : }
#     162                 :            : 
#     163                 :            : bool FillableSigningProvider::HaveCScript(const CScriptID& hash) const
#     164                 :     796444 : {
#     165                 :     796444 :     LOCK(cs_KeyStore);
#     166                 :     796444 :     return mapScripts.count(hash) > 0;
#     167                 :     796444 : }
#     168                 :            : 
#     169                 :            : std::set<CScriptID> FillableSigningProvider::GetCScripts() const
#     170                 :          7 : {
#     171                 :          7 :     LOCK(cs_KeyStore);
#     172                 :          7 :     std::set<CScriptID> set_script;
#     173         [ +  + ]:       1437 :     for (const auto& mi : mapScripts) {
#     174                 :       1437 :         set_script.insert(mi.first);
#     175                 :       1437 :     }
#     176                 :          7 :     return set_script;
#     177                 :          7 : }
#     178                 :            : 
#     179                 :            : bool FillableSigningProvider::GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const
#     180                 :     122887 : {
#     181                 :     122887 :     LOCK(cs_KeyStore);
#     182                 :     122887 :     ScriptMap::const_iterator mi = mapScripts.find(hash);
#     183         [ +  + ]:     122887 :     if (mi != mapScripts.end())
#     184                 :      65171 :     {
#     185                 :      65171 :         redeemScriptOut = (*mi).second;
#     186                 :      65171 :         return true;
#     187                 :      65171 :     }
#     188                 :      57716 :     return false;
#     189                 :     122887 : }
#     190                 :            : 
#     191                 :            : CKeyID GetKeyForDestination(const SigningProvider& store, const CTxDestination& dest)
#     192                 :       1555 : {
#     193                 :            :     // Only supports destinations which map to single public keys:
#     194                 :            :     // P2PKH, P2WPKH, P2SH-P2WPKH, P2TR
#     195         [ +  + ]:       1555 :     if (auto id = std::get_if<PKHash>(&dest)) {
#     196                 :        383 :         return ToKeyID(*id);
#     197                 :        383 :     }
#     198         [ +  + ]:       1172 :     if (auto witness_id = std::get_if<WitnessV0KeyHash>(&dest)) {
#     199                 :        653 :         return ToKeyID(*witness_id);
#     200                 :        653 :     }
#     201         [ +  + ]:        519 :     if (auto script_hash = std::get_if<ScriptHash>(&dest)) {
#     202                 :        390 :         CScript script;
#     203                 :        390 :         CScriptID script_id(*script_hash);
#     204                 :        390 :         CTxDestination inner_dest;
#     205 [ +  + ][ +  + ]:        390 :         if (store.GetCScript(script_id, script) && ExtractDestination(script, inner_dest)) {
#     206         [ +  + ]:        335 :             if (auto inner_witness_id = std::get_if<WitnessV0KeyHash>(&inner_dest)) {
#     207                 :        294 :                 return ToKeyID(*inner_witness_id);
#     208                 :        294 :             }
#     209                 :        335 :         }
#     210                 :        390 :     }
#     211         [ +  + ]:        225 :     if (auto output_key = std::get_if<WitnessV1Taproot>(&dest)) {
#     212                 :         66 :         TaprootSpendData spenddata;
#     213                 :         66 :         CPubKey pub;
#     214         [ +  - ]:         66 :         if (store.GetTaprootSpendData(*output_key, spenddata)
#     215         [ +  - ]:         66 :             && !spenddata.internal_key.IsNull()
#     216         [ +  + ]:         66 :             && spenddata.merkle_root.IsNull()
#     217         [ +  - ]:         66 :             && store.GetPubKeyByXOnly(spenddata.internal_key, pub)) {
#     218                 :          6 :             return pub.GetID();
#     219                 :          6 :         }
#     220                 :         66 :     }
#     221                 :        219 :     return CKeyID();
#     222                 :        225 : }

Generated by: LCOV version 0-eol-96201-ge66f56f4af6a