LCOV - code coverage report
Current view: top level - src/script - sign.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 348 358 97.2 %
Date: 2021-06-29 14:35:33 Functions: 24 24 100.0 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 171 208 82.2 %

           Branch data     Line data    Source code
#       1                 :            : // Copyright (c) 2009-2010 Satoshi Nakamoto
#       2                 :            : // Copyright (c) 2009-2020 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/sign.h>
#       7                 :            : 
#       8                 :            : #include <key.h>
#       9                 :            : #include <policy/policy.h>
#      10                 :            : #include <primitives/transaction.h>
#      11                 :            : #include <script/signingprovider.h>
#      12                 :            : #include <script/standard.h>
#      13                 :            : #include <uint256.h>
#      14                 :            : 
#      15                 :            : typedef std::vector<unsigned char> valtype;
#      16                 :            : 
#      17                 :      81379 : MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn, MissingDataBehavior::FAIL) {}
#      18                 :            : 
#      19                 :            : bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
#      20                 :      42763 : {
#      21                 :      42763 :     CKey key;
#      22         [ +  + ]:      42763 :     if (!provider.GetKey(address, key))
#      23                 :       1963 :         return false;
#      24                 :            : 
#      25                 :            :     // Signing with uncompressed keys is disabled in witness scripts
#      26 [ +  + ][ +  + ]:      40800 :     if (sigversion == SigVersion::WITNESS_V0 && !key.IsCompressed())
#      27                 :          8 :         return false;
#      28                 :            : 
#      29                 :            :     // Signing for witness scripts needs the amount.
#      30 [ +  + ][ -  + ]:      40792 :     if (sigversion == SigVersion::WITNESS_V0 && amount < 0) return false;
#      31                 :            : 
#      32                 :      40792 :     uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion);
#      33         [ -  + ]:      40792 :     if (!key.Sign(hash, vchSig))
#      34                 :          0 :         return false;
#      35                 :      40792 :     vchSig.push_back((unsigned char)nHashType);
#      36                 :      40792 :     return true;
#      37                 :      40792 : }
#      38                 :            : 
#      39                 :            : static bool GetCScript(const SigningProvider& provider, const SignatureData& sigdata, const CScriptID& scriptid, CScript& script)
#      40                 :       8692 : {
#      41         [ +  + ]:       8692 :     if (provider.GetCScript(scriptid, script)) {
#      42                 :       8038 :         return true;
#      43                 :       8038 :     }
#      44                 :            :     // Look for scripts in SignatureData
#      45         [ +  + ]:        654 :     if (CScriptID(sigdata.redeem_script) == scriptid) {
#      46                 :        296 :         script = sigdata.redeem_script;
#      47                 :        296 :         return true;
#      48         [ +  + ]:        358 :     } else if (CScriptID(sigdata.witness_script) == scriptid) {
#      49                 :         64 :         script = sigdata.witness_script;
#      50                 :         64 :         return true;
#      51                 :         64 :     }
#      52                 :        294 :     return false;
#      53                 :        294 : }
#      54                 :            : 
#      55                 :            : static bool GetPubKey(const SigningProvider& provider, const SignatureData& sigdata, const CKeyID& address, CPubKey& pubkey)
#      56                 :     932608 : {
#      57                 :            :     // Look for pubkey in all partial sigs
#      58                 :     932608 :     const auto it = sigdata.signatures.find(address);
#      59         [ +  + ]:     932608 :     if (it != sigdata.signatures.end()) {
#      60                 :          2 :         pubkey = it->second.first;
#      61                 :          2 :         return true;
#      62                 :          2 :     }
#      63                 :            :     // Look for pubkey in pubkey list
#      64                 :     932606 :     const auto& pk_it = sigdata.misc_pubkeys.find(address);
#      65         [ +  + ]:     932606 :     if (pk_it != sigdata.misc_pubkeys.end()) {
#      66                 :        869 :         pubkey = pk_it->second.first;
#      67                 :        869 :         return true;
#      68                 :        869 :     }
#      69                 :            :     // Query the underlying provider
#      70                 :     931737 :     return provider.GetPubKey(address, pubkey);
#      71                 :     931737 : }
#      72                 :            : 
#      73                 :            : static bool CreateSig(const BaseSignatureCreator& creator, SignatureData& sigdata, const SigningProvider& provider, std::vector<unsigned char>& sig_out, const CPubKey& pubkey, const CScript& scriptcode, SigVersion sigversion)
#      74                 :     906267 : {
#      75                 :     906267 :     CKeyID keyid = pubkey.GetID();
#      76                 :     906267 :     const auto it = sigdata.signatures.find(keyid);
#      77         [ +  + ]:     906267 :     if (it != sigdata.signatures.end()) {
#      78                 :        814 :         sig_out = it->second.second;
#      79                 :        814 :         return true;
#      80                 :        814 :     }
#      81                 :     905453 :     KeyOriginInfo info;
#      82         [ +  + ]:     905453 :     if (provider.GetKeyOrigin(keyid, info)) {
#      83                 :     894610 :         sigdata.misc_pubkeys.emplace(keyid, std::make_pair(pubkey, std::move(info)));
#      84                 :     894610 :     }
#      85         [ +  + ]:     905453 :     if (creator.CreateSig(provider, sig_out, keyid, scriptcode, sigversion)) {
#      86                 :     903482 :         auto i = sigdata.signatures.emplace(keyid, SigPair(pubkey, sig_out));
#      87                 :     903482 :         assert(i.second);
#      88                 :     903482 :         return true;
#      89                 :     903482 :     }
#      90                 :            :     // Could not make signature or signature not found, add keyid to missing
#      91                 :       1971 :     sigdata.missing_sigs.push_back(keyid);
#      92                 :       1971 :     return false;
#      93                 :       1971 : }
#      94                 :            : 
#      95                 :            : /**
#      96                 :            :  * Sign scriptPubKey using signature made with creator.
#      97                 :            :  * Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
#      98                 :            :  * unless whichTypeRet is TxoutType::SCRIPTHASH, in which case scriptSigRet is the redemption script.
#      99                 :            :  * Returns false if scriptPubKey could not be completely satisfied.
#     100                 :            :  */
#     101                 :            : static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey,
#     102                 :            :                      std::vector<valtype>& ret, TxoutType& whichTypeRet, SigVersion sigversion, SignatureData& sigdata)
#     103                 :    1573822 : {
#     104                 :    1573822 :     CScript scriptRet;
#     105                 :    1573822 :     uint160 h160;
#     106                 :    1573822 :     ret.clear();
#     107                 :    1573822 :     std::vector<unsigned char> sig;
#     108                 :            : 
#     109                 :    1573822 :     std::vector<valtype> vSolutions;
#     110                 :    1573822 :     whichTypeRet = Solver(scriptPubKey, vSolutions);
#     111                 :            : 
#     112         [ -  + ]:    1573822 :     switch (whichTypeRet) {
#     113         [ +  + ]:     110055 :     case TxoutType::NONSTANDARD:
#     114         [ +  + ]:     110061 :     case TxoutType::NULL_DATA:
#     115         [ -  + ]:     110061 :     case TxoutType::WITNESS_UNKNOWN:
#     116         [ -  + ]:     110061 :     case TxoutType::WITNESS_V1_TAPROOT:
#     117                 :     110061 :         return false;
#     118         [ +  + ]:     110061 :     case TxoutType::PUBKEY:
#     119         [ -  + ]:       4008 :         if (!CreateSig(creator, sigdata, provider, sig, CPubKey(vSolutions[0]), scriptPubKey, sigversion)) return false;
#     120                 :       4008 :         ret.push_back(std::move(sig));
#     121                 :       4008 :         return true;
#     122         [ +  + ]:     932608 :     case TxoutType::PUBKEYHASH: {
#     123                 :     932608 :         CKeyID keyID = CKeyID(uint160(vSolutions[0]));
#     124                 :     932608 :         CPubKey pubkey;
#     125         [ +  + ]:     932608 :         if (!GetPubKey(provider, sigdata, keyID, pubkey)) {
#     126                 :            :             // Pubkey could not be found, add to missing
#     127                 :      38565 :             sigdata.missing_pubkeys.push_back(keyID);
#     128                 :      38565 :             return false;
#     129                 :      38565 :         }
#     130         [ +  + ]:     894043 :         if (!CreateSig(creator, sigdata, provider, sig, pubkey, scriptPubKey, sigversion)) return false;
#     131                 :     892689 :         ret.push_back(std::move(sig));
#     132                 :     892689 :         ret.push_back(ToByteVector(pubkey));
#     133                 :     892689 :         return true;
#     134                 :     892689 :     }
#     135         [ +  + ]:     892689 :     case TxoutType::SCRIPTHASH:
#     136                 :       6104 :         h160 = uint160(vSolutions[0]);
#     137         [ +  + ]:       6104 :         if (GetCScript(provider, sigdata, CScriptID{h160}, scriptRet)) {
#     138                 :       5940 :             ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
#     139                 :       5940 :             return true;
#     140                 :       5940 :         }
#     141                 :            :         // Could not find redeemScript, add to missing
#     142                 :        164 :         sigdata.missing_redeem_script = h160;
#     143                 :        164 :         return false;
#     144                 :            : 
#     145         [ +  + ]:       3084 :     case TxoutType::MULTISIG: {
#     146                 :       3084 :         size_t required = vSolutions.front()[0];
#     147                 :       3084 :         ret.push_back(valtype()); // workaround CHECKMULTISIG bug
#     148         [ +  + ]:      11300 :         for (size_t i = 1; i < vSolutions.size() - 1; ++i) {
#     149                 :       8216 :             CPubKey pubkey = CPubKey(vSolutions[i]);
#     150                 :            :             // We need to always call CreateSig in order to fill sigdata with all
#     151                 :            :             // possible signatures that we can create. This will allow further PSBT
#     152                 :            :             // processing to work as it needs all possible signature and pubkey pairs
#     153         [ +  + ]:       8216 :             if (CreateSig(creator, sigdata, provider, sig, pubkey, scriptPubKey, sigversion)) {
#     154         [ +  + ]:       7599 :                 if (ret.size() < required + 1) {
#     155                 :       7184 :                     ret.push_back(std::move(sig));
#     156                 :       7184 :                 }
#     157                 :       7599 :             }
#     158                 :       8216 :         }
#     159                 :       3084 :         bool ok = ret.size() == required + 1;
#     160         [ +  + ]:       3385 :         for (size_t i = 0; i + ret.size() < required + 1; ++i) {
#     161                 :        301 :             ret.push_back(valtype());
#     162                 :        301 :         }
#     163                 :       3084 :         return ok;
#     164                 :        164 :     }
#     165         [ +  + ]:     515369 :     case TxoutType::WITNESS_V0_KEYHASH:
#     166                 :     515369 :         ret.push_back(vSolutions[0]);
#     167                 :     515369 :         return true;
#     168                 :            : 
#     169         [ +  + ]:       2588 :     case TxoutType::WITNESS_V0_SCRIPTHASH:
#     170                 :       2588 :         CRIPEMD160().Write(vSolutions[0].data(), vSolutions[0].size()).Finalize(h160.begin());
#     171         [ +  + ]:       2588 :         if (GetCScript(provider, sigdata, CScriptID{h160}, scriptRet)) {
#     172                 :       2458 :             ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
#     173                 :       2458 :             return true;
#     174                 :       2458 :         }
#     175                 :            :         // Could not find witnessScript, add to missing
#     176                 :        130 :         sigdata.missing_witness_script = uint256(vSolutions[0]);
#     177                 :        130 :         return false;
#     178                 :          0 :     } // no default case, so the compiler can warn about missing cases
#     179                 :          0 :     assert(false);
#     180                 :          0 : }
#     181                 :            : 
#     182                 :            : static CScript PushAll(const std::vector<valtype>& values)
#     183                 :    1050055 : {
#     184                 :    1050055 :     CScript result;
#     185         [ +  + ]:    1050055 :     for (const valtype& v : values) {
#     186         [ +  + ]:     791518 :         if (v.size() == 0) {
#     187                 :       1428 :             result << OP_0;
#     188 [ -  + ][ #  # ]:     790090 :         } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) {
#                 [ #  # ]
#     189                 :          0 :             result << CScript::EncodeOP_N(v[0]);
#     190 [ -  + ][ #  # ]:     790090 :         } else if (v.size() == 1 && v[0] == 0x81) {
#     191                 :          0 :             result << OP_1NEGATE;
#     192                 :     790090 :         } else {
#     193                 :     790090 :             result << v;
#     194                 :     790090 :         }
#     195                 :     791518 :     }
#     196                 :    1050055 :     return result;
#     197                 :    1050055 : }
#     198                 :            : 
#     199                 :            : bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata)
#     200                 :    1051445 : {
#     201         [ +  + ]:    1051445 :     if (sigdata.complete) return true;
#     202                 :            : 
#     203                 :    1050055 :     std::vector<valtype> result;
#     204                 :    1050055 :     TxoutType whichType;
#     205                 :    1050055 :     bool solved = SignStep(provider, creator, fromPubKey, result, whichType, SigVersion::BASE, sigdata);
#     206                 :    1050055 :     bool P2SH = false;
#     207                 :    1050055 :     CScript subscript;
#     208                 :    1050055 :     sigdata.scriptWitness.stack.clear();
#     209                 :            : 
#     210 [ +  + ][ +  + ]:    1050055 :     if (solved && whichType == TxoutType::SCRIPTHASH)
#     211                 :       5940 :     {
#     212                 :            :         // Solver returns the subscript that needs to be evaluated;
#     213                 :            :         // the final scriptSig is the signatures from that
#     214                 :            :         // and then the serialized subscript:
#     215                 :       5940 :         subscript = CScript(result[0].begin(), result[0].end());
#     216                 :       5940 :         sigdata.redeem_script = subscript;
#     217 [ +  - ][ +  + ]:       5940 :         solved = solved && SignStep(provider, creator, subscript, result, whichType, SigVersion::BASE, sigdata) && whichType != TxoutType::SCRIPTHASH;
#                 [ +  - ]
#     218                 :       5940 :         P2SH = true;
#     219                 :       5940 :     }
#     220                 :            : 
#     221 [ +  + ][ +  + ]:    1050055 :     if (solved && whichType == TxoutType::WITNESS_V0_KEYHASH)
#     222                 :     515369 :     {
#     223                 :     515369 :         CScript witnessscript;
#     224                 :     515369 :         witnessscript << OP_DUP << OP_HASH160 << ToByteVector(result[0]) << OP_EQUALVERIFY << OP_CHECKSIG;
#     225                 :     515369 :         TxoutType subType;
#     226 [ +  - ][ +  + ]:     515369 :         solved = solved && SignStep(provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0, sigdata);
#     227                 :     515369 :         sigdata.scriptWitness.stack = result;
#     228                 :     515369 :         sigdata.witness = true;
#     229                 :     515369 :         result.clear();
#     230                 :     515369 :     }
#     231 [ +  + ][ +  + ]:     534686 :     else if (solved && whichType == TxoutType::WITNESS_V0_SCRIPTHASH)
#     232                 :       2458 :     {
#     233                 :       2458 :         CScript witnessscript(result[0].begin(), result[0].end());
#     234                 :       2458 :         sigdata.witness_script = witnessscript;
#     235                 :       2458 :         TxoutType subType;
#     236 [ +  - ][ +  + ]:       2458 :         solved = solved && SignStep(provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0, sigdata) && subType != TxoutType::SCRIPTHASH && subType != TxoutType::WITNESS_V0_SCRIPTHASH && subType != TxoutType::WITNESS_V0_KEYHASH;
#         [ +  - ][ +  - ]
#                 [ +  - ]
#     237                 :       2458 :         result.push_back(std::vector<unsigned char>(witnessscript.begin(), witnessscript.end()));
#     238                 :       2458 :         sigdata.scriptWitness.stack = result;
#     239                 :       2458 :         sigdata.witness = true;
#     240                 :       2458 :         result.clear();
#     241 [ +  + ][ -  + ]:     532228 :     } else if (solved && whichType == TxoutType::WITNESS_UNKNOWN) {
#     242                 :          0 :         sigdata.witness = true;
#     243                 :          0 :     }
#     244                 :            : 
#     245         [ +  + ]:    1050055 :     if (P2SH) {
#     246                 :       5940 :         result.push_back(std::vector<unsigned char>(subscript.begin(), subscript.end()));
#     247                 :       5940 :     }
#     248                 :    1050055 :     sigdata.scriptSig = PushAll(result);
#     249                 :            : 
#     250                 :            :     // Test solution
#     251 [ +  + ][ +  - ]:    1050055 :     sigdata.complete = solved && VerifyScript(sigdata.scriptSig, fromPubKey, &sigdata.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker());
#     252                 :    1050055 :     return sigdata.complete;
#     253                 :    1050055 : }
#     254                 :            : 
#     255                 :            : namespace {
#     256                 :            : class SignatureExtractorChecker final : public DeferringSignatureChecker
#     257                 :            : {
#     258                 :            : private:
#     259                 :            :     SignatureData& sigdata;
#     260                 :            : 
#     261                 :            : public:
#     262                 :      69463 :     SignatureExtractorChecker(SignatureData& sigdata, BaseSignatureChecker& checker) : DeferringSignatureChecker(checker), sigdata(sigdata) {}
#     263                 :            : 
#     264                 :            :     bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override
#     265                 :       1734 :     {
#     266         [ +  + ]:       1734 :         if (m_checker.CheckECDSASignature(scriptSig, vchPubKey, scriptCode, sigversion)) {
#     267                 :       1423 :             CPubKey pubkey(vchPubKey);
#     268                 :       1423 :             sigdata.signatures.emplace(pubkey.GetID(), SigPair(pubkey, scriptSig));
#     269                 :       1423 :             return true;
#     270                 :       1423 :         }
#     271                 :        311 :         return false;
#     272                 :        311 :     }
#     273                 :            : };
#     274                 :            : 
#     275                 :            : struct Stacks
#     276                 :            : {
#     277                 :            :     std::vector<valtype> script;
#     278                 :            :     std::vector<valtype> witness;
#     279                 :            : 
#     280                 :            :     Stacks() = delete;
#     281                 :            :     Stacks(const Stacks&) = delete;
#     282                 :      69463 :     explicit Stacks(const SignatureData& data) : witness(data.scriptWitness.stack) {
#     283                 :      69463 :         EvalScript(script, data.scriptSig, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), SigVersion::BASE);
#     284                 :      69463 :     }
#     285                 :            : };
#     286                 :            : }
#     287                 :            : 
#     288                 :            : // Extracts signatures and scripts from incomplete scriptSigs. Please do not extend this, use PSBT instead
#     289                 :            : SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn, const CTxOut& txout)
#     290                 :      69463 : {
#     291                 :      69463 :     SignatureData data;
#     292                 :      69463 :     assert(tx.vin.size() > nIn);
#     293                 :      69463 :     data.scriptSig = tx.vin[nIn].scriptSig;
#     294                 :      69463 :     data.scriptWitness = tx.vin[nIn].scriptWitness;
#     295                 :      69463 :     Stacks stack(data);
#     296                 :            : 
#     297                 :            :     // Get signatures
#     298                 :      69463 :     MutableTransactionSignatureChecker tx_checker(&tx, nIn, txout.nValue, MissingDataBehavior::FAIL);
#     299                 :      69463 :     SignatureExtractorChecker extractor_checker(data, tx_checker);
#     300         [ +  + ]:      69463 :     if (VerifyScript(data.scriptSig, txout.scriptPubKey, &data.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, extractor_checker)) {
#     301                 :       1384 :         data.complete = true;
#     302                 :       1384 :         return data;
#     303                 :       1384 :     }
#     304                 :            : 
#     305                 :            :     // Get scripts
#     306                 :      68079 :     std::vector<std::vector<unsigned char>> solutions;
#     307                 :      68079 :     TxoutType script_type = Solver(txout.scriptPubKey, solutions);
#     308                 :      68079 :     SigVersion sigversion = SigVersion::BASE;
#     309                 :      68079 :     CScript next_script = txout.scriptPubKey;
#     310                 :            : 
#     311 [ +  + ][ +  + ]:      68079 :     if (script_type == TxoutType::SCRIPTHASH && !stack.script.empty() && !stack.script.back().empty()) {
#                 [ +  - ]
#     312                 :            :         // Get the redeemScript
#     313                 :         24 :         CScript redeem_script(stack.script.back().begin(), stack.script.back().end());
#     314                 :         24 :         data.redeem_script = redeem_script;
#     315                 :         24 :         next_script = std::move(redeem_script);
#     316                 :            : 
#     317                 :            :         // Get redeemScript type
#     318                 :         24 :         script_type = Solver(next_script, solutions);
#     319                 :         24 :         stack.script.pop_back();
#     320                 :         24 :     }
#     321 [ +  + ][ +  + ]:      68079 :     if (script_type == TxoutType::WITNESS_V0_SCRIPTHASH && !stack.witness.empty() && !stack.witness.back().empty()) {
#                 [ +  - ]
#     322                 :            :         // Get the witnessScript
#     323                 :         28 :         CScript witness_script(stack.witness.back().begin(), stack.witness.back().end());
#     324                 :         28 :         data.witness_script = witness_script;
#     325                 :         28 :         next_script = std::move(witness_script);
#     326                 :            : 
#     327                 :            :         // Get witnessScript type
#     328                 :         28 :         script_type = Solver(next_script, solutions);
#     329                 :         28 :         stack.witness.pop_back();
#     330                 :         28 :         stack.script = std::move(stack.witness);
#     331                 :         28 :         stack.witness.clear();
#     332                 :         28 :         sigversion = SigVersion::WITNESS_V0;
#     333                 :         28 :     }
#     334 [ +  + ][ +  + ]:      68079 :     if (script_type == TxoutType::MULTISIG && !stack.script.empty()) {
#     335                 :            :         // Build a map of pubkey -> signature by matching sigs to pubkeys:
#     336                 :         44 :         assert(solutions.size() > 1);
#     337                 :         44 :         unsigned int num_pubkeys = solutions.size()-2;
#     338                 :         44 :         unsigned int last_success_key = 0;
#     339         [ +  + ]:        144 :         for (const valtype& sig : stack.script) {
#     340         [ +  + ]:        364 :             for (unsigned int i = last_success_key; i < num_pubkeys; ++i) {
#     341                 :        276 :                 const valtype& pubkey = solutions[i+1];
#     342                 :            :                 // We either have a signature for this pubkey, or we have found a signature and it is valid
#     343 [ -  + ][ +  + ]:        276 :                 if (data.signatures.count(CPubKey(pubkey).GetID()) || extractor_checker.CheckECDSASignature(sig, pubkey, next_script, sigversion)) {
#                 [ +  + ]
#     344                 :         56 :                     last_success_key = i + 1;
#     345                 :         56 :                     break;
#     346                 :         56 :                 }
#     347                 :        276 :             }
#     348                 :        144 :         }
#     349                 :         44 :     }
#     350                 :            : 
#     351                 :      68079 :     return data;
#     352                 :      68079 : }
#     353                 :            : 
#     354                 :            : void UpdateInput(CTxIn& input, const SignatureData& data)
#     355                 :     513450 : {
#     356                 :     513450 :     input.scriptSig = data.scriptSig;
#     357                 :     513450 :     input.scriptWitness = data.scriptWitness;
#     358                 :     513450 : }
#     359                 :            : 
#     360                 :            : void SignatureData::MergeSignatureData(SignatureData sigdata)
#     361                 :         78 : {
#     362         [ +  + ]:         78 :     if (complete) return;
#     363         [ +  + ]:         68 :     if (sigdata.complete) {
#     364                 :         16 :         *this = std::move(sigdata);
#     365                 :         16 :         return;
#     366                 :         16 :     }
#     367 [ +  + ][ -  + ]:         52 :     if (redeem_script.empty() && !sigdata.redeem_script.empty()) {
#     368                 :          0 :         redeem_script = sigdata.redeem_script;
#     369                 :          0 :     }
#     370 [ +  + ][ +  + ]:         52 :     if (witness_script.empty() && !sigdata.witness_script.empty()) {
#     371                 :          1 :         witness_script = sigdata.witness_script;
#     372                 :          1 :     }
#     373                 :         52 :     signatures.insert(std::make_move_iterator(sigdata.signatures.begin()), std::make_move_iterator(sigdata.signatures.end()));
#     374                 :         52 : }
#     375                 :            : 
#     376                 :            : bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType)
#     377                 :       9586 : {
#     378                 :       9586 :     assert(nIn < txTo.vin.size());
#     379                 :            : 
#     380                 :       9586 :     MutableTransactionSignatureCreator creator(&txTo, nIn, amount, nHashType);
#     381                 :            : 
#     382                 :       9586 :     SignatureData sigdata;
#     383                 :       9586 :     bool ret = ProduceSignature(provider, creator, fromPubKey, sigdata);
#     384                 :       9586 :     UpdateInput(txTo.vin.at(nIn), sigdata);
#     385                 :       9586 :     return ret;
#     386                 :       9586 : }
#     387                 :            : 
#     388                 :            : bool SignSignature(const SigningProvider &provider, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
#     389                 :        214 : {
#     390                 :        214 :     assert(nIn < txTo.vin.size());
#     391                 :        214 :     const CTxIn& txin = txTo.vin[nIn];
#     392                 :        214 :     assert(txin.prevout.n < txFrom.vout.size());
#     393                 :        214 :     const CTxOut& txout = txFrom.vout[txin.prevout.n];
#     394                 :            : 
#     395                 :        214 :     return SignSignature(provider, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType);
#     396                 :        214 : }
#     397                 :            : 
#     398                 :            : namespace {
#     399                 :            : /** Dummy signature checker which accepts all signatures. */
#     400                 :            : class DummySignatureChecker final : public BaseSignatureChecker
#     401                 :            : {
#     402                 :            : public:
#     403                 :        753 :     DummySignatureChecker() {}
#     404                 :    1290789 :     bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override { return true; }
#     405                 :            : };
#     406                 :            : const DummySignatureChecker DUMMY_CHECKER;
#     407                 :            : 
#     408                 :            : class DummySignatureCreator final : public BaseSignatureCreator {
#     409                 :            : private:
#     410                 :            :     char m_r_len = 32;
#     411                 :            :     char m_s_len = 32;
#     412                 :            : public:
#     413                 :       1506 :     DummySignatureCreator(char r_len, char s_len) : m_r_len(r_len), m_s_len(s_len) {}
#     414                 :     859580 :     const BaseSignatureChecker& Checker() const override { return DUMMY_CHECKER; }
#     415                 :            :     bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override
#     416                 :     862690 :     {
#     417                 :            :         // Create a dummy signature that is a valid DER-encoding
#     418                 :     862690 :         vchSig.assign(m_r_len + m_s_len + 7, '\000');
#     419                 :     862690 :         vchSig[0] = 0x30;
#     420                 :     862690 :         vchSig[1] = m_r_len + m_s_len + 4;
#     421                 :     862690 :         vchSig[2] = 0x02;
#     422                 :     862690 :         vchSig[3] = m_r_len;
#     423                 :     862690 :         vchSig[4] = 0x01;
#     424                 :     862690 :         vchSig[4 + m_r_len] = 0x02;
#     425                 :     862690 :         vchSig[5 + m_r_len] = m_s_len;
#     426                 :     862690 :         vchSig[6 + m_r_len] = 0x01;
#     427                 :     862690 :         vchSig[6 + m_r_len + m_s_len] = SIGHASH_ALL;
#     428                 :     862690 :         return true;
#     429                 :     862690 :     }
#     430                 :            : };
#     431                 :            : 
#     432                 :            : }
#     433                 :            : 
#     434                 :            : const BaseSignatureCreator& DUMMY_SIGNATURE_CREATOR = DummySignatureCreator(32, 32);
#     435                 :            : const BaseSignatureCreator& DUMMY_MAXIMUM_SIGNATURE_CREATOR = DummySignatureCreator(33, 32);
#     436                 :            : 
#     437                 :            : bool IsSolvable(const SigningProvider& provider, const CScript& script)
#     438                 :     425352 : {
#     439                 :            :     // This check is to make sure that the script we created can actually be solved for and signed by us
#     440                 :            :     // if we were to have the private keys. This is just to make sure that the script is valid and that,
#     441                 :            :     // if found in a transaction, we would still accept and relay that transaction. In particular,
#     442                 :            :     // it will reject witness outputs that require signing with an uncompressed public key.
#     443                 :     425352 :     SignatureData sigs;
#     444                 :            :     // Make sure that STANDARD_SCRIPT_VERIFY_FLAGS includes SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, the most
#     445                 :            :     // important property this function is designed to test for.
#     446                 :     425352 :     static_assert(STANDARD_SCRIPT_VERIFY_FLAGS & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, "IsSolvable requires standard script flags to include WITNESS_PUBKEYTYPE");
#     447         [ +  + ]:     425352 :     if (ProduceSignature(provider, DUMMY_SIGNATURE_CREATOR, script, sigs)) {
#     448                 :            :         // VerifyScript check is just defensive, and should never fail.
#     449                 :     425164 :         bool verified = VerifyScript(sigs.scriptSig, script, &sigs.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, DUMMY_CHECKER);
#     450                 :     425164 :         assert(verified);
#     451                 :     425164 :         return true;
#     452                 :     425164 :     }
#     453                 :        188 :     return false;
#     454                 :        188 : }
#     455                 :            : 
#     456                 :            : bool IsSegWitOutput(const SigningProvider& provider, const CScript& script)
#     457                 :         12 : {
#     458                 :         12 :     std::vector<valtype> solutions;
#     459                 :         12 :     auto whichtype = Solver(script, solutions);
#     460 [ -  + ][ +  + ]:         12 :     if (whichtype == TxoutType::WITNESS_V0_SCRIPTHASH || whichtype == TxoutType::WITNESS_V0_KEYHASH || whichtype == TxoutType::WITNESS_UNKNOWN) return true;
#                 [ -  + ]
#     461         [ +  + ]:          8 :     if (whichtype == TxoutType::SCRIPTHASH) {
#     462                 :          4 :         auto h160 = uint160(solutions[0]);
#     463                 :          4 :         CScript subscript;
#     464         [ +  + ]:          4 :         if (provider.GetCScript(CScriptID{h160}, subscript)) {
#     465                 :          2 :             whichtype = Solver(subscript, solutions);
#     466 [ -  + ][ +  - ]:          2 :             if (whichtype == TxoutType::WITNESS_V0_SCRIPTHASH || whichtype == TxoutType::WITNESS_V0_KEYHASH || whichtype == TxoutType::WITNESS_UNKNOWN) return true;
#                 [ #  # ]
#     467                 :          6 :         }
#     468                 :          4 :     }
#     469                 :          6 :     return false;
#     470                 :          6 : }
#     471                 :            : 
#     472                 :            : bool SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore, const std::map<COutPoint, Coin>& coins, int nHashType, std::map<int, std::string>& input_errors)
#     473                 :      13880 : {
#     474                 :      13880 :     bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
#     475                 :            : 
#     476                 :            :     // Use CTransaction for the constant parts of the
#     477                 :            :     // transaction to avoid rehashing.
#     478                 :      13880 :     const CTransaction txConst(mtx);
#     479                 :            :     // Sign what we can:
#     480         [ +  + ]:      83341 :     for (unsigned int i = 0; i < mtx.vin.size(); i++) {
#     481                 :      69461 :         CTxIn& txin = mtx.vin[i];
#     482                 :      69461 :         auto coin = coins.find(txin.prevout);
#     483 [ -  + ][ +  + ]:      69461 :         if (coin == coins.end() || coin->second.IsSpent()) {
#                 [ +  + ]
#     484                 :         26 :             input_errors[i] = "Input not found or already spent";
#     485                 :         26 :             continue;
#     486                 :         26 :         }
#     487                 :      69435 :         const CScript& prevPubKey = coin->second.out.scriptPubKey;
#     488                 :      69435 :         const CAmount& amount = coin->second.out.nValue;
#     489                 :            : 
#     490                 :      69435 :         SignatureData sigdata = DataFromTransaction(mtx, i, coin->second.out);
#     491                 :            :         // Only sign SIGHASH_SINGLE if there's a corresponding output:
#     492 [ +  - ][ #  # ]:      69435 :         if (!fHashSingle || (i < mtx.vout.size())) {
#     493                 :      69435 :             ProduceSignature(*keystore, MutableTransactionSignatureCreator(&mtx, i, amount, nHashType), prevPubKey, sigdata);
#     494                 :      69435 :         }
#     495                 :            : 
#     496                 :      69435 :         UpdateInput(txin, sigdata);
#     497                 :            : 
#     498                 :            :         // amount must be specified for valid segwit signature
#     499 [ +  + ][ +  + ]:      69435 :         if (amount == MAX_MONEY && !txin.scriptWitness.IsNull()) {
#     500                 :         13 :             input_errors[i] = "Missing amount";
#     501                 :         13 :             continue;
#     502                 :         13 :         }
#     503                 :            : 
#     504                 :      69422 :         ScriptError serror = SCRIPT_ERR_OK;
#     505         [ +  + ]:      69422 :         if (!VerifyScript(txin.scriptSig, prevPubKey, &txin.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount, MissingDataBehavior::FAIL), &serror)) {
#     506         [ +  + ]:      37876 :             if (serror == SCRIPT_ERR_INVALID_STACK_OPERATION) {
#     507                 :            :                 // Unable to sign input and verification failed (possible attempt to partially sign).
#     508                 :      27086 :                 input_errors[i] = "Unable to sign input, invalid stack size (possibly missing key)";
#     509         [ +  + ]:      27086 :             } else if (serror == SCRIPT_ERR_SIG_NULLFAIL) {
#     510                 :            :                 // Verification failed (possibly due to insufficient signatures).
#     511                 :         76 :                 input_errors[i] = "CHECK(MULTI)SIG failing with non-zero signature (possibly need more signatures)";
#     512                 :      10714 :             } else {
#     513                 :      10714 :                 input_errors[i] = ScriptErrorString(serror);
#     514                 :      10714 :             }
#     515                 :      37876 :         } else {
#     516                 :            :             // If this input succeeds, make sure there is no error set for it
#     517                 :      31546 :             input_errors.erase(i);
#     518                 :      31546 :         }
#     519                 :      69422 :     }
#     520                 :      13880 :     return input_errors.empty();
#     521                 :      13880 : }

Generated by: LCOV version 1.14