135 testcase(
"No Params, None Enabled");
137 using namespace test::jtx;
143 auto jrr = env.rpc(
"feature")[jss::result];
144 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
146 for (
auto const& feature : jrr[jss::features])
148 if (!BEAST_EXPECT(feature.isMember(jss::name)))
153 (votes.
at(feature[jss::name].asString()) ==
155 bool expectObsolete =
156 (votes.
at(feature[jss::name].asString()) ==
159 feature.isMember(jss::enabled) &&
160 !feature[jss::enabled].asBool(),
161 feature[jss::name].asString() +
" enabled");
163 feature.isMember(jss::vetoed) &&
164 feature[jss::vetoed].isBool() == !expectObsolete &&
165 (!feature[jss::vetoed].isBool() ||
166 feature[jss::vetoed].asBool() == expectVeto) &&
167 (feature[jss::vetoed].isBool() ||
168 feature[jss::vetoed].asString() ==
"Obsolete"),
169 feature[jss::name].asString() +
" vetoed");
171 feature.isMember(jss::supported) &&
172 feature[jss::supported].asBool(),
173 feature[jss::name].asString() +
" supported");
182 using namespace test::jtx;
185 auto jrr = env.rpc(
"feature",
"MultiSignReserve")[jss::result];
186 BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status");
187 jrr.removeMember(jss::status);
188 BEAST_EXPECT(jrr.size() == 1);
190 jrr.isMember(
"586480873651E106F1D6339B0C4A8945BA705A777F3F4524626FF"
192 auto feature = *(jrr.begin());
194 BEAST_EXPECTS(feature[jss::name] ==
"MultiSignReserve",
"name");
195 BEAST_EXPECTS(!feature[jss::enabled].asBool(),
"enabled");
197 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
199 BEAST_EXPECTS(feature[jss::supported].asBool(),
"supported");
202 jrr = env.rpc(
"feature",
"multiSignReserve")[jss::result];
203 BEAST_EXPECT(jrr[jss::error] ==
"badFeature");
204 BEAST_EXPECT(jrr[jss::error_message] ==
"Feature unknown or invalid.");
244 using namespace test::jtx;
246 (*cfg)[
"port_rpc"].set(
"admin",
"");
247 (*cfg)[
"port_ws"].set(
"admin",
"");
252 auto result = env.rpc(
"feature")[jss::result];
253 BEAST_EXPECT(result.isMember(jss::features));
257 BEAST_EXPECT(result[jss::features].size() >= 50);
258 for (
auto it = result[jss::features].begin();
259 it != result[jss::features].end();
263 (void)
id.parseHex(it.key().asString().c_str());
264 if (!BEAST_EXPECT((*it).isMember(jss::name)))
267 env.app().getAmendmentTable().isEnabled(
id);
268 bool expectSupported =
269 env.app().getAmendmentTable().isSupported(
id);
271 (*it).isMember(jss::enabled) &&
272 (*it)[jss::enabled].asBool() == expectEnabled,
273 (*it)[jss::name].asString() +
" enabled");
275 (*it).isMember(jss::supported) &&
276 (*it)[jss::supported].asBool() == expectSupported,
277 (*it)[jss::name].asString() +
" supported");
278 BEAST_EXPECT(!(*it).isMember(jss::vetoed));
279 BEAST_EXPECT(!(*it).isMember(jss::majority));
280 BEAST_EXPECT(!(*it).isMember(jss::count));
281 BEAST_EXPECT(!(*it).isMember(jss::validations));
282 BEAST_EXPECT(!(*it).isMember(jss::threshold));
289 params[jss::feature] =
290 "1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCD"
293 env.rpc(
"json",
"feature",
to_string(params))[jss::result];
295 result[jss::error] ==
"badFeature", result.toStyledString());
297 result[jss::error_message] ==
"Feature unknown or invalid.");
302 params[jss::feature] =
303 "93E516234E35E08CA689FA33A6D38E103881F8DCB53023F728C307AA89D515"
306 params[jss::vetoed] =
true;
308 env.rpc(
"json",
"feature",
to_string(params))[jss::result];
310 result[jss::error] ==
"noPermission",
311 result[jss::error].asString());
313 result[jss::error_message] ==
314 "You don't have permission for this command.");
321 testcase(
"No Params, Some Enabled");
323 using namespace test::jtx;
325 *
this,
FeatureBitset(featureDepositAuth, featureDepositPreauth)};
330 auto jrr = env.rpc(
"feature")[jss::result];
331 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
333 for (
auto it = jrr[jss::features].begin();
334 it != jrr[jss::features].end();
338 (void)
id.parseHex(it.key().asString().c_str());
339 if (!BEAST_EXPECT((*it).isMember(jss::name)))
341 bool expectEnabled = env.app().getAmendmentTable().isEnabled(
id);
342 bool expectSupported =
343 env.app().getAmendmentTable().isSupported(
id);
345 (votes.
at((*it)[jss::name].asString()) ==
347 bool expectObsolete =
348 (votes.
at((*it)[jss::name].asString()) ==
351 (*it).isMember(jss::enabled) &&
352 (*it)[jss::enabled].asBool() == expectEnabled,
353 (*it)[jss::name].asString() +
" enabled");
356 !(*it).isMember(jss::vetoed),
357 (*it)[jss::name].asString() +
" vetoed");
360 (*it).isMember(jss::vetoed) &&
361 (*it)[jss::vetoed].isBool() == !expectObsolete &&
362 (!(*it)[jss::vetoed].isBool() ||
363 (*it)[jss::vetoed].asBool() == expectVeto) &&
364 ((*it)[jss::vetoed].isBool() ||
365 (*it)[jss::vetoed].asString() ==
"Obsolete"),
366 (*it)[jss::name].asString() +
" vetoed");
368 (*it).isMember(jss::supported) &&
369 (*it)[jss::supported].asBool() == expectSupported,
370 (*it)[jss::name].asString() +
" supported");
379 using namespace test::jtx;
380 Env env{*
this, envconfig(validator,
"")};
382 auto jrr = env.rpc(
"feature")[jss::result];
383 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
388 for (
auto const& feature : jrr[jss::features])
390 if (!BEAST_EXPECT(feature.isMember(jss::name)))
393 !feature.isMember(jss::majority),
394 feature[jss::name].asString() +
" majority");
396 !feature.isMember(jss::count),
397 feature[jss::name].asString() +
" count");
399 !feature.isMember(jss::threshold),
400 feature[jss::name].asString() +
" threshold");
402 !feature.isMember(jss::validations),
403 feature[jss::name].asString() +
" validations");
405 !feature.isMember(jss::vote),
406 feature[jss::name].asString() +
" vote");
410 if (!BEAST_EXPECT(majorities.empty()))
414 for (
auto i = 0; i <= 256; ++i)
418 if (!majorities.empty())
424 BEAST_EXPECT(majorities.size() >= 5);
428 jrr = env.rpc(
"feature")[jss::result];
429 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
431 for (
auto const& feature : jrr[jss::features])
433 if (!BEAST_EXPECT(feature.isMember(jss::name)))
436 (votes.
at(feature[jss::name].asString()) ==
438 bool expectObsolete =
439 (votes.
at(feature[jss::name].asString()) ==
442 (expectVeto || expectObsolete) ^
443 feature.isMember(jss::majority),
444 feature[jss::name].asString() +
" majority");
446 feature.isMember(jss::vetoed) &&
447 feature[jss::vetoed].isBool() == !expectObsolete &&
448 (!feature[jss::vetoed].isBool() ||
449 feature[jss::vetoed].asBool() == expectVeto) &&
450 (feature[jss::vetoed].isBool() ||
451 feature[jss::vetoed].asString() ==
"Obsolete"),
452 feature[jss::name].asString() +
" vetoed");
454 feature.isMember(jss::count),
455 feature[jss::name].asString() +
" count");
457 feature.isMember(jss::threshold),
458 feature[jss::name].asString() +
" threshold");
460 feature.isMember(jss::validations),
461 feature[jss::name].asString() +
" validations");
463 feature[jss::count] ==
464 ((expectVeto || expectObsolete) ? 0 : 1));
465 BEAST_EXPECT(feature[jss::threshold] == 1);
466 BEAST_EXPECT(feature[jss::validations] == 1);
468 expectVeto || expectObsolete || feature[jss::majority] == 2540,
469 "Majority: " + feature[jss::majority].asString());
478 using namespace test::jtx;
480 constexpr char const* featureName =
"MultiSignReserve";
482 auto jrr = env.rpc(
"feature", featureName)[jss::result];
483 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
485 jrr.removeMember(jss::status);
486 if (!BEAST_EXPECT(jrr.size() == 1))
488 auto feature = *(jrr.begin());
489 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
491 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
494 jrr = env.rpc(
"feature", featureName,
"reject")[jss::result];
495 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
497 jrr.removeMember(jss::status);
498 if (!BEAST_EXPECT(jrr.size() == 1))
500 feature = *(jrr.begin());
501 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
503 feature[jss::vetoed].isBool() && feature[jss::vetoed].asBool(),
506 jrr = env.rpc(
"feature", featureName,
"accept")[jss::result];
507 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
509 jrr.removeMember(jss::status);
510 if (!BEAST_EXPECT(jrr.size() == 1))
512 feature = *(jrr.begin());
513 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
515 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
519 jrr = env.rpc(
"feature", featureName,
"maybe");
520 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
521 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid parameters.");
529 using namespace test::jtx;
531 constexpr char const* featureName =
"CryptoConditionsSuite";
533 auto jrr = env.rpc(
"feature", featureName)[jss::result];
534 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
536 jrr.removeMember(jss::status);
537 if (!BEAST_EXPECT(jrr.size() == 1))
539 auto feature = *(jrr.begin());
540 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
542 feature[jss::vetoed].isString() &&
543 feature[jss::vetoed].asString() ==
"Obsolete",
546 jrr = env.rpc(
"feature", featureName,
"reject")[jss::result];
547 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
549 jrr.removeMember(jss::status);
550 if (!BEAST_EXPECT(jrr.size() == 1))
552 feature = *(jrr.begin());
553 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
555 feature[jss::vetoed].isString() &&
556 feature[jss::vetoed].asString() ==
"Obsolete",
559 jrr = env.rpc(
"feature", featureName,
"accept")[jss::result];
560 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
562 jrr.removeMember(jss::status);
563 if (!BEAST_EXPECT(jrr.size() == 1))
565 feature = *(jrr.begin());
566 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
568 feature[jss::vetoed].isString() &&
569 feature[jss::vetoed].asString() ==
"Obsolete",
573 jrr = env.rpc(
"feature", featureName,
"maybe");
574 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
575 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid parameters.");