rippled
Loading...
Searching...
No Matches
CTID.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2019 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_RPC_CTID_H_INCLUDED
21#define RIPPLE_RPC_CTID_H_INCLUDED
22
23#include <boost/regex.hpp>
24
25#include <optional>
26#include <regex>
27#include <sstream>
28
29namespace ripple {
30
31namespace RPC {
32
33// CTID stands for Concise Transaction ID.
34//
35// The CTID comes from XLS-15d: Concise Transaction Identifier #34
36//
37// https://github.com/XRPLF/XRPL-Standards/discussions/34
38//
39// The Concise Transaction ID provides a way to identify a transaction
40// that includes which network the transaction was submitted to.
41
53encodeCTID(uint32_t ledgerSeq, uint32_t txnIndex, uint32_t networkID) noexcept
54{
55 constexpr uint32_t maxLedgerSeq = 0x0FFF'FFFF;
56 constexpr uint32_t maxTxnIndex = 0xFFFF;
57 constexpr uint32_t maxNetworkID = 0xFFFF;
58
59 if (ledgerSeq > maxLedgerSeq || txnIndex > maxTxnIndex ||
60 networkID > maxNetworkID)
61 return std::nullopt;
62
63 uint64_t ctidValue =
64 ((0xC000'0000ULL + static_cast<uint64_t>(ledgerSeq)) << 32) |
65 ((static_cast<uint64_t>(txnIndex) << 16) | networkID);
66
67 std::stringstream buffer;
68 buffer << std::hex << std::uppercase << std::setfill('0') << std::setw(16)
69 << ctidValue;
70 return buffer.str();
71}
72
81template <typename T>
83decodeCTID(T const ctid) noexcept
84{
85 uint64_t ctidValue = 0;
86
87 if constexpr (
90 {
91 std::string const ctidString(ctid);
92
93 if (ctidString.size() != 16)
94 return std::nullopt;
95
96 static boost::regex const hexRegex("^[0-9A-Fa-f]{16}$");
97 if (!boost::regex_match(ctidString, hexRegex))
98 return std::nullopt;
99
100 try
101 {
102 ctidValue = std::stoull(ctidString, nullptr, 16);
103 }
104 // LCOV_EXCL_START
105 catch (...)
106 {
107 // should be impossible to hit given the length/regex check
108 return std::nullopt;
109 }
110 // LCOV_EXCL_STOP
111 }
112 else if constexpr (std::is_integral_v<T>)
113 {
114 ctidValue = static_cast<uint64_t>(ctid);
115 }
116 else
117 {
118 return std::nullopt;
119 }
120
121 // Validate CTID prefix.
122 constexpr uint64_t ctidPrefixMask = 0xF000'0000'0000'0000ULL;
123 constexpr uint64_t ctidPrefix = 0xC000'0000'0000'0000ULL;
124 if ((ctidValue & ctidPrefixMask) != ctidPrefix)
125 return std::nullopt;
126
127 uint32_t ledgerSeq = static_cast<uint32_t>((ctidValue >> 32) & 0x0FFF'FFFF);
128 uint16_t txnIndex = static_cast<uint16_t>((ctidValue >> 16) & 0xFFFF);
129 uint16_t networkID = static_cast<uint16_t>(ctidValue & 0xFFFF);
130
131 return std::make_tuple(ledgerSeq, txnIndex, networkID);
132}
133
134} // namespace RPC
135} // namespace ripple
136
137#endif
T hex(T... args)
T is_same_v
T make_tuple(T... args)
std::optional< std::string > encodeCTID(uint32_t ledgerSeq, uint32_t txnIndex, uint32_t networkID) noexcept
Encodes ledger sequence, transaction index, and network ID into a CTID string.
Definition CTID.h:53
std::optional< std::tuple< uint32_t, uint16_t, uint16_t > > decodeCTID(T const ctid) noexcept
Decodes a CTID string or integer into its component parts.
Definition CTID.h:83
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
T setfill(T... args)
T setw(T... args)
T size(T... args)
T stoull(T... args)
T str(T... args)
T uppercase(T... args)