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