LCOV - code coverage report
Current view: top level - src/script - sign.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 272 278 97.8 %
Date: 2026-06-25 07:23:43 Functions: 37 44 84.1 %

          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/sign.h>
       7             : 
       8             : #include <consensus/amount.h>
       9             : #include <key.h>
      10             : #include <policy/policy.h>
      11             : #include <primitives/transaction.h>
      12             : #include <script/keyorigin.h>
      13             : #include <script/signingprovider.h>
      14             : #include <script/standard.h>
      15             : #include <uint256.h>
      16             : #include <util/translation.h>
      17             : 
      18             : typedef std::vector<unsigned char> valtype;
      19             : 
      20        3204 : MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction& tx, unsigned int input_idx, const CAmount& amount, int hash_type)
      21        1602 :     : m_txto{tx}, nIn{input_idx}, nHashType{hash_type}, amount{amount}, checker{&m_txto, nIn, amount, MissingDataBehavior::FAIL},
      22        1602 :       m_txdata(nullptr)
      23        3204 : {
      24        3204 : }
      25             : 
      26      182794 : MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction& tx, unsigned int input_idx, const CAmount& amount, const PrecomputedTransactionData* txdata, int hash_type)
      27       91397 :     : m_txto{tx}, nIn{input_idx}, nHashType{hash_type}, amount{amount},
      28       91397 :       checker{txdata ? MutableTransactionSignatureChecker{&m_txto, nIn, amount, *txdata, MissingDataBehavior::FAIL} :
      29           0 :                        MutableTransactionSignatureChecker{&m_txto, nIn, amount, MissingDataBehavior::FAIL}},
      30       91397 :       m_txdata(txdata)
      31      182794 : {
      32      182794 : }
      33             : 
      34       67465 : bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
      35             : {
      36       67465 :     CKey key;
      37       67465 :     if (!provider.GetKey(address, key))
      38        2907 :         return false;
      39             : 
      40       64558 :     uint256 hash = SignatureHash(scriptCode, m_txto, nIn, nHashType, amount, sigversion, m_txdata);
      41       64558 :     if (!key.Sign(hash, vchSig))
      42           0 :         return false;
      43       64558 :     vchSig.push_back((unsigned char)nHashType);
      44       64558 :     return true;
      45       67465 : }
      46             : 
      47        2088 : static bool GetCScript(const SigningProvider& provider, const SignatureData& sigdata, const CScriptID& scriptid, CScript& script)
      48             : {
      49        2088 :     if (provider.GetCScript(scriptid, script)) {
      50         815 :         return true;
      51             :     }
      52             :     // Look for scripts in SignatureData
      53        1273 :     if (CScriptID(sigdata.redeem_script) == scriptid) {
      54         118 :         script = sigdata.redeem_script;
      55         118 :         return true;
      56             :     }
      57        1155 :     return false;
      58        2088 : }
      59             : 
      60      796518 : static bool GetPubKey(const SigningProvider& provider, const SignatureData& sigdata, const CKeyID& address, CPubKey& pubkey)
      61             : {
      62             :     // Look for pubkey in all partial sigs
      63      796518 :     const auto it = sigdata.signatures.find(address);
      64      796518 :     if (it != sigdata.signatures.end()) {
      65          20 :         pubkey = it->second.first;
      66          20 :         return true;
      67             :     }
      68             :     // Look for pubkey in pubkey list
      69      796498 :     const auto& pk_it = sigdata.misc_pubkeys.find(address);
      70      796498 :     if (pk_it != sigdata.misc_pubkeys.end()) {
      71        1831 :         pubkey = pk_it->second.first;
      72        1831 :         return true;
      73             :     }
      74             :     // Query the underlying provider
      75      794667 :     return provider.GetPubKey(address, pubkey);
      76      796518 : }
      77             : 
      78      714042 : 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)
      79             : {
      80      714042 :     CKeyID keyid = pubkey.GetID();
      81      714042 :     const auto it = sigdata.signatures.find(keyid);
      82      714042 :     if (it != sigdata.signatures.end()) {
      83         400 :         sig_out = it->second.second;
      84         400 :         return true;
      85             :     }
      86      713642 :     KeyOriginInfo info;
      87      713642 :     if (provider.GetKeyOrigin(keyid, info)) {
      88      696191 :         sigdata.misc_pubkeys.emplace(keyid, std::make_pair(pubkey, std::move(info)));
      89      696191 :     }
      90      713642 :     if (creator.CreateSig(provider, sig_out, keyid, scriptcode, sigversion)) {
      91      710735 :         auto i = sigdata.signatures.emplace(keyid, SigPair(pubkey, sig_out));
      92      710735 :         assert(i.second);
      93      710735 :         return true;
      94             :     }
      95             :     // Could not make signature or signature not found, add keyid to missing
      96        2907 :     sigdata.missing_sigs.push_back(keyid);
      97        2907 :     return false;
      98      714042 : }
      99             : 
     100             : /**
     101             :  * Sign scriptPubKey using signature made with creator.
     102             :  * Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
     103             :  * unless whichTypeRet is TxoutType::SCRIPTHASH, in which case scriptSigRet is the redemption script.
     104             :  * Returns false if scriptPubKey could not be completely satisfied.
     105             :  */
     106      810787 : static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey,
     107             :                      std::vector<valtype>& ret, TxoutType& whichTypeRet, SigVersion sigversion, SignatureData& sigdata)
     108             : {
     109      810787 :     CScript scriptRet;
     110      810787 :     ret.clear();
     111      810787 :     std::vector<unsigned char> sig;
     112             : 
     113      810787 :     std::vector<valtype> vSolutions;
     114      810787 :     whichTypeRet = Solver(scriptPubKey, vSolutions);
     115             : 
     116      810787 :     switch (whichTypeRet) {
     117             :     case TxoutType::NONSTANDARD:
     118             :     case TxoutType::NULL_DATA:
     119       10975 :         return false;
     120             :     case TxoutType::PUBKEY:
     121         657 :         if (!CreateSig(creator, sigdata, provider, sig, CPubKey(vSolutions[0]), scriptPubKey, sigversion)) return false;
     122         637 :         ret.push_back(std::move(sig));
     123         637 :         return true;
     124             :     case TxoutType::PUBKEYHASH: {
     125      796518 :         CKeyID keyID = CKeyID(uint160(vSolutions[0]));
     126      796518 :         CPubKey pubkey;
     127      796518 :         if (!GetPubKey(provider, sigdata, keyID, pubkey)) {
     128             :             // Pubkey could not be found, add to missing
     129       84935 :             sigdata.missing_pubkeys.push_back(keyID);
     130       84935 :             return false;
     131             :         }
     132      711583 :         if (!CreateSig(creator, sigdata, provider, sig, pubkey, scriptPubKey, sigversion)) return false;
     133      708985 :         ret.push_back(std::move(sig));
     134      708985 :         ret.push_back(ToByteVector(pubkey));
     135      708985 :         return true;
     136             :     }
     137             :     case TxoutType::SCRIPTHASH: {
     138        2088 :         uint160 h160{vSolutions[0]};
     139        2088 :         if (GetCScript(provider, sigdata, CScriptID{h160}, scriptRet)) {
     140         933 :             ret.emplace_back(scriptRet.begin(), scriptRet.end());
     141         933 :             return true;
     142             :         }
     143             :         // Could not find redeemScript, add to missing
     144        1155 :         sigdata.missing_redeem_script = h160;
     145        1155 :         return false;
     146             :     }
     147             :     case TxoutType::MULTISIG: {
     148         549 :         size_t required = vSolutions.front()[0];
     149         549 :         ret.emplace_back(); // workaround CHECKMULTISIG bug
     150        2351 :         for (size_t i = 1; i < vSolutions.size() - 1; ++i) {
     151        1802 :             CPubKey pubkey = CPubKey(vSolutions[i]);
     152             :             // We need to always call CreateSig in order to fill sigdata with all
     153             :             // possible signatures that we can create. This will allow further PSBT
     154             :             // processing to work as it needs all possible signature and pubkey pairs
     155        1802 :             if (CreateSig(creator, sigdata, provider, sig, pubkey, scriptPubKey, sigversion)) {
     156        1513 :                 if (ret.size() < required + 1) {
     157        1196 :                     ret.push_back(std::move(sig));
     158        1196 :                 }
     159        1513 :             }
     160        1802 :         }
     161         549 :         bool ok = ret.size() == required + 1;
     162         685 :         for (size_t i = 0; i + ret.size() < required + 1; ++i) {
     163         136 :             ret.emplace_back();
     164         136 :         }
     165         549 :         return ok;
     166             :     }
     167             :     } // no default case, so the compiler can warn about missing cases
     168           0 :     assert(false);
     169      810787 : }
     170             : 
     171      809854 : static CScript PushAll(const std::vector<valtype>& values)
     172             : {
     173      809854 :     CScript result;
     174     2231275 :     for(const valtype& v : values) {
     175     1421421 :         if (v.size() == 0) {
     176         685 :             result << OP_0;
     177     1421421 :         } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) {
     178           0 :             result << CScript::EncodeOP_N(v[0]);
     179     1420736 :         } else if (v.size() == 1 && v[0] == 0x81) {
     180           0 :             result << OP_1NEGATE;
     181           0 :         } else {
     182     1420736 :             result << v;
     183             :         }
     184             :     }
     185      809854 :     return result;
     186      809854 : }
     187             : 
     188      810249 : bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata)
     189             : {
     190      810249 :     if (sigdata.complete) return true;
     191             : 
     192      809854 :     std::vector<valtype> result;
     193             :     TxoutType whichType;
     194      809854 :     bool solved = SignStep(provider, creator, fromPubKey, result, whichType, SigVersion::BASE, sigdata);
     195      809854 :     bool P2SH = false;
     196      809854 :     CScript subscript;
     197             : 
     198      809854 :     if (solved && whichType == TxoutType::SCRIPTHASH)
     199             :     {
     200             :         // Solver returns the subscript that needs to be evaluated;
     201             :         // the final scriptSig is the signatures from that
     202             :         // and then the serialized subscript:
     203         933 :         subscript = CScript(result[0].begin(), result[0].end());
     204         933 :         sigdata.redeem_script = subscript;
     205         933 :         solved = solved && SignStep(provider, creator, subscript, result, whichType, SigVersion::BASE, sigdata) && whichType != TxoutType::SCRIPTHASH;
     206         933 :         P2SH = true;
     207         933 :     }
     208             : 
     209      809854 :     if (P2SH) {
     210         933 :         result.emplace_back(subscript.begin(), subscript.end());
     211         933 :     }
     212      809854 :     sigdata.scriptSig = PushAll(result);
     213             : 
     214             :     // Test solution
     215     1519889 :     sigdata.complete = solved && VerifyScript(sigdata.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker());
     216      809854 :     return sigdata.complete;
     217      810249 : }
     218             : 
     219             : namespace {
     220             : class SignatureExtractorChecker final : public DeferringSignatureChecker
     221             : {
     222             : private:
     223             :     SignatureData& sigdata;
     224             : 
     225             : public:
     226      176928 :     SignatureExtractorChecker(SignatureData& sigdata, BaseSignatureChecker& checker) : DeferringSignatureChecker(checker), sigdata(sigdata) {}
     227             : 
     228        1577 :     bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override
     229             :     {
     230        1577 :         if (m_checker.CheckSig(scriptSig, vchPubKey, scriptCode, sigversion)) {
     231         411 :             CPubKey pubkey(vchPubKey);
     232         411 :             sigdata.signatures.emplace(pubkey.GetID(), SigPair(pubkey, scriptSig));
     233         411 :             return true;
     234             :         }
     235        1166 :         return false;
     236        1577 :     }
     237             : };
     238             : 
     239             : struct Stacks
     240             : {
     241             :     std::vector<valtype> script;
     242             : 
     243             :     Stacks() = delete;
     244             :     Stacks(const Stacks&) = delete;
     245      176928 :     explicit Stacks(const SignatureData& data) {
     246       88464 :         EvalScript(script, data.scriptSig, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), SigVersion::BASE);
     247      176928 :     }
     248             : };
     249             : }
     250             : 
     251             : // Extracts signatures and scripts from incomplete scriptSigs. Please do not extend this, use PSBT instead
     252       88464 : SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn, const CTxOut& txout)
     253             : {
     254       88464 :     SignatureData data;
     255       88464 :     assert(tx.vin.size() > nIn);
     256       88464 :     data.scriptSig = tx.vin[nIn].scriptSig;
     257       88464 :     Stacks stack(data);
     258             : 
     259             :     // Get signatures
     260       88464 :     MutableTransactionSignatureChecker tx_checker(&tx, nIn, txout.nValue, MissingDataBehavior::FAIL);
     261       88464 :     SignatureExtractorChecker extractor_checker(data, tx_checker);
     262       88464 :     if (VerifyScript(data.scriptSig, txout.scriptPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, extractor_checker)) {
     263         392 :         data.complete = true;
     264         392 :         return data;
     265             :     }
     266             : 
     267             :     // Get scripts
     268       88072 :     std::vector<std::vector<unsigned char>> solutions;
     269       88072 :     TxoutType script_type = Solver(txout.scriptPubKey, solutions);
     270       88072 :     SigVersion sigversion = SigVersion::BASE;
     271       88072 :     CScript next_script = txout.scriptPubKey;
     272             : 
     273       88072 :     if (script_type == TxoutType::SCRIPTHASH && !stack.script.empty() && !stack.script.back().empty()) {
     274             :         // Get the redeemScript
     275          18 :         CScript redeem_script(stack.script.back().begin(), stack.script.back().end());
     276          18 :         data.redeem_script = redeem_script;
     277          18 :         next_script = std::move(redeem_script);
     278             : 
     279             :         // Get redeemScript type
     280          18 :         script_type = Solver(next_script, solutions);
     281          18 :         stack.script.pop_back();
     282          18 :     }
     283             : 
     284       88072 :     if (script_type == TxoutType::MULTISIG && !stack.script.empty()) {
     285             :         // Build a map of pubkey -> signature by matching sigs to pubkeys:
     286          18 :         assert(solutions.size() > 1);
     287          18 :         unsigned int num_pubkeys = solutions.size()-2;
     288          18 :         unsigned int last_success_key = 0;
     289          76 :         for (const valtype& sig : stack.script) {
     290         152 :             for (unsigned int i = last_success_key; i < num_pubkeys; ++i) {
     291         116 :                 const valtype& pubkey = solutions[i+1];
     292             :                 // We either have a signature for this pubkey, or we have found a signature and it is valid
     293         116 :                 if (data.signatures.count(CPubKey(pubkey).GetID()) || extractor_checker.CheckSig(sig, pubkey, next_script, sigversion)) {
     294          22 :                     last_success_key = i + 1;
     295          22 :                     break;
     296             :                 }
     297          94 :             }
     298             :         }
     299          18 :     }
     300             : 
     301       88072 :     return data;
     302       88464 : }
     303             : 
     304      732285 : void UpdateInput(CTxIn& input, const SignatureData& data)
     305             : {
     306      732285 :     input.scriptSig = data.scriptSig;
     307      732285 : }
     308             : 
     309          38 : void SignatureData::MergeSignatureData(SignatureData sigdata)
     310             : {
     311          38 :     if (complete) return;
     312          33 :     if (sigdata.complete) {
     313           8 :         *this = std::move(sigdata);
     314           8 :         return;
     315             :     }
     316          25 :     if (redeem_script.empty() && !sigdata.redeem_script.empty()) {
     317           2 :         redeem_script = sigdata.redeem_script;
     318           2 :     }
     319          25 :     signatures.insert(std::make_move_iterator(sigdata.signatures.begin()), std::make_move_iterator(sigdata.signatures.end()));
     320          38 : }
     321             : 
     322         319 : bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType)
     323             : {
     324         319 :     assert(nIn < txTo.vin.size());
     325             : 
     326         319 :     MutableTransactionSignatureCreator creator(txTo, nIn, amount, nHashType);
     327             : 
     328         319 :     SignatureData sigdata;
     329         319 :     bool ret = ProduceSignature(provider, creator, fromPubKey, sigdata);
     330         319 :     UpdateInput(txTo.vin.at(nIn), sigdata);
     331         319 :     return ret;
     332         319 : }
     333             : 
     334         217 : bool SignSignature(const SigningProvider &provider, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
     335             : {
     336         217 :     assert(nIn < txTo.vin.size());
     337         217 :     const CTxIn& txin = txTo.vin[nIn];
     338         217 :     assert(txin.prevout.n < txFrom.vout.size());
     339         217 :     const CTxOut& txout = txFrom.vout[txin.prevout.n];
     340             : 
     341         217 :     return SignSignature(provider, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType);
     342             : }
     343             : 
     344             : namespace {
     345             : /** Dummy signature checker which accepts all signatures. */
     346             : class DummySignatureChecker final : public BaseSignatureChecker
     347             : {
     348             : public:
     349        7032 :     DummySignatureChecker() = default;
     350      648379 :     bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override { return true; }
     351             : };
     352             : }
     353             : 
     354        3516 : const BaseSignatureChecker& DUMMY_CHECKER = DummySignatureChecker();
     355             : 
     356             : namespace {
     357             : class DummySignatureCreator final : public BaseSignatureCreator {
     358             : private:
     359             :     char m_r_len = 32;
     360             :     char m_s_len = 32;
     361             : public:
     362       14064 :     DummySignatureCreator(char r_len, char s_len) : m_r_len(r_len), m_s_len(s_len) {}
     363      645547 :     const BaseSignatureChecker& Checker() const override { return DUMMY_CHECKER; }
     364      646177 :     bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override
     365             :     {
     366             :         // Create a dummy signature that is a valid DER-encoding
     367      646177 :         vchSig.assign(m_r_len + m_s_len + 7, '\000');
     368      646177 :         vchSig[0] = 0x30;
     369      646177 :         vchSig[1] = m_r_len + m_s_len + 4;
     370      646177 :         vchSig[2] = 0x02;
     371      646177 :         vchSig[3] = m_r_len;
     372      646177 :         vchSig[4] = 0x01;
     373      646177 :         vchSig[4 + m_r_len] = 0x02;
     374      646177 :         vchSig[5 + m_r_len] = m_s_len;
     375      646177 :         vchSig[6 + m_r_len] = 0x01;
     376      646177 :         vchSig[6 + m_r_len + m_s_len] = SIGHASH_ALL;
     377      646177 :         return true;
     378             :     }
     379             : };
     380             : 
     381             : }
     382             : 
     383        3516 : const BaseSignatureCreator& DUMMY_SIGNATURE_CREATOR = DummySignatureCreator(32, 32);
     384        3516 : const BaseSignatureCreator& DUMMY_MAXIMUM_SIGNATURE_CREATOR = DummySignatureCreator(33, 32);
     385             : 
     386        2063 : bool IsSolvable(const SigningProvider& provider, const CScript& script)
     387             : {
     388             :     // This check is to make sure that the script we created can actually be solved for and signed by us
     389             :     // if we were to have the private keys. This is just to make sure that the script is valid and that,
     390             :     // if found in a transaction, we would still accept and relay that transaction.
     391        2063 :     SignatureData sigs;
     392        2063 :     if (ProduceSignature(provider, DUMMY_SIGNATURE_CREATOR, script, sigs)) {
     393             :         // VerifyScript check is just defensive, and should never fail.
     394        2030 :         bool verified = VerifyScript(sigs.scriptSig, script, STANDARD_SCRIPT_VERIFY_FLAGS, DUMMY_CHECKER);
     395        2030 :         assert(verified);
     396        2030 :         return true;
     397             :     }
     398          33 :     return false;
     399        2063 : }
     400             : 
     401       20544 : bool SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore, const std::map<COutPoint, Coin>& coins, int nHashType, std::map<int, bilingual_str>& input_errors)
     402             : {
     403       20544 :     bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
     404             : 
     405             :     // Use CTransaction for the constant parts of the
     406             :     // transaction to avoid rehashing.
     407       20544 :     const CTransaction txConst(mtx);
     408             : 
     409       20544 :     PrecomputedTransactionData txdata;
     410       20544 :     std::vector<CTxOut> spent_outputs;
     411       20544 :     spent_outputs.resize(mtx.vin.size());
     412       20544 :     bool have_all_spent_outputs = true;
     413      109000 :     for (unsigned int i = 0; i < mtx.vin.size(); i++) {
     414       88456 :         CTxIn& txin = mtx.vin[i];
     415       88456 :         auto coin = coins.find(txin.prevout);
     416       88456 :         if (coin == coins.end() || coin->second.IsSpent()) {
     417           4 :             have_all_spent_outputs = false;
     418           4 :         } else {
     419       88452 :             spent_outputs[i] = CTxOut(coin->second.out.nValue, coin->second.out.scriptPubKey);
     420             :         }
     421       88456 :     }
     422       20544 :     if (have_all_spent_outputs) {
     423       20540 :         txdata.Init(txConst, std::move(spent_outputs), true);
     424       20540 :     } else {
     425           4 :         txdata.Init(txConst, {}, true);
     426             :     }
     427             : 
     428             :     // Sign what we can:
     429      109000 :     for (unsigned int i = 0; i < mtx.vin.size(); i++) {
     430       88456 :         CTxIn& txin = mtx.vin[i];
     431       88456 :         auto coin = coins.find(txin.prevout);
     432       88456 :         if (coin == coins.end() || coin->second.IsSpent()) {
     433           4 :             input_errors[i] = _("Input not found or already spent");
     434           4 :             continue;
     435             :         }
     436       88452 :         const CScript& prevPubKey = coin->second.out.scriptPubKey;
     437       88452 :         const CAmount& amount = coin->second.out.nValue;
     438             : 
     439       88452 :         SignatureData sigdata = DataFromTransaction(mtx, i, coin->second.out);
     440             :         // Only sign SIGHASH_SINGLE if there's a corresponding output:
     441       88452 :         if (!fHashSingle || (i < mtx.vout.size())) {
     442       88452 :             ProduceSignature(*keystore, MutableTransactionSignatureCreator(mtx, i, amount, &txdata, nHashType), prevPubKey, sigdata);
     443       88452 :         }
     444             : 
     445       88452 :         UpdateInput(txin, sigdata);
     446             : 
     447       88452 :         ScriptError serror = SCRIPT_ERR_OK;
     448       88452 :         if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount, txdata, MissingDataBehavior::FAIL), &serror)) {
     449       24564 :             if (serror == SCRIPT_ERR_INVALID_STACK_OPERATION) {
     450             :                 // Unable to sign input and verification failed (possible attempt to partially sign).
     451       24537 :                 input_errors[i] = Untranslated("Unable to sign input, invalid stack size (possibly missing key)");
     452       24564 :             } else if (serror == SCRIPT_ERR_SIG_NULLFAIL) {
     453             :                 // Verification failed (possibly due to insufficient signatures).
     454          26 :                 input_errors[i] = Untranslated("CHECK(MULTI)SIG failing with non-zero signature (possibly need more signatures)");
     455          26 :             } else {
     456           1 :                 input_errors[i] = Untranslated(ScriptErrorString(serror));
     457             :             }
     458       24564 :         } else {
     459             :             // If this input succeeds, make sure there is no error set for it
     460       63888 :             input_errors.erase(i);
     461             :         }
     462       88452 :     }
     463       20544 :     return input_errors.empty();
     464       20544 : }

Generated by: LCOV version 1.16