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 3516 : const SigningProvider& DUMMY_SIGNING_PROVIDER = SigningProvider(); 13 : 14 : template<typename M, typename K, typename V> 15 796814 : bool LookupHelper(const M& map, const K& key, V& value) 16 : { 17 796814 : auto it = map.find(key); 18 796814 : if (it != map.end()) { 19 767750 : value = it->second; 20 767750 : return true; 21 : } 22 29064 : return false; 23 796814 : } 24 : 25 182 : bool HidingSigningProvider::GetCScript(const CScriptID& scriptid, CScript& script) const 26 : { 27 182 : return m_provider->GetCScript(scriptid, script); 28 : } 29 : 30 2173 : bool HidingSigningProvider::GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const 31 : { 32 2173 : return m_provider->GetPubKey(keyid, pubkey); 33 : } 34 : 35 3438 : bool HidingSigningProvider::GetKey(const CKeyID& keyid, CKey& key) const 36 : { 37 3438 : if (m_hide_secret) return false; 38 1106 : return m_provider->GetKey(keyid, key); 39 3438 : } 40 : 41 3438 : bool HidingSigningProvider::GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const 42 : { 43 3438 : if (m_hide_origin) return false; 44 2421 : return m_provider->GetKeyOrigin(keyid, info); 45 3438 : } 46 : 47 38616 : bool FlatSigningProvider::GetCScript(const CScriptID& scriptid, CScript& script) const { return LookupHelper(scripts, scriptid, script); } 48 343900 : bool FlatSigningProvider::GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const { return LookupHelper(pubkeys, keyid, pubkey); } 49 357040 : bool FlatSigningProvider::GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const 50 : { 51 357040 : std::pair<CPubKey, KeyOriginInfo> out; 52 357040 : bool ret = LookupHelper(origins, keyid, out); 53 357040 : if (ret) info = std::move(out.second); 54 357040 : return ret; 55 357040 : } 56 57258 : bool FlatSigningProvider::GetKey(const CKeyID& keyid, CKey& key) const { return LookupHelper(keys, keyid, key); } 57 : 58 693819 : FlatSigningProvider& FlatSigningProvider::Merge(FlatSigningProvider&& b) 59 : { 60 693819 : scripts.merge(b.scripts); 61 693819 : pubkeys.merge(b.pubkeys); 62 693819 : keys.merge(b.keys); 63 693819 : origins.merge(b.origins); 64 693819 : return *this; 65 : } 66 : 67 382308 : bool FillableSigningProvider::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const 68 : { 69 382308 : CKey key; 70 382308 : if (!GetKey(address, key)) { 71 61427 : return false; 72 : } 73 320881 : vchPubKeyOut = key.GetPubKey(); 74 320881 : return true; 75 382308 : } 76 : 77 1016210 : bool FillableSigningProvider::AddKeyPubKey(const CKey& key, const CPubKey &pubkey) 78 : { 79 1016210 : LOCK(cs_KeyStore); 80 1016210 : mapKeys[pubkey.GetID()] = key; 81 : return true; 82 1016210 : } 83 : 84 1276542 : bool FillableSigningProvider::HaveKey(const CKeyID &address) const 85 : { 86 1276542 : LOCK(cs_KeyStore); 87 1276542 : return mapKeys.count(address) > 0; 88 1276542 : } 89 : 90 16 : std::set<CKeyID> FillableSigningProvider::GetKeys() const 91 : { 92 16 : LOCK(cs_KeyStore); 93 16 : std::set<CKeyID> set_address; 94 29 : for (const auto& mi : mapKeys) { 95 13 : set_address.insert(mi.first); 96 : } 97 16 : return set_address; 98 16 : } 99 : 100 420263 : bool FillableSigningProvider::GetKey(const CKeyID &address, CKey &keyOut) const 101 : { 102 420263 : LOCK(cs_KeyStore); 103 420263 : KeyMap::const_iterator mi = mapKeys.find(address); 104 420263 : if (mi != mapKeys.end()) { 105 358715 : keyOut = mi->second; 106 358715 : return true; 107 : } 108 61548 : return false; 109 420263 : } 110 : 111 401 : bool FillableSigningProvider::AddCScript(const CScript& redeemScript) 112 : { 113 401 : if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE) 114 0 : return error("FillableSigningProvider::AddCScript(): redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE); 115 : 116 401 : LOCK(cs_KeyStore); 117 401 : mapScripts[CScriptID(redeemScript)] = redeemScript; 118 401 : return true; 119 401 : } 120 : 121 38 : bool FillableSigningProvider::HaveCScript(const CScriptID& hash) const 122 : { 123 38 : LOCK(cs_KeyStore); 124 38 : return mapScripts.count(hash) > 0; 125 38 : } 126 : 127 19 : std::set<CScriptID> FillableSigningProvider::GetCScripts() const 128 : { 129 19 : LOCK(cs_KeyStore); 130 19 : std::set<CScriptID> set_script; 131 31 : for (const auto& mi : mapScripts) { 132 12 : set_script.insert(mi.first); 133 : } 134 19 : return set_script; 135 19 : } 136 : 137 21813 : bool FillableSigningProvider::GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const 138 : { 139 21813 : LOCK(cs_KeyStore); 140 21813 : ScriptMap::const_iterator mi = mapScripts.find(hash); 141 21813 : if (mi != mapScripts.end()) 142 : { 143 1947 : redeemScriptOut = (*mi).second; 144 1947 : return true; 145 : } 146 19866 : return false; 147 21813 : } 148 : 149 1691 : CKeyID GetKeyForDestination(const SigningProvider& store, const CTxDestination& dest) 150 : { 151 : // Only supports destinations which map to single public keys, i.e. P2PKH 152 1691 : const PKHash *pkhash = std::get_if<PKHash>(&dest); 153 : 154 1691 : if (pkhash != nullptr) return ToKeyID(*pkhash); 155 : 156 88 : return CKeyID(); 157 1691 : }