LCOV - code coverage report
Current view: top level - src - psbt.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 234 274 85.4 %
Date: 2021-06-29 14:35:33 Functions: 20 24 83.3 %
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: 123 174 70.7 %

           Branch data     Line data    Source code
#       1                 :            : // Copyright (c) 2009-2020 The Bitcoin Core developers
#       2                 :            : // Distributed under the MIT software license, see the accompanying
#       3                 :            : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#       4                 :            : 
#       5                 :            : #include <psbt.h>
#       6                 :            : 
#       7                 :            : #include <util/check.h>
#       8                 :            : #include <util/strencodings.h>
#       9                 :            : 
#      10                 :            : 
#      11                 :            : PartiallySignedTransaction::PartiallySignedTransaction(const CMutableTransaction& tx) : tx(tx)
#      12                 :        153 : {
#      13                 :        153 :     inputs.resize(tx.vin.size());
#      14                 :        153 :     outputs.resize(tx.vout.size());
#      15                 :        153 : }
#      16                 :            : 
#      17                 :            : bool PartiallySignedTransaction::IsNull() const
#      18                 :          0 : {
#      19 [ #  # ][ #  # ]:          0 :     return !tx && inputs.empty() && outputs.empty() && unknown.empty();
#         [ #  # ][ #  # ]
#      20                 :          0 : }
#      21                 :            : 
#      22                 :            : bool PartiallySignedTransaction::Merge(const PartiallySignedTransaction& psbt)
#      23                 :          6 : {
#      24                 :            :     // Prohibited to merge two PSBTs over different transactions
#      25         [ -  + ]:          6 :     if (tx->GetHash() != psbt.tx->GetHash()) {
#      26                 :          0 :         return false;
#      27                 :          0 :     }
#      28                 :            : 
#      29         [ +  + ]:         16 :     for (unsigned int i = 0; i < inputs.size(); ++i) {
#      30                 :         10 :         inputs[i].Merge(psbt.inputs[i]);
#      31                 :         10 :     }
#      32         [ +  + ]:         14 :     for (unsigned int i = 0; i < outputs.size(); ++i) {
#      33                 :          8 :         outputs[i].Merge(psbt.outputs[i]);
#      34                 :          8 :     }
#      35                 :          6 :     unknown.insert(psbt.unknown.begin(), psbt.unknown.end());
#      36                 :            : 
#      37                 :          6 :     return true;
#      38                 :          6 : }
#      39                 :            : 
#      40                 :            : bool PartiallySignedTransaction::AddInput(const CTxIn& txin, PSBTInput& psbtin)
#      41                 :         36 : {
#      42         [ +  + ]:         36 :     if (std::find(tx->vin.begin(), tx->vin.end(), txin) != tx->vin.end()) {
#      43                 :          2 :         return false;
#      44                 :          2 :     }
#      45                 :         34 :     tx->vin.push_back(txin);
#      46                 :         34 :     psbtin.partial_sigs.clear();
#      47                 :         34 :     psbtin.final_script_sig.clear();
#      48                 :         34 :     psbtin.final_script_witness.SetNull();
#      49                 :         34 :     inputs.push_back(psbtin);
#      50                 :         34 :     return true;
#      51                 :         34 : }
#      52                 :            : 
#      53                 :            : bool PartiallySignedTransaction::AddOutput(const CTxOut& txout, const PSBTOutput& psbtout)
#      54                 :         18 : {
#      55                 :         18 :     tx->vout.push_back(txout);
#      56                 :         18 :     outputs.push_back(psbtout);
#      57                 :         18 :     return true;
#      58                 :         18 : }
#      59                 :            : 
#      60                 :            : bool PartiallySignedTransaction::GetInputUTXO(CTxOut& utxo, int input_index) const
#      61                 :         22 : {
#      62                 :         22 :     PSBTInput input = inputs[input_index];
#      63                 :         22 :     uint32_t prevout_index = tx->vin[input_index].prevout.n;
#      64         [ +  + ]:         22 :     if (input.non_witness_utxo) {
#      65         [ +  + ]:         10 :         if (prevout_index >= input.non_witness_utxo->vout.size()) {
#      66                 :          2 :             return false;
#      67                 :          2 :         }
#      68                 :          8 :         utxo = input.non_witness_utxo->vout[prevout_index];
#      69         [ +  + ]:         12 :     } else if (!input.witness_utxo.IsNull()) {
#      70                 :         10 :         utxo = input.witness_utxo;
#      71                 :         10 :     } else {
#      72                 :          2 :         return false;
#      73                 :          2 :     }
#      74                 :         18 :     return true;
#      75                 :         18 : }
#      76                 :            : 
#      77                 :            : bool PSBTInput::IsNull() const
#      78                 :          0 : {
#      79 [ #  # ][ #  # ]:          0 :     return !non_witness_utxo && witness_utxo.IsNull() && partial_sigs.empty() && unknown.empty() && hd_keypaths.empty() && redeem_script.empty() && witness_script.empty();
#         [ #  # ][ #  # ]
#         [ #  # ][ #  # ]
#                 [ #  # ]
#      80                 :          0 : }
#      81                 :            : 
#      82                 :            : void PSBTInput::FillSignatureData(SignatureData& sigdata) const
#      83                 :       3541 : {
#      84         [ -  + ]:       3541 :     if (!final_script_sig.empty()) {
#      85                 :          0 :         sigdata.scriptSig = final_script_sig;
#      86                 :          0 :         sigdata.complete = true;
#      87                 :          0 :     }
#      88         [ -  + ]:       3541 :     if (!final_script_witness.IsNull()) {
#      89                 :          0 :         sigdata.scriptWitness = final_script_witness;
#      90                 :          0 :         sigdata.complete = true;
#      91                 :          0 :     }
#      92         [ -  + ]:       3541 :     if (sigdata.complete) {
#      93                 :          0 :         return;
#      94                 :          0 :     }
#      95                 :            : 
#      96                 :       3541 :     sigdata.signatures.insert(partial_sigs.begin(), partial_sigs.end());
#      97         [ +  + ]:       3541 :     if (!redeem_script.empty()) {
#      98                 :        608 :         sigdata.redeem_script = redeem_script;
#      99                 :        608 :     }
#     100         [ +  + ]:       3541 :     if (!witness_script.empty()) {
#     101                 :        148 :         sigdata.witness_script = witness_script;
#     102                 :        148 :     }
#     103         [ +  + ]:       3541 :     for (const auto& key_pair : hd_keypaths) {
#     104                 :       2161 :         sigdata.misc_pubkeys.emplace(key_pair.first.GetID(), key_pair);
#     105                 :       2161 :     }
#     106                 :       3541 : }
#     107                 :            : 
#     108                 :            : void PSBTInput::FromSignatureData(const SignatureData& sigdata)
#     109                 :       1755 : {
#     110         [ +  + ]:       1755 :     if (sigdata.complete) {
#     111                 :        126 :         partial_sigs.clear();
#     112                 :        126 :         hd_keypaths.clear();
#     113                 :        126 :         redeem_script.clear();
#     114                 :        126 :         witness_script.clear();
#     115                 :            : 
#     116         [ +  + ]:        126 :         if (!sigdata.scriptSig.empty()) {
#     117                 :         86 :             final_script_sig = sigdata.scriptSig;
#     118                 :         86 :         }
#     119         [ +  + ]:        126 :         if (!sigdata.scriptWitness.IsNull()) {
#     120                 :         54 :             final_script_witness = sigdata.scriptWitness;
#     121                 :         54 :         }
#     122                 :        126 :         return;
#     123                 :        126 :     }
#     124                 :            : 
#     125                 :       1629 :     partial_sigs.insert(sigdata.signatures.begin(), sigdata.signatures.end());
#     126 [ +  + ][ +  + ]:       1629 :     if (redeem_script.empty() && !sigdata.redeem_script.empty()) {
#     127                 :        107 :         redeem_script = sigdata.redeem_script;
#     128                 :        107 :     }
#     129 [ +  + ][ +  + ]:       1629 :     if (witness_script.empty() && !sigdata.witness_script.empty()) {
#     130                 :         32 :         witness_script = sigdata.witness_script;
#     131                 :         32 :     }
#     132         [ +  + ]:       1629 :     for (const auto& entry : sigdata.misc_pubkeys) {
#     133                 :       1330 :         hd_keypaths.emplace(entry.second);
#     134                 :       1330 :     }
#     135                 :       1629 : }
#     136                 :            : 
#     137                 :            : void PSBTInput::Merge(const PSBTInput& input)
#     138                 :         10 : {
#     139 [ +  + ][ +  + ]:         10 :     if (!non_witness_utxo && input.non_witness_utxo) non_witness_utxo = input.non_witness_utxo;
#     140 [ +  + ][ +  + ]:         10 :     if (witness_utxo.IsNull() && !input.witness_utxo.IsNull()) {
#     141                 :            :         // TODO: For segwit v1, we will want to clear out the non-witness utxo when setting a witness one. For v0 and non-segwit, this is not safe
#     142                 :          2 :         witness_utxo = input.witness_utxo;
#     143                 :          2 :     }
#     144                 :            : 
#     145                 :         10 :     partial_sigs.insert(input.partial_sigs.begin(), input.partial_sigs.end());
#     146                 :         10 :     hd_keypaths.insert(input.hd_keypaths.begin(), input.hd_keypaths.end());
#     147                 :         10 :     unknown.insert(input.unknown.begin(), input.unknown.end());
#     148                 :            : 
#     149 [ +  + ][ -  + ]:         10 :     if (redeem_script.empty() && !input.redeem_script.empty()) redeem_script = input.redeem_script;
#     150 [ +  + ][ -  + ]:         10 :     if (witness_script.empty() && !input.witness_script.empty()) witness_script = input.witness_script;
#     151 [ +  - ][ -  + ]:         10 :     if (final_script_sig.empty() && !input.final_script_sig.empty()) final_script_sig = input.final_script_sig;
#     152 [ +  + ][ +  + ]:         10 :     if (final_script_witness.IsNull() && !input.final_script_witness.IsNull()) final_script_witness = input.final_script_witness;
#     153                 :         10 : }
#     154                 :            : 
#     155                 :            : void PSBTOutput::FillSignatureData(SignatureData& sigdata) const
#     156                 :        530 : {
#     157         [ +  + ]:        530 :     if (!redeem_script.empty()) {
#     158                 :         16 :         sigdata.redeem_script = redeem_script;
#     159                 :         16 :     }
#     160         [ +  + ]:        530 :     if (!witness_script.empty()) {
#     161                 :          3 :         sigdata.witness_script = witness_script;
#     162                 :          3 :     }
#     163         [ +  + ]:        530 :     for (const auto& key_pair : hd_keypaths) {
#     164                 :        115 :         sigdata.misc_pubkeys.emplace(key_pair.first.GetID(), key_pair);
#     165                 :        115 :     }
#     166                 :        530 : }
#     167                 :            : 
#     168                 :            : void PSBTOutput::FromSignatureData(const SignatureData& sigdata)
#     169                 :        530 : {
#     170 [ +  + ][ +  + ]:        530 :     if (redeem_script.empty() && !sigdata.redeem_script.empty()) {
#     171                 :         66 :         redeem_script = sigdata.redeem_script;
#     172                 :         66 :     }
#     173 [ +  + ][ +  + ]:        530 :     if (witness_script.empty() && !sigdata.witness_script.empty()) {
#     174                 :         26 :         witness_script = sigdata.witness_script;
#     175                 :         26 :     }
#     176         [ +  + ]:        530 :     for (const auto& entry : sigdata.misc_pubkeys) {
#     177                 :        434 :         hd_keypaths.emplace(entry.second);
#     178                 :        434 :     }
#     179                 :        530 : }
#     180                 :            : 
#     181                 :            : bool PSBTOutput::IsNull() const
#     182                 :          0 : {
#     183 [ #  # ][ #  # ]:          0 :     return redeem_script.empty() && witness_script.empty() && hd_keypaths.empty() && unknown.empty();
#         [ #  # ][ #  # ]
#     184                 :          0 : }
#     185                 :            : 
#     186                 :            : void PSBTOutput::Merge(const PSBTOutput& output)
#     187                 :          8 : {
#     188                 :          8 :     hd_keypaths.insert(output.hd_keypaths.begin(), output.hd_keypaths.end());
#     189                 :          8 :     unknown.insert(output.unknown.begin(), output.unknown.end());
#     190                 :            : 
#     191 [ +  - ][ -  + ]:          8 :     if (redeem_script.empty() && !output.redeem_script.empty()) redeem_script = output.redeem_script;
#     192 [ +  - ][ -  + ]:          8 :     if (witness_script.empty() && !output.witness_script.empty()) witness_script = output.witness_script;
#     193                 :          8 : }
#     194                 :            : bool PSBTInputSigned(const PSBTInput& input)
#     195                 :       6757 : {
#     196 [ +  + ][ +  + ]:       6757 :     return !input.final_script_sig.empty() || !input.final_script_witness.IsNull();
#     197                 :       6757 : }
#     198                 :            : 
#     199                 :          0 : size_t CountPSBTUnsignedInputs(const PartiallySignedTransaction& psbt) {
#     200                 :          0 :     size_t count = 0;
#     201         [ #  # ]:          0 :     for (const auto& input : psbt.inputs) {
#     202         [ #  # ]:          0 :         if (!PSBTInputSigned(input)) {
#     203                 :          0 :             count++;
#     204                 :          0 :         }
#     205                 :          0 :     }
#     206                 :            : 
#     207                 :          0 :     return count;
#     208                 :          0 : }
#     209                 :            : 
#     210                 :            : void UpdatePSBTOutput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index)
#     211                 :        530 : {
#     212                 :        530 :     CMutableTransaction& tx = *Assert(psbt.tx);
#     213                 :        530 :     const CTxOut& out = tx.vout.at(index);
#     214                 :        530 :     PSBTOutput& psbt_out = psbt.outputs.at(index);
#     215                 :            : 
#     216                 :            :     // Fill a SignatureData with output info
#     217                 :        530 :     SignatureData sigdata;
#     218                 :        530 :     psbt_out.FillSignatureData(sigdata);
#     219                 :            : 
#     220                 :            :     // Construct a would-be spend of this output, to update sigdata with.
#     221                 :            :     // Note that ProduceSignature is used to fill in metadata (not actual signatures),
#     222                 :            :     // so provider does not need to provide any private keys (it can be a HidingSigningProvider).
#     223                 :        530 :     MutableTransactionSignatureCreator creator(&tx, /* index */ 0, out.nValue, SIGHASH_ALL);
#     224                 :        530 :     ProduceSignature(provider, creator, out.scriptPubKey, sigdata);
#     225                 :            : 
#     226                 :            :     // Put redeem_script, witness_script, key paths, into PSBTOutput.
#     227                 :        530 :     psbt_out.FromSignatureData(sigdata);
#     228                 :        530 : }
#     229                 :            : 
#     230                 :            : bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, int sighash, SignatureData* out_sigdata, bool use_dummy)
#     231                 :       1900 : {
#     232                 :       1900 :     PSBTInput& input = psbt.inputs.at(index);
#     233                 :       1900 :     const CMutableTransaction& tx = *psbt.tx;
#     234                 :            : 
#     235         [ +  + ]:       1900 :     if (PSBTInputSigned(input)) {
#     236                 :        113 :         return true;
#     237                 :        113 :     }
#     238                 :            : 
#     239                 :            :     // Fill SignatureData with input info
#     240                 :       1787 :     SignatureData sigdata;
#     241                 :       1787 :     input.FillSignatureData(sigdata);
#     242                 :            : 
#     243                 :            :     // Get UTXO
#     244                 :       1787 :     bool require_witness_sig = false;
#     245                 :       1787 :     CTxOut utxo;
#     246                 :            : 
#     247         [ +  + ]:       1787 :     if (input.non_witness_utxo) {
#     248                 :            :         // If we're taking our information from a non-witness UTXO, verify that it matches the prevout.
#     249                 :       1708 :         COutPoint prevout = tx.vin[index].prevout;
#     250         [ -  + ]:       1708 :         if (prevout.n >= input.non_witness_utxo->vout.size()) {
#     251                 :          0 :             return false;
#     252                 :          0 :         }
#     253         [ -  + ]:       1708 :         if (input.non_witness_utxo->GetHash() != prevout.hash) {
#     254                 :          0 :             return false;
#     255                 :          0 :         }
#     256                 :       1708 :         utxo = input.non_witness_utxo->vout[prevout.n];
#     257         [ +  + ]:       1708 :     } else if (!input.witness_utxo.IsNull()) {
#     258                 :         73 :         utxo = input.witness_utxo;
#     259                 :            :         // When we're taking our information from a witness UTXO, we can't verify it is actually data from
#     260                 :            :         // the output being spent. This is safe in case a witness signature is produced (which includes this
#     261                 :            :         // information directly in the hash), but not for non-witness signatures. Remember that we require
#     262                 :            :         // a witness signature in this situation.
#     263                 :         73 :         require_witness_sig = true;
#     264                 :         73 :     } else {
#     265                 :          6 :         return false;
#     266                 :          6 :     }
#     267                 :            : 
#     268                 :       1781 :     sigdata.witness = false;
#     269                 :       1781 :     bool sig_complete;
#     270         [ +  + ]:       1781 :     if (use_dummy) {
#     271                 :          2 :         sig_complete = ProduceSignature(provider, DUMMY_SIGNATURE_CREATOR, utxo.scriptPubKey, sigdata);
#     272                 :       1779 :     } else {
#     273                 :       1779 :         MutableTransactionSignatureCreator creator(&tx, index, utxo.nValue, sighash);
#     274                 :       1779 :         sig_complete = ProduceSignature(provider, creator, utxo.scriptPubKey, sigdata);
#     275                 :       1779 :     }
#     276                 :            :     // Verify that a witness signature was produced in case one was required.
#     277 [ +  + ][ +  + ]:       1781 :     if (require_witness_sig && !sigdata.witness) return false;
#     278                 :       1755 :     input.FromSignatureData(sigdata);
#     279                 :            : 
#     280                 :            :     // If we have a witness signature, put a witness UTXO.
#     281                 :            :     // TODO: For segwit v1, we should remove the non_witness_utxo
#     282         [ +  + ]:       1755 :     if (sigdata.witness) {
#     283                 :        864 :         input.witness_utxo = utxo;
#     284                 :            :         // input.non_witness_utxo = nullptr;
#     285                 :        864 :     }
#     286                 :            : 
#     287                 :            :     // Fill in the missing info
#     288         [ +  + ]:       1755 :     if (out_sigdata) {
#     289                 :          6 :         out_sigdata->missing_pubkeys = sigdata.missing_pubkeys;
#     290                 :          6 :         out_sigdata->missing_sigs = sigdata.missing_sigs;
#     291                 :          6 :         out_sigdata->missing_redeem_script = sigdata.missing_redeem_script;
#     292                 :          6 :         out_sigdata->missing_witness_script = sigdata.missing_witness_script;
#     293                 :          6 :     }
#     294                 :            : 
#     295                 :       1755 :     return sig_complete;
#     296                 :       1755 : }
#     297                 :            : 
#     298                 :            : bool FinalizePSBT(PartiallySignedTransaction& psbtx)
#     299                 :         98 : {
#     300                 :            :     // Finalize input signatures -- in case we have partial signatures that add up to a complete
#     301                 :            :     //   signature, but have not combined them yet (e.g. because the combiner that created this
#     302                 :            :     //   PartiallySignedTransaction did not understand them), this will combine them into a final
#     303                 :            :     //   script.
#     304                 :         98 :     bool complete = true;
#     305         [ +  + ]:        220 :     for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
#     306                 :        122 :         complete &= SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, SIGHASH_ALL);
#     307                 :        122 :     }
#     308                 :            : 
#     309                 :         98 :     return complete;
#     310                 :         98 : }
#     311                 :            : 
#     312                 :            : bool FinalizeAndExtractPSBT(PartiallySignedTransaction& psbtx, CMutableTransaction& result)
#     313                 :         98 : {
#     314                 :            :     // It's not safe to extract a PSBT that isn't finalized, and there's no easy way to check
#     315                 :            :     //   whether a PSBT is finalized without finalizing it, so we just do this.
#     316         [ +  + ]:         98 :     if (!FinalizePSBT(psbtx)) {
#     317                 :          7 :         return false;
#     318                 :          7 :     }
#     319                 :            : 
#     320                 :         91 :     result = *psbtx.tx;
#     321         [ +  + ]:        204 :     for (unsigned int i = 0; i < result.vin.size(); ++i) {
#     322                 :        113 :         result.vin[i].scriptSig = psbtx.inputs[i].final_script_sig;
#     323                 :        113 :         result.vin[i].scriptWitness = psbtx.inputs[i].final_script_witness;
#     324                 :        113 :     }
#     325                 :         91 :     return true;
#     326                 :         91 : }
#     327                 :            : 
#     328                 :            : TransactionError CombinePSBTs(PartiallySignedTransaction& out, const std::vector<PartiallySignedTransaction>& psbtxs)
#     329                 :          6 : {
#     330                 :          6 :     out = psbtxs[0]; // Copy the first one
#     331                 :            : 
#     332                 :            :     // Merge
#     333         [ +  + ]:         12 :     for (auto it = std::next(psbtxs.begin()); it != psbtxs.end(); ++it) {
#     334         [ -  + ]:          6 :         if (!out.Merge(*it)) {
#     335                 :          0 :             return TransactionError::PSBT_MISMATCH;
#     336                 :          0 :         }
#     337                 :          6 :     }
#     338                 :          6 :     return TransactionError::OK;
#     339                 :          6 : }
#     340                 :            : 
#     341                 :         24 : std::string PSBTRoleName(PSBTRole role) {
#     342         [ -  + ]:         24 :     switch (role) {
#     343         [ +  + ]:          8 :     case PSBTRole::CREATOR: return "creator";
#     344         [ +  + ]:          4 :     case PSBTRole::UPDATER: return "updater";
#     345         [ +  + ]:          4 :     case PSBTRole::SIGNER: return "signer";
#     346         [ +  + ]:          4 :     case PSBTRole::FINALIZER: return "finalizer";
#     347         [ +  + ]:          4 :     case PSBTRole::EXTRACTOR: return "extractor";
#     348                 :            :         // no default case, so the compiler can warn about missing cases
#     349                 :          0 :     }
#     350                 :          0 :     assert(false);
#     351                 :          0 : }
#     352                 :            : 
#     353                 :            : bool DecodeBase64PSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx, std::string& error)
#     354                 :        520 : {
#     355                 :        520 :     bool invalid;
#     356                 :        520 :     std::string tx_data = DecodeBase64(base64_tx, &invalid);
#     357         [ +  + ]:        520 :     if (invalid) {
#     358                 :          4 :         error = "invalid base64";
#     359                 :          4 :         return false;
#     360                 :          4 :     }
#     361                 :        516 :     return DecodeRawPSBT(psbt, tx_data, error);
#     362                 :        516 : }
#     363                 :            : 
#     364                 :            : bool DecodeRawPSBT(PartiallySignedTransaction& psbt, const std::string& tx_data, std::string& error)
#     365                 :        516 : {
#     366                 :        516 :     CDataStream ss_data(MakeUCharSpan(tx_data), SER_NETWORK, PROTOCOL_VERSION);
#     367                 :        516 :     try {
#     368                 :        516 :         ss_data >> psbt;
#     369         [ -  + ]:        516 :         if (!ss_data.empty()) {
#     370                 :          0 :             error = "extra data after PSBT";
#     371                 :          0 :             return false;
#     372                 :          0 :         }
#     373                 :         54 :     } catch (const std::exception& e) {
#     374                 :         54 :         error = e.what();
#     375                 :         54 :         return false;
#     376                 :         54 :     }
#     377                 :        462 :     return true;
#     378                 :        462 : }

Generated by: LCOV version 1.14