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 [ + - ]: 971 : 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 [ + - ]: 170849 : CallOneOf(
37 : : fuzzed_data_provider,
38 : 10803 : [&] {
39 : 10803 : std::optional<COutPoint> optional_out_point = ConsumeDeserializable<COutPoint>(fuzzed_data_provider);
40 [ + + ]: 10803 : if (!optional_out_point) {
41 : : return;
42 : : }
43 : 954 : out_point = *optional_out_point;
44 : : },
45 : 8685 : [&] {
46 : 8685 : (void)coin_control.HasSelected();
47 : 8685 : },
48 : 1436 : [&] {
49 : 1436 : (void)coin_control.IsSelected(out_point);
50 : 1436 : },
51 : 2619 : [&] {
52 : 2619 : (void)coin_control.IsExternalSelected(out_point);
53 : 2619 : },
54 : 33513 : [&] {
55 : 33513 : (void)coin_control.GetExternalOutput(out_point);
56 : 33513 : },
57 : 28209 : [&] {
58 : 28209 : (void)coin_control.Select(out_point);
59 [ - + ]: 28209 : assert(coin_control.IsSelected(out_point));
60 : 28209 : },
61 : 7161 : [&] {
62 [ + - ]: 7161 : const CTxOut tx_out{ConsumeMoney(fuzzed_data_provider), ConsumeScript(fuzzed_data_provider)};
63 [ + - ]: 7161 : auto& input = coin_control.Select(out_point);
64 : 7161 : const auto set_tx_out{fuzzed_data_provider.ConsumeBool()};
65 [ + + ]: 7161 : if (set_tx_out) {
66 [ + - ]: 6686 : input.SetTxOut(tx_out);
67 : : }
68 [ + - ]: 7161 : auto has_tx_out{input.HasTxOut()};
69 [ + - ]: 7161 : auto is_external_selected{coin_control.IsExternalSelected(out_point)};
70 [ + + ]: 7161 : if (set_tx_out) {
71 [ - + ]: 6686 : assert(has_tx_out);
72 [ + - - + ]: 6686 : assert(input.GetTxOut() == tx_out);
73 [ - + ]: 6686 : assert(is_external_selected);
74 [ + + ]: 475 : } else if (!has_tx_out) {
75 [ - + ]: 147 : assert(!is_external_selected);
76 : : }
77 : 7161 : },
78 : 8601 : [&] {
79 : 8601 : coin_control.UnSelect(out_point);
80 [ - + ]: 8601 : assert(!coin_control.IsSelected(out_point));
81 : 8601 : },
82 : 9689 : [&] {
83 : 9689 : coin_control.UnSelectAll();
84 [ - + ]: 9689 : assert(!coin_control.HasSelected());
85 : 9689 : },
86 : 1583 : [&] {
87 : 1583 : const std::vector<COutPoint> selected = coin_control.ListSelected();
88 [ + + ]: 3905 : for (const auto& out : selected) {
89 [ + - - + ]: 2322 : assert(coin_control.IsSelected(out));
90 : : }
91 : 1583 : },
92 : 2493 : [&] {
93 : 2493 : int64_t weight{fuzzed_data_provider.ConsumeIntegral<int64_t>()};
94 : 2493 : coin_control.SetInputWeight(out_point, weight);
95 [ + - ]: 2493 : assert(coin_control.GetInputWeight(out_point) == weight);
96 : 2493 : },
97 : 1701 : [&] {
98 : 1701 : const bool is_selected = coin_control.IsSelected(out_point);
99 [ + + - + ]: 1701 : assert(!coin_control.GetInputWeight(out_point) || is_selected);
100 [ + + - + ]: 1701 : assert(!coin_control.GetSequence(out_point) || is_selected);
101 : 1701 : },
102 : 11940 : [&] {
103 : 11940 : const auto scripts = coin_control.GetScripts(out_point);
104 [ + - + + : 11940 : assert(coin_control.IsSelected(out_point) || (!scripts.first && !scripts.second));
+ - - + ]
105 : 11940 : },
106 : 4280 : [&] {
107 [ + + - + ]: 4280 : assert(coin_control.HasSelectedOrder() || !coin_control.GetSelectionPos(out_point));
108 : 4280 : },
109 : 1564 : [&] {
110 [ + + - + ]: 1564 : assert(!coin_control.GetSelectionPos(out_point) || coin_control.IsSelected(out_point));
111 : 1564 : },
112 : 11401 : [&] {
113 : 11401 : auto& input = coin_control.Select(out_point);
114 : 11401 : uint32_t sequence{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
115 : 11401 : input.SetSequence(sequence);
116 [ + - ]: 11401 : assert(input.GetSequence() == sequence);
117 [ + - ]: 11401 : assert(coin_control.GetSequence(out_point) == sequence);
118 : 11401 : },
119 : 16817 : [&] {
120 : 16817 : auto& input = coin_control.Select(out_point);
121 : 16817 : const CScript script{ConsumeScript(fuzzed_data_provider)};
122 [ + - ]: 16817 : input.SetScriptSig(script);
123 [ + - - + ]: 16817 : assert(input.HasScripts());
124 [ + - - + ]: 16817 : assert(input.GetScripts().first == script);
125 [ + - - + ]: 33634 : assert(coin_control.GetScripts(out_point).first == script);
126 : 16817 : },
127 : 6906 : [&] {
128 : 6906 : auto& input = coin_control.Select(out_point);
129 : 6906 : const CScriptWitness script_wit{ConsumeScriptWitness(fuzzed_data_provider)};
130 [ + - ]: 6906 : input.SetScriptWitness(script_wit);
131 [ + - - + ]: 6906 : assert(input.HasScripts());
132 [ + - - + ]: 6906 : assert(input.GetScripts().second->stack == script_wit.stack);
133 [ + - - + ]: 13812 : assert(coin_control.GetScripts(out_point).second->stack == script_wit.stack);
134 : 6906 : },
135 : 1448 : [&] {
136 : 1448 : auto& input = coin_control.Select(out_point);
137 : 1448 : unsigned int pos{fuzzed_data_provider.ConsumeIntegral<unsigned int>()};
138 : 1448 : input.SetPosition(pos);
139 [ + - ]: 1448 : assert(input.GetPosition() == pos);
140 [ + - ]: 1448 : assert(coin_control.GetSelectionPos(out_point) == pos);
141 : 1448 : });
142 : : }
143 : 497 : }
144 : : } // namespace
145 : : } // namespace wallet
|