diff --git a/src/xrpld/rpc/handlers/account/AccountInfo.cpp b/src/xrpld/rpc/handlers/account/AccountInfo.cpp index 6b244af1a9..2276f98a0e 100644 --- a/src/xrpld/rpc/handlers/account/AccountInfo.cpp +++ b/src/xrpld/rpc/handlers/account/AccountInfo.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,7 @@ #include #include #include +#include #include namespace xrpl { @@ -115,29 +117,37 @@ doAccountInfo(rpc::JsonContext& context) } auto const accountID{id.value()}; - static constexpr std::array, 9> kLsFlags{ - {{"defaultRipple", lsfDefaultRipple}, - {"depositAuth", lsfDepositAuth}, - {"disableMasterKey", lsfDisableMaster}, - {"disallowIncomingXRP", lsfDisallowXRP}, - {"globalFreeze", lsfGlobalFreeze}, - {"noFreeze", lsfNoFreeze}, - {"passwordSpent", lsfPasswordSpent}, - {"requireAuthorization", lsfRequireAuth}, - {"requireDestinationTag", lsfRequireDestTag}}}; - - static constexpr std::array, 4> - kDisallowIncomingFlags{ - {{"disallowIncomingNFTokenOffer", lsfDisallowIncomingNFTokenOffer}, + // Flags that are always reported. + static constexpr auto kAccountRootFlags = + std::to_array>( + {{"allowTrustLineClawback", lsfAllowTrustLineClawback}, + {"defaultRipple", lsfDefaultRipple}, + {"depositAuth", lsfDepositAuth}, + {"disableMasterKey", lsfDisableMaster}, {"disallowIncomingCheck", lsfDisallowIncomingCheck}, + {"disallowIncomingNFTokenOffer", lsfDisallowIncomingNFTokenOffer}, {"disallowIncomingPayChan", lsfDisallowIncomingPayChan}, - {"disallowIncomingTrustline", lsfDisallowIncomingTrustline}}}; + {"disallowIncomingTrustline", lsfDisallowIncomingTrustline}, + {"disallowIncomingXRP", lsfDisallowXRP}, + {"globalFreeze", lsfGlobalFreeze}, + {"noFreeze", lsfNoFreeze}, + {"passwordSpent", lsfPasswordSpent}, + {"requireAuthorization", lsfRequireAuth}, + {"requireDestinationTag", lsfRequireDestTag}}); - static constexpr std::pair kAllowTrustLineClawbackFlag{ - "allowTrustLineClawback", lsfAllowTrustLineClawback}; + // Flags that are only reported when their amendment is enabled. This can't be `constexpr`, + // since the amendment IDs are computed at runtime. + static auto const kAmendmentGatedFlags = + std::to_array>( + {{"allowTrustLineLocking", lsfAllowTrustLineLocking, featureTokenEscrow}}); - static constexpr std::pair kAllowTrustLineLockingFlag{ - "allowTrustLineLocking", lsfAllowTrustLineLocking}; + // Every `AccountRoot` flag must be reported by `account_info`, so if a new flag is added, it + // needs to be added to one of the arrays above. This can't be a `static_assert` because + // `getAccountRootFlags()` builds its map at runtime. + XRPL_ASSERT_PARTS( + kAccountRootFlags.size() + kAmendmentGatedFlags.size() == getAccountRootFlags().size(), + "xrpl::doAccountInfo", + "number of account flags"); auto const sleAccepted = ledger->read(keylet::account(accountID)); if (sleAccepted) @@ -157,19 +167,13 @@ doAccountInfo(rpc::JsonContext& context) result[jss::account_data] = jvAccepted; json::Value acctFlags{json::ValueType::Object}; - for (auto const& lsf : kLsFlags) - acctFlags[lsf.first.data()] = sleAccepted->isFlag(lsf.second); + for (auto const& [name, flag] : kAccountRootFlags) + acctFlags[name.data()] = sleAccepted->isFlag(flag); - for (auto const& lsf : kDisallowIncomingFlags) - acctFlags[lsf.first.data()] = sleAccepted->isFlag(lsf.second); - - acctFlags[kAllowTrustLineClawbackFlag.first.data()] = - sleAccepted->isFlag(kAllowTrustLineClawbackFlag.second); - - if (ledger->rules().enabled(featureTokenEscrow)) + for (auto const& [name, flag, amendment] : kAmendmentGatedFlags) { - acctFlags[kAllowTrustLineLockingFlag.first.data()] = - sleAccepted->isFlag(kAllowTrustLineLockingFlag.second); + if (ledger->rules().enabled(amendment)) + acctFlags[name.data()] = sleAccepted->isFlag(flag); } result[jss::account_flags] = std::move(acctFlags);