LCOV - code coverage report
Current view: top level - src/script - signingprovider.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 116 119 97.5 %
Date: 2020-09-26 01:30:44 Functions: 25 25 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2019 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         731 : const SigningProvider& DUMMY_SIGNING_PROVIDER = SigningProvider();
      13             : 
      14             : template<typename M, typename K, typename V>
      15      214948 : bool LookupHelper(const M& map, const K& key, V& value)
      16             : {
      17      214948 :     auto it = map.find(key);
      18      214948 :     if (it != map.end()) {
      19      209973 :         value = it->second;
      20      209973 :         return true;
      21             :     }
      22        4975 :     return false;
      23      214948 : }
      24             : 
      25         385 : bool HidingSigningProvider::GetCScript(const CScriptID& scriptid, CScript& script) const
      26             : {
      27         385 :     return m_provider->GetCScript(scriptid, script);
      28             : }
      29             : 
      30         449 : bool HidingSigningProvider::GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const
      31             : {
      32         449 :     return m_provider->GetPubKey(keyid, pubkey);
      33             : }
      34             : 
      35         764 : bool HidingSigningProvider::GetKey(const CKeyID& keyid, CKey& key) const
      36             : {
      37         764 :     if (m_hide_secret) return false;
      38         299 :     return m_provider->GetKey(keyid, key);
      39         764 : }
      40             : 
      41         764 : bool HidingSigningProvider::GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const
      42             : {
      43         764 :     if (m_hide_origin) return false;
      44         702 :     return m_provider->GetKeyOrigin(keyid, info);
      45         764 : }
      46             : 
      47       19072 : bool FlatSigningProvider::GetCScript(const CScriptID& scriptid, CScript& script) const { return LookupHelper(scripts, scriptid, script); }
      48       84860 : bool FlatSigningProvider::GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const { return LookupHelper(pubkeys, keyid, pubkey); }
      49      101065 : bool FlatSigningProvider::GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const
      50             : {
      51      101065 :     std::pair<CPubKey, KeyOriginInfo> out;
      52      101065 :     bool ret = LookupHelper(origins, keyid, out);
      53      101065 :     if (ret) info = std::move(out.second);
      54             :     return ret;
      55      101065 : }
      56        9951 : bool FlatSigningProvider::GetKey(const CKeyID& keyid, CKey& key) const { return LookupHelper(keys, keyid, key); }
      57             : 
      58       19208 : FlatSigningProvider Merge(const FlatSigningProvider& a, const FlatSigningProvider& b)
      59             : {
      60       19208 :     FlatSigningProvider ret;
      61       19208 :     ret.scripts = a.scripts;
      62       19208 :     ret.scripts.insert(b.scripts.begin(), b.scripts.end());
      63       19208 :     ret.pubkeys = a.pubkeys;
      64       19208 :     ret.pubkeys.insert(b.pubkeys.begin(), b.pubkeys.end());
      65       19208 :     ret.keys = a.keys;
      66       19208 :     ret.keys.insert(b.keys.begin(), b.keys.end());
      67       19208 :     ret.origins = a.origins;
      68       19208 :     ret.origins.insert(b.origins.begin(), b.origins.end());
      69             :     return ret;
      70       19208 : }
      71             : 
      72       38183 : void FillableSigningProvider::ImplicitlyLearnRelatedKeyScripts(const CPubKey& pubkey)
      73             : {
      74       38183 :     AssertLockHeld(cs_KeyStore);
      75       38183 :     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       38183 :     if (pubkey.IsCompressed()) {
      88       33149 :         CScript script = GetScriptForDestination(WitnessV0KeyHash(key_id));
      89             :         // This does not use AddCScript, as it may be overridden.
      90       33149 :         CScriptID id(script);
      91       33149 :         mapScripts[id] = std::move(script);
      92       33149 :     }
      93       38183 : }
      94             : 
      95      798995 : bool FillableSigningProvider::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
      96             : {
      97      798995 :     CKey key;
      98      798995 :     if (!GetKey(address, key)) {
      99       29144 :         return false;
     100             :     }
     101      769851 :     vchPubKeyOut = key.GetPubKey();
     102      769851 :     return true;
     103      798995 : }
     104             : 
     105       37109 : bool FillableSigningProvider::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
     106             : {
     107       37109 :     LOCK(cs_KeyStore);
     108       37109 :     mapKeys[pubkey.GetID()] = key;
     109       37109 :     ImplicitlyLearnRelatedKeyScripts(pubkey);
     110             :     return true;
     111       37109 : }
     112             : 
     113      881121 : bool FillableSigningProvider::HaveKey(const CKeyID &address) const
     114             : {
     115      881121 :     LOCK(cs_KeyStore);
     116      881121 :     return mapKeys.count(address) > 0;
     117      881121 : }
     118             : 
     119           5 : std::set<CKeyID> FillableSigningProvider::GetKeys() const
     120             : {
     121           5 :     LOCK(cs_KeyStore);
     122           5 :     std::set<CKeyID> set_address;
     123         863 :     for (const auto& mi : mapKeys) {
     124         858 :         set_address.insert(mi.first);
     125           0 :     }
     126             :     return set_address;
     127           5 : }
     128             : 
     129      841510 : bool FillableSigningProvider::GetKey(const CKeyID &address, CKey &keyOut) const
     130             : {
     131      841510 :     LOCK(cs_KeyStore);
     132      841510 :     KeyMap::const_iterator mi = mapKeys.find(address);
     133      841510 :     if (mi != mapKeys.end()) {
     134      812115 :         keyOut = mi->second;
     135      812115 :         return true;
     136             :     }
     137       29395 :     return false;
     138      841510 : }
     139             : 
     140       20081 : bool FillableSigningProvider::AddCScript(const CScript& redeemScript)
     141             : {
     142       20081 :     if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
     143           0 :         return error("FillableSigningProvider::AddCScript(): redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE);
     144             : 
     145       20081 :     LOCK(cs_KeyStore);
     146       20081 :     mapScripts[CScriptID(redeemScript)] = redeemScript;
     147             :     return true;
     148       20081 : }
     149             : 
     150      462616 : bool FillableSigningProvider::HaveCScript(const CScriptID& hash) const
     151             : {
     152      462616 :     LOCK(cs_KeyStore);
     153      462616 :     return mapScripts.count(hash) > 0;
     154      462616 : }
     155             : 
     156           6 : std::set<CScriptID> FillableSigningProvider::GetCScripts() const
     157             : {
     158           6 :     LOCK(cs_KeyStore);
     159           6 :     std::set<CScriptID> set_script;
     160        1258 :     for (const auto& mi : mapScripts) {
     161        1252 :         set_script.insert(mi.first);
     162           0 :     }
     163             :     return set_script;
     164           6 : }
     165             : 
     166      157958 : bool FillableSigningProvider::GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const
     167             : {
     168      157958 :     LOCK(cs_KeyStore);
     169      157958 :     ScriptMap::const_iterator mi = mapScripts.find(hash);
     170      157958 :     if (mi != mapScripts.end())
     171             :     {
     172       34232 :         redeemScriptOut = (*mi).second;
     173       34232 :         return true;
     174             :     }
     175      123726 :     return false;
     176      157958 : }
     177             : 
     178        1245 : CKeyID GetKeyForDestination(const SigningProvider& store, const CTxDestination& dest)
     179             : {
     180             :     // Only supports destinations which map to single public keys, i.e. P2PKH,
     181             :     // P2WPKH, and P2SH-P2WPKH.
     182        1245 :     if (auto id = boost::get<PKHash>(&dest)) {
     183         335 :         return ToKeyID(*id);
     184             :     }
     185         910 :     if (auto witness_id = boost::get<WitnessV0KeyHash>(&dest)) {
     186         562 :         return ToKeyID(*witness_id);
     187             :     }
     188         439 :     if (auto script_hash = boost::get<ScriptHash>(&dest)) {
     189         305 :         CScript script;
     190         305 :         CScriptID script_id(*script_hash);
     191         305 :         CTxDestination inner_dest;
     192         305 :         if (store.GetCScript(script_id, script) && ExtractDestination(script, inner_dest)) {
     193         249 :             if (auto inner_witness_id = boost::get<WitnessV0KeyHash>(&inner_dest)) {
     194         214 :                 return ToKeyID(*inner_witness_id);
     195             :             }
     196             :         }
     197         305 :     }
     198         134 :     return CKeyID();
     199        1245 : }

Generated by: LCOV version 1.15