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.");
340 testcase(
"No Params, Some Enabled");
342 using namespace test::jtx;
344 *
this,
FeatureBitset(featureDepositAuth, featureDepositPreauth)};
349 auto jrr = env.rpc(
"feature")[jss::result];
350 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
352 for (
auto it = jrr[jss::features].begin();
353 it != jrr[jss::features].end();
357 (void)
id.parseHex(it.key().asString().c_str());
358 if (!BEAST_EXPECT((*it).isMember(jss::name)))
360 bool expectEnabled = env.app().getAmendmentTable().isEnabled(
id);
361 bool expectSupported =
362 env.app().getAmendmentTable().isSupported(
id);
364 (votes.
at((*it)[jss::name].asString()) ==
366 bool expectObsolete =
367 (votes.
at((*it)[jss::name].asString()) ==
370 (*it).isMember(jss::enabled) &&
371 (*it)[jss::enabled].asBool() == expectEnabled,
372 (*it)[jss::name].asString() +
" enabled");
375 !(*it).isMember(jss::vetoed),
376 (*it)[jss::name].asString() +
" vetoed");
379 (*it).isMember(jss::vetoed) &&
380 (*it)[jss::vetoed].isBool() == !expectObsolete &&
381 (!(*it)[jss::vetoed].isBool() ||
382 (*it)[jss::vetoed].asBool() == expectVeto) &&
383 ((*it)[jss::vetoed].isBool() ||
384 (*it)[jss::vetoed].asString() ==
"Obsolete"),
385 (*it)[jss::name].asString() +
" vetoed");
387 (*it).isMember(jss::supported) &&
388 (*it)[jss::supported].asBool() == expectSupported,
389 (*it)[jss::name].asString() +
" supported");
398 using namespace test::jtx;
399 Env env{*
this, envconfig(validator,
"")};
401 auto jrr = env.rpc(
"feature")[jss::result];
402 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
407 for (
auto const& feature : jrr[jss::features])
409 if (!BEAST_EXPECT(feature.isMember(jss::name)))
412 !feature.isMember(jss::majority),
413 feature[jss::name].asString() +
" majority");
415 !feature.isMember(jss::count),
416 feature[jss::name].asString() +
" count");
418 !feature.isMember(jss::threshold),
419 feature[jss::name].asString() +
" threshold");
421 !feature.isMember(jss::validations),
422 feature[jss::name].asString() +
" validations");
424 !feature.isMember(jss::vote),
425 feature[jss::name].asString() +
" vote");
429 if (!BEAST_EXPECT(majorities.empty()))
433 for (
auto i = 0; i <= 256; ++i)
437 if (!majorities.empty())
443 BEAST_EXPECT(majorities.size() >= 5);
447 jrr = env.rpc(
"feature")[jss::result];
448 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
450 for (
auto const& feature : jrr[jss::features])
452 if (!BEAST_EXPECT(feature.isMember(jss::name)))
455 (votes.
at(feature[jss::name].asString()) ==
457 bool expectObsolete =
458 (votes.
at(feature[jss::name].asString()) ==
461 (expectVeto || expectObsolete) ^
462 feature.isMember(jss::majority),
463 feature[jss::name].asString() +
" majority");
465 feature.isMember(jss::vetoed) &&
466 feature[jss::vetoed].isBool() == !expectObsolete &&
467 (!feature[jss::vetoed].isBool() ||
468 feature[jss::vetoed].asBool() == expectVeto) &&
469 (feature[jss::vetoed].isBool() ||
470 feature[jss::vetoed].asString() ==
"Obsolete"),
471 feature[jss::name].asString() +
" vetoed");
473 feature.isMember(jss::count),
474 feature[jss::name].asString() +
" count");
476 feature.isMember(jss::threshold),
477 feature[jss::name].asString() +
" threshold");
479 feature.isMember(jss::validations),
480 feature[jss::name].asString() +
" validations");
482 feature[jss::count] ==
483 ((expectVeto || expectObsolete) ? 0 : 1));
484 BEAST_EXPECT(feature[jss::threshold] == 1);
485 BEAST_EXPECT(feature[jss::validations] == 1);
487 expectVeto || expectObsolete || feature[jss::majority] == 2540,
488 "Majority: " + feature[jss::majority].asString());
497 using namespace test::jtx;
499 constexpr char const* featureName =
"MultiSignReserve";
501 auto jrr = env.rpc(
"feature", featureName)[jss::result];
502 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
504 jrr.removeMember(jss::status);
505 if (!BEAST_EXPECT(jrr.size() == 1))
507 auto feature = *(jrr.begin());
508 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
510 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
513 jrr = env.rpc(
"feature", featureName,
"reject")[jss::result];
514 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
516 jrr.removeMember(jss::status);
517 if (!BEAST_EXPECT(jrr.size() == 1))
519 feature = *(jrr.begin());
520 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
522 feature[jss::vetoed].isBool() && feature[jss::vetoed].asBool(),
525 jrr = env.rpc(
"feature", featureName,
"accept")[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 feature = *(jrr.begin());
532 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
534 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
538 jrr = env.rpc(
"feature", featureName,
"maybe");
539 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
540 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid parameters.");
548 using namespace test::jtx;
550 constexpr char const* featureName =
"NonFungibleTokensV1";
552 auto jrr = env.rpc(
"feature", featureName)[jss::result];
553 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
555 jrr.removeMember(jss::status);
556 if (!BEAST_EXPECT(jrr.size() == 1))
558 auto feature = *(jrr.begin());
559 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
561 feature[jss::vetoed].isString() &&
562 feature[jss::vetoed].asString() ==
"Obsolete",
565 jrr = env.rpc(
"feature", featureName,
"reject")[jss::result];
566 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
568 jrr.removeMember(jss::status);
569 if (!BEAST_EXPECT(jrr.size() == 1))
571 feature = *(jrr.begin());
572 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
574 feature[jss::vetoed].isString() &&
575 feature[jss::vetoed].asString() ==
"Obsolete",
578 jrr = env.rpc(
"feature", featureName,
"accept")[jss::result];
579 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
581 jrr.removeMember(jss::status);
582 if (!BEAST_EXPECT(jrr.size() == 1))
584 feature = *(jrr.begin());
585 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
587 feature[jss::vetoed].isString() &&
588 feature[jss::vetoed].asString() ==
"Obsolete",
592 jrr = env.rpc(
"feature", featureName,
"maybe");
593 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
594 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid parameters.");