136 testcase(
"No Params, None Enabled");
138 using namespace test::jtx;
144 auto jrr = env.rpc(
"feature")[jss::result];
145 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
147 for (
auto const& feature : jrr[jss::features])
149 if (!BEAST_EXPECT(feature.isMember(jss::name)))
154 (votes.
at(feature[jss::name].asString()) ==
156 bool expectObsolete =
157 (votes.
at(feature[jss::name].asString()) ==
160 feature.isMember(jss::enabled) &&
161 !feature[jss::enabled].asBool(),
162 feature[jss::name].asString() +
" enabled");
164 feature.isMember(jss::vetoed) &&
165 feature[jss::vetoed].isBool() == !expectObsolete &&
166 (!feature[jss::vetoed].isBool() ||
167 feature[jss::vetoed].asBool() == expectVeto) &&
168 (feature[jss::vetoed].isBool() ||
169 feature[jss::vetoed].asString() ==
"Obsolete"),
170 feature[jss::name].asString() +
" vetoed");
172 feature.isMember(jss::supported) &&
173 feature[jss::supported].asBool(),
174 feature[jss::name].asString() +
" supported");
183 using namespace test::jtx;
186 auto jrr = env.rpc(
"feature",
"MultiSignReserve")[jss::result];
187 BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status");
188 jrr.removeMember(jss::status);
189 BEAST_EXPECT(jrr.size() == 1);
191 jrr.isMember(
"586480873651E106F1D6339B0C4A8945BA705A777F3F4524626FF"
193 auto feature = *(jrr.begin());
195 BEAST_EXPECTS(feature[jss::name] ==
"MultiSignReserve",
"name");
196 BEAST_EXPECTS(!feature[jss::enabled].asBool(),
"enabled");
198 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
200 BEAST_EXPECTS(feature[jss::supported].asBool(),
"supported");
203 jrr = env.rpc(
"feature",
"multiSignReserve")[jss::result];
204 BEAST_EXPECT(jrr[jss::error] ==
"badFeature");
205 BEAST_EXPECT(jrr[jss::error_message] ==
"Feature unknown or invalid.");
245 using namespace test::jtx;
247 (*cfg)[
"port_rpc"].set(
"admin",
"");
248 (*cfg)[
"port_ws"].set(
"admin",
"");
253 auto result = env.rpc(
"feature")[jss::result];
254 BEAST_EXPECT(result.isMember(jss::features));
258 BEAST_EXPECT(result[jss::features].size() >= 50);
259 for (
auto it = result[jss::features].begin();
260 it != result[jss::features].end();
264 (void)
id.parseHex(it.key().asString().c_str());
265 if (!BEAST_EXPECT((*it).isMember(jss::name)))
268 env.app().getAmendmentTable().isEnabled(
id);
269 bool expectSupported =
270 env.app().getAmendmentTable().isSupported(
id);
272 (*it).isMember(jss::enabled) &&
273 (*it)[jss::enabled].asBool() == expectEnabled,
274 (*it)[jss::name].asString() +
" enabled");
276 (*it).isMember(jss::supported) &&
277 (*it)[jss::supported].asBool() == expectSupported,
278 (*it)[jss::name].asString() +
" supported");
279 BEAST_EXPECT(!(*it).isMember(jss::vetoed));
280 BEAST_EXPECT(!(*it).isMember(jss::majority));
281 BEAST_EXPECT(!(*it).isMember(jss::count));
282 BEAST_EXPECT(!(*it).isMember(jss::validations));
283 BEAST_EXPECT(!(*it).isMember(jss::threshold));
290 params[jss::feature] =
291 "1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCD"
294 env.rpc(
"json",
"feature",
to_string(params))[jss::result];
296 result[jss::error] ==
"badFeature", result.toStyledString());
298 result[jss::error_message] ==
"Feature unknown or invalid.");
303 params[jss::feature] =
304 "93E516234E35E08CA689FA33A6D38E103881F8DCB53023F728C307AA89D515"
307 params[jss::vetoed] =
true;
309 env.rpc(
"json",
"feature",
to_string(params))[jss::result];
311 result[jss::error] ==
"noPermission",
312 result[jss::error].asString());
314 result[jss::error_message] ==
315 "You don't have permission for this command.");
322 testcase(
"No Params, Some Enabled");
324 using namespace test::jtx;
326 *
this,
FeatureBitset(featureDepositAuth, featureDepositPreauth)};
331 auto jrr = env.rpc(
"feature")[jss::result];
332 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
334 for (
auto it = jrr[jss::features].begin();
335 it != jrr[jss::features].end();
339 (void)
id.parseHex(it.key().asString().c_str());
340 if (!BEAST_EXPECT((*it).isMember(jss::name)))
342 bool expectEnabled = env.app().getAmendmentTable().isEnabled(
id);
343 bool expectSupported =
344 env.app().getAmendmentTable().isSupported(
id);
346 (votes.
at((*it)[jss::name].asString()) ==
348 bool expectObsolete =
349 (votes.
at((*it)[jss::name].asString()) ==
352 (*it).isMember(jss::enabled) &&
353 (*it)[jss::enabled].asBool() == expectEnabled,
354 (*it)[jss::name].asString() +
" enabled");
357 !(*it).isMember(jss::vetoed),
358 (*it)[jss::name].asString() +
" vetoed");
361 (*it).isMember(jss::vetoed) &&
362 (*it)[jss::vetoed].isBool() == !expectObsolete &&
363 (!(*it)[jss::vetoed].isBool() ||
364 (*it)[jss::vetoed].asBool() == expectVeto) &&
365 ((*it)[jss::vetoed].isBool() ||
366 (*it)[jss::vetoed].asString() ==
"Obsolete"),
367 (*it)[jss::name].asString() +
" vetoed");
369 (*it).isMember(jss::supported) &&
370 (*it)[jss::supported].asBool() == expectSupported,
371 (*it)[jss::name].asString() +
" supported");
380 using namespace test::jtx;
381 Env env{*
this, envconfig(validator,
"")};
383 auto jrr = env.rpc(
"feature")[jss::result];
384 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
389 for (
auto const& feature : jrr[jss::features])
391 if (!BEAST_EXPECT(feature.isMember(jss::name)))
394 !feature.isMember(jss::majority),
395 feature[jss::name].asString() +
" majority");
397 !feature.isMember(jss::count),
398 feature[jss::name].asString() +
" count");
400 !feature.isMember(jss::threshold),
401 feature[jss::name].asString() +
" threshold");
403 !feature.isMember(jss::validations),
404 feature[jss::name].asString() +
" validations");
406 !feature.isMember(jss::vote),
407 feature[jss::name].asString() +
" vote");
411 if (!BEAST_EXPECT(majorities.empty()))
415 for (
auto i = 0; i <= 256; ++i)
419 if (!majorities.empty())
425 BEAST_EXPECT(majorities.size() >= 5);
429 jrr = env.rpc(
"feature")[jss::result];
430 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
432 for (
auto const& feature : jrr[jss::features])
434 if (!BEAST_EXPECT(feature.isMember(jss::name)))
437 (votes.
at(feature[jss::name].asString()) ==
439 bool expectObsolete =
440 (votes.
at(feature[jss::name].asString()) ==
443 (expectVeto || expectObsolete) ^
444 feature.isMember(jss::majority),
445 feature[jss::name].asString() +
" majority");
447 feature.isMember(jss::vetoed) &&
448 feature[jss::vetoed].isBool() == !expectObsolete &&
449 (!feature[jss::vetoed].isBool() ||
450 feature[jss::vetoed].asBool() == expectVeto) &&
451 (feature[jss::vetoed].isBool() ||
452 feature[jss::vetoed].asString() ==
"Obsolete"),
453 feature[jss::name].asString() +
" vetoed");
455 feature.isMember(jss::count),
456 feature[jss::name].asString() +
" count");
458 feature.isMember(jss::threshold),
459 feature[jss::name].asString() +
" threshold");
461 feature.isMember(jss::validations),
462 feature[jss::name].asString() +
" validations");
464 feature[jss::count] ==
465 ((expectVeto || expectObsolete) ? 0 : 1));
466 BEAST_EXPECT(feature[jss::threshold] == 1);
467 BEAST_EXPECT(feature[jss::validations] == 1);
469 expectVeto || expectObsolete || feature[jss::majority] == 2540,
470 "Majority: " + feature[jss::majority].asString());
479 using namespace test::jtx;
481 constexpr char const* featureName =
"MultiSignReserve";
483 auto jrr = env.rpc(
"feature", featureName)[jss::result];
484 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
486 jrr.removeMember(jss::status);
487 if (!BEAST_EXPECT(jrr.size() == 1))
489 auto feature = *(jrr.begin());
490 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
492 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
495 jrr = env.rpc(
"feature", featureName,
"reject")[jss::result];
496 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
498 jrr.removeMember(jss::status);
499 if (!BEAST_EXPECT(jrr.size() == 1))
501 feature = *(jrr.begin());
502 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
504 feature[jss::vetoed].isBool() && feature[jss::vetoed].asBool(),
507 jrr = env.rpc(
"feature", featureName,
"accept")[jss::result];
508 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
510 jrr.removeMember(jss::status);
511 if (!BEAST_EXPECT(jrr.size() == 1))
513 feature = *(jrr.begin());
514 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
516 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
520 jrr = env.rpc(
"feature", featureName,
"maybe");
521 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
522 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid parameters.");
530 using namespace test::jtx;
532 constexpr char const* featureName =
"CryptoConditionsSuite";
534 auto jrr = env.rpc(
"feature", featureName)[jss::result];
535 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
537 jrr.removeMember(jss::status);
538 if (!BEAST_EXPECT(jrr.size() == 1))
540 auto feature = *(jrr.begin());
541 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
543 feature[jss::vetoed].isString() &&
544 feature[jss::vetoed].asString() ==
"Obsolete",
547 jrr = env.rpc(
"feature", featureName,
"reject")[jss::result];
548 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
550 jrr.removeMember(jss::status);
551 if (!BEAST_EXPECT(jrr.size() == 1))
553 feature = *(jrr.begin());
554 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
556 feature[jss::vetoed].isString() &&
557 feature[jss::vetoed].asString() ==
"Obsolete",
560 jrr = env.rpc(
"feature", featureName,
"accept")[jss::result];
561 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
563 jrr.removeMember(jss::status);
564 if (!BEAST_EXPECT(jrr.size() == 1))
566 feature = *(jrr.begin());
567 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
569 feature[jss::vetoed].isString() &&
570 feature[jss::vetoed].asString() ==
"Obsolete",
574 jrr = env.rpc(
"feature", featureName,
"maybe");
575 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
576 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid parameters.");