LCOV - code coverage report
Current view: top level - src - keystore.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 127 130 97.7 %
Date: 2025-02-23 09:33:43 Functions: 28 28 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2014 The Bitcoin developers
       3             : // Copyright (c) 2017-2021 The PIVX Core developers
       4             : // Distributed under the MIT software license, see the accompanying
       5             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       6             : 
       7             : #include "keystore.h"
       8             : 
       9             : #include "script/script.h"
      10             : #include "script/standard.h"
      11             : #include "util/system.h"
      12             : 
      13             : 
      14         176 : bool CKeyStore::AddKey(const CKey& key)
      15             : {
      16         176 :     return AddKeyPubKey(key, key.GetPubKey());
      17             : }
      18             : 
      19     3536960 : bool CBasicKeyStore::GetPubKey(const CKeyID& address, CPubKey& vchPubKeyOut) const
      20             : {
      21     7073920 :     CKey key;
      22     3536960 :     if (!GetKey(address, key)) {
      23          30 :         WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
      24          30 :         if (it != mapWatchKeys.end()) {
      25           9 :             vchPubKeyOut = it->second;
      26           9 :             return true;
      27             :         }
      28             :         return false;
      29             :     }
      30     3536930 :     vchPubKeyOut = key.GetPubKey();
      31             :     return true;
      32             : }
      33             : 
      34       19765 : bool CBasicKeyStore::AddKeyPubKey(const CKey& key, const CPubKey& pubkey)
      35             : {
      36       19765 :     LOCK(cs_KeyStore);
      37       19765 :     mapKeys[pubkey.GetID()] = key;
      38       39530 :     return true;
      39             : }
      40             : 
      41          36 : bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
      42             : {
      43          65 :     if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
      44           0 :         return error("CBasicKeyStore::AddCScript() : redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE);
      45             : 
      46          72 :     LOCK(cs_KeyStore);
      47          36 :     mapScripts[CScriptID(redeemScript)] = redeemScript;
      48          36 :     return true;
      49             : }
      50             : 
      51           3 : bool CBasicKeyStore::HaveCScript(const CScriptID& hash) const
      52             : {
      53           3 :     LOCK(cs_KeyStore);
      54           6 :     return mapScripts.count(hash) > 0;
      55             : }
      56             : 
      57       85618 : bool CBasicKeyStore::GetCScript(const CScriptID& hash, CScript& redeemScriptOut) const
      58             : {
      59       85618 :     LOCK(cs_KeyStore);
      60       85618 :     ScriptMap::const_iterator mi = mapScripts.find(hash);
      61       85618 :     if (mi != mapScripts.end()) {
      62         669 :         redeemScriptOut = (*mi).second;
      63         669 :         return true;
      64             :     }
      65             :     return false;
      66             : }
      67             : 
      68          53 : static bool ExtractPubKey(const CScript& dest, CPubKey& pubKeyOut)
      69             : {
      70             :     //TODO: Use Solver to extract this?
      71          53 :     CScript::const_iterator pc = dest.begin();
      72          53 :     opcodetype opcode;
      73         106 :     std::vector<unsigned char> vch;
      74          53 :     if (!dest.GetOp(pc, opcode, vch) || vch.size() < 33 || vch.size() > 65)
      75             :         return false;
      76          13 :     pubKeyOut = CPubKey(vch);
      77          13 :     if (!pubKeyOut.IsFullyValid())
      78             :         return false;
      79          26 :     if (!dest.GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG || dest.GetOp(pc, opcode, vch))
      80           0 :         return false;
      81             :     return true;
      82             : }
      83             : 
      84          52 : bool CBasicKeyStore::AddWatchOnly(const CScript& dest)
      85             : {
      86          52 :     LOCK(cs_KeyStore);
      87          52 :     setWatchOnly.insert(dest);
      88          52 :     CPubKey pubKey;
      89          52 :     if (ExtractPubKey(dest, pubKey))
      90          13 :         mapWatchKeys[pubKey.GetID()] = pubKey;
      91         104 :     return true;
      92             : }
      93             : 
      94           1 : bool CBasicKeyStore::RemoveWatchOnly(const CScript& dest)
      95             : {
      96           1 :     LOCK(cs_KeyStore);
      97           1 :     setWatchOnly.erase(dest);
      98           1 :     CPubKey pubKey;
      99           1 :     if (ExtractPubKey(dest, pubKey))
     100           0 :         mapWatchKeys.erase(pubKey.GetID());
     101           2 :     return true;
     102             : }
     103             : 
     104      934503 : bool CBasicKeyStore::HaveWatchOnly(const CScript& dest) const
     105             : {
     106      934503 :     LOCK(cs_KeyStore);
     107     1869004 :     return setWatchOnly.count(dest) > 0;
     108             : }
     109             : 
     110           1 : bool CBasicKeyStore::HaveWatchOnly() const
     111             : {
     112           1 :     LOCK(cs_KeyStore);
     113           1 :     return (!setWatchOnly.empty());
     114             : }
     115             : 
     116     6966618 : bool CBasicKeyStore::HaveKey(const CKeyID& address) const
     117             : {
     118     6966618 :     bool result;
     119     6966618 :     {
     120     6966618 :         LOCK(cs_KeyStore);
     121    13933256 :         result = (mapKeys.count(address) > 0);
     122             :     }
     123     6966618 :     return result;
     124             : }
     125             : 
     126           7 : std::set<CKeyID> CBasicKeyStore::GetKeys() const
     127             : {
     128           7 :     LOCK(cs_KeyStore);
     129           7 :     std::set<CKeyID> set_address;
     130        1368 :     for (const auto& mi : mapKeys) {
     131        1361 :         set_address.insert(mi.first);
     132             :     }
     133          14 :     return set_address;
     134             : }
     135             : 
     136     3765600 : bool CBasicKeyStore::GetKey(const CKeyID& address, CKey& keyOut) const
     137             : {
     138     7531190 :     LOCK(cs_KeyStore);
     139     3765600 :     KeyMap::const_iterator mi = mapKeys.find(address);
     140     3765600 :     if (mi != mapKeys.end()) {
     141     3765600 :         keyOut = mi->second;
     142             :         return true;
     143             :     }
     144             :     return false;
     145             : }
     146             : 
     147             : //! Sapling
     148        2299 : bool CBasicKeyStore::AddSaplingSpendingKey(
     149             :     const libzcash::SaplingExtendedSpendingKey& sk)
     150             : {
     151        4598 :     LOCK(cs_KeyStore);
     152        2299 :     auto extfvk = sk.ToXFVK();
     153             : 
     154             :     // if extfvk is not in SaplingFullViewingKeyMap, add it
     155        2299 :     if (!AddSaplingFullViewingKey(extfvk)) {
     156             :         return false;
     157             :     }
     158             : 
     159        2299 :     mapSaplingSpendingKeys[extfvk] = sk;
     160             : 
     161        2299 :     return true;
     162             : }
     163             : 
     164        2409 : bool CBasicKeyStore::AddSaplingFullViewingKey(
     165             :     const libzcash::SaplingExtendedFullViewingKey& extfvk)
     166             : {
     167        2409 :     LOCK(cs_KeyStore);
     168        2409 :     auto ivk = extfvk.fvk.in_viewing_key();
     169        2409 :     mapSaplingFullViewingKeys[ivk] = extfvk;
     170             : 
     171        4818 :     return CBasicKeyStore::AddSaplingIncomingViewingKey(ivk, extfvk.DefaultAddress());
     172             : }
     173             : 
     174             : // This function updates the wallet's internal address->ivk map.
     175             : // If we add an address that is already in the map, the map will
     176             : // remain unchanged as each address only has one ivk.
     177        2411 : bool CBasicKeyStore::AddSaplingIncomingViewingKey(
     178             :     const libzcash::SaplingIncomingViewingKey& ivk,
     179             :     const libzcash::SaplingPaymentAddress& addr)
     180             : {
     181        2411 :     LOCK(cs_KeyStore);
     182             : 
     183             :     // Add addr -> SaplingIncomingViewing to SaplingIncomingViewingKeyMap
     184        2411 :     mapSaplingIncomingViewingKeys[addr] = ivk;
     185             : 
     186        4822 :     return true;
     187             : }
     188             : 
     189        7993 : bool CBasicKeyStore::HaveSaplingSpendingKey(const libzcash::SaplingExtendedFullViewingKey& extfvk) const
     190             : {
     191       23979 :     return WITH_LOCK(cs_KeyStore, return mapSaplingSpendingKeys.count(extfvk) > 0);
     192             : }
     193             : 
     194          21 : bool CBasicKeyStore::HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey& ivk) const
     195             : {
     196          63 :     return WITH_LOCK(cs_KeyStore, return mapSaplingFullViewingKeys.count(ivk) > 0);
     197             : }
     198             : 
     199          12 : bool CBasicKeyStore::HaveSaplingIncomingViewingKey(const libzcash::SaplingPaymentAddress& addr) const
     200             : {
     201          36 :     return WITH_LOCK(cs_KeyStore, return mapSaplingIncomingViewingKeys.count(addr) > 0);
     202             : }
     203             : 
     204        1147 : bool CBasicKeyStore::GetSaplingSpendingKey(const libzcash::SaplingExtendedFullViewingKey& extfvk, libzcash::SaplingExtendedSpendingKey& skOut) const
     205             : {
     206        1147 :     LOCK(cs_KeyStore);
     207        1147 :     SaplingSpendingKeyMap::const_iterator mi = mapSaplingSpendingKeys.find(extfvk);
     208        1147 :     if (mi != mapSaplingSpendingKeys.end()) {
     209        1144 :         skOut = mi->second;
     210        1144 :         return true;
     211             :     }
     212             :     return false;
     213             : }
     214             : 
     215        7164 : bool CBasicKeyStore::GetSaplingFullViewingKey(
     216             :     const libzcash::SaplingIncomingViewingKey& ivk,
     217             :     libzcash::SaplingExtendedFullViewingKey& extfvkOut) const
     218             : {
     219        7164 :     LOCK(cs_KeyStore);
     220        7164 :     SaplingFullViewingKeyMap::const_iterator mi = mapSaplingFullViewingKeys.find(ivk);
     221        7164 :     if (mi != mapSaplingFullViewingKeys.end()) {
     222        7162 :         extfvkOut = mi->second;
     223        7162 :         return true;
     224             :     }
     225             :     return false;
     226             : }
     227             : 
     228        7499 : bool CBasicKeyStore::GetSaplingIncomingViewingKey(const libzcash::SaplingPaymentAddress& addr,
     229             :     libzcash::SaplingIncomingViewingKey& ivkOut) const
     230             : {
     231        7499 :     LOCK(cs_KeyStore);
     232        7499 :     SaplingIncomingViewingKeyMap::const_iterator mi = mapSaplingIncomingViewingKeys.find(addr);
     233        7499 :     if (mi != mapSaplingIncomingViewingKeys.end()) {
     234        7491 :         ivkOut = mi->second;
     235        7491 :         return true;
     236             :     }
     237             :     return false;
     238             : }
     239             : 
     240        1147 : bool CBasicKeyStore::GetSaplingExtendedSpendingKey(const libzcash::SaplingPaymentAddress& addr,
     241             :     libzcash::SaplingExtendedSpendingKey& extskOut) const
     242             : {
     243        1147 :     libzcash::SaplingIncomingViewingKey ivk;
     244        1147 :     libzcash::SaplingExtendedFullViewingKey extfvk;
     245             : 
     246        1147 :     LOCK(cs_KeyStore);
     247        2294 :     return GetSaplingIncomingViewingKey(addr, ivk) &&
     248        2294 :            GetSaplingFullViewingKey(ivk, extfvk) &&
     249        3441 :            GetSaplingSpendingKey(extfvk, extskOut);
     250             : }
     251             : 
     252          41 : void CBasicKeyStore::GetSaplingPaymentAddresses(std::set<libzcash::SaplingPaymentAddress>& setAddress) const
     253             : {
     254          41 :     setAddress.clear();
     255          41 :     {
     256          41 :         LOCK(cs_KeyStore);
     257          41 :         auto mi = mapSaplingIncomingViewingKeys.begin();
     258        5731 :         while (mi != mapSaplingIncomingViewingKeys.end()) {
     259        5690 :             setAddress.insert((*mi).first);
     260        5731 :             mi++;
     261             :         }
     262             :     }
     263          41 : }

Generated by: LCOV version 1.14