137 testcase(
"No Params, None Enabled");
139 using namespace test::jtx;
145 auto jrr = env.rpc(
"feature")[jss::result];
146 if (!BEAST_EXPECT(jrr.isMember(jss::features)))
148 for (
auto const& feature : jrr[jss::features])
150 if (!BEAST_EXPECT(feature.isMember(jss::name)))
155 (votes.
at(feature[jss::name].asString()) ==
157 bool expectObsolete =
158 (votes.
at(feature[jss::name].asString()) ==
161 feature.isMember(jss::enabled) &&
162 !feature[jss::enabled].asBool(),
163 feature[jss::name].asString() +
" enabled");
165 feature.isMember(jss::vetoed) &&
166 feature[jss::vetoed].isBool() == !expectObsolete &&
167 (!feature[jss::vetoed].isBool() ||
168 feature[jss::vetoed].asBool() == expectVeto) &&
169 (feature[jss::vetoed].isBool() ||
170 feature[jss::vetoed].asString() ==
"Obsolete"),
171 feature[jss::name].asString() +
" vetoed");
173 feature.isMember(jss::supported) &&
174 feature[jss::supported].asBool(),
175 feature[jss::name].asString() +
" supported");
184 using namespace test::jtx;
187 auto jrr = env.rpc(
"feature",
"RequireFullyCanonicalSig")[jss::result];
188 BEAST_EXPECTS(jrr[jss::status] == jss::success,
"status");
189 jrr.removeMember(jss::status);
190 BEAST_EXPECT(jrr.size() == 1);
192 jrr.isMember(
"00C1FC4A53E60AB02C864641002B3172F38677E29C26C54066851"
194 auto feature = *(jrr.begin());
196 BEAST_EXPECTS(feature[jss::name] ==
"RequireFullyCanonicalSig",
"name");
197 BEAST_EXPECTS(!feature[jss::enabled].asBool(),
"enabled");
199 feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(),
201 BEAST_EXPECTS(feature[jss::supported].asBool(),
"supported");
204 jrr = env.rpc(
"feature",
"requireFullyCanonicalSig")[jss::result];
205 BEAST_EXPECT(jrr[jss::error] ==
"badFeature");
206 BEAST_EXPECT(jrr[jss::error_message] ==
"Feature unknown or invalid.");
246 using namespace test::jtx;
248 (*cfg)[
"port_rpc"].set(
"admin",
"");
249 (*cfg)[
"port_ws"].set(
"admin",
"");
254 auto result = env.rpc(
"feature")[jss::result];
255 BEAST_EXPECT(result.isMember(jss::features));
259 BEAST_EXPECT(result[jss::features].size() >= 50);
260 for (
auto it = result[jss::features].begin();
261 it != result[jss::features].end();
265 (void)
id.parseHex(it.key().asString().c_str());
266 if (!BEAST_EXPECT((*it).isMember(jss::name)))
269 env.app().getAmendmentTable().isEnabled(
id);
270 bool expectSupported =
271 env.app().getAmendmentTable().isSupported(
id);
273 (*it).isMember(jss::enabled) &&
274 (*it)[jss::enabled].asBool() == expectEnabled,
275 (*it)[jss::name].asString() +
" enabled");
277 (*it).isMember(jss::supported) &&
278 (*it)[jss::supported].asBool() == expectSupported,
279 (*it)[jss::name].asString() +
" supported");
280 BEAST_EXPECT(!(*it).isMember(jss::vetoed));
281 BEAST_EXPECT(!(*it).isMember(jss::majority));
282 BEAST_EXPECT(!(*it).isMember(jss::count));
283 BEAST_EXPECT(!(*it).isMember(jss::validations));
284 BEAST_EXPECT(!(*it).isMember(jss::threshold));
291 params[jss::feature] =
292 "1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCD"
295 env.rpc(
"json",
"feature",
to_string(params))[jss::result];
297 result[jss::error] ==
"badFeature", result.toStyledString());
299 result[jss::error_message] ==
"Feature unknown or invalid.");
304 params[jss::feature] =
305 "93E516234E35E08CA689FA33A6D38E103881F8DCB53023F728C307AA89D515"
308 params[jss::vetoed] =
true;
310 env.rpc(
"json",
"feature",
to_string(params))[jss::result];
312 result[jss::error] ==
"noPermission",
313 result[jss::error].asString());
315 result[jss::error_message] ==
316 "You don't have permission for this command.");
323 testcase(
"No Params, Some Enabled");
325 using namespace test::jtx;
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;
480 Env env{*
this,
FeatureBitset{featureRequireFullyCanonicalSig}};
481 constexpr char const* featureName =
"RequireFullyCanonicalSig";
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.");