Files
rippled/src/libxrpl/telemetry/TxAccountSpanNames.cpp
Pratik Mankawde 509fc7853e feat(telemetry): Emit every account a transaction names on tx.process
A transaction names one or more accounts: the sender in Account, and by
type a Destination, Owner, Issuer, Holder and so on. tx.process now
carries each top-level account-typed field as its own attribute, keyed
tx_<field> in lower snake case (tx_account, tx_destination, ...), so an
account can be searched for in traces whatever role it played.
Addresses are public ledger identifiers and are emitted raw.

The keys live in TxAccountSpanNames.h in libxrpl, with a field-to-key
table in TxAccountSpanNames.cpp. A library test walks TxFormats and the
SField registry: every account field a transaction can carry has a key,
and no field that only ledger entries carry has one. An empty account
field is skipped rather than rendered as the zero address.
2026-09-23 18:01:14 +01:00

46 lines
2.0 KiB
C++

#include <xrpl/telemetry/TxAccountSpanNames.h>
#include <xrpl/protocol/SField.h>
#include <optional>
#include <string_view>
#include <unordered_map>
namespace xrpl::telemetry {
std::optional<std::string_view>
accountFieldAttributeKey(SField const& field)
{
// Built on first call, not at static initialisation: the sf* objects are
// globals in another translation unit, so their codes are only safe to
// read once main() has started.
static std::unordered_map<int, std::string_view> const kTable = {
{sfAccount.getCode(), tx_account_span::attr::account},
{sfDestination.getCode(), tx_account_span::attr::destination},
{sfOwner.getCode(), tx_account_span::attr::owner},
{sfIssuer.getCode(), tx_account_span::attr::issuer},
{sfAuthorize.getCode(), tx_account_span::attr::authorize},
{sfUnauthorize.getCode(), tx_account_span::attr::unauthorize},
{sfRegularKey.getCode(), tx_account_span::attr::regularKey},
{sfNFTokenMinter.getCode(), tx_account_span::attr::nftokenMinter},
{sfHolder.getCode(), tx_account_span::attr::holder},
{sfDelegate.getCode(), tx_account_span::attr::delegate},
{sfSponsor.getCode(), tx_account_span::attr::sponsor},
{sfSponsee.getCode(), tx_account_span::attr::sponsee},
{sfCounterparty.getCode(), tx_account_span::attr::counterparty},
{sfCounterpartySponsor.getCode(), tx_account_span::attr::counterpartySponsor},
{sfSubject.getCode(), tx_account_span::attr::subject},
{sfOtherChainSource.getCode(), tx_account_span::attr::otherChainSource},
{sfOtherChainDestination.getCode(), tx_account_span::attr::otherChainDestination},
{sfAttestationSignerAccount.getCode(), tx_account_span::attr::attestationSignerAccount},
{sfAttestationRewardAccount.getCode(), tx_account_span::attr::attestationRewardAccount},
};
auto const it = kTable.find(field.getCode());
if (it == kTable.end())
return std::nullopt;
return it->second;
}
} // namespace xrpl::telemetry