Branch data Line data Source code
1 : : // Copyright (c) 2022-present 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 : : #include <test/fuzz/util.h>
8 : : #include <test/util/setup_common.h>
9 : : #include <wallet/coincontrol.h>
10 : : #include <wallet/test/util.h>
11 : :
12 : : namespace wallet {
13 : : namespace {
14 : :
15 : : const TestingSetup* g_setup;
16 : :
17 : 1 : void initialize_coincontrol()
18 : : {
19 [ + - + - : 1 : static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
+ - ]
20 : 1 : g_setup = testing_setup.get();
21 : 1 : }
22 : :
23 [ + - ]: 963 : FUZZ_TARGET(coincontrol, .init = initialize_coincontrol)
24 : : {
25 : 497 : FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
26 : 497 : const auto& node = g_setup->m_node;
27 : 497 : ArgsManager& args = *node.args;
28 : :
29 : : // for GetBoolArg to return true sometimes
30 [ + + + - : 1167 : args.ForceSetArg("-avoidpartialspends", fuzzed_data_provider.ConsumeBool()?"1":"0");
+ - ]
31 : :
32 : 497 : CCoinControl coin_control;
33 : 497 : COutPoint out_point;
34 : :
35 [ + + + + ]: 171346 : LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000)
36 : : {
37 [ + - ]: 170849 : CallOneOf(
38 : : fuzzed_data_provider,
39 : 10803 : [&] {
40 : 10803 : std::optional<COutPoint> optional_out_point = ConsumeDeserializable<COutPoint>(fuzzed_data_provider);
41 [ + + ]: 10803 : if (!optional_out_point) {
42 : : return;
43 : : }
44 : 954 : out_point = *optional_out_point;
45 : : },
46 : 8685 : [&] {
47 : 8685 : (void)coin_control.HasSelected();
48 : 8685 : },
49 : 1436 : [&] {
50 : 1436 : (void)coin_control.IsSelected(out_point);
51 : 1436 : },
52 : 2619 : [&] {
53 : 2619 : (void)coin_control.IsExternalSelected(out_point);
54 : 2619 : },
55 : 33513 : [&] {
56 : 33513 : (void)coin_control.GetExternalOutput(out_point);
57 : 33513 : },
58 : 28209 : [&] {
59 : 28209 : (void)coin_control.Select(out_point);
60 [ - + ]: 28209 : assert(coin_control.IsSelected(out_point));
61 : 28209 : },
62 : 7161 : [&] {
63 [ + - ]: 7161 : const CTxOut tx_out{ConsumeMoney(fuzzed_data_provider), ConsumeScript(fuzzed_data_provider)};
64 [ + - ]: 7161 : auto& input = coin_control.Select(out_point);
65 : 7161 : const auto set_tx_out{fuzzed_data_provider.ConsumeBool()};
66 [ + + ]: 7161 : if (set_tx_out) {
67 [ + - ]: 6686 : input.SetTxOut(tx_out);
68 : : }
69 [ + - ]: 7161 : auto has_tx_out{input.HasTxOut()};
70 [ + - ]: 7161 : auto is_external_selected{coin_control.IsExternalSelected(out_point)};
71 [ + + ]: 7161 : if (set_tx_out) {
72 [ - + ]: 6686 : assert(has_tx_out);
73 [ + - - + ]: 6686 : assert(input.GetTxOut() == tx_out);
74 [ - + ]: 6686 : assert(is_external_selected);
75 [ + + ]: 475 : } else if (!has_tx_out) {
76 [ - + ]: 147 : assert(!is_external_selected);
77 : : }
78 : 7161 : },
79 : 8601 : [&] {
80 : 8601 : coin_control.UnSelect(out_point);
81 [ - + ]: 8601 : assert(!coin_control.IsSelected(out_point));
82 : 8601 : },
83 : 9689 : [&] {
84 : 9689 : coin_control.UnSelectAll();
85 [ - + ]: 9689 : assert(!coin_control.HasSelected());
86 : 9689 : },
87 : 1583 : [&] {
88 : 1583 : const std::vector<COutPoint> selected = coin_control.ListSelected();
89 [ + + ]: 3905 : for (const auto& out : selected) {
90 [ + - - + ]: 2322 : assert(coin_control.IsSelected(out));
91 : : }
92 : 1583 : },
93 : 2493 : [&] {
94 : 2493 : int64_t weight{fuzzed_data_provider.ConsumeIntegral<int64_t>()};
95 : 2493 : coin_control.SetInputWeight(out_point, weight);
96 [ + - ]: 2493 : assert(coin_control.GetInputWeight(out_point) == weight);
97 : 2493 : },
98 : 1701 : [&] {
99 : 1701 : const bool is_selected = coin_control.IsSelected(out_point);
100 [ + + - + ]: 1701 : assert(!coin_control.GetInputWeight(out_point) || is_selected);
101 [ + + - + ]: 1701 : assert(!coin_control.GetSequence(out_point) || is_selected);
102 : 1701 : },
103 : 11940 : [&] {
104 : 11940 : const auto scripts = coin_control.GetScripts(out_point);
105 [ + - + + : 11940 : assert(coin_control.IsSelected(out_point) || (!scripts.first && !scripts.second));
+ - - + ]
106 : 11940 : },
107 : 4280 : [&] {
108 [ + + - + ]: 4280 : assert(coin_control.HasSelectedOrder() || !coin_control.GetSelectionPos(out_point));
109 : 4280 : },
110 : 1564 : [&] {
111 [ + + - + ]: 1564 : assert(!coin_control.GetSelectionPos(out_point) || coin_control.IsSelected(out_point));
112 : 1564 : },
113 : 11401 : [&] {
114 : 11401 : auto& input = coin_control.Select(out_point);
115 : 11401 : uint32_t sequence{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
116 : 11401 : input.SetSequence(sequence);
117 [ + - ]: 11401 : assert(input.GetSequence() == sequence);
118 [ + - ]: 11401 : assert(coin_control.GetSequence(out_point) == sequence);
119 : 11401 : },
120 : 16817 : [&] {
121 : 16817 : auto& input = coin_control.Select(out_point);
122 : 16817 : const CScript script{ConsumeScript(fuzzed_data_provider)};
123 [ + - ]: 16817 : input.SetScriptSig(script);
124 [ + - - + ]: 16817 : assert(input.HasScripts());
125 [ + - - + ]: 16817 : assert(input.GetScripts().first == script);
126 [ + - - + ]: 33634 : assert(coin_control.GetScripts(out_point).first == script);
127 : 16817 : },
128 : 6906 : [&] {
129 : 6906 : auto& input = coin_control.Select(out_point);
130 : 6906 : const CScriptWitness script_wit{ConsumeScriptWitness(fuzzed_data_provider)};
131 [ + - ]: 6906 : input.SetScriptWitness(script_wit);
132 [ + - - + ]: 6906 : assert(input.HasScripts());
133 [ + - - + ]: 6906 : assert(input.GetScripts().second->stack == script_wit.stack);
134 [ + - - + ]: 13812 : assert(coin_control.GetScripts(out_point).second->stack == script_wit.stack);
135 : 6906 : },
136 : 1448 : [&] {
137 : 1448 : auto& input = coin_control.Select(out_point);
138 : 1448 : unsigned int pos{fuzzed_data_provider.ConsumeIntegral<unsigned int>()};
139 : 1448 : input.SetPosition(pos);
140 [ + - ]: 1448 : assert(input.GetPosition() == pos);
141 [ + - ]: 1448 : assert(coin_control.GetSelectionPos(out_point) == pos);
142 : 1448 : });
143 : : }
144 : 497 : }
145 : : } // namespace
146 : : } // namespace wallet
|