LCOV - code coverage report
Current view: top level - src/script - ismine.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 62 64 96.9 %
Date: 2025-02-23 09:33:43 Functions: 5 5 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2014 The Bitcoin developers
       3             : // Copyright (c) 2016-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 "ismine.h"
       8             : 
       9             : #include "keystore.h"
      10             : #include "script/script.h"
      11             : #include "script/sign.h"
      12             : #include "util/system.h"
      13             : 
      14             : 
      15             : 
      16             : typedef std::vector<unsigned char> valtype;
      17             : 
      18         370 : unsigned int HaveKeys(const std::vector<valtype>& pubkeys, const CKeyStore& keystore)
      19             : {
      20         370 :     unsigned int nResult = 0;
      21        1593 :     for (const valtype& pubkey : pubkeys) {
      22        1223 :         CKeyID keyID = CPubKey(pubkey).GetID();
      23        1223 :         if(keystore.HaveKey(keyID))
      24         607 :             ++nResult;
      25             :     }
      26         370 :     return nResult;
      27             : }
      28             : 
      29        4677 : isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest)
      30             : {
      31        4677 :     CScript script = GetScriptForDestination(dest);
      32        4677 :     return IsMine(keystore, script);
      33             : }
      34             : 
      35        1307 : isminetype IsMine(const CKeyStore& keystore, const libzcash::SaplingPaymentAddress& pa)
      36             : {
      37        1307 :     libzcash::SaplingIncomingViewingKey ivk;
      38        1307 :     libzcash::SaplingExtendedFullViewingKey exfvk;
      39        2614 :     if (keystore.GetSaplingIncomingViewingKey(pa, ivk) &&
      40        2614 :         keystore.GetSaplingFullViewingKey(ivk, exfvk) &&
      41        1307 :         keystore.HaveSaplingSpendingKey(exfvk)) {
      42             :         return ISMINE_SPENDABLE_SHIELDED;
      43           0 :     } else if (!ivk.IsNull()) {
      44             :         return ISMINE_WATCH_ONLY_SHIELDED;
      45             :     } else {
      46           0 :         return ISMINE_NO;
      47             :     }
      48             : }
      49             : 
      50             : namespace
      51             : {
      52             :     class CWDestinationVisitor : public boost::static_visitor<isminetype>
      53             :     {
      54             :     private:
      55             :         const CKeyStore& keystore;
      56             :     public:
      57        4318 :         explicit CWDestinationVisitor(const CKeyStore& _keystore) : keystore(_keystore) {}
      58             : 
      59        3011 :         isminetype operator()(const CTxDestination& dest) const {
      60        3011 :             return ::IsMine(keystore, dest);
      61             :         }
      62             : 
      63        1307 :         isminetype operator()(const libzcash::SaplingPaymentAddress& pa) const {
      64        1307 :             return ::IsMine(keystore, pa);
      65             :         }
      66             :     };
      67             : }
      68             : 
      69        4318 : isminetype IsMine(const CKeyStore& keystore, const CWDestination& dest)
      70             : {
      71        4318 :     return boost::apply_visitor(CWDestinationVisitor(keystore), dest);
      72             : }
      73             : 
      74     6247427 : isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey)
      75             : {
      76    12494814 :     std::vector<valtype> vSolutions;
      77     6247427 :     txnouttype whichType;
      78     6247427 :     if(!Solver(scriptPubKey, whichType, vSolutions)) {
      79      327559 :         if(keystore.HaveWatchOnly(scriptPubKey)) {
      80             :             return ISMINE_WATCH_ONLY;
      81             :         }
      82             : 
      83      327559 :         return ISMINE_NO;
      84             :     }
      85             : 
      86     5919863 :     CKeyID keyID;
      87     5919863 :     switch (whichType) {
      88             :     case TX_NONSTANDARD:
      89             :     case TX_NULL_DATA:
      90             :         break;
      91       10727 :     case TX_PUBKEY:
      92       10727 :         keyID = CPubKey(vSolutions[0]).GetID();
      93       10727 :         if(keystore.HaveKey(keyID))
      94             :             return ISMINE_SPENDABLE;
      95             :         break;
      96     5807583 :     case TX_PUBKEYHASH:
      97     5807583 :     case TX_EXCHANGEADDR:
      98     5807583 :         keyID = CKeyID(uint160(vSolutions[0]));
      99     5807583 :         if(keystore.HaveKey(keyID))
     100             :             return ISMINE_SPENDABLE;
     101             :         break;
     102       85122 :     case TX_SCRIPTHASH: {
     103       85122 :         CScriptID scriptID = CScriptID(uint160(vSolutions[0]));
     104       85122 :         CScript subscript;
     105       85122 :         if(keystore.GetCScript(scriptID, subscript)) {
     106         368 :             isminetype ret = IsMine(keystore, subscript);
     107         368 :             if(ret != ISMINE_NO)
     108         710 :                 return ret;
     109             :         }
     110       84775 :         break;
     111             :     }
     112        1914 :     case TX_COLDSTAKE: {
     113        1914 :         CKeyID stakeKeyID = CKeyID(uint160(vSolutions[0]));
     114        1914 :         bool stakeKeyIsMine = keystore.HaveKey(stakeKeyID);
     115        1914 :         CKeyID ownerKeyID = CKeyID(uint160(vSolutions[1]));
     116        1914 :         bool spendKeyIsMine = keystore.HaveKey(ownerKeyID);
     117             : 
     118        1914 :         if (spendKeyIsMine) {
     119             :             // If the wallet has both keys, ISMINE_SPENDABLE_DELEGATED
     120             :             // takes precedence over ISMINE_COLD
     121        1826 :             return ISMINE_SPENDABLE_DELEGATED;
     122         806 :         } else if (stakeKeyIsMine) {
     123             :             return ISMINE_COLD;
     124             :         } else {
     125             :             // todo: Include watch only..
     126             :         }
     127          88 :         break;
     128             :     }
     129         370 :     case TX_MULTISIG: {
     130             :         // Only consider transactions "mine" if we own ALL the
     131             :         // keys involved. multi-signature transactions that are
     132             :         // partially owned (somebody else has a key that can spend
     133             :         // them) enable spend-out-from-under-you attacks, especially
     134             :         // in shared-wallet situations.
     135         370 :         std::vector<valtype> keys(vSolutions.begin() + 1, vSolutions.begin() + vSolutions.size() - 1);
     136         370 :         if(HaveKeys(keys, keystore) == keys.size())
     137          87 :             return ISMINE_SPENDABLE;
     138         283 :         break;
     139             :     }
     140             :     }
     141             : 
     142      583160 :     if (keystore.HaveWatchOnly(scriptPubKey)) {
     143         620 :         return ISMINE_WATCH_ONLY;
     144             :     }
     145             : 
     146             :     return ISMINE_NO;
     147             : }

Generated by: LCOV version 1.14