Skip to content
Bitcoin Roots

v31.1-roots.1 · Commit 2: [PATCH 02/17] feat(policy): preserve Roots parsing and local transaction checks

src/test/policy_args_tests.cpp

Before: /dev/null · After: src/test/policy_args_tests.cpp

File metadata
new file mode 100644
index 0000000000000000000000000000000000000000..ee01e859e56684e025eafb8e4ddc2fa2e8f272f6

Download original patch · Release notes

Diff rows 1–219 of 219. Line numbers refer to the original before/after files.

+ Added− RemovedUnmarked lines are context.

Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.

src/test/policy_args_tests.cpp ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2026 The Bitcoin Roots 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 <chainparams.h>
6
+ #include <common/args.h>
7
+ #include <common/settings.h>
8
+ #include <consensus/consensus.h>
9
+ #include <init.h>
10
+ #include <kernel/mempool_options.h>
11
+ #include <node/mempool_args.h>
12
+ #include <policy/settings.h>
13
+ #include <test/util/setup_common.h>
14
+ #include <univalue.h>
15
+ #include <util/result.h>
16
+ #include <util/translation.h>
17
+
18
+ #include <cstdint>
19
+ #include <string>
20
+ #include <utility>
21
+ #include <vector>
22
+
23
+ #include <boost/test/unit_test.hpp>
24
+
25
+ namespace {
26
+ const std::vector<std::string> BOOL_OPTIONS{
27
+ "subdustfeepenalty", "rejectparasites", "acceptunknownwitness", "datacarrierfullcount",
28
+ "permitbareanchor", "rejecttokens", "permitbarepubkey", "permitbaredatacarrier", "acceptnonstddatacarrier"};
29
+
30
+ bool ParseOptions(ArgsManager& args, const std::vector<std::string>& options, std::string& error)
31
+ {
32
+ std::vector<const char*> argv{"test_bitcoin"};
33
+ for (const auto& option : options) argv.push_back(option.c_str());
34
+ return args.ParseParameters(argv.size(), argv.data(), error);
35
+ }
36
+ }
37
+
38
+ BOOST_FIXTURE_TEST_SUITE(policy_args_tests, BasicTestingSetup)
39
+
40
+ BOOST_AUTO_TEST_CASE(boolean_values)
41
+ {
42
+ for (const auto& option : BOOL_OPTIONS) {
43
+ for (const std::string value : {"", "0", "1", "2", "-1", "+1", "01", " 1", "1 ", "1junk", "junk", "false", "0.5", "1.0", "2147483648"}) {
44
+ BOOST_TEST_CONTEXT(option << "=" << value) {
45
+ ArgsManager args;
46
+ args.ForceSetArg("-" + option, value);
47
+ const auto result = ValidateRootsPolicyOptions(args);
48
+ BOOST_CHECK_EQUAL(bool(result), value.empty() || value == "0" || value == "1");
49
+ if (!result) BOOST_CHECK(util::ErrorString(result).original.find("-" + option) != std::string::npos);
50
+ }
51
+ }
52
+ }
53
+ }
54
+
55
+ BOOST_AUTO_TEST_CASE(integer_boundaries)
56
+ {
57
+ for (const auto& [option, maximum] : std::vector<std::pair<std::string, std::string>>{
58
+ {"maxscriptsize", "4294967295"}, {"bytespersigopstrict", "4294967295"},
59
+ {"maxtxlegacysigops", "4294967295"}, {"minrelaycoinblocks", "9223372036854775807"},
60
+ {"minrelaymaturity", "2147483647"}, {"blockmaxsize", "4000000"},
61
+ {"blockprioritysize", "9223372036854775807"}}) {
62
+ for (const auto& value : std::vector<std::string>{"0", "1", "+1", "01", "-0", maximum}) {
63
+ BOOST_TEST_CONTEXT(option << "=" << value) {
64
+ ArgsManager args;
65
+ args.ForceSetArg("-" + option, value);
66
+ BOOST_CHECK(ValidateRootsPolicyOptions(args));
67
+ }
68
+ }
69
+ for (const auto& value : std::vector<std::string>{"", "-1", "+-0", "++1", " 1", "1 ", "1junk", "1.5", "1e0", "junk", "9223372036854775808", std::to_string(std::stoull(maximum) + 1)}) {
70
+ BOOST_TEST_CONTEXT(option << "=" << value) {
71
+ ArgsManager args;
72
+ args.ForceSetArg("-" + option, value);
73
+ BOOST_CHECK(!ValidateRootsPolicyOptions(args));
74
+ }
75
+ }
76
+ }
77
+ }
78
+
79
+ BOOST_AUTO_TEST_CASE(carrier_cost_compatibility)
80
+ {
81
+ for (const auto& [value, weight] : std::vector<std::pair<std::string, uint32_t>>{
82
+ {"0", 0}, {"-0", 0}, {"-0.00", 0}, {"0.01", 1}, {"0.25", 1}, {"0.26", 2},
83
+ {"1", 4}, {"1.2300", 5}, {"1e0", 4}, {"1e-2", 1}, {"1073741823.75", 4294967295U}}) {
84
+ ArgsManager args;
85
+ args.ForceSetArg("-datacarriercost", value);
86
+ BOOST_TEST_CONTEXT(value) {
87
+ BOOST_CHECK(ValidateRootsPolicyOptions(args));
88
+ const auto parsed = ParseDataCarrierCost(value);
89
+ BOOST_REQUIRE(parsed);
90
+ BOOST_CHECK_EQUAL(*parsed, weight);
91
+ }
92
+ }
93
+ for (const std::string value : {"", "-1", "+1", "01", ".5", "1.", "0.001", " 1", "1 ", "1junk", "1073741823.76", "1e100", "9223372036854775808"}) {
94
+ ArgsManager args;
95
+ args.ForceSetArg("-datacarriercost", value);
96
+ BOOST_TEST_CONTEXT(value) { BOOST_CHECK(!ValidateRootsPolicyOptions(args)); }
97
+ }
98
+ }
99
+
100
+ BOOST_AUTO_TEST_CASE(mode_tokens)
101
+ {
102
+ const std::vector<std::pair<std::string, std::vector<std::string>>> modes{
103
+ {"mempoolreplacement", {"fee", "optin", "-optin", "fee,optin", "fee+-optin", "optin,-optin,fee"}},
104
+ {"mempooltruc", {"reject", "accept", "enforce", "optin", "-enforce", "-optin", "accept+enforce", "reject,accept", "0,enforce"}},
105
+ {"permitephemeral", {"anchor", "dust", "send", "reject", "-anchor", "-dust", "-send", "-reject", "-0", "anchor+dust,-send", "0,anchor"}},
106
+ {"spkreuse", {"allow", "conflict"}}};
107
+ for (const auto& [option, tokens] : modes) {
108
+ auto accepted{tokens};
109
+ accepted.insert(accepted.end(), {"", "0", "1"});
110
+ for (const auto& value : accepted) {
111
+ ArgsManager args;
112
+ args.ForceSetArg("-" + option, value);
113
+ BOOST_TEST_CONTEXT(option << "=" << value) { BOOST_CHECK(ValidateRootsPolicyOptions(args)); }
114
+ }
115
+ for (const auto& value : std::vector<std::string>{"junk", "2", "01", "1junk", " 1", "1 ", tokens[0] + ",junk", "," + tokens[0], tokens[0] + ",", tokens[0] + ",," + tokens[0]}) {
116
+ ArgsManager args;
117
+ args.ForceSetArg("-" + option, value);
118
+ BOOST_TEST_CONTEXT(option << "=" << value) { BOOST_CHECK(!ValidateRootsPolicyOptions(args)); }
119
+ }
120
+ }
121
+ }
122
+
123
+ BOOST_AUTO_TEST_CASE(raw_negation_is_scoped)
124
+ {
125
+ auto options{BOOL_OPTIONS};
126
+ options.insert(options.end(), {"maxscriptsize", "bytespersigopstrict", "maxtxlegacysigops", "minrelaycoinblocks", "minrelaymaturity", "blockmaxsize", "blockprioritysize", "datacarriercost", "dustdynamic", "mempoolreplacement", "mempooltruc", "permitephemeral", "spkreuse"});
127
+ for (const auto& option : options) {
128
+ ArgsManager args;
129
+ SetupServerArgs(args);
130
+ std::string error;
131
+ for (const std::string value : {"junk", "2", "01", "+1", "1junk", "1.0", " 1"}) {
132
+ BOOST_TEST_CONTEXT(option << " negated=" << value) {
133
+ BOOST_CHECK(!ParseOptions(args, {"-no" + option + "=" + value, "-" + option + "=1"}, error));
134
+ BOOST_CHECK(error.find("-no" + option) != std::string::npos);
135
+ }
136
+ }
137
+ for (const std::string value : {"", "0", "1"}) {
138
+ BOOST_REQUIRE(ParseOptions(args, {"-no" + option + "=" + value}, error));
139
+ BOOST_CHECK_EQUAL(args.GetArg("-" + option, "missing"), value == "0" ? "1" : "0");
140
+ }
141
+ BOOST_REQUIRE(ParseOptions(args, {"-no" + option}, error));
142
+ BOOST_CHECK_EQUAL(args.GetArg("-" + option, "missing"), "0");
143
+ }
144
+ ArgsManager args;
145
+ SetupServerArgs(args);
146
+ std::string error;
147
+ BOOST_REQUIRE(ParseOptions(args, {"-nodatacarrier=junk", "-bytespersigop=12junk", "-datacarriersize=83junk"}, error));
148
+ BOOST_CHECK(args.GetBoolArg("-datacarrier", false));
149
+ BOOST_CHECK_EQUAL(args.GetIntArg("-bytespersigop", 0), 12);
150
+ BOOST_CHECK_EQUAL(args.GetIntArg("-datacarriersize", 0), 83);
151
+ BOOST_CHECK(ValidateRootsPolicyOptions(args));
152
+ }
153
+
154
+ BOOST_AUTO_TEST_CASE(local_defaults_and_ephemeral_semantics)
155
+ {
156
+ ArgsManager args;
157
+ kernel::MemPoolOptions options;
158
+ BOOST_REQUIRE(ApplyArgsManOptions(args, Params(), options));
159
+ BOOST_CHECK_EQUAL(g_script_size_policy_limit, 1650);
160
+ BOOST_CHECK_EQUAL(nBytesPerSigOpStrict, 20);
161
+ BOOST_CHECK(options.reject_parasites && options.acceptunknownwitness);
162
+ BOOST_CHECK(options.datacarrier_fullcount && options.permitbareanchor);
163
+ BOOST_CHECK(!options.reject_tokens && !options.permit_bare_pubkey && !options.permit_bare_multisig);
164
+ BOOST_CHECK(!options.permitbaredatacarrier && !options.accept_non_std_datacarrier);
165
+ BOOST_CHECK_EQUAL(options.maxtxlegacysigops, 2500);
166
+ BOOST_CHECK_EQUAL(options.minrelaycoinblocks, 0);
167
+ BOOST_CHECK_EQUAL(options.minrelaymaturity, 0);
168
+ BOOST_CHECK_EQUAL(options.max_datacarrier_bytes.value(), 83);
169
+ BOOST_CHECK_EQUAL(options.min_relay_feerate.GetFeePerK(), 1000);
170
+ BOOST_CHECK_EQUAL(options.incremental_relay_feerate.GetFeePerK(), 100);
171
+ BOOST_CHECK(options.permitephemeral_anchor && !options.permitephemeral_dust && !options.permitephemeral_send);
172
+ args.ForceSetArg("-permitephemeral", "0,anchor,dust,-send");
173
+ BOOST_REQUIRE(ApplyArgsManOptions(args, Params(), options));
174
+ BOOST_CHECK(options.permitephemeral_anchor && options.permitephemeral_dust && !options.permitephemeral_send);
175
+ args.ForceSetArg("-permitephemeral", "1");
176
+ BOOST_REQUIRE(ApplyArgsManOptions(args, Params(), options));
177
+ BOOST_CHECK(options.permitephemeral_anchor && options.permitephemeral_dust && options.permitephemeral_send);
178
+ args.ForceSetArg("-permitephemeral", "reject");
179
+ BOOST_REQUIRE(ApplyArgsManOptions(args, Params(), options));
180
+ BOOST_CHECK(!options.permitephemeral_anchor && !options.permitephemeral_dust && !options.permitephemeral_send);
181
+ }
182
+
183
+ BOOST_AUTO_TEST_CASE(settings_types_and_precedence)
184
+ {
185
+ ArgsManager args;
186
+ SetupServerArgs(args);
187
+ for (const auto& value : std::vector<UniValue>{UniValue{true}, UniValue{false}, UniValue{1}, UniValue{"0"}}) {
188
+ args.LockSettings([&](common::Settings& settings) { settings.rw_settings["subdustfeepenalty"] = value; });
189
+ BOOST_CHECK(ValidateRootsPolicyOptions(args));
190
+ }
191
+ for (const auto& value : std::vector<UniValue>{UniValue{2}, UniValue{UniValue::VARR}, UniValue{UniValue::VOBJ}}) {
192
+ args.LockSettings([&](common::Settings& settings) { settings.rw_settings["subdustfeepenalty"] = value; });
193
+ BOOST_CHECK(!ValidateRootsPolicyOptions(args));
194
+ }
195
+ std::string error;
196
+ BOOST_REQUIRE(ParseOptions(args, {"-subdustfeepenalty=junk", "-subdustfeepenalty=1"}, error));
197
+ BOOST_CHECK(ValidateRootsPolicyOptions(args));
198
+ BOOST_REQUIRE(ParseOptions(args, {"-subdustfeepenalty=1", "-subdustfeepenalty=junk"}, error));
199
+ BOOST_CHECK(!ValidateRootsPolicyOptions(args));
200
+ }
201
+
202
+ BOOST_AUTO_TEST_CASE(dynamic_dust_grammar_without_runtime_claim)
203
+ {
204
+ const auto target = ParseDustDynamicOpt("1e0*target:2", 1008);
205
+ BOOST_REQUIRE(target);
206
+ BOOST_CHECK_EQUAL(target->first, -2);
207
+ BOOST_CHECK_EQUAL(target->second, 1000);
208
+ const auto position = ParseDustDynamicOpt("1.0000*mempool:01", 1008);
209
+ BOOST_REQUIRE(position);
210
+ BOOST_CHECK_EQUAL(position->first, 1);
211
+ for (const std::string value : {"", "target:1", "target:2junk", "mempool:+1", "mempool:0", "mempool:2147483648", "0*mempool:1", "1.0001*mempool:1", "junk"}) {
212
+ ArgsManager args;
213
+ args.ForceSetArg("-dustdynamic", value);
214
+ kernel::MemPoolOptions options;
215
+ BOOST_TEST_CONTEXT(value) { BOOST_CHECK(!ApplyArgsManOptions(args, Params(), options)); }
216
+ }
217
+ }
218
+
219
+ BOOST_AUTO_TEST_SUITE_END()