xrpld
Loading...
Searching...
No Matches
TxFlags.h
1#pragma once
2
3// NOLINTBEGIN(readability-identifier-naming)
4
5#include <xrpl/protocol/LedgerFormats.h>
6
7#include <cstdint>
8#include <map>
9#include <string>
10#include <utility>
11#include <vector>
12
13namespace xrpl {
14
38
40
41// Universal Transaction flags:
42inline constexpr FlagValue tfFullyCanonicalSig = 0x80000000;
43inline constexpr FlagValue tfInnerBatchTxn = 0x40000000;
46
47#pragma push_macro("XMACRO")
48#pragma push_macro("TO_VALUE")
49#pragma push_macro("VALUE_TO_MAP")
50#pragma push_macro("NULL_NAME")
51#pragma push_macro("NULL_OUTPUT")
52#pragma push_macro("TO_MAP")
53#pragma push_macro("TO_MASK")
54#pragma push_macro("VALUE_TO_MASK")
55#pragma push_macro("ALL_TX_FLAGS")
56#pragma push_macro("NULL_MASK_ADJ")
57#pragma push_macro("MASK_ADJ_TO_MASK")
58
59#undef XMACRO
60#undef TO_VALUE
61#undef VALUE_TO_MAP
62#undef NULL_NAME
63#undef NULL_OUTPUT
64#undef TO_MAP
65#undef TO_MASK
66#undef VALUE_TO_MASK
67#undef NULL_MASK_ADJ
68#undef MASK_ADJ_TO_MASK
69
70// clang-format off
71#undef ALL_TX_FLAGS
72
73// XMACRO parameters:
74// - TRANSACTION: handles the transaction name, its flags, and mask adjustment
75// - TF_FLAG: defines a new flag constant
76// - TF_FLAG2: references an existing flag constant (no new definition)
77// - MASK_ADJ: specifies flags to add back to the mask (making them invalid for this tx type)
78//
79// Note: MASK_ADJ is used when a universal flag should be invalid for a specific transaction.
80// For example, Batch uses MASK_ADJ(tfInnerBatchTxn) because the outer Batch transaction
81// must not have tfInnerBatchTxn set (only inner transactions should have it).
82//
83// TODO: Consider rewriting this using reflection in C++26 or later. Alternatively this could be a DSL processed by a script at build time.
84#define XMACRO(TRANSACTION, TF_FLAG, TF_FLAG2, MASK_ADJ) \
85 TRANSACTION(AccountSet, \
86 TF_FLAG(tfRequireDestTag, 0x00010000) \
87 TF_FLAG(tfOptionalDestTag, 0x00020000) \
88 TF_FLAG(tfRequireAuth, 0x00040000) \
89 TF_FLAG(tfOptionalAuth, 0x00080000) \
90 TF_FLAG(tfDisallowXRP, 0x00100000) \
91 TF_FLAG(tfAllowXRP, 0x00200000), \
92 MASK_ADJ(0)) \
93 \
94 TRANSACTION(OfferCreate, \
95 TF_FLAG(tfPassive, 0x00010000) \
96 TF_FLAG(tfImmediateOrCancel, 0x00020000) \
97 TF_FLAG(tfFillOrKill, 0x00040000) \
98 TF_FLAG(tfSell, 0x00080000) \
99 TF_FLAG(tfHybrid, 0x00100000), \
100 MASK_ADJ(0)) \
101 \
102 TRANSACTION(Payment, \
103 TF_FLAG(tfNoRippleDirect, 0x00010000) \
104 TF_FLAG(tfPartialPayment, 0x00020000) \
105 TF_FLAG(tfLimitQuality, 0x00040000), \
106 MASK_ADJ(0)) \
107 \
108 TRANSACTION(TrustSet, \
109 TF_FLAG(tfSetfAuth, 0x00010000) \
110 TF_FLAG(tfSetNoRipple, 0x00020000) \
111 TF_FLAG(tfClearNoRipple, 0x00040000) \
112 TF_FLAG(tfSetFreeze, 0x00100000) \
113 TF_FLAG(tfClearFreeze, 0x00200000) \
114 TF_FLAG(tfSetDeepFreeze, 0x00400000) \
115 TF_FLAG(tfClearDeepFreeze, 0x00800000), \
116 MASK_ADJ(0)) \
117 \
118 TRANSACTION(EnableAmendment, \
119 TF_FLAG(tfGotMajority, 0x00010000) \
120 TF_FLAG(tfLostMajority, 0x00020000), \
121 MASK_ADJ(0)) \
122 \
123 TRANSACTION(PaymentChannelClaim, \
124 TF_FLAG(tfRenew, 0x00010000) \
125 TF_FLAG(tfClose, 0x00020000), \
126 MASK_ADJ(0)) \
127 \
128 TRANSACTION(NFTokenMint, \
129 TF_FLAG(tfBurnable, 0x00000001) \
130 TF_FLAG(tfOnlyXRP, 0x00000002) \
131 /* deprecated TF_FLAG(tfTrustLine, 0x00000004) */ \
132 TF_FLAG(tfTransferable, 0x00000008) \
133 TF_FLAG(tfMutable, 0x00000010), \
134 MASK_ADJ(0)) \
135 \
136 TRANSACTION(MPTokenIssuanceCreate, \
137 /* Note: tf/lsfMPTLocked is intentionally omitted since this transaction is not allowed to modify it. */ \
138 TF_FLAG(tfMPTCanLock, lsfMPTCanLock) \
139 TF_FLAG(tfMPTRequireAuth, lsfMPTRequireAuth) \
140 TF_FLAG(tfMPTCanEscrow, lsfMPTCanEscrow) \
141 TF_FLAG(tfMPTCanTrade, lsfMPTCanTrade) \
142 TF_FLAG(tfMPTCanTransfer, lsfMPTCanTransfer) \
143 TF_FLAG(tfMPTCanClawback, lsfMPTCanClawback) \
144 TF_FLAG(tfMPTCanHoldConfidentialBalance, lsfMPTCanHoldConfidentialBalance), \
145 MASK_ADJ(0)) \
146 \
147 TRANSACTION(MPTokenAuthorize, \
148 TF_FLAG(tfMPTUnauthorize, 0x00000001), \
149 MASK_ADJ(0)) \
150 \
151 TRANSACTION(MPTokenIssuanceSet, \
152 TF_FLAG(tfMPTLock, 0x00000001) \
153 TF_FLAG(tfMPTUnlock, 0x00000002), \
154 MASK_ADJ(0)) \
155 \
156 TRANSACTION(NFTokenCreateOffer, \
157 TF_FLAG(tfSellNFToken, 0x00000001), \
158 MASK_ADJ(0)) \
159 \
160 TRANSACTION(AMMDeposit, \
161 TF_FLAG(tfLPToken, 0x00010000) \
162 TF_FLAG(tfSingleAsset, 0x00080000) \
163 TF_FLAG(tfTwoAsset, 0x00100000) \
164 TF_FLAG(tfOneAssetLPToken, 0x00200000) \
165 TF_FLAG(tfLimitLPToken, 0x00400000) \
166 TF_FLAG(tfTwoAssetIfEmpty, 0x00800000), \
167 MASK_ADJ(0)) \
168 \
169 TRANSACTION(AMMWithdraw, \
170 TF_FLAG2(tfLPToken, 0x00010000) \
171 TF_FLAG(tfWithdrawAll, 0x00020000) \
172 TF_FLAG(tfOneAssetWithdrawAll, 0x00040000) \
173 TF_FLAG2(tfSingleAsset, 0x00080000) \
174 TF_FLAG2(tfTwoAsset, 0x00100000) \
175 TF_FLAG2(tfOneAssetLPToken, 0x00200000) \
176 TF_FLAG2(tfLimitLPToken, 0x00400000), \
177 MASK_ADJ(0)) \
178 \
179 TRANSACTION(AMMClawback, \
180 TF_FLAG(tfClawTwoAssets, 0x00000001), \
181 MASK_ADJ(0)) \
182 \
183 TRANSACTION(XChainModifyBridge, \
184 TF_FLAG(tfClearAccountCreateAmount, 0x00010000), \
185 MASK_ADJ(0)) \
186 \
187 TRANSACTION(VaultCreate, \
188 TF_FLAG(tfVaultPrivate, lsfVaultPrivate) \
189 TF_FLAG(tfVaultShareNonTransferable, 0x00020000), \
190 MASK_ADJ(0)) \
191 \
192 TRANSACTION(Batch, \
193 TF_FLAG(tfAllOrNothing, 0x00010000) \
194 TF_FLAG(tfOnlyOne, 0x00020000) \
195 TF_FLAG(tfUntilFailure, 0x00040000) \
196 TF_FLAG(tfIndependent, 0x00080000), \
197 MASK_ADJ(tfInnerBatchTxn)) /* Batch must reject tfInnerBatchTxn - only inner transactions should have this flag */ \
198 \
199 TRANSACTION(LoanSet, /* True indicates the loan supports overpayments */ \
200 TF_FLAG(tfLoanOverpayment, 0x00010000), \
201 MASK_ADJ(0)) \
202 \
203 TRANSACTION(LoanPay, /* True indicates any excess in this payment can be used as an overpayment. */ \
204 /* False: no overpayments will be taken. */ \
205 TF_FLAG2(tfLoanOverpayment, 0x00010000) \
206 TF_FLAG(tfLoanFullPayment, 0x00020000) /* True indicates that the payment is an early full payment. */ \
207 /* It must pay the entire loan including close interest and fees, or it will fail. */ \
208 /* False: Not a full payment. */ \
209 TF_FLAG(tfLoanLatePayment, 0x00040000), /* True indicates that the payment is late, and includes late interest and fees. */ \
210 /* If the loan is not late, it will fail. */ \
211 /* False: not a late payment. If the current payment is overdue, the transaction will fail.*/ \
212 MASK_ADJ(0)) \
213 \
214 TRANSACTION(LoanManage, \
215 TF_FLAG(tfLoanDefault, 0x00010000) \
216 TF_FLAG(tfLoanImpair, 0x00020000) \
217 TF_FLAG(tfLoanUnimpair, 0x00040000), \
218 MASK_ADJ(0))
219
220// clang-format on
221
222// Create all the flag values.
223//
224// example:
225// inline constexpr FlagValue tfAccountSetRequireDestTag = 0x00010000;
226#define TO_VALUE(name, value) inline constexpr FlagValue name = value;
227#define NULL_NAME(name, values, maskAdj) values
228#define NULL_OUTPUT(name, value)
229#define NULL_MASK_ADJ(value)
230XMACRO(NULL_NAME, TO_VALUE, NULL_OUTPUT, NULL_MASK_ADJ)
231
232// Create masks for each transaction type that has flags.
233//
234// example:
235// inline constexpr FlagValue tfAccountSetMask = ~(tfUniversal | tfRequireDestTag |
236// tfOptionalDestTag | tfRequireAuth | tfOptionalAuth | tfDisallowXRP | tfAllowXRP);
237//
238// The mask adjustment (maskAdj) allows adding flags back to the mask, making them invalid.
239// For example, Batch uses MASK_ADJ(tfInnerBatchTxn) to reject tfInnerBatchTxn on outer Batch.
240#define TO_MASK(name, values, maskAdj) \
241 inline constexpr FlagValue tf##name##Mask = ~(tfUniversal values) | (maskAdj);
242#define VALUE_TO_MASK(name, value) | name
243#define MASK_ADJ_TO_MASK(value) value
244XMACRO(TO_MASK, VALUE_TO_MASK, VALUE_TO_MASK, MASK_ADJ_TO_MASK)
245
246// Verify that tfBatchMask correctly rejects tfInnerBatchTxn.
247// The outer Batch transaction must NOT have tfInnerBatchTxn set; only inner transactions should
248// have it.
249static_assert(
250 (tfBatchMask & tfInnerBatchTxn) == tfInnerBatchTxn,
251 "tfBatchMask must include tfInnerBatchTxn to reject it on outer Batch");
252
253// Verify that other transaction masks correctly allow tfInnerBatchTxn.
254// Inner transactions need tfInnerBatchTxn to be valid, so these masks must not reject it.
255static_assert(
256 (tfPaymentMask & tfInnerBatchTxn) == 0,
257 "tfPaymentMask must not reject tfInnerBatchTxn");
258static_assert(
259 (tfAccountSetMask & tfInnerBatchTxn) == 0,
260 "tfAccountSetMask must not reject tfInnerBatchTxn");
261
262// Create getter functions for each set of flags using Meyer's singleton pattern.
263// This avoids static initialization order fiasco while still providing efficient access.
264// This is used below in `getAllTxFlags()` to generate the server_definitions RPC
265// output.
266//
267// example:
268// inline FlagMap const& getAccountSetFlags() {
269// static FlagMap const flags = {
270// {"tfRequireDestTag", 0x00010000},
271// {"tfOptionalDestTag", 0x00020000},
272// ...};
273// return flags;
274// }
276#define VALUE_TO_MAP(name, value) {#name, value},
277#define TO_MAP(name, values, maskAdj) \
278 inline FlagMap const& get##name##Flags() \
279 { \
280 static FlagMap const flags = {values}; \
281 return flags; \
282 }
283XMACRO(TO_MAP, VALUE_TO_MAP, VALUE_TO_MAP, NULL_MASK_ADJ)
284
285inline FlagMap const&
287{
288 static FlagMap const flags = {
289 {"tfFullyCanonicalSig", tfFullyCanonicalSig}, {"tfInnerBatchTxn", tfInnerBatchTxn}};
290 return flags;
291}
292
293// Create a getter function for all transaction flag maps using Meyer's singleton pattern.
294// This is used to generate the server_definitions RPC output.
295//
296// example:
297// inline FlagMapPairList const& getAllTxFlags() {
298// static FlagMapPairList const flags = {
299// {"AccountSet", getAccountSetFlags()},
300// ...};
301// return flags;
302// }
304#define ALL_TX_FLAGS(name, values, maskAdj) {#name, get##name##Flags()},
305inline FlagMapPairList const&
307{
308 static FlagMapPairList const flags = {
309 {"universal", getUniversalFlags()},
310 XMACRO(ALL_TX_FLAGS, NULL_OUTPUT, NULL_OUTPUT, NULL_MASK_ADJ)};
311 return flags;
312}
313
314#undef XMACRO
315#undef TO_VALUE
316#undef VALUE_TO_MAP
317#undef NULL_NAME
318#undef NULL_OUTPUT
319#undef TO_MAP
320#undef TO_MASK
321#undef VALUE_TO_MASK
322#undef ALL_TX_FLAGS
323#undef NULL_MASK_ADJ
324#undef MASK_ADJ_TO_MASK
325
326#pragma pop_macro("XMACRO")
327#pragma pop_macro("TO_VALUE")
328#pragma pop_macro("VALUE_TO_MAP")
329#pragma pop_macro("NULL_NAME")
330#pragma pop_macro("NULL_OUTPUT")
331#pragma pop_macro("TO_MAP")
332#pragma pop_macro("TO_MASK")
333#pragma pop_macro("VALUE_TO_MASK")
334#pragma pop_macro("ALL_TX_FLAGS")
335#pragma pop_macro("NULL_MASK_ADJ")
336#pragma pop_macro("MASK_ADJ_TO_MASK")
337
338// Additional transaction masks and combos
339inline constexpr FlagValue tfMPTPaymentMask = ~(tfUniversal | tfPartialPayment);
341 ~(tfUniversal | tfSetfAuth | tfSetFreeze | tfClearFreeze);
342
343// MPTokenIssuanceCreate MutableFlags:
344// Indicating specific fields or flags may be changed after issuance.
345inline constexpr FlagValue tmfMPTCanEnableCanLock = lsmfMPTCanEnableCanLock;
346inline constexpr FlagValue tmfMPTCanEnableRequireAuth = lsmfMPTCanEnableRequireAuth;
347inline constexpr FlagValue tmfMPTCanEnableCanEscrow = lsmfMPTCanEnableCanEscrow;
348inline constexpr FlagValue tmfMPTCanEnableCanTrade = lsmfMPTCanEnableCanTrade;
349inline constexpr FlagValue tmfMPTCanEnableCanTransfer = lsmfMPTCanEnableCanTransfer;
350inline constexpr FlagValue tmfMPTCanEnableCanClawback = lsmfMPTCanEnableCanClawback;
351inline constexpr FlagValue tmfMPTCanMutateMetadata = lsmfMPTCanMutateMetadata;
352inline constexpr FlagValue tmfMPTCanMutateTransferFee = lsmfMPTCanMutateTransferFee;
354 lsmfMPTCannotEnableCanHoldConfidentialBalance;
360
361// MPTokenIssuanceSet MutableFlags:
362// Enable mutable capability flags. These flags are one-way: once enabled,
363// the corresponding capability cannot be disabled by MPTokenIssuanceSet.
364
365inline constexpr FlagValue tmfMPTSetCanLock = 0x00000001;
366inline constexpr FlagValue tmfMPTSetRequireAuth = 0x00000002;
367inline constexpr FlagValue tmfMPTSetCanEscrow = 0x00000004;
368inline constexpr FlagValue tmfMPTSetCanTrade = 0x00000008;
369inline constexpr FlagValue tmfMPTSetCanTransfer = 0x00000010;
370inline constexpr FlagValue tmfMPTSetCanClawback = 0x00000020;
371inline constexpr FlagValue tmfMPTSetCanHoldConfidentialBalance = 0x00000040;
375
376// Prior to fixRemoveNFTokenAutoTrustLine, transfer of an NFToken between accounts allowed a
377// TrustLine to be added to the issuer of that token without explicit permission from that issuer.
378// This was enabled by minting the NFToken with the tfTrustLine flag set.
379//
380// That capability could be used to attack the NFToken issuer.
381// It would be possible for two accounts to trade the NFToken back and forth building up any number
382// of TrustLines on the issuer, increasing the issuer's reserve without bound.
383//
384// The fixRemoveNFTokenAutoTrustLine amendment disables minting with the tfTrustLine flag as a way
385// to prevent the attack. But until the amendment passes we still need to keep the old behavior
386// available.
387inline constexpr FlagValue tfTrustLine = 0x00000004; // needed for backwards compatibility
389 ~(tfUniversal | tfBurnable | tfOnlyXRP | tfTransferable);
390
392
393// if featureDynamicNFT enabled then new flag allowing mutable URI available.
395
396inline constexpr FlagValue tfWithdrawSubTx = tfLPToken | tfSingleAsset | tfTwoAsset |
397 tfOneAssetLPToken | tfLimitLPToken | tfWithdrawAll | tfOneAssetWithdrawAll;
398inline constexpr FlagValue tfDepositSubTx =
399 tfLPToken | tfSingleAsset | tfTwoAsset | tfOneAssetLPToken | tfLimitLPToken | tfTwoAssetIfEmpty;
400
401#pragma push_macro("ACCOUNTSET_FLAGS")
402#pragma push_macro("ACCOUNTSET_FLAG_TO_VALUE")
403#pragma push_macro("ACCOUNTSET_FLAG_TO_MAP")
404
405// AccountSet SetFlag/ClearFlag values
406#define ACCOUNTSET_FLAGS(ASF_FLAG) \
407 ASF_FLAG(asfRequireDest, 1) \
408 ASF_FLAG(asfRequireAuth, 2) \
409 ASF_FLAG(asfDisallowXRP, 3) \
410 ASF_FLAG(asfDisableMaster, 4) \
411 ASF_FLAG(asfAccountTxnID, 5) \
412 ASF_FLAG(asfNoFreeze, 6) \
413 ASF_FLAG(asfGlobalFreeze, 7) \
414 ASF_FLAG(asfDefaultRipple, 8) \
415 ASF_FLAG(asfDepositAuth, 9) \
416 ASF_FLAG(asfAuthorizedNFTokenMinter, 10) \
417 /* 11 is reserved for Hooks amendment */ \
418 /* ASF_FLAG(asfTshCollect, 11) */ \
419 ASF_FLAG(asfDisallowIncomingNFTokenOffer, 12) \
420 ASF_FLAG(asfDisallowIncomingCheck, 13) \
421 ASF_FLAG(asfDisallowIncomingPayChan, 14) \
422 ASF_FLAG(asfDisallowIncomingTrustline, 15) \
423 ASF_FLAG(asfAllowTrustLineClawback, 16) \
424 ASF_FLAG(asfAllowTrustLineLocking, 17)
425
426#define ACCOUNTSET_FLAG_TO_VALUE(name, value) inline constexpr FlagValue name = value;
427#define ACCOUNTSET_FLAG_TO_MAP(name, value) {#name, value},
428
429ACCOUNTSET_FLAGS(ACCOUNTSET_FLAG_TO_VALUE)
430
433{
434 static std::map<std::string, FlagValue> const flags = {
435 ACCOUNTSET_FLAGS(ACCOUNTSET_FLAG_TO_MAP)};
436 return flags;
437}
438
439#undef ACCOUNTSET_FLAG_TO_VALUE
440#undef ACCOUNTSET_FLAG_TO_MAP
441#undef ACCOUNTSET_FLAGS
442
443#pragma pop_macro("ACCOUNTSET_FLAG_TO_VALUE")
444#pragma pop_macro("ACCOUNTSET_FLAG_TO_MAP")
445#pragma pop_macro("ACCOUNTSET_FLAGS")
446
447} // namespace xrpl
448
449// NOLINTEND(readability-identifier-naming)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
constexpr FlagValue tmfMPTCanEnableCanClawback
Definition TxFlags.h:350
constexpr FlagValue tmfMPTCanEnableCanTransfer
Definition TxFlags.h:349
constexpr FlagValue tfInnerBatchTxn
Definition TxFlags.h:43
constexpr FlagValue tmfMPTSetCanLock
Definition TxFlags.h:365
constexpr FlagValue tmfMPTSetCanClawback
Definition TxFlags.h:370
std::uint32_t FlagValue
Transaction flags.
Definition TxFlags.h:39
constexpr FlagValue tmfMPTCannotEnableCanHoldConfidentialBalance
Definition TxFlags.h:353
constexpr FlagValue tmfMPTokenIssuanceCreateMutableMask
Definition TxFlags.h:355
constexpr FlagValue tfDepositSubTx
Definition TxFlags.h:398
constexpr FlagValue tfTrustLine
Definition TxFlags.h:387
constexpr FlagValue tfNFTokenMintMaskWithoutMutable
Definition TxFlags.h:388
constexpr FlagValue tmfMPTSetCanHoldConfidentialBalance
Definition TxFlags.h:371
constexpr FlagValue tfNFTokenMintOldMaskWithMutable
Definition TxFlags.h:394
constexpr FlagValue tmfMPTCanEnableCanLock
Definition TxFlags.h:345
constexpr FlagValue tmfMPTSetCanTrade
Definition TxFlags.h:368
constexpr FlagValue tfTrustSetPermissionMask
Definition TxFlags.h:340
std::vector< std::pair< std::string, FlagMap > > FlagMapPairList
Definition TxFlags.h:303
constexpr FlagValue tfUniversal
Definition TxFlags.h:44
constexpr FlagValue tmfMPTSetCanTransfer
Definition TxFlags.h:369
constexpr FlagValue tmfMPTSetCanEscrow
Definition TxFlags.h:367
constexpr FlagValue tfMPTPaymentMask
Definition TxFlags.h:339
FlagMap const & getUniversalFlags()
Definition TxFlags.h:286
FlagMapPairList const & getAllTxFlags()
Definition TxFlags.h:306
constexpr FlagValue tmfMPTCanMutateMetadata
Definition TxFlags.h:351
constexpr FlagValue tmfMPTokenIssuanceSetMutableMask
Definition TxFlags.h:372
constexpr FlagValue tfNFTokenMintOldMask
Definition TxFlags.h:391
constexpr FlagValue tmfMPTCanMutateTransferFee
Definition TxFlags.h:352
std::map< std::string, FlagValue > FlagMap
Definition TxFlags.h:275
constexpr FlagValue tmfMPTCanEnableRequireAuth
Definition TxFlags.h:346
constexpr FlagValue tmfMPTCanEnableCanEscrow
Definition TxFlags.h:347
constexpr FlagValue tmfMPTCanEnableCanTrade
Definition TxFlags.h:348
std::map< std::string, FlagValue > const & getAsfFlagMap()
Definition TxFlags.h:432
constexpr FlagValue tfWithdrawSubTx
Definition TxFlags.h:396
constexpr FlagValue tfUniversalMask
Definition TxFlags.h:45
constexpr FlagValue tfFullyCanonicalSig
Definition TxFlags.h:42
constexpr FlagValue tmfMPTSetRequireAuth
Definition TxFlags.h:366