154 testcase(
"No Params, None Enabled");
156 using namespace test::jtx;
162 auto jrr = env.rpc(
"feature")[jss::result];
163 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
165 for (
auto const& feature : jrr[jss::features])
167 if (!BEAST_EXPECT(feature.isMember(jss::name)))
172 (votes.
at(feature[jss::name].asString()) ==
174 bool expectObsolete =
175 (votes.
at(feature[jss::name].asString()) ==
178 feature.isMember(jss::enabled) &&
179 !feature[jss::enabled].asBool(),
180 feature[jss::name].asString() +
" enabled");
182 feature.isMember(jss::vetoed) &&
183 feature[jss::vetoed].isBool() == !expectObsolete &&
184 (!feature[jss::vetoed].isBool() ||
185 feature[jss::vetoed].asBool() == expectVeto) &&
186 (feature[jss::vetoed].isBool() ||
187 feature[jss::vetoed].asString() ==
"Obsolete"),
188 feature[jss::name].asString() +
" vetoed");
190 feature.isMember(jss::supported) &&
191 feature[jss::supported].asBool(),
192 feature[jss::name].asString() +
" supported");
201 using namespace test::jtx;
204 auto jrr = env.rpc(
"feature",
"MultiSignReserve")[jss::result];
205 BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status");
206 jrr.removeMember(jss::status);
207 BEAST_EXPECT(jrr.size() == 1);
209 jrr.isMember(
"586480873651E106F1D6339B0C4A8945BA705A777F3F4524626FF"
211 auto feature = *(jrr.begin());
213 BEAST_EXPECTS(feature[jss::name] ==
"MultiSignReserve",
"name");
214 BEAST_EXPECTS(!feature[jss::enabled].asBool(),
"enabled");
216 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
218 BEAST_EXPECTS(feature[jss::supported].asBool(),
"supported");
221 jrr = env.rpc(
"feature",
"multiSignReserve")[jss::result];
222 BEAST_EXPECT(jrr[jss::error] ==
"badFeature");
223 BEAST_EXPECT(jrr[jss::error_message] ==
"Feature unknown or invalid.");
263 using namespace test::jtx;
265 (*cfg)[
"port_rpc"].set(
"admin",
"");
266 (*cfg)[
"port_ws"].set(
"admin",
"");
271 auto result = env.rpc(
"feature")[jss::result];
272 BEAST_EXPECT(result.isMember(jss::features));
276 BEAST_EXPECT(result[jss::features].size() >= 50);
277 for (
auto it = result[jss::features].begin();
278 it != result[jss::features].end();
282 (void)
id.parseHex(it.key().asString().c_str());
283 if (!BEAST_EXPECT((*it).isMember(jss::name)))
286 env.app().getAmendmentTable().isEnabled(
id);
287 bool expectSupported =
288 env.app().getAmendmentTable().isSupported(
id);
290 (*it).isMember(jss::enabled) &&
291 (*it)[jss::enabled].asBool() == expectEnabled,
292 (*it)[jss::name].asString() +
" enabled");
294 (*it).isMember(jss::supported) &&
295 (*it)[jss::supported].asBool() == expectSupported,
296 (*it)[jss::name].asString() +
" supported");
297 BEAST_EXPECT(!(*it).isMember(jss::vetoed));
298 BEAST_EXPECT(!(*it).isMember(jss::majority));
299 BEAST_EXPECT(!(*it).isMember(jss::count));
300 BEAST_EXPECT(!(*it).isMember(jss::validations));
301 BEAST_EXPECT(!(*it).isMember(jss::threshold));
308 params[jss::feature] =
309 "1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCD"
312 env.rpc(
"json",
"feature",
to_string(params))[jss::result];
314 result[jss::error] ==
"badFeature", result.toStyledString());
316 result[jss::error_message] ==
"Feature unknown or invalid.");
321 params[jss::feature] =
322 "93E516234E35E08CA689FA33A6D38E103881F8DCB53023F728C307AA89D515"
325 params[jss::vetoed] =
true;
327 env.rpc(
"json",
"feature",
to_string(params))[jss::result];
329 result[jss::error] ==
"noPermission",
330 result[jss::error].asString());
332 result[jss::error_message] ==
333 "You don't have permission for this command.");
338 "C4483A1896170C66C098DEA5B0E024309C60DC960DE5F01CD7AF986AA3D9AD"
341 params[jss::feature] = feature;
343 env.rpc(
"json",
"feature",
to_string(params))[jss::result];
344 BEAST_EXPECT(result.isMember(feature));
345 auto const amendmentResult = result[feature];
346 BEAST_EXPECT(amendmentResult[jss::enabled].asBool() ==
false);
347 BEAST_EXPECT(amendmentResult[jss::supported].asBool() ==
true);
349 amendmentResult[jss::name].asString() ==
350 "fixMasterKeyAsRegularKey");
357 testcase(
"No Params, Some Enabled");
359 using namespace test::jtx;
361 *
this,
FeatureBitset(featureDepositAuth, featureDepositPreauth)};
366 auto jrr = env.rpc(
"feature")[jss::result];
367 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
369 for (
auto it = jrr[jss::features].begin();
370 it != jrr[jss::features].end();
374 (void)
id.parseHex(it.key().asString().c_str());
375 if (!BEAST_EXPECT((*it).isMember(jss::name)))
377 bool expectEnabled = env.app().getAmendmentTable().isEnabled(
id);
378 bool expectSupported =
379 env.app().getAmendmentTable().isSupported(
id);
381 (votes.
at((*it)[jss::name].asString()) ==
383 bool expectObsolete =
384 (votes.
at((*it)[jss::name].asString()) ==
387 (*it).isMember(jss::enabled) &&
388 (*it)[jss::enabled].asBool() == expectEnabled,
389 (*it)[jss::name].asString() +
" enabled");
392 !(*it).isMember(jss::vetoed),
393 (*it)[jss::name].asString() +
" vetoed");
396 (*it).isMember(jss::vetoed) &&
397 (*it)[jss::vetoed].isBool() == !expectObsolete &&
398 (!(*it)[jss::vetoed].isBool() ||
399 (*it)[jss::vetoed].asBool() == expectVeto) &&
400 ((*it)[jss::vetoed].isBool() ||
401 (*it)[jss::vetoed].asString() ==
"Obsolete"),
402 (*it)[jss::name].asString() +
" vetoed");
404 (*it).isMember(jss::supported) &&
405 (*it)[jss::supported].asBool() == expectSupported,
406 (*it)[jss::name].asString() +
" supported");
415 using namespace test::jtx;
416 Env env{*
this, envconfig(validator,
"")};
418 auto jrr = env.rpc(
"feature")[jss::result];
419 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
424 for (
auto const& feature : jrr[jss::features])
426 if (!BEAST_EXPECT(feature.isMember(jss::name)))
429 !feature.isMember(jss::majority),
430 feature[jss::name].asString() +
" majority");
432 !feature.isMember(jss::count),
433 feature[jss::name].asString() +
" count");
435 !feature.isMember(jss::threshold),
436 feature[jss::name].asString() +
" threshold");
438 !feature.isMember(jss::validations),
439 feature[jss::name].asString() +
" validations");
441 !feature.isMember(jss::vote),
442 feature[jss::name].asString() +
" vote");
446 if (!BEAST_EXPECT(majorities.empty()))
450 for (
auto i = 0; i <= 256; ++i)
454 if (!majorities.empty())
460 BEAST_EXPECT(majorities.size() >= 5);
464 jrr = env.rpc(
"feature")[jss::result];
465 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
467 for (
auto const& feature : jrr[jss::features])
469 if (!BEAST_EXPECT(feature.isMember(jss::name)))
472 (votes.
at(feature[jss::name].asString()) ==
474 bool expectObsolete =
475 (votes.
at(feature[jss::name].asString()) ==
478 (expectVeto || expectObsolete) ^
479 feature.isMember(jss::majority),
480 feature[jss::name].asString() +
" majority");
482 feature.isMember(jss::vetoed) &&
483 feature[jss::vetoed].isBool() == !expectObsolete &&
484 (!feature[jss::vetoed].isBool() ||
485 feature[jss::vetoed].asBool() == expectVeto) &&
486 (feature[jss::vetoed].isBool() ||
487 feature[jss::vetoed].asString() ==
"Obsolete"),
488 feature[jss::name].asString() +
" vetoed");
490 feature.isMember(jss::count),
491 feature[jss::name].asString() +
" count");
493 feature.isMember(jss::threshold),
494 feature[jss::name].asString() +
" threshold");
496 feature.isMember(jss::validations),
497 feature[jss::name].asString() +
" validations");
499 feature[jss::count] ==
500 ((expectVeto || expectObsolete) ? 0 : 1));
501 BEAST_EXPECT(feature[jss::threshold] == 1);
502 BEAST_EXPECT(feature[jss::validations] == 1);
504 expectVeto || expectObsolete || feature[jss::majority] == 2540,
505 "Majority: " + feature[jss::majority].asString());
514 using namespace test::jtx;
516 constexpr char const* featureName =
"MultiSignReserve";
518 auto jrr = env.rpc(
"feature", featureName)[jss::result];
519 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
521 jrr.removeMember(jss::status);
522 if (!BEAST_EXPECT(jrr.size() == 1))
524 auto feature = *(jrr.begin());
525 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
527 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
530 jrr = env.rpc(
"feature", featureName,
"reject")[jss::result];
531 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
533 jrr.removeMember(jss::status);
534 if (!BEAST_EXPECT(jrr.size() == 1))
536 feature = *(jrr.begin());
537 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
539 feature[jss::vetoed].isBool() && feature[jss::vetoed].asBool(),
542 jrr = env.rpc(
"feature", featureName,
"accept")[jss::result];
543 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
545 jrr.removeMember(jss::status);
546 if (!BEAST_EXPECT(jrr.size() == 1))
548 feature = *(jrr.begin());
549 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
551 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
555 jrr = env.rpc(
"feature", featureName,
"maybe");
556 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
557 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid parameters.");
565 using namespace test::jtx;
567 constexpr char const* featureName =
"NonFungibleTokensV1";
569 auto jrr = env.rpc(
"feature", featureName)[jss::result];
570 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
572 jrr.removeMember(jss::status);
573 if (!BEAST_EXPECT(jrr.size() == 1))
575 auto feature = *(jrr.begin());
576 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
578 feature[jss::vetoed].isString() &&
579 feature[jss::vetoed].asString() ==
"Obsolete",
582 jrr = env.rpc(
"feature", featureName,
"reject")[jss::result];
583 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
585 jrr.removeMember(jss::status);
586 if (!BEAST_EXPECT(jrr.size() == 1))
588 feature = *(jrr.begin());
589 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
591 feature[jss::vetoed].isString() &&
592 feature[jss::vetoed].asString() ==
"Obsolete",
595 jrr = env.rpc(
"feature", featureName,
"accept")[jss::result];
596 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
598 jrr.removeMember(jss::status);
599 if (!BEAST_EXPECT(jrr.size() == 1))
601 feature = *(jrr.begin());
602 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
604 feature[jss::vetoed].isString() &&
605 feature[jss::vetoed].asString() ==
"Obsolete",
609 jrr = env.rpc(
"feature", featureName,
"maybe");
610 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
611 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid parameters.");