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"
312 auto const result = env.rpc(
315 boost::lexical_cast<std::string>(params))[jss::result];
317 result[jss::error] ==
"badFeature", result.toStyledString());
319 result[jss::error_message] ==
"Feature unknown or invalid.");
324 params[jss::feature] =
325 "93E516234E35E08CA689FA33A6D38E103881F8DCB53023F728C307AA89D515"
328 params[jss::vetoed] =
true;
329 auto const result = env.rpc(
332 boost::lexical_cast<std::string>(params))[jss::result];
334 result[jss::error] ==
"noPermission",
335 result[jss::error].asString());
337 result[jss::error_message] ==
338 "You don't have permission for this command.");
343 "C4483A1896170C66C098DEA5B0E024309C60DC960DE5F01CD7AF986AA3D9AD"
346 params[jss::feature] = feature;
347 auto const result = env.rpc(
350 boost::lexical_cast<std::string>(params))[jss::result];
351 BEAST_EXPECT(result.isMember(feature));
352 auto const amendmentResult = result[feature];
353 BEAST_EXPECT(amendmentResult[jss::enabled].asBool() ==
false);
354 BEAST_EXPECT(amendmentResult[jss::supported].asBool() ==
true);
356 amendmentResult[jss::name].asString() ==
357 "fixMasterKeyAsRegularKey");
364 testcase(
"No Params, Some Enabled");
366 using namespace test::jtx;
368 *
this,
FeatureBitset(featureDepositAuth, featureDepositPreauth)};
373 auto jrr = env.rpc(
"feature")[jss::result];
374 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
376 for (
auto it = jrr[jss::features].begin();
377 it != jrr[jss::features].end();
381 (void)
id.parseHex(it.key().asString().c_str());
382 if (!BEAST_EXPECT((*it).isMember(jss::name)))
384 bool expectEnabled = env.app().getAmendmentTable().isEnabled(
id);
385 bool expectSupported =
386 env.app().getAmendmentTable().isSupported(
id);
388 (votes.
at((*it)[jss::name].asString()) ==
390 bool expectObsolete =
391 (votes.
at((*it)[jss::name].asString()) ==
394 (*it).isMember(jss::enabled) &&
395 (*it)[jss::enabled].asBool() == expectEnabled,
396 (*it)[jss::name].asString() +
" enabled");
399 !(*it).isMember(jss::vetoed),
400 (*it)[jss::name].asString() +
" vetoed");
403 (*it).isMember(jss::vetoed) &&
404 (*it)[jss::vetoed].isBool() == !expectObsolete &&
405 (!(*it)[jss::vetoed].isBool() ||
406 (*it)[jss::vetoed].asBool() == expectVeto) &&
407 ((*it)[jss::vetoed].isBool() ||
408 (*it)[jss::vetoed].asString() ==
"Obsolete"),
409 (*it)[jss::name].asString() +
" vetoed");
411 (*it).isMember(jss::supported) &&
412 (*it)[jss::supported].asBool() == expectSupported,
413 (*it)[jss::name].asString() +
" supported");
422 using namespace test::jtx;
423 Env env{*
this, envconfig(validator,
"")};
425 auto jrr = env.rpc(
"feature")[jss::result];
426 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
431 for (
auto const& feature : jrr[jss::features])
433 if (!BEAST_EXPECT(feature.isMember(jss::name)))
436 !feature.isMember(jss::majority),
437 feature[jss::name].asString() +
" majority");
439 !feature.isMember(jss::count),
440 feature[jss::name].asString() +
" count");
442 !feature.isMember(jss::threshold),
443 feature[jss::name].asString() +
" threshold");
445 !feature.isMember(jss::validations),
446 feature[jss::name].asString() +
" validations");
448 !feature.isMember(jss::vote),
449 feature[jss::name].asString() +
" vote");
453 if (!BEAST_EXPECT(majorities.empty()))
457 for (
auto i = 0; i <= 256; ++i)
461 if (!majorities.empty())
467 BEAST_EXPECT(majorities.size() >= 5);
471 jrr = env.rpc(
"feature")[jss::result];
472 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
474 for (
auto const& feature : jrr[jss::features])
476 if (!BEAST_EXPECT(feature.isMember(jss::name)))
479 (votes.
at(feature[jss::name].asString()) ==
481 bool expectObsolete =
482 (votes.
at(feature[jss::name].asString()) ==
485 (expectVeto || expectObsolete) ^
486 feature.isMember(jss::majority),
487 feature[jss::name].asString() +
" majority");
489 feature.isMember(jss::vetoed) &&
490 feature[jss::vetoed].isBool() == !expectObsolete &&
491 (!feature[jss::vetoed].isBool() ||
492 feature[jss::vetoed].asBool() == expectVeto) &&
493 (feature[jss::vetoed].isBool() ||
494 feature[jss::vetoed].asString() ==
"Obsolete"),
495 feature[jss::name].asString() +
" vetoed");
497 feature.isMember(jss::count),
498 feature[jss::name].asString() +
" count");
500 feature.isMember(jss::threshold),
501 feature[jss::name].asString() +
" threshold");
503 feature.isMember(jss::validations),
504 feature[jss::name].asString() +
" validations");
506 feature[jss::count] ==
507 ((expectVeto || expectObsolete) ? 0 : 1));
508 BEAST_EXPECT(feature[jss::threshold] == 1);
509 BEAST_EXPECT(feature[jss::validations] == 1);
511 expectVeto || expectObsolete || feature[jss::majority] == 2540,
512 "Majority: " + feature[jss::majority].asString());
521 using namespace test::jtx;
523 constexpr char const* featureName =
"MultiSignReserve";
525 auto jrr = env.rpc(
"feature", featureName)[jss::result];
526 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
528 jrr.removeMember(jss::status);
529 if (!BEAST_EXPECT(jrr.size() == 1))
531 auto feature = *(jrr.begin());
532 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
534 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
537 jrr = env.rpc(
"feature", featureName,
"reject")[jss::result];
538 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
540 jrr.removeMember(jss::status);
541 if (!BEAST_EXPECT(jrr.size() == 1))
543 feature = *(jrr.begin());
544 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
546 feature[jss::vetoed].isBool() && feature[jss::vetoed].asBool(),
549 jrr = env.rpc(
"feature", featureName,
"accept")[jss::result];
550 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
552 jrr.removeMember(jss::status);
553 if (!BEAST_EXPECT(jrr.size() == 1))
555 feature = *(jrr.begin());
556 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
558 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
562 jrr = env.rpc(
"feature", featureName,
"maybe");
563 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
564 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid parameters.");
572 using namespace test::jtx;
574 constexpr char const* featureName =
"NonFungibleTokensV1";
576 auto jrr = env.rpc(
"feature", featureName)[jss::result];
577 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
579 jrr.removeMember(jss::status);
580 if (!BEAST_EXPECT(jrr.size() == 1))
582 auto feature = *(jrr.begin());
583 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
585 feature[jss::vetoed].isString() &&
586 feature[jss::vetoed].asString() ==
"Obsolete",
589 jrr = env.rpc(
"feature", featureName,
"reject")[jss::result];
590 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
592 jrr.removeMember(jss::status);
593 if (!BEAST_EXPECT(jrr.size() == 1))
595 feature = *(jrr.begin());
596 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
598 feature[jss::vetoed].isString() &&
599 feature[jss::vetoed].asString() ==
"Obsolete",
602 jrr = env.rpc(
"feature", featureName,
"accept")[jss::result];
603 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
605 jrr.removeMember(jss::status);
606 if (!BEAST_EXPECT(jrr.size() == 1))
608 feature = *(jrr.begin());
609 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
611 feature[jss::vetoed].isString() &&
612 feature[jss::vetoed].asString() ==
"Obsolete",
616 jrr = env.rpc(
"feature", featureName,
"maybe");
617 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
618 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid parameters.");