Compare commits

..

3 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
710f319cbe Update all test assertions to validate new boolean vetoed and obsolete fields
Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-01-30 15:51:42 +00:00
copilot-swe-agent[bot]
3a696131ef Fix amendment vetoed field type - use boolean and add obsolete field
Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-01-30 15:45:39 +00:00
copilot-swe-agent[bot]
d1fb93e0cf Initial plan 2026-01-30 15:42:41 +00:00
4 changed files with 51 additions and 16 deletions

View File

@@ -87,6 +87,10 @@ The `network_id` field was added in the `server_info` response in version 1.5.0
As of 2025-04-04, version 2.5.0 is in development. You can use a pre-release version by building from source or [using the `nightly` package](https://xrpl.org/docs/infrastructure/installation/install-rippled-on-ubuntu).
### Breaking changes in 2.5.0
- `feature`: The `vetoed` field is now always a boolean. Obsolete amendments now have `"vetoed": true` and a new `"obsolete": true` field, instead of the previous `"vetoed": "Obsolete"` string value. This change improves type safety for API clients.
### Additions and bugfixes in 2.5.0
- `channel_authorize`: If `signing_support` is not enabled in the config, the RPC is disabled.

View File

@@ -450,6 +450,7 @@ JSS(node_write_retries); // out: GetCounts
JSS(node_writes_delayed); // out::GetCounts
JSS(nth); // out: RPC server_definitions
JSS(obligations); // out: GatewayBalances
JSS(obsolete); // out: AmendmentTableImpl
JSS(offers); // out: NetworkOPs, AccountOffers, Subscribe
JSS(offer_id); // out: insertNFTokenOfferID
JSS(offline); // in: TransactionSign

View File

@@ -140,10 +140,17 @@ class Feature_test : public beast::unit_test::suite
feature.isMember(jss::enabled) && !feature[jss::enabled].asBool(),
feature[jss::name].asString() + " enabled");
BEAST_EXPECTS(
feature.isMember(jss::vetoed) && feature[jss::vetoed].isBool() == !expectObsolete &&
(!feature[jss::vetoed].isBool() || feature[jss::vetoed].asBool() == expectVeto) &&
(feature[jss::vetoed].isBool() || feature[jss::vetoed].asString() == "Obsolete"),
feature[jss::name].asString() + " vetoed");
feature.isMember(jss::vetoed) && feature[jss::vetoed].isBool(),
feature[jss::name].asString() + " vetoed is bool");
BEAST_EXPECTS(
feature[jss::vetoed].asBool() == (expectVeto || expectObsolete),
feature[jss::name].asString() + " vetoed value");
if (expectObsolete)
BEAST_EXPECTS(
feature.isMember(jss::obsolete) && feature[jss::obsolete].asBool() == true,
feature[jss::name].asString() + " obsolete");
else
BEAST_EXPECTS(!feature.isMember(jss::obsolete), feature[jss::name].asString() + " no obsolete");
BEAST_EXPECTS(
feature.isMember(jss::supported) && feature[jss::supported].asBool(),
feature[jss::name].asString() + " supported");
@@ -242,6 +249,7 @@ class Feature_test : public beast::unit_test::suite
(*it).isMember(jss::supported) && (*it)[jss::supported].asBool() == expectSupported,
(*it)[jss::name].asString() + " supported");
BEAST_EXPECT(!(*it).isMember(jss::vetoed));
BEAST_EXPECT(!(*it).isMember(jss::obsolete));
BEAST_EXPECT(!(*it).isMember(jss::majority));
BEAST_EXPECT(!(*it).isMember(jss::count));
BEAST_EXPECT(!(*it).isMember(jss::validations));
@@ -302,11 +310,20 @@ class Feature_test : public beast::unit_test::suite
if (expectEnabled)
BEAST_EXPECTS(!(*it).isMember(jss::vetoed), (*it)[jss::name].asString() + " vetoed");
else
{
BEAST_EXPECTS(
(*it).isMember(jss::vetoed) && (*it)[jss::vetoed].isBool() == !expectObsolete &&
(!(*it)[jss::vetoed].isBool() || (*it)[jss::vetoed].asBool() == expectVeto) &&
((*it)[jss::vetoed].isBool() || (*it)[jss::vetoed].asString() == "Obsolete"),
(*it)[jss::name].asString() + " vetoed");
(*it).isMember(jss::vetoed) && (*it)[jss::vetoed].isBool(),
(*it)[jss::name].asString() + " vetoed is bool");
BEAST_EXPECTS(
(*it)[jss::vetoed].asBool() == (expectVeto || expectObsolete),
(*it)[jss::name].asString() + " vetoed value");
if (expectObsolete)
BEAST_EXPECTS(
(*it).isMember(jss::obsolete) && (*it)[jss::obsolete].asBool() == true,
(*it)[jss::name].asString() + " obsolete");
else
BEAST_EXPECTS(!(*it).isMember(jss::obsolete), (*it)[jss::name].asString() + " no obsolete");
}
BEAST_EXPECTS(
(*it).isMember(jss::supported) && (*it)[jss::supported].asBool() == expectSupported,
(*it)[jss::name].asString() + " supported");
@@ -369,10 +386,17 @@ class Feature_test : public beast::unit_test::suite
(expectVeto || expectObsolete) ^ feature.isMember(jss::majority),
feature[jss::name].asString() + " majority");
BEAST_EXPECTS(
feature.isMember(jss::vetoed) && feature[jss::vetoed].isBool() == !expectObsolete &&
(!feature[jss::vetoed].isBool() || feature[jss::vetoed].asBool() == expectVeto) &&
(feature[jss::vetoed].isBool() || feature[jss::vetoed].asString() == "Obsolete"),
feature[jss::name].asString() + " vetoed");
feature.isMember(jss::vetoed) && feature[jss::vetoed].isBool(),
feature[jss::name].asString() + " vetoed is bool");
BEAST_EXPECTS(
feature[jss::vetoed].asBool() == (expectVeto || expectObsolete),
feature[jss::name].asString() + " vetoed value");
if (expectObsolete)
BEAST_EXPECTS(
feature.isMember(jss::obsolete) && feature[jss::obsolete].asBool() == true,
feature[jss::name].asString() + " obsolete");
else
BEAST_EXPECTS(!feature.isMember(jss::obsolete), feature[jss::name].asString() + " no obsolete");
BEAST_EXPECTS(feature.isMember(jss::count), feature[jss::name].asString() + " count");
BEAST_EXPECTS(feature.isMember(jss::threshold), feature[jss::name].asString() + " threshold");
BEAST_EXPECTS(feature.isMember(jss::validations), feature[jss::name].asString() + " validations");
@@ -460,7 +484,8 @@ class Feature_test : public beast::unit_test::suite
return;
auto feature = *(jrr.begin());
BEAST_EXPECTS(feature[jss::name] == featureName, "name");
BEAST_EXPECTS(feature[jss::vetoed].isString() && feature[jss::vetoed].asString() == "Obsolete", "vetoed");
BEAST_EXPECTS(feature[jss::vetoed].isBool() && feature[jss::vetoed].asBool() == true, "vetoed");
BEAST_EXPECTS(feature[jss::obsolete].isBool() && feature[jss::obsolete].asBool() == true, "obsolete");
jrr = env.rpc("feature", featureName, "reject")[jss::result];
if (!BEAST_EXPECTS(jrr[jss::status] == jss::success, "status"))
@@ -470,7 +495,8 @@ class Feature_test : public beast::unit_test::suite
return;
feature = *(jrr.begin());
BEAST_EXPECTS(feature[jss::name] == featureName, "name");
BEAST_EXPECTS(feature[jss::vetoed].isString() && feature[jss::vetoed].asString() == "Obsolete", "vetoed");
BEAST_EXPECTS(feature[jss::vetoed].isBool() && feature[jss::vetoed].asBool() == true, "vetoed");
BEAST_EXPECTS(feature[jss::obsolete].isBool() && feature[jss::obsolete].asBool() == true, "obsolete");
jrr = env.rpc("feature", featureName, "accept")[jss::result];
if (!BEAST_EXPECTS(jrr[jss::status] == jss::success, "status"))
@@ -480,7 +506,8 @@ class Feature_test : public beast::unit_test::suite
return;
feature = *(jrr.begin());
BEAST_EXPECTS(feature[jss::name] == featureName, "name");
BEAST_EXPECTS(feature[jss::vetoed].isString() && feature[jss::vetoed].asString() == "Obsolete", "vetoed");
BEAST_EXPECTS(feature[jss::vetoed].isBool() && feature[jss::vetoed].asBool() == true, "vetoed");
BEAST_EXPECTS(feature[jss::obsolete].isBool() && feature[jss::obsolete].asBool() == true, "obsolete");
// anything other than accept or reject is an error
jrr = env.rpc("feature", featureName, "maybe");

View File

@@ -903,7 +903,10 @@ AmendmentTableImpl::injectJson(
if (!fs.enabled && isAdmin)
{
if (fs.vote == AmendmentVote::obsolete)
v[jss::vetoed] = "Obsolete";
{
v[jss::vetoed] = true;
v[jss::obsolete] = true;
}
else
v[jss::vetoed] = fs.vote == AmendmentVote::down;
}