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