/ src / test / fuzz / psbt.cpp
psbt.cpp
 1  // Copyright (c) 2019-2022 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 <test/fuzz/FuzzedDataProvider.h>
 6  #include <test/fuzz/fuzz.h>
 7  
 8  #include <node/psbt.h>
 9  #include <psbt.h>
10  #include <pubkey.h>
11  #include <script/script.h>
12  #include <streams.h>
13  #include <util/check.h>
14  
15  #include <cstdint>
16  #include <optional>
17  #include <string>
18  #include <vector>
19  
20  using node::AnalyzePSBT;
21  using node::PSBTAnalysis;
22  using node::PSBTInputAnalysis;
23  
24  FUZZ_TARGET(psbt)
25  {
26      FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
27      PartiallySignedTransaction psbt_mut;
28      std::string error;
29      auto str = fuzzed_data_provider.ConsumeRandomLengthString();
30      if (!DecodeRawPSBT(psbt_mut, MakeByteSpan(str), error)) {
31          return;
32      }
33      const PartiallySignedTransaction psbt = psbt_mut;
34  
35      const PSBTAnalysis analysis = AnalyzePSBT(psbt);
36      (void)PSBTRoleName(analysis.next);
37      for (const PSBTInputAnalysis& input_analysis : analysis.inputs) {
38          (void)PSBTRoleName(input_analysis.next);
39      }
40  
41      (void)psbt.IsNull();
42  
43      std::optional<CMutableTransaction> tx = psbt.tx;
44      if (tx) {
45          const CMutableTransaction& mtx = *tx;
46          const PartiallySignedTransaction psbt_from_tx{mtx};
47      }
48  
49      for (const PSBTInput& input : psbt.inputs) {
50          (void)PSBTInputSigned(input);
51          (void)input.IsNull();
52      }
53      (void)CountPSBTUnsignedInputs(psbt);
54  
55      for (const PSBTOutput& output : psbt.outputs) {
56          (void)output.IsNull();
57      }
58  
59      for (size_t i = 0; i < psbt.tx->vin.size(); ++i) {
60          CTxOut tx_out;
61          if (psbt.GetInputUTXO(tx_out, i)) {
62              (void)tx_out.IsNull();
63              (void)tx_out.ToString();
64          }
65      }
66  
67      psbt_mut = psbt;
68      (void)FinalizePSBT(psbt_mut);
69  
70      psbt_mut = psbt;
71      CMutableTransaction result;
72      if (FinalizeAndExtractPSBT(psbt_mut, result)) {
73          const PartiallySignedTransaction psbt_from_tx{result};
74      }
75  
76      PartiallySignedTransaction psbt_merge;
77      str = fuzzed_data_provider.ConsumeRandomLengthString();
78      if (!DecodeRawPSBT(psbt_merge, MakeByteSpan(str), error)) {
79          psbt_merge = psbt;
80      }
81      psbt_mut = psbt;
82      (void)psbt_mut.Merge(psbt_merge);
83      psbt_mut = psbt;
84      (void)CombinePSBTs(psbt_mut, {psbt_mut, psbt_merge});
85      psbt_mut = psbt;
86      for (unsigned int i = 0; i < psbt_merge.tx->vin.size(); ++i) {
87          (void)psbt_mut.AddInput(psbt_merge.tx->vin[i], psbt_merge.inputs[i]);
88      }
89      for (unsigned int i = 0; i < psbt_merge.tx->vout.size(); ++i) {
90          Assert(psbt_mut.AddOutput(psbt_merge.tx->vout[i], psbt_merge.outputs[i]));
91      }
92      psbt_mut.unknown.insert(psbt_merge.unknown.begin(), psbt_merge.unknown.end());
93  }