155 testcase(
"No Params, None Enabled");
157 using namespace test::jtx;
163 auto jrr = env.rpc(
"feature")[jss::result];
164 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
166 for (
auto const& feature : jrr[jss::features])
168 if (!BEAST_EXPECT(feature.isMember(jss::name)))
173 (votes.
at(feature[jss::name].asString()) ==
175 bool expectObsolete =
176 (votes.
at(feature[jss::name].asString()) ==
179 feature.isMember(jss::enabled) &&
180 !feature[jss::enabled].asBool(),
181 feature[jss::name].asString() +
" enabled");
183 feature.isMember(jss::vetoed) &&
184 feature[jss::vetoed].isBool() == !expectObsolete &&
185 (!feature[jss::vetoed].isBool() ||
186 feature[jss::vetoed].asBool() == expectVeto) &&
187 (feature[jss::vetoed].isBool() ||
188 feature[jss::vetoed].asString() ==
"Obsolete"),
189 feature[jss::name].asString() +
" vetoed");
191 feature.isMember(jss::supported) &&
192 feature[jss::supported].asBool(),
193 feature[jss::name].asString() +
" supported");
202 using namespace test::jtx;
205 auto jrr = env.rpc(
"feature",
"MultiSignReserve")[jss::result];
206 BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status");
207 jrr.removeMember(jss::status);
208 BEAST_EXPECT(jrr.size() == 1);
210 jrr.isMember(
"586480873651E106F1D6339B0C4A8945BA705A777F3F4524626FF"
212 auto feature = *(jrr.begin());
214 BEAST_EXPECTS(feature[jss::name] ==
"MultiSignReserve",
"name");
215 BEAST_EXPECTS(!feature[jss::enabled].asBool(),
"enabled");
217 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
219 BEAST_EXPECTS(feature[jss::supported].asBool(),
"supported");
222 jrr = env.rpc(
"feature",
"multiSignReserve")[jss::result];
223 BEAST_EXPECT(jrr[jss::error] ==
"badFeature");
224 BEAST_EXPECT(jrr[jss::error_message] ==
"Feature unknown or invalid.");
264 using namespace test::jtx;
266 (*cfg)[
"port_rpc"].set(
"admin",
"");
267 (*cfg)[
"port_ws"].set(
"admin",
"");
272 auto result = env.rpc(
"feature")[jss::result];
273 BEAST_EXPECT(result.isMember(jss::features));
277 BEAST_EXPECT(result[jss::features].size() >= 50);
278 for (
auto it = result[jss::features].begin();
279 it != result[jss::features].end();
283 (void)
id.parseHex(it.key().asString().c_str());
284 if (!BEAST_EXPECT((*it).isMember(jss::name)))
287 env.app().getAmendmentTable().isEnabled(
id);
288 bool expectSupported =
289 env.app().getAmendmentTable().isSupported(
id);
291 (*it).isMember(jss::enabled) &&
292 (*it)[jss::enabled].asBool() == expectEnabled,
293 (*it)[jss::name].asString() +
" enabled");
295 (*it).isMember(jss::supported) &&
296 (*it)[jss::supported].asBool() == expectSupported,
297 (*it)[jss::name].asString() +
" supported");
298 BEAST_EXPECT(!(*it).isMember(jss::vetoed));
299 BEAST_EXPECT(!(*it).isMember(jss::majority));
300 BEAST_EXPECT(!(*it).isMember(jss::count));
301 BEAST_EXPECT(!(*it).isMember(jss::validations));
302 BEAST_EXPECT(!(*it).isMember(jss::threshold));
309 params[jss::feature] =
310 "1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCD"
313 env.rpc(
"json",
"feature",
to_string(params))[jss::result];
315 result[jss::error] ==
"badFeature", result.toStyledString());
317 result[jss::error_message] ==
"Feature unknown or invalid.");
322 params[jss::feature] =
323 "93E516234E35E08CA689FA33A6D38E103881F8DCB53023F728C307AA89D515"
326 params[jss::vetoed] =
true;
328 env.rpc(
"json",
"feature",
to_string(params))[jss::result];
330 result[jss::error] ==
"noPermission",
331 result[jss::error].asString());
333 result[jss::error_message] ==
334 "You don't have permission for this command.");
339 "C4483A1896170C66C098DEA5B0E024309C60DC960DE5F01CD7AF986AA3D9AD"
342 params[jss::feature] = feature;
344 env.rpc(
"json",
"feature",
to_string(params))[jss::result];
345 BEAST_EXPECT(result.isMember(feature));
346 auto const amendmentResult = result[feature];
347 BEAST_EXPECT(amendmentResult[jss::enabled].asBool() ==
false);
348 BEAST_EXPECT(amendmentResult[jss::supported].asBool() ==
true);
350 amendmentResult[jss::name].asString() ==
351 "fixMasterKeyAsRegularKey");
358 testcase(
"No Params, Some Enabled");
360 using namespace test::jtx;
362 *
this,
FeatureBitset(featureDepositAuth, featureDepositPreauth)};
367 auto jrr = env.rpc(
"feature")[jss::result];
368 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
370 for (
auto it = jrr[jss::features].begin();
371 it != jrr[jss::features].end();
375 (void)
id.parseHex(it.key().asString().c_str());
376 if (!BEAST_EXPECT((*it).isMember(jss::name)))
378 bool expectEnabled = env.app().getAmendmentTable().isEnabled(
id);
379 bool expectSupported =
380 env.app().getAmendmentTable().isSupported(
id);
382 (votes.
at((*it)[jss::name].asString()) ==
384 bool expectObsolete =
385 (votes.
at((*it)[jss::name].asString()) ==
388 (*it).isMember(jss::enabled) &&
389 (*it)[jss::enabled].asBool() == expectEnabled,
390 (*it)[jss::name].asString() +
" enabled");
393 !(*it).isMember(jss::vetoed),
394 (*it)[jss::name].asString() +
" vetoed");
397 (*it).isMember(jss::vetoed) &&
398 (*it)[jss::vetoed].isBool() == !expectObsolete &&
399 (!(*it)[jss::vetoed].isBool() ||
400 (*it)[jss::vetoed].asBool() == expectVeto) &&
401 ((*it)[jss::vetoed].isBool() ||
402 (*it)[jss::vetoed].asString() ==
"Obsolete"),
403 (*it)[jss::name].asString() +
" vetoed");
405 (*it).isMember(jss::supported) &&
406 (*it)[jss::supported].asBool() == expectSupported,
407 (*it)[jss::name].asString() +
" supported");
416 using namespace test::jtx;
417 Env env{*
this, envconfig(validator,
"")};
419 auto jrr = env.rpc(
"feature")[jss::result];
420 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
425 for (
auto const& feature : jrr[jss::features])
427 if (!BEAST_EXPECT(feature.isMember(jss::name)))
430 !feature.isMember(jss::majority),
431 feature[jss::name].asString() +
" majority");
433 !feature.isMember(jss::count),
434 feature[jss::name].asString() +
" count");
436 !feature.isMember(jss::threshold),
437 feature[jss::name].asString() +
" threshold");
439 !feature.isMember(jss::validations),
440 feature[jss::name].asString() +
" validations");
442 !feature.isMember(jss::vote),
443 feature[jss::name].asString() +
" vote");
447 if (!BEAST_EXPECT(majorities.empty()))
451 for (
auto i = 0; i <= 256; ++i)
455 if (!majorities.empty())
461 BEAST_EXPECT(majorities.size() >= 5);
465 jrr = env.rpc(
"feature")[jss::result];
466 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
468 for (
auto const& feature : jrr[jss::features])
470 if (!BEAST_EXPECT(feature.isMember(jss::name)))
473 (votes.
at(feature[jss::name].asString()) ==
475 bool expectObsolete =
476 (votes.
at(feature[jss::name].asString()) ==
479 (expectVeto || expectObsolete) ^
480 feature.isMember(jss::majority),
481 feature[jss::name].asString() +
" majority");
483 feature.isMember(jss::vetoed) &&
484 feature[jss::vetoed].isBool() == !expectObsolete &&
485 (!feature[jss::vetoed].isBool() ||
486 feature[jss::vetoed].asBool() == expectVeto) &&
487 (feature[jss::vetoed].isBool() ||
488 feature[jss::vetoed].asString() ==
"Obsolete"),
489 feature[jss::name].asString() +
" vetoed");
491 feature.isMember(jss::count),
492 feature[jss::name].asString() +
" count");
494 feature.isMember(jss::threshold),
495 feature[jss::name].asString() +
" threshold");
497 feature.isMember(jss::validations),
498 feature[jss::name].asString() +
" validations");
500 feature[jss::count] ==
501 ((expectVeto || expectObsolete) ? 0 : 1));
502 BEAST_EXPECT(feature[jss::threshold] == 1);
503 BEAST_EXPECT(feature[jss::validations] == 1);
505 expectVeto || expectObsolete || feature[jss::majority] == 2540,
506 "Majority: " + feature[jss::majority].asString());
515 using namespace test::jtx;
517 constexpr char const* featureName =
"MultiSignReserve";
519 auto jrr = env.rpc(
"feature", featureName)[jss::result];
520 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
522 jrr.removeMember(jss::status);
523 if (!BEAST_EXPECT(jrr.size() == 1))
525 auto feature = *(jrr.begin());
526 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
528 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
531 jrr = env.rpc(
"feature", featureName,
"reject")[jss::result];
532 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
534 jrr.removeMember(jss::status);
535 if (!BEAST_EXPECT(jrr.size() == 1))
537 feature = *(jrr.begin());
538 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
540 feature[jss::vetoed].isBool() && feature[jss::vetoed].asBool(),
543 jrr = env.rpc(
"feature", featureName,
"accept")[jss::result];
544 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
546 jrr.removeMember(jss::status);
547 if (!BEAST_EXPECT(jrr.size() == 1))
549 feature = *(jrr.begin());
550 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
552 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
556 jrr = env.rpc(
"feature", featureName,
"maybe");
557 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
558 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid parameters.");
566 using namespace test::jtx;
568 constexpr char const* featureName =
"NonFungibleTokensV1";
570 auto jrr = env.rpc(
"feature", featureName)[jss::result];
571 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
573 jrr.removeMember(jss::status);
574 if (!BEAST_EXPECT(jrr.size() == 1))
576 auto feature = *(jrr.begin());
577 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
579 feature[jss::vetoed].isString() &&
580 feature[jss::vetoed].asString() ==
"Obsolete",
583 jrr = env.rpc(
"feature", featureName,
"reject")[jss::result];
584 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
586 jrr.removeMember(jss::status);
587 if (!BEAST_EXPECT(jrr.size() == 1))
589 feature = *(jrr.begin());
590 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
592 feature[jss::vetoed].isString() &&
593 feature[jss::vetoed].asString() ==
"Obsolete",
596 jrr = env.rpc(
"feature", featureName,
"accept")[jss::result];
597 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
599 jrr.removeMember(jss::status);
600 if (!BEAST_EXPECT(jrr.size() == 1))
602 feature = *(jrr.begin());
603 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
605 feature[jss::vetoed].isString() &&
606 feature[jss::vetoed].asString() ==
"Obsolete",
610 jrr = env.rpc(
"feature", featureName,
"maybe");
611 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
612 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid parameters.");