121 testcase(
"No Params, None Enabled");
123 using namespace test::jtx;
128 auto jrr = env.rpc(
"feature")[jss::result];
129 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
131 for (
auto const& feature : jrr[jss::features])
133 if (!BEAST_EXPECT(feature.isMember(jss::name)))
140 feature.isMember(jss::enabled) && !feature[jss::enabled].asBool(),
141 feature[jss::name].asString() +
" enabled");
143 feature.isMember(jss::vetoed) && feature[jss::vetoed].isBool() == !expectObsolete &&
144 (!feature[jss::vetoed].isBool() || feature[jss::vetoed].asBool() == expectVeto) &&
145 (feature[jss::vetoed].isBool() || feature[jss::vetoed].asString() ==
"Obsolete"),
146 feature[jss::name].asString() +
" vetoed");
148 feature.isMember(jss::supported) && feature[jss::supported].asBool(),
149 feature[jss::name].asString() +
" supported");
158 using namespace test::jtx;
161 auto jrr = env.rpc(
"feature",
"fixAMMOverflowOffer")[jss::result];
162 BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status");
163 jrr.removeMember(jss::status);
164 BEAST_EXPECT(jrr.size() == 1);
166 jrr.isMember(
"12523DF04B553A0B1AD74F42DDB741DE8DC06A03FC089A0EF197E"
168 auto feature = *(jrr.begin());
170 BEAST_EXPECTS(feature[jss::name] ==
"fixAMMOverflowOffer",
"name");
171 BEAST_EXPECTS(!feature[jss::enabled].asBool(),
"enabled");
172 BEAST_EXPECTS(feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
"vetoed");
173 BEAST_EXPECTS(feature[jss::supported].asBool(),
"supported");
176 jrr = env.rpc(
"feature",
"fMM")[jss::result];
177 BEAST_EXPECT(jrr[jss::error] ==
"badFeature");
178 BEAST_EXPECT(jrr[jss::error_message] ==
"Feature unknown or invalid.");
216 using namespace test::jtx;
218 (*cfg)[
"port_rpc"].set(
"admin",
"");
219 (*cfg)[
"port_ws"].set(
"admin",
"");
224 auto result = env.rpc(
"feature")[jss::result];
225 BEAST_EXPECT(result.isMember(jss::features));
229 BEAST_EXPECT(result[jss::features].size() >= 50);
230 for (
auto it = result[jss::features].begin(); it != result[jss::features].end(); ++it)
233 (void)
id.parseHex(it.key().asString().c_str());
234 if (!BEAST_EXPECT((*it).isMember(jss::name)))
236 bool expectEnabled = env.app().getAmendmentTable().isEnabled(
id);
237 bool expectSupported = env.app().getAmendmentTable().isSupported(
id);
239 (*it).isMember(jss::enabled) && (*it)[jss::enabled].asBool() == expectEnabled,
240 (*it)[jss::name].asString() +
" enabled");
242 (*it).isMember(jss::supported) && (*it)[jss::supported].asBool() == expectSupported,
243 (*it)[jss::name].asString() +
" supported");
244 BEAST_EXPECT(!(*it).isMember(jss::vetoed));
245 BEAST_EXPECT(!(*it).isMember(jss::majority));
246 BEAST_EXPECT(!(*it).isMember(jss::count));
247 BEAST_EXPECT(!(*it).isMember(jss::validations));
248 BEAST_EXPECT(!(*it).isMember(jss::threshold));
255 params[jss::feature] =
256 "1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCD"
258 auto const result = env.rpc(
"json",
"feature",
to_string(params))[jss::result];
259 BEAST_EXPECTS(result[jss::error] ==
"badFeature", result.toStyledString());
260 BEAST_EXPECT(result[jss::error_message] ==
"Feature unknown or invalid.");
265 params[jss::feature] =
266 "93E516234E35E08CA689FA33A6D38E103881F8DCB53023F728C307AA89D515"
269 params[jss::vetoed] =
true;
270 auto const result = env.rpc(
"json",
"feature",
to_string(params))[jss::result];
271 BEAST_EXPECTS(result[jss::error] ==
"noPermission", result[jss::error].asString());
272 BEAST_EXPECT(result[jss::error_message] ==
"You don't have permission for this command.");
279 testcase(
"No Params, Some Enabled");
281 using namespace test::jtx;
286 auto jrr = env.rpc(
"feature")[jss::result];
287 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
289 for (
auto it = jrr[jss::features].begin(); it != jrr[jss::features].end(); ++it)
292 (void)
id.parseHex(it.key().asString().c_str());
293 if (!BEAST_EXPECT((*it).isMember(jss::name)))
295 bool expectEnabled = env.app().getAmendmentTable().isEnabled(
id);
296 bool expectSupported = env.app().getAmendmentTable().isSupported(
id);
300 (*it).isMember(jss::enabled) && (*it)[jss::enabled].asBool() == expectEnabled,
301 (*it)[jss::name].asString() +
" enabled");
303 BEAST_EXPECTS(!(*it).isMember(jss::vetoed), (*it)[jss::name].asString() +
" vetoed");
306 (*it).isMember(jss::vetoed) && (*it)[jss::vetoed].isBool() == !expectObsolete &&
307 (!(*it)[jss::vetoed].isBool() || (*it)[jss::vetoed].asBool() == expectVeto) &&
308 ((*it)[jss::vetoed].isBool() || (*it)[jss::vetoed].asString() ==
"Obsolete"),
309 (*it)[jss::name].asString() +
" vetoed");
311 (*it).isMember(jss::supported) && (*it)[jss::supported].asBool() == expectSupported,
312 (*it)[jss::name].asString() +
" supported");
321 using namespace test::jtx;
322 Env env{*
this, envconfig(validator,
"")};
324 auto jrr = env.rpc(
"feature")[jss::result];
325 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
330 for (
auto const& feature : jrr[jss::features])
332 if (!BEAST_EXPECT(feature.isMember(jss::name)))
334 BEAST_EXPECTS(!feature.isMember(jss::majority), feature[jss::name].asString() +
" majority");
335 BEAST_EXPECTS(!feature.isMember(jss::count), feature[jss::name].asString() +
" count");
336 BEAST_EXPECTS(!feature.isMember(jss::threshold), feature[jss::name].asString() +
" threshold");
337 BEAST_EXPECTS(!feature.isMember(jss::validations), feature[jss::name].asString() +
" validations");
338 BEAST_EXPECTS(!feature.isMember(jss::vote), feature[jss::name].asString() +
" vote");
342 if (!BEAST_EXPECT(majorities.empty()))
346 for (
auto i = 0; i <= 256; ++i)
350 if (!majorities.empty())
356 BEAST_EXPECT(majorities.size() >= 2);
359 jrr = env.rpc(
"feature")[jss::result];
360 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
362 for (
auto const& feature : jrr[jss::features])
364 if (!BEAST_EXPECT(feature.isMember(jss::name)))
369 (expectVeto || expectObsolete) ^ feature.isMember(jss::majority),
370 feature[jss::name].asString() +
" majority");
372 feature.isMember(jss::vetoed) && feature[jss::vetoed].isBool() == !expectObsolete &&
373 (!feature[jss::vetoed].isBool() || feature[jss::vetoed].asBool() == expectVeto) &&
374 (feature[jss::vetoed].isBool() || feature[jss::vetoed].asString() ==
"Obsolete"),
375 feature[jss::name].asString() +
" vetoed");
376 BEAST_EXPECTS(feature.isMember(jss::count), feature[jss::name].asString() +
" count");
377 BEAST_EXPECTS(feature.isMember(jss::threshold), feature[jss::name].asString() +
" threshold");
378 BEAST_EXPECTS(feature.isMember(jss::validations), feature[jss::name].asString() +
" validations");
379 BEAST_EXPECT(feature[jss::count] == ((expectVeto || expectObsolete) ? 0 : 1));
380 BEAST_EXPECT(feature[jss::threshold] == 1);
381 BEAST_EXPECT(feature[jss::validations] == 1);
383 expectVeto || expectObsolete || feature[jss::majority] == 2540,
384 "Majority: " + feature[jss::majority].asString());
393 using namespace test::jtx;
395 constexpr char const* featureName =
"fixAMMOverflowOffer";
397 auto jrr = env.rpc(
"feature", featureName)[jss::result];
398 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
400 jrr.removeMember(jss::status);
401 if (!BEAST_EXPECT(jrr.size() == 1))
403 auto feature = *(jrr.begin());
404 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
405 BEAST_EXPECTS(feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
"vetoed");
407 jrr = env.rpc(
"feature", featureName,
"reject")[jss::result];
408 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
410 jrr.removeMember(jss::status);
411 if (!BEAST_EXPECT(jrr.size() == 1))
413 feature = *(jrr.begin());
414 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
415 BEAST_EXPECTS(feature[jss::vetoed].isBool() && feature[jss::vetoed].asBool(),
"vetoed");
417 jrr = env.rpc(
"feature", featureName,
"accept")[jss::result];
418 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
420 jrr.removeMember(jss::status);
421 if (!BEAST_EXPECT(jrr.size() == 1))
423 feature = *(jrr.begin());
424 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
425 BEAST_EXPECTS(feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
"vetoed");
428 jrr = env.rpc(
"feature", featureName,
"maybe");
429 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
430 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid parameters.");
438 using namespace test::jtx;
442 auto obsoleteFeature =
447 if (obsoleteFeature ==
std::end(supportedAmendments))
453 auto const featureName = obsoleteFeature->first;
455 auto jrr = env.rpc(
"feature", featureName)[jss::result];
456 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
458 jrr.removeMember(jss::status);
459 if (!BEAST_EXPECT(jrr.size() == 1))
461 auto feature = *(jrr.begin());
462 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
463 BEAST_EXPECTS(feature[jss::vetoed].isString() && feature[jss::vetoed].asString() ==
"Obsolete",
"vetoed");
465 jrr = env.rpc(
"feature", featureName,
"reject")[jss::result];
466 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
468 jrr.removeMember(jss::status);
469 if (!BEAST_EXPECT(jrr.size() == 1))
471 feature = *(jrr.begin());
472 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
473 BEAST_EXPECTS(feature[jss::vetoed].isString() && feature[jss::vetoed].asString() ==
"Obsolete",
"vetoed");
475 jrr = env.rpc(
"feature", featureName,
"accept")[jss::result];
476 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
478 jrr.removeMember(jss::status);
479 if (!BEAST_EXPECT(jrr.size() == 1))
481 feature = *(jrr.begin());
482 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
483 BEAST_EXPECTS(feature[jss::vetoed].isString() && feature[jss::vetoed].asString() ==
"Obsolete",
"vetoed");
486 jrr = env.rpc(
"feature", featureName,
"maybe");
487 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
488 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid parameters.");