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;
330 auto jrr = env.rpc(
"feature")[jss::result];
331 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
333 for (
auto it = jrr[jss::features].begin();
334 it != jrr[jss::features].end();
338 (void)
id.parseHex(it.key().asString().c_str());
339 if (!BEAST_EXPECT((*it).isMember(jss::name)))
341 bool expectEnabled = env.app().getAmendmentTable().isEnabled(
id);
342 bool expectSupported =
343 env.app().getAmendmentTable().isSupported(
id);
345 (votes.
at((*it)[jss::name].asString()) ==
347 bool expectObsolete =
348 (votes.
at((*it)[jss::name].asString()) ==
351 (*it).isMember(jss::enabled) &&
352 (*it)[jss::enabled].asBool() == expectEnabled,
353 (*it)[jss::name].asString() +
" enabled");
356 !(*it).isMember(jss::vetoed),
357 (*it)[jss::name].asString() +
" vetoed");
360 (*it).isMember(jss::vetoed) &&
361 (*it)[jss::vetoed].isBool() == !expectObsolete &&
362 (!(*it)[jss::vetoed].isBool() ||
363 (*it)[jss::vetoed].asBool() == expectVeto) &&
364 ((*it)[jss::vetoed].isBool() ||
365 (*it)[jss::vetoed].asString() ==
"Obsolete"),
366 (*it)[jss::name].asString() +
" vetoed");
368 (*it).isMember(jss::supported) &&
369 (*it)[jss::supported].asBool() == expectSupported,
370 (*it)[jss::name].asString() +
" supported");
379 using namespace test::jtx;
380 Env env{*
this, envconfig(validator,
"")};
382 auto jrr = env.rpc(
"feature")[jss::result];
383 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
388 for (
auto const& feature : jrr[jss::features])
390 if (!BEAST_EXPECT(feature.isMember(jss::name)))
393 !feature.isMember(jss::majority),
394 feature[jss::name].asString() +
" majority");
396 !feature.isMember(jss::count),
397 feature[jss::name].asString() +
" count");
399 !feature.isMember(jss::threshold),
400 feature[jss::name].asString() +
" threshold");
402 !feature.isMember(jss::validations),
403 feature[jss::name].asString() +
" validations");
405 !feature.isMember(jss::vote),
406 feature[jss::name].asString() +
" vote");
410 if (!BEAST_EXPECT(majorities.empty()))
414 for (
auto i = 0; i <= 256; ++i)
418 if (!majorities.empty())
424 BEAST_EXPECT(majorities.size() >= 5);
428 jrr = env.rpc(
"feature")[jss::result];
429 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
431 for (
auto const& feature : jrr[jss::features])
433 if (!BEAST_EXPECT(feature.isMember(jss::name)))
436 (votes.
at(feature[jss::name].asString()) ==
438 bool expectObsolete =
439 (votes.
at(feature[jss::name].asString()) ==
442 (expectVeto || expectObsolete) ^
443 feature.isMember(jss::majority),
444 feature[jss::name].asString() +
" majority");
446 feature.isMember(jss::vetoed) &&
447 feature[jss::vetoed].isBool() == !expectObsolete &&
448 (!feature[jss::vetoed].isBool() ||
449 feature[jss::vetoed].asBool() == expectVeto) &&
450 (feature[jss::vetoed].isBool() ||
451 feature[jss::vetoed].asString() ==
"Obsolete"),
452 feature[jss::name].asString() +
" vetoed");
454 feature.isMember(jss::count),
455 feature[jss::name].asString() +
" count");
457 feature.isMember(jss::threshold),
458 feature[jss::name].asString() +
" threshold");
460 feature.isMember(jss::validations),
461 feature[jss::name].asString() +
" validations");
463 feature[jss::count] ==
464 ((expectVeto || expectObsolete) ? 0 : 1));
465 BEAST_EXPECT(feature[jss::threshold] == 1);
466 BEAST_EXPECT(feature[jss::validations] == 1);
468 expectVeto || expectObsolete || feature[jss::majority] == 2540,
469 "Majority: " + feature[jss::majority].asString());
478 using namespace test::jtx;
480 constexpr char const* featureName =
"MultiSignReserve";
482 auto jrr = env.rpc(
"feature", featureName)[jss::result];
483 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
485 jrr.removeMember(jss::status);
486 if (!BEAST_EXPECT(jrr.size() == 1))
488 auto feature = *(jrr.begin());
489 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
491 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
494 jrr = env.rpc(
"feature", featureName,
"reject")[jss::result];
495 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
497 jrr.removeMember(jss::status);
498 if (!BEAST_EXPECT(jrr.size() == 1))
500 feature = *(jrr.begin());
501 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
503 feature[jss::vetoed].isBool() && feature[jss::vetoed].asBool(),
506 jrr = env.rpc(
"feature", featureName,
"accept")[jss::result];
507 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
509 jrr.removeMember(jss::status);
510 if (!BEAST_EXPECT(jrr.size() == 1))
512 feature = *(jrr.begin());
513 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
515 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
519 jrr = env.rpc(
"feature", featureName,
"maybe");
520 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
521 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid parameters.");
529 using namespace test::jtx;
531 constexpr char const* featureName =
"CryptoConditionsSuite";
533 auto jrr = env.rpc(
"feature", featureName)[jss::result];
534 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
536 jrr.removeMember(jss::status);
537 if (!BEAST_EXPECT(jrr.size() == 1))
539 auto feature = *(jrr.begin());
540 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
542 feature[jss::vetoed].isString() &&
543 feature[jss::vetoed].asString() ==
"Obsolete",
546 jrr = env.rpc(
"feature", featureName,
"reject")[jss::result];
547 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
549 jrr.removeMember(jss::status);
550 if (!BEAST_EXPECT(jrr.size() == 1))
552 feature = *(jrr.begin());
553 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
555 feature[jss::vetoed].isString() &&
556 feature[jss::vetoed].asString() ==
"Obsolete",
559 jrr = env.rpc(
"feature", featureName,
"accept")[jss::result];
560 if (!BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status"))
562 jrr.removeMember(jss::status);
563 if (!BEAST_EXPECT(jrr.size() == 1))
565 feature = *(jrr.begin());
566 BEAST_EXPECTS(feature[jss::name] == featureName,
"name");
568 feature[jss::vetoed].isString() &&
569 feature[jss::vetoed].asString() ==
"Obsolete",
573 jrr = env.rpc(
"feature", featureName,
"maybe");
574 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
575 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid parameters.");