Compare commits

...

1 Commits

Author SHA1 Message Date
Denis Angell
c7bfd6a7e1 feat: export ledger name spaces via server_definitions 2026-07-16 20:54:14 -04:00
6 changed files with 141 additions and 59 deletions

View File

@@ -17,11 +17,46 @@
#include <array>
#include <cstdint>
#include <functional>
#include <map>
#include <set>
#include <string>
#include <utility>
namespace xrpl {
/**
* Type-specific prefix for calculating ledger indices.
*
* The identifier for a given object within the ledger is calculated based
* on some object-specific parameters. To ensure that different types of
* objects have different indices, even if they happen to use the same set
* of parameters, we use "tagged hashing" by adding a type-specific prefix.
*
* The name spaces are listed in detail/ledger_name_spaces.macro.
*/
#pragma push_macro("LEDGER_NAME_SPACE")
#undef LEDGER_NAME_SPACE
#pragma push_macro("LEDGER_NAME_SPACE_DEPRECATED")
#undef LEDGER_NAME_SPACE_DEPRECATED
#define LEDGER_NAME_SPACE(name, value) name = (value),
#define LEDGER_NAME_SPACE_DEPRECATED(name, value) name [[deprecated]] = (value),
enum class LedgerNameSpace : std::uint16_t {
#include <xrpl/protocol/detail/ledger_name_spaces.macro>
};
#undef LEDGER_NAME_SPACE_DEPRECATED
#pragma pop_macro("LEDGER_NAME_SPACE_DEPRECATED")
#undef LEDGER_NAME_SPACE
#pragma pop_macro("LEDGER_NAME_SPACE")
/**
* The name->value map of active (non-deprecated) ledger name spaces.
*/
std::map<std::string, std::uint16_t> const&
ledgerNameSpaceMap();
class SeqProxy;
/**
* Keylet computation functions.

View File

@@ -0,0 +1,59 @@
#if !defined(LEDGER_NAME_SPACE)
#error "undefined macro: LEDGER_NAME_SPACE"
#endif
#if !defined(LEDGER_NAME_SPACE_DEPRECATED)
#error "undefined macro: LEDGER_NAME_SPACE_DEPRECATED"
#endif
// Active ledger name spaces.
//
// @note These values are part of the protocol and *CANNOT* be arbitrarily
// changed. If they were, on-ledger objects may no longer be able to
// be located or addressed.
//
// Additions to this list are OK, but changing existing entries to
// assign them a different values should never be needed.
//
// Entries that are removed should be moved to the deprecated list
// below to prevent accidental reuse.
LEDGER_NAME_SPACE(Account, 'a')
LEDGER_NAME_SPACE(DirNode, 'd')
LEDGER_NAME_SPACE(TrustLine, 'r')
LEDGER_NAME_SPACE(Offer, 'o')
LEDGER_NAME_SPACE(OwnerDir, 'O')
LEDGER_NAME_SPACE(BookDir, 'B')
LEDGER_NAME_SPACE(SkipList, 's')
LEDGER_NAME_SPACE(Escrow, 'u')
LEDGER_NAME_SPACE(Amendments, 'f')
LEDGER_NAME_SPACE(FeeSettings, 'e')
LEDGER_NAME_SPACE(Ticket, 'T')
LEDGER_NAME_SPACE(SignerList, 'S')
LEDGER_NAME_SPACE(XRPPaymentChannel, 'x')
LEDGER_NAME_SPACE(Check, 'C')
LEDGER_NAME_SPACE(DepositPreauth, 'p')
LEDGER_NAME_SPACE(DepositPreauthCredentials, 'P')
LEDGER_NAME_SPACE(NegativeUnl, 'N')
LEDGER_NAME_SPACE(NftokenOffer, 'q')
LEDGER_NAME_SPACE(NftokenBuyOffers, 'h')
LEDGER_NAME_SPACE(NftokenSellOffers, 'i')
LEDGER_NAME_SPACE(Amm, 'A')
LEDGER_NAME_SPACE(Bridge, 'H')
LEDGER_NAME_SPACE(XchainClaimId, 'Q')
LEDGER_NAME_SPACE(XchainCreateAccountClaimId, 'K')
LEDGER_NAME_SPACE(Did, 'I')
LEDGER_NAME_SPACE(Oracle, 'R')
LEDGER_NAME_SPACE(MPTokenIssuance, '~')
LEDGER_NAME_SPACE(MPToken, 't')
LEDGER_NAME_SPACE(Credential, 'D')
LEDGER_NAME_SPACE(PermissionedDomain, 'm')
LEDGER_NAME_SPACE(Delegate, 'E')
LEDGER_NAME_SPACE(Vault, 'V')
LEDGER_NAME_SPACE(LoanBroker, 'l') // lower-case L
LEDGER_NAME_SPACE(Loan, 'L')
LEDGER_NAME_SPACE(Sponsorship, '>')
// No longer used or supported. Left here to reserve the space to avoid
// accidental reuse, and intentionally not exported to clients.
LEDGER_NAME_SPACE_DEPRECATED(Contract, 'c')
LEDGER_NAME_SPACE_DEPRECATED(Generator, 'g')
LEDGER_NAME_SPACE_DEPRECATED(Nickname, 'n')

View File

@@ -350,6 +350,7 @@ JSS(LEDGER_ENTRY_TYPES); // out: RPC server_definitions
// matches definitions.json format
JSS(LEDGER_ENTRY_FLAGS); // out: RPC server_definitions
JSS(LEDGER_ENTRY_FORMATS); // out: RPC server_definitions
JSS(LEDGER_NAME_SPACES); // out: RPC server_definitions
JSS(levels); // LogLevels
JSS(limit); // in/out: AccountTx*, AccountOffers, AccountLines, AccountObjects
// in: LedgerData, BookOffers

View File

@@ -26,7 +26,9 @@
#include <array>
#include <cstdint>
#include <cstring>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <variant>
#include <vector>
@@ -50,66 +52,28 @@ std::array<KeyletDesc<AccountID const&>, 6> const kDirectAccountKeylets{
.includeInTests = true},
{.function = &keylet::did, .expectedLEName = jss::DID, .includeInTests = true}}};
/**
* Type-specific prefix for calculating ledger indices.
*
* The identifier for a given object within the ledger is calculated based
* on some object-specific parameters. To ensure that different types of
* objects have different indices, even if they happen to use the same set
* of parameters, we use "tagged hashing" by adding a type-specific prefix.
*
* @note These values are part of the protocol and *CANNOT* be arbitrarily
* changed. If they were, on-ledger objects may no longer be able to
* be located or addressed.
*
* Additions to this list are OK, but changing existing entries to
* assign them a different values should never be needed.
*
* Entries that are removed should be moved to the bottom of the enum
* and marked as [[deprecated]] to prevent accidental reuse.
*/
enum class LedgerNameSpace : std::uint16_t {
Account = 'a',
DirNode = 'd',
TrustLine = 'r',
Offer = 'o',
OwnerDir = 'O',
BookDir = 'B',
SkipList = 's',
Escrow = 'u',
Amendments = 'f',
FeeSettings = 'e',
Ticket = 'T',
SignerList = 'S',
XRPPaymentChannel = 'x',
Check = 'C',
DepositPreauth = 'p',
DepositPreauthCredentials = 'P',
NegativeUnl = 'N',
NftokenOffer = 'q',
NftokenBuyOffers = 'h',
NftokenSellOffers = 'i',
Amm = 'A',
Bridge = 'H',
XchainClaimId = 'Q',
XchainCreateAccountClaimId = 'K',
Did = 'I',
Oracle = 'R',
MPTokenIssuance = '~',
MPToken = 't',
Credential = 'D',
PermissionedDomain = 'm',
Delegate = 'E',
Vault = 'V',
LoanBroker = 'l', // lower-case L
Loan = 'L',
Sponsorship = '>',
std::map<std::string, std::uint16_t> const&
ledgerNameSpaceMap()
{
#pragma push_macro("LEDGER_NAME_SPACE")
#undef LEDGER_NAME_SPACE
#pragma push_macro("LEDGER_NAME_SPACE_DEPRECATED")
#undef LEDGER_NAME_SPACE_DEPRECATED
// No longer used or supported. Left here to reserve the space to avoid accidental reuse.
Contract [[deprecated]] = 'c',
Generator [[deprecated]] = 'g',
Nickname [[deprecated]] = 'n',
};
#define LEDGER_NAME_SPACE(name, value) {#name, static_cast<std::uint16_t>(LedgerNameSpace::name)},
#define LEDGER_NAME_SPACE_DEPRECATED(name, value)
static std::map<std::string, std::uint16_t> const kMap{
#include <xrpl/protocol/detail/ledger_name_spaces.macro>
};
#undef LEDGER_NAME_SPACE_DEPRECATED
#pragma pop_macro("LEDGER_NAME_SPACE_DEPRECATED")
#undef LEDGER_NAME_SPACE
#pragma pop_macro("LEDGER_NAME_SPACE")
return kMap;
}
template <class... Args>
static uint256

View File

@@ -31,6 +31,7 @@ public:
BEAST_EXPECT(result[jss::result][jss::status] == "success");
BEAST_EXPECT(result[jss::result].isMember(jss::FIELDS));
BEAST_EXPECT(result[jss::result].isMember(jss::LEDGER_ENTRY_TYPES));
BEAST_EXPECT(result[jss::result].isMember(jss::LEDGER_NAME_SPACES));
BEAST_EXPECT(result[jss::result].isMember(jss::TRANSACTION_RESULTS));
BEAST_EXPECT(result[jss::result].isMember(jss::TRANSACTION_TYPES));
BEAST_EXPECT(result[jss::result].isMember(jss::TYPES));
@@ -107,6 +108,18 @@ public:
BEAST_EXPECT(result[jss::result][jss::TRANSACTION_TYPES]["Payment"].asUInt() == 0);
BEAST_EXPECT(result[jss::result][jss::TYPES]["AccountID"].asUInt() == 8);
// test the properties of the LEDGER_NAME_SPACES section
{
json::Value const& nameSpaces = result[jss::result][jss::LEDGER_NAME_SPACES];
BEAST_EXPECT(nameSpaces["Account"].asUInt() == 97); // 'a'
BEAST_EXPECT(nameSpaces["Vault"].asUInt() == 86); // 'V'
// deprecated name spaces are not exported
BEAST_EXPECT(!nameSpaces.isMember("Contract"));
BEAST_EXPECT(!nameSpaces.isMember("Generator"));
BEAST_EXPECT(!nameSpaces.isMember("Nickname"));
}
// test the properties of the LEDGER_ENTRY_FLAGS section
{
BEAST_EXPECT(result[jss::result].isMember(jss::LEDGER_ENTRY_FLAGS));
@@ -441,6 +454,7 @@ public:
BEAST_EXPECT(!result[jss::result].isMember(jss::LEDGER_ENTRY_TYPES));
BEAST_EXPECT(!result[jss::result].isMember(jss::LEDGER_ENTRY_FLAGS));
BEAST_EXPECT(!result[jss::result].isMember(jss::LEDGER_ENTRY_FORMATS));
BEAST_EXPECT(!result[jss::result].isMember(jss::LEDGER_NAME_SPACES));
BEAST_EXPECT(!result[jss::result].isMember(jss::TRANSACTION_RESULTS));
BEAST_EXPECT(!result[jss::result].isMember(jss::TRANSACTION_TYPES));
BEAST_EXPECT(!result[jss::result].isMember(jss::TRANSACTION_FLAGS));
@@ -464,6 +478,7 @@ public:
BEAST_EXPECT(result[jss::result].isMember(jss::LEDGER_ENTRY_TYPES));
BEAST_EXPECT(result[jss::result].isMember(jss::LEDGER_ENTRY_FLAGS));
BEAST_EXPECT(result[jss::result].isMember(jss::LEDGER_ENTRY_FORMATS));
BEAST_EXPECT(result[jss::result].isMember(jss::LEDGER_NAME_SPACES));
BEAST_EXPECT(result[jss::result].isMember(jss::TRANSACTION_RESULTS));
BEAST_EXPECT(result[jss::result].isMember(jss::TRANSACTION_TYPES));
BEAST_EXPECT(result[jss::result].isMember(jss::TRANSACTION_FLAGS));
@@ -486,6 +501,7 @@ public:
jss::LEDGER_ENTRY_FLAGS,
jss::LEDGER_ENTRY_FORMATS,
jss::LEDGER_ENTRY_TYPES,
jss::LEDGER_NAME_SPACES,
jss::TRANSACTION_FLAGS,
jss::TRANSACTION_FORMATS,
jss::TRANSACTION_RESULTS,

View File

@@ -6,6 +6,7 @@
#include <xrpl/json/json_value.h>
#include <xrpl/json/json_writer.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/TER.h>
@@ -358,6 +359,12 @@ ServerDefinitions::ServerDefinitions() : defs_{json::ValueType::Object}
defs_[jss::ACCOUNT_SET_FLAGS][name] = value;
}
defs_[jss::LEDGER_NAME_SPACES] = json::ValueType::Object;
for (auto const& [name, value] : ledgerNameSpaceMap())
{
defs_[jss::LEDGER_NAME_SPACES][name] = value;
}
// generate hash
{
std::string const out = json::FastWriter().write(defs_);