Compare commits

..

286 Commits

Author SHA1 Message Date
Ed Hennis
b3c23de0ad fixup! Implement LoanPay (untested) 2025-05-08 10:48:23 -04:00
Ed Hennis
cc8d36892a Implement LoanPay (untested)
- Also fix the case of the names of the new Lending helper functions.
- Also add an XRPL_ASSERT2, which splits the parts of the assert message
  so I don't have to remember the proper formatting.
2025-05-07 23:44:13 -04:00
Ed Hennis
37f365a053 Start implementing LoanPay transaction 2025-05-07 18:01:59 -04:00
Ed Hennis
f2b78454da fixup! Implement LoanDraw, and made good progress on related tests 2025-05-07 12:31:04 -04:00
Ed Hennis
ba63f8d99f Implement LoanDraw, and made good progress on related tests 2025-05-07 12:31:04 -04:00
Ed Hennis
27fb4c1b08 refactor: Define getFlagsMask in the base Transactor class
- Returns tfUniversalMask for most transactors
- Only transactors that use other flags need to override
2025-05-07 12:31:04 -04:00
Ed Hennis
7ff2f58a98 fixup! Update to match latest spec: compute interest, LoanBroker reserves 2025-05-07 12:31:03 -04:00
Ed Hennis
ee8643f533 Restructure the LendingHelpers files 2025-05-07 12:31:03 -04:00
Ed Hennis
bcece6d680 Update to match latest spec: compute interest, LoanBroker reserves 2025-05-07 12:31:03 -04:00
Ed Hennis
f2178a38f3 Fix clang build error 2025-05-07 12:31:03 -04:00
Ed Hennis
9a86602417 Implement LoanDelete, and fix a bunch of math errors in LoanManage 2025-05-07 12:31:03 -04:00
Ed Hennis
b5c1301f78 Allow existing trust lines to loan brokers to be managed (by issuer) 2025-05-07 12:31:03 -04:00
Ed Hennis
3d01829a16 fixup! Fix a couple of conversions in tests that were lost in recent rebase 2025-05-07 12:31:03 -04:00
Ed Hennis
5295f47999 Finish LoanManage functionality and tests, modulo LoanDraw/Pay 2025-05-07 12:31:02 -04:00
Ed Hennis
ef2a0edc67 Start implementing LoanManage transaction (untested)
- Also add a ValidLoan invariant
2025-05-07 12:31:02 -04:00
Ed Hennis
71de1a0d93 Refactor issuance validity check in VaultCreate
- Utility function: canAddHolding
- Call canAddHolding from any transactor that call addEmptyHolding
  (LoanBrokerSet, LoanSet)
2025-05-07 12:30:59 -04:00
Ed Hennis
c3d420e49e Fix a couple of conversions in tests that were lost in recent rebase 2025-05-07 12:11:56 -04:00
Ed Hennis
196b08fc72 Add unit tests to create a Loan successfully
- Fix a few field initializations in LoanSet
2025-05-07 12:11:56 -04:00
Ed Hennis
2013e7e64d Remove the new TenthBips serialized type
- It was a neat idea, but more trouble than it's worth. The conversion
  functions are sufficient for what I need.
- Partially reverts
  - d7357d3eca0b70c36b5665fdf23ee5e7a3cea0d7
  - cbb4dbcbe7023cb8a8d30f0e794acf9d1d9a458a
  - 396b981fc0da0d2d248b8c68bd3fac68c5f0b64c
2025-05-07 12:11:56 -04:00
Ed Hennis
ceeb11aee0 Ensure that an account is not deleted with a non-zero owner count
- Updates the AccountRootsDeletedClean invariant
2025-05-07 12:11:56 -04:00
Ed Hennis
b97811d45c Change Loan object indexing, fix several broken LoanSet unit tests
- Loan objects will now only be indexed by LoanBrokerID and
  LoanSequence, which is a new field in LoanBroker. Also changes
  Loan.Sequence to Loan.LoanSequence to match up.
- Several tests weren't working because of `PrettyAsset` scaling. Also,
  `PrettyAsset` calculations could overflow. Made that less likely by
  changing the type of `scale_`.
- LoanSet will fail if an account tries to loan to itself.
2025-05-07 12:11:55 -04:00
Ed Hennis
01538ef108 Fix build errors 2025-05-07 12:11:55 -04:00
Ed Hennis
70155a5ac2 Add more LoanSet unit tests, added LoanBroker LoanSequence field
- LoanSequence will prevent loan key collisions
2025-05-07 12:11:55 -04:00
Ed Hennis
0a4c0a555d Get Counterparty signing working 2025-05-07 12:11:55 -04:00
Ed Hennis
7823c8b186 Start writing Loan tests
- Required adding support for counterparty signature to jtx framework:
  arbitrary signature field destination, multiple signer callbacks
2025-05-07 12:11:55 -04:00
Ed Hennis
d6353e593f Get arithmetic operators working for typed-values 2025-05-07 12:11:55 -04:00
Ed Hennis
c3fef1b9ad Get that strong Bips field type working (mostly) 2025-05-07 12:11:54 -04:00
Ed Hennis
a5376c7d76 [WIP] Turns out that adding a new serialized type is harder than it looks 2025-05-07 12:11:54 -04:00
Ed Hennis
939d3d4446 Fix formatting 2025-05-07 12:11:54 -04:00
Ed Hennis
89f0b3b9e4 [WIP] Continue implementing LoanSet Transactor
- Needs tests
- Started trying to add strong typing to the fields used as bips or 1/10
  bips.
2025-05-07 12:11:54 -04:00
Ed Hennis
cbb14627ea Generalize the check*Sign functions to support CounterParty
- checkSign, checkSingleSign, and checkMultiSign in STTx and Transactor
2025-05-07 12:11:54 -04:00
Ed Hennis
5bed1d94e6 [WIP] Start implementing LoanSet transactor
- Add some more values and functions to make it easier to work with
  basis point values / bips.
- Fix several earlier mistakes.
2025-05-07 12:11:54 -04:00
Ed Hennis
a01ce0ad00 Fix a couple of cross-platform build errors 2025-05-07 12:11:54 -04:00
Ed Hennis
327d576d7e Move inclusion of Transactor headers to transactions.macro
- Only need to update in one place when adding a new transaction.
2025-05-07 12:11:53 -04:00
Ed Hennis
4326b5941c Finish up the Loan Broker tests 2025-05-07 12:11:53 -04:00
Ed Hennis
1798be0ba9 Ensure that an account is not deleted with an XRP balance
- Updates the AccountRootsDeletedClean invariant
2025-05-07 12:11:53 -04:00
Ed Hennis
56ff345a99 Add Asset and MPTIssue support to more jtx objects / functions
- Unfortunately, to work around some ambiguous symbol compilation
  errors, I had to change the implicit conversion from IOU to Asset to
  a conversion from IOU to PrettyAsset, and add a more explicit
  `asset()` function. This workaround only required changing two
  existing tests, so seems acceptable.
2025-05-07 12:11:53 -04:00
Ed Hennis
79a1a8a9c6 Finish(?) unit tests for Loan Broker Cover amounts. Untested.
- Add support for `Asset` and `MPTIssue` to some `jtx` helper classes
  and functions (`balance`, `expectLine`)
- Add support for pseudo-accounts to `jtx::Account` by allowing directly
  setting the AccountID without a matching key.
2025-05-07 12:11:53 -04:00
Ed Hennis
2bcc8cedfd Start writing tests for LoanBrokerCover* 2025-05-07 12:11:53 -04:00
Ed Hennis
1bb1992cf0 Add LoanBrokerCoverWithdraw transaction
- Untested
2025-05-07 12:11:52 -04:00
Ed Hennis
ffbc068dc8 Add LoanBrokerCoverDeposit transaction
- Untested. Will need Withdraw to do a good test.
2025-05-07 12:11:52 -04:00
Ed Hennis
fc66227f69 Move all detail namespaces to be under ripple
- Avoids problems with namespace collisions / ambiguous symbol issues
  with unity builds, especially when adding or removing files.
2025-05-07 12:11:52 -04:00
Ed Hennis
27fbf2db8e Start writing Loan Broker invariants and tests
- Specifically those mentioned for LoanBrokerDelete
2025-05-07 12:11:52 -04:00
Ed Hennis
7ab5bdbf3d Refactor ApplyView::dirAdd to give access to low-level operations
- Takes a page from #5362, which may turn out to be useful!
2025-05-07 12:11:52 -04:00
Ed Hennis
7d6155cc99 Clean ups 2025-05-07 12:11:52 -04:00
Ed Hennis
17a970d80c Continue updating LoanBroker tests
- It builds now
2025-05-07 12:11:51 -04:00
Ed Hennis
da10ba6fd0 Start adding tests for LoanBrokerDelete
- Start fixing the inevitable problems found along the way
- Generalize the LoanBroker lifecycle test
2025-05-07 12:11:51 -04:00
Ed Hennis
853c42fb9e Initial implementation of LoanBrokerDelete
- Completely untested
2025-05-07 12:11:51 -04:00
Ed Hennis
cc0fe0db07 LoanBrokerSet will charge a reserve increment when creating
- Refactor: Add a Transactor base function to make it easier to get the
  owner reserve increment as a fee.
- Refactor: Add an overload jtx::fee(increment) to pay an owner reserve.
2025-05-07 12:11:51 -04:00
Ed Hennis
781136ed2e Clang wants an explicit ctor to emplace in a vector 2025-05-07 12:11:51 -04:00
Ed Hennis
5db3c5e023 Fix a few build errors 2025-05-07 12:11:51 -04:00
Ed Hennis
a8118ff582 Add unit tests for new invariants:
- NoModifiedUnmodifiableFields and ValidPseudoAccounts
- Move the Invariants_test class into the test namespace
2025-05-07 12:11:51 -04:00
Ed Hennis
e3241dc143 Clean up more Invariant privilege checking
- Change more "failed" messages. The goal here is to be able to search
  the log for "failed" and ONLY get test failures.
2025-05-07 12:11:50 -04:00
Ed Hennis
c63cc88dc6 Fix a couple more build errors 2025-05-07 12:11:50 -04:00
Ed Hennis
ed27377435 Add a validity range for sfDebtMaximum
- Fix several test and build errors
2025-05-07 12:11:50 -04:00
Ed Hennis
41d83a4b24 Fix account creation to check both amendments 2025-05-07 12:11:50 -04:00
Ed Hennis
b7152496c1 Add LoanBroker update tests
- Move some helper functions.
- Check the regular key in the pseudo-transaction invariant check.
- Transactor::checkSign will always fail for a pseudo-account, so even
  if someone figures out how to get a good signature, it won't work.
2025-05-07 12:11:50 -04:00
Ed Hennis
1db5e9b4d3 Pseudo-account improvements
- Define pseudo-account fields with an sfield flag
- Pseudo-account invariant checks rules whenever a pseudo-account is
  created or modified.
2025-05-07 12:11:50 -04:00
Ed Hennis
1bbe5383ca Reserve a few values between Vault and Lending for future use
- Ledger objects and transactions
2025-05-07 12:11:49 -04:00
Ed Hennis
33e666bfff Enumerate transaction privileges for invariants
- Allows them to be defined in transactions.macro instead of needing to
  scrutinize every existing Invariant class.
- List is not necessarily comprehensive, but does cover every check
  where more than one transaction type is involved.
2025-05-07 12:11:49 -04:00
Ed Hennis
3b59817952 Generalize some of the Invariant checks using macro files
- Valid ledger entry type
- Valid new account root and pseudo account check
2025-05-07 12:11:49 -04:00
Ed Hennis
d4c2d46984 Update tests, update pseudo-account checking 2025-05-07 12:11:49 -04:00
Ed Hennis
47fa8ff59f Fix formatting 2025-05-07 12:11:49 -04:00
Ed Hennis
0d26065321 Start writing LoanBrokerSet tests 2025-05-07 12:11:49 -04:00
Ed Hennis
943a52cf2e Fix some build errors and typos 2025-05-07 12:11:48 -04:00
Ed Hennis
301a64be10 Add more fields 2025-05-07 12:11:48 -04:00
Ed Hennis
95e7cf4fc6 Fix formatting 2025-05-07 12:11:48 -04:00
Ed Hennis
19900bb87e Finish creating helper classes for JTx fields
- Also change the pseudo account field lookup to a function that uses
  a switch
2025-05-07 12:11:48 -04:00
Ed Hennis
536af58316 Fix formatting 2025-05-07 12:11:48 -04:00
Ed Hennis
abf5f08297 Update type of CoverRate fields 2025-05-07 12:11:48 -04:00
Ed Hennis
f77d435fdc Create some helper classes for transaction fields
- Test that they work by converting some of the existing classes
2025-05-07 12:11:48 -04:00
Ed Hennis
6489d73766 Rename LoanBroker.* files to LoanBrokerSet.* 2025-05-07 12:11:47 -04:00
Ed Hennis
f8c708f20c Finish LoanBrokerSet
- Update changed field name.
- Modify modifiable fields in an update. Note there are only two.
- Add a node field to dirLink, defaulting sfOwnerNode, so other
  relationships can be updated.
2025-05-07 12:11:47 -04:00
Ed Hennis
a04c07c5c4 Fix a couple of build errors 2025-05-07 12:11:47 -04:00
Ed Hennis
24374c548b [WIP] Define remaining transactions, start implementing LoanBrokerSet
- Does not build
- Transactions: LoanDelete, LoanManage, LoanDraw, LoanPay
- LoanBrokerSet creation mostly done. Need update.
- Also added a lookup table for pseudo account fields.
2025-05-07 12:11:47 -04:00
Ed Hennis
009ae8183f refactor: Generalize Transactor preflight:
- Derived classes no longer need to explicitly check amendments, nor
  call into preflight1 or preflight2.
- Untested.
2025-05-07 12:11:47 -04:00
Ed Hennis
145215d4ab Fix bug in new invariant 2025-05-07 12:11:47 -04:00
Ed Hennis
34f7bc7502 refactor: Check transaction flags in preflight0
- Adds a flagMask parameter to preflight1 so that it's impossible to
  forget to check flags.
- Also adds a short hash prefix to all Transactor log messages.
2025-05-07 12:11:46 -04:00
Ed Hennis
c6127ef034 Update list of "constant" fields from spec
- Also add a general check for all object types for the type and index
  fields
2025-05-07 12:11:46 -04:00
Ed Hennis
319e7a6bcb Start adding transaction layouts, flags, and fields
(Does not compile)
2025-05-07 12:11:46 -04:00
Ed Hennis
9d1b98a5a4 Fix some duplicated SField codes, speed up SField by name lookup 2025-05-07 12:11:46 -04:00
Ed Hennis
687b7944fb Fix build error - missing include 2025-05-07 12:11:46 -04:00
Ed Hennis
60a888619b Add Loan Broker and Loan ledger objects:
- Also add new SFields, Keylet functions, and an Invariant to verify no
  illegal field modification
2025-05-07 12:11:46 -04:00
Ed Hennis
8165f9d5b1 Add the LendingProtocol amendment 2025-05-07 12:11:46 -04:00
Bronek Kozicki
fc9197837c Add // LCOV_EXCL_LINE 2025-05-07 16:57:15 +01:00
Bronek Kozicki
65fe44a449 Review feedback 2025-05-06 20:07:02 +01:00
Bronek Kozicki
ac0e4dec96 Do not use isIntegral() 2025-05-06 19:57:15 +01:00
Bronek Kozicki
aead1bfb3d Review feedback 2025-05-06 19:06:45 +01:00
Bronek Kozicki
e6b9108d26 Add unit tests 2025-05-06 13:10:21 +01:00
Bronek Kozicki
8eaa9e7b96 Minor, use tecLOCKED when appropriate 2025-05-06 12:01:23 +01:00
Bronek Kozicki
283331b3bd Minor cleanup 2025-05-06 11:44:41 +01:00
Bronek Kozicki
4189aa8713 Merge branch 'develop' into vault 2025-05-02 17:53:51 +01:00
Bronek Kozicki
bbe49132a6 Reorganize and extend unit tests 2025-05-02 17:23:25 +01:00
Bronek Kozicki
84abcba497 Add defensive checks for IOU issuer and MPTokenIssuance 2025-05-02 16:56:47 +01:00
Bronek Kozicki
a87f58eb22 Code cleanup in SetTrust 2025-05-02 11:38:08 +01:00
Bronek Kozicki
1925ceace6 Add unit test 2025-05-01 21:36:03 +01:00
Bronek Kozicki
140fd829a0 Enforce defult rippling in VaultCreate::preclaim 2025-05-01 21:11:16 +01:00
Bronek Kozicki
b3657220de More tests 2025-05-01 16:59:15 +01:00
Bronek Kozicki
117bfcc4a1 Consolidate preflight tests 2025-05-01 15:15:00 +01:00
Bronek Kozicki
4c6c8a08c9 Add LCOV_EXCL_LINE in appropriate locations 2025-05-01 12:30:33 +01:00
Bronek Kozicki
7b680ed47b Remove redundant check, add test
There is no way to pass a non-object params to an RPC because it is
always prepared as an object inside ServerHandler.cpp
2025-05-01 11:42:34 +01:00
Bronek Kozicki
6c97d2ec7e Update addEmptyHolding from review
Co-authored-by: Ed Hennis <ed@ripple.com>
2025-05-01 10:09:49 +01:00
Bronek Kozicki
3c386bee4e Minor cleanup 2025-04-30 18:18:49 +01:00
Bronek Kozicki
5472d7e1ff Minor cleanup 2025-04-30 13:45:28 +01:00
Bronek Kozicki
01cc089b0c Revert changes preventing deletion of a vault 2025-04-29 15:29:59 +01:00
Bronek Kozicki
ffb1959be5 Disallow deletion of vault if asset is under global lock 2025-04-29 14:38:57 +01:00
Bronek Kozicki
efe9f99b50 Unit test fix 2025-04-29 14:02:09 +01:00
Bronek Kozicki
b03cd57a92 Merge branch 'develop' into vault 2025-04-29 13:18:02 +01:00
Bronek Kozicki
071beca306 Allow freezeing trust line to vault, disallow deleting vault when asset is locked 2025-04-29 13:16:04 +01:00
Bronek Kozicki
298aaac456 Check for pseudo-account in other transaction types 2025-04-28 19:41:14 +01:00
Bronek Kozicki
a205906e54 Prevent pseudo-accounts from receiving checks 2025-04-28 15:58:04 +01:00
Bronek Kozicki
d46a2d8a71 Allow resetting DomainID 2025-04-28 15:21:34 +01:00
Bronek Kozicki
5bfbb09970 Minor improvements 2025-04-28 14:49:47 +01:00
Bronek Kozicki
7e5845f209 Merge branch 'develop' into vault 2025-04-28 14:20:54 +01:00
Bronek Kozicki
22901af25d Minor cleanup 2025-04-25 19:57:14 +01:00
Bronek Kozicki
e9491669a7 Add unit tests 2025-04-25 16:31:28 +01:00
Bronek Kozicki
77c70d8a64 Update RPC codes, improve seq parsing 2025-04-25 15:23:41 +01:00
Bronek Kozicki
afeb6287f5 Cleanup in MPTokenAuthorize 2025-04-25 14:09:26 +01:00
Bronek Kozicki
b2abfc0bd2 Minor cleanup in MPTokenIssuanceCreate 2025-04-25 13:03:43 +01:00
Bronek Kozicki
6a25ac9481 Decouple VaultDestroy from MPTokenIssuanceDestroy
Also drive-by fix in MPTokenIssuanceDestroy, the sfOutstandingAmount
field is required.
2025-04-25 12:37:53 +01:00
Bronek Kozicki
fb2eb3522d Prohibit VaultCreate to assets without real issuer 2025-04-24 15:53:35 +01:00
Bronek Kozicki
270355f77a Keep existing order of checks 2025-04-24 14:27:19 +01:00
Bronek Kozicki
5cd3b1fb59 Add check in preclaim and extra tests 2025-04-24 14:26:34 +01:00
Bronek Kozicki
7eadb88d0d Replace tecKILLED with tecLIMIT_EXCEEDED in VaultCreate depth exceeded 2025-04-23 17:35:36 +01:00
Bronek Kozicki
0ab792263a Code cleanup 2025-04-23 16:13:58 +01:00
Ed Hennis
20ce0e79ab Need to decrement owner counts in removeEmptyHolding 2025-04-14 20:14:39 +01:00
Bronek Kozicki
d6d07e6fcf Fix authorization issues 2025-04-14 17:20:37 +01:00
Ed Hennis
51f1764e50 Fix formatting 2025-04-11 19:09:22 -04:00
Ed Hennis
b1bf115536 Merge branch 'develop' into vault 2025-04-11 18:26:58 -04:00
Ed Hennis
457877118e Merge branch 'develop' into vault 2025-04-11 15:33:17 -04:00
Ed Hennis
5fea68eb41 Merge branch 'develop' into vault 2025-04-10 11:39:33 -04:00
Ed Hennis
2abbb25bc3 Fix unit test that fails with varying reference fee
- Caused by a env.close() in the middle of the test that could change
  transaction ordering. Moved it to after the successful transaction
  that caused the later transactions to fail.
2025-04-10 11:38:37 -04:00
Ed Hennis
75375905a4 Merge remote-tracking branch 'upstream/develop' into vault
* upstream/develop:
  fix: `fixPayChanV1` (4717)
2025-04-09 18:26:02 -04:00
Ed Hennis
cd726f96d4 Merge remote-tracking branch 'upstream/develop' into vault
* upstream/develop:
  refactor(trivial): reorganize ledger entry tests and helper functions (5376)
2025-04-09 18:22:48 -04:00
Ed Hennis
870f42e5f7 Merge branch 'develop' into vault 2025-04-09 12:33:23 -04:00
Ed Hennis
780d05ec97 Clang wants an explicit ctor to emplace in a vector 2025-04-09 12:32:18 -04:00
Bronek Kozicki
f839049de7 Enforce max recursion depth in VaultCreate, improve VaultDeposit checks
Also fix off-by-one error in recursive checks isFrozen and requireAuth
2025-04-07 21:19:06 +01:00
Bronek Kozicki
5f051c53f1 Merge branch 'develop' into vault 2025-04-07 15:39:24 +01:00
Bronek Kozicki
db19760ee8 Both isFrozen and requireAuth are now recursive for vault shares 2025-04-07 15:37:50 +01:00
Bronek Kozicki
9c967f83be Disallow deleting locked MPToken 2025-04-07 13:01:02 +01:00
Bronek Kozicki
442795bfeb Change vault_info to take vault_id or owner&seq 2025-04-07 11:29:55 +01:00
Bronek Kozicki
e1e8859137 Add // LCOV_EXCL_LINE with UNREACHABLE 2025-04-04 18:14:52 +01:00
Bronek Kozicki
1494ae38e1 Fix VaultDeposit::preclaim checks 2025-04-04 12:36:05 +01:00
Bronek Kozicki
8f9524b5af Enforce lsfDefaultRipple flag in addEmptyHolding 2025-04-03 19:43:12 +01:00
Bronek Kozicki
676ed9ad04 Return ter code from dirLink 2025-04-03 19:33:38 +01:00
Bronek Kozicki
f6a9b4f5b1 Remove unnecessary include 2025-04-03 19:30:24 +01:00
Bronek Kozicki
2737249500 Merge branch 'develop' into vault 2025-04-03 14:30:42 +01:00
Bronek Kozicki
591437b914 Mark featureSingleAssetVault as Supported::no 2025-04-03 14:13:21 +01:00
Bronek Kozicki
af8ea3fb40 Rename 'share' to 'shares' in vault_info RPC 2025-04-03 11:45:47 +01:00
Bronek Kozicki
6f4e7e8e44 Move isPseudoAccount near createPseudoAccount 2025-04-03 11:35:46 +01:00
Bronek Kozicki
392e3846ed Change error code to tecLOCKED 2025-04-03 11:33:17 +01:00
Bronek Kozicki
85e7d293ca Factor out isPseudoAccount 2025-04-02 19:29:04 +01:00
Bronek Kozicki
dbbf6829b9 Gate VaultCreate on featureMPTokensV1 2025-04-02 17:11:49 +01:00
Bronek Kozicki
5f53e4d1f8 Change output structure of vault_info 2025-04-02 17:09:49 +01:00
Bronek Kozicki
fa0b021fb8 Add RPC vault_info, remove RPC::supplementJson<ltVAULT> 2025-04-02 16:40:37 +01:00
Bronek Kozicki
09833abd46 Improve checks in VaultWithdraw, more tests 2025-04-02 12:10:22 +01:00
Bronek Kozicki
dc249b8b6d Add unit tests 2025-04-01 19:06:45 +01:00
Bronek Kozicki
ad6e048ab2 Bring back addEmptyHolding and removeEmptyHolding to View 2025-04-01 13:51:47 +01:00
Bronek Kozicki
2b86a1a557 Enforce Destination checks on VaultWithdraw 2025-04-01 13:51:43 +01:00
Bronek Kozicki
93bd26547f Move addEmptyHolding to VaultCreate and removeEmptyHolding to VaultDelete 2025-03-31 18:20:31 +01:00
Bronek Kozicki
b6c74303c1 Add nullptr checks 2025-03-31 16:53:58 +01:00
Bronek Kozicki
a1c21a06bc Rename sfMPTokenIssuanceID in Vault to sfShareMPTID 2025-03-31 16:40:46 +01:00
Bronek Kozicki
b67d8e676b Add more comments on usage of enforceMPTokenAuthorization 2025-03-31 16:26:30 +01:00
Bronek Kozicki
83582b6731 Add RPC unit test 2025-03-31 15:13:58 +01:00
Bronek Kozicki
124512eba9 Add terADDRESS_COLLISION to AMMCreate::preclaim 2025-03-28 21:56:56 +00:00
Bronek Kozicki
1807b441ee Fix bug in pseudoAccountAddress and add unit test 2025-03-28 21:03:49 +00:00
Bronek Kozicki
d3c1d02c72 Return terADDRESS_COLLISION from preclaim if cannot allocate AccountID 2025-03-28 19:49:37 +00:00
Bronek Kozicki
f77ad36283 Merge branch 'develop' into vault 2025-03-28 17:06:06 +00:00
Bronek Kozicki
aff08b7543 Add invariant checks for pseudo-account 2025-03-28 17:04:38 +00:00
Bronek Kozicki
696cf2b563 Merge branch 'develop' into vault 2025-03-28 17:03:15 +00:00
Bronek Kozicki
abaf213336 Fix clang, minor refactor of createPseudoAccount 2025-03-27 19:29:41 +00:00
Bronek Kozicki
0f99955ae9 Merge branch 'develop' into vault 2025-03-27 13:07:02 +00:00
Bronek Kozicki
7686c3d88d Rename ShareTotal to SharesTotal 2025-03-27 11:50:03 +00:00
Bronek Kozicki
33660eadc6 Add comment on tecNO_ENTRY vs tecOBJECT_NOT_FOUND 2025-03-26 19:43:35 +00:00
Bronek Kozicki
0636d4695d Rename sfAsset... fields to sfAssets... 2025-03-26 19:19:30 +00:00
Bronek Kozicki
b6d7ef6c02 Add check for AssetTotal in VaultDelete 2025-03-26 19:17:07 +00:00
Bronek Kozicki
2e13dc1e85 Switch 'vault not found' to tecNO_ENTRY 2025-03-26 19:07:10 +00:00
Bronek Kozicki
dee06df012 Remove tecINVALID_DOMAIN error code
Also remove superflous checks in CredentialHelpers
2025-03-26 17:24:41 +00:00
Bronek Kozicki
f5042df72b Expand tests for numberFromJson 2025-03-26 16:16:31 +00:00
Bronek Kozicki
d16e0518fd Remove Env::vault() 2025-03-26 13:22:43 +00:00
Bronek Kozicki
3883bafd52 Update transactions.macro comment for ttVAULT_CLAWBACK 2025-03-26 12:29:56 +00:00
Bronek Kozicki
275e02f190 Add UNREACHABLE and LCOV_EXCL_LINE 2025-03-26 12:20:07 +00:00
Bronek Kozicki
afaa6aec8b Add test for nontransferable shares 2025-03-25 18:50:07 +00:00
Bronek Kozicki
05ebd0d8a6 Make empty VaultID a temMALFORMED 2025-03-25 17:54:59 +00:00
Bronek Kozicki
372555bda8 Rename tecVAULT_ACCOUNT to tecPSEUDO_ACCOUNT 2025-03-25 15:04:30 +00:00
Bronek Kozicki
2f06b344a7 Extend tests for updating permissioned domain 2025-03-25 12:47:44 +00:00
Bronek Kozicki
fbe28f6536 Switch sfAssetTotal sfAssetAvailable and sfLossUnrealized to required 2025-03-25 12:07:48 +00:00
Bronek Kozicki
ae68a09b06 Supplement ShareTotal in ledger_entry, ledger_data and account_objects. 2025-03-25 11:22:26 +00:00
Bronek Kozicki
dd3edbd5b0 Missed one getSeqValue() 2025-03-24 17:23:47 +00:00
Bronek Kozicki
a173dd20e2 Disallow regular Clawback on Vault accounts 2025-03-24 11:45:50 +00:00
Bronek Kozicki
cc4f87729f Merge branch 'develop' into vault 2025-03-24 11:25:35 +00:00
Bronek Kozicki
1e565e8488 Pseudo-accounts to use sequence 0 2025-03-24 11:10:31 +00:00
Bronek Kozicki
9c1a0aad7d Cleanup handling of unsupported PseudoAccountOwnerType 2025-03-24 10:41:19 +00:00
Bronek Kozicki
d8880ddb48 Replace getSeqProxy().value() with getSeqValue() where appropriate 2025-03-24 10:35:11 +00:00
Bronek Kozicki
1f005d2370 Add WaiveTransferFee::Yes for consistency
This has no actual effect since we do not set TransferRate in
mptIssuance of the vault shares; and transfers to the issuer are never
subject to TransferRate.
2025-03-21 16:48:40 +00:00
Bronek Kozicki
0959bf82b7 Enforce no negative balance at the end of transaction 2025-03-21 16:45:52 +00:00
Bronek Kozicki
58f15307ba Add ShareTotal to ledger_entry output 2025-03-21 16:33:31 +00:00
Bronek Kozicki
3d2102106c Show Share.mpt_issuance_id rather than MPTokenIssuanceID 2025-03-21 13:52:13 +00:00
Bronek Kozicki
4c7119b92f Add support for Destination field in VaultWithdraw 2025-03-20 15:28:09 +00:00
Bronek Kozicki
6b1cf7cee7 Fix clang compilation error 2025-03-20 14:35:47 +00:00
Bronek Kozicki
9a7def38b5 Do not apply IOU fees on VaultDeposit/VaultWithdraw 2025-03-20 13:21:11 +00:00
Bronek Kozicki
b1fc3b7c41 Do not fail VaultSet if nothing changed
One of the failure conditions for VaultSet is:
* The transaction does not specify any of the modifiable fields.

This section was added because I've misread the specification as:
"The transaction does not modify any of the modifiable fields."

Turns out I was wrong, should have read more carefully.
2025-03-20 10:51:00 +00:00
Bronek Kozicki
4e862e0afd AssetMaximum less than zero should yield temMALFORMED 2025-03-19 17:50:48 +00:00
Bronek Kozicki
403ef0d6c2 Allow resetting AssetMaximum to zero 2025-03-19 17:37:20 +00:00
Bronek Kozicki
6db2144912 Improve checks in VaultSet VaultCreate and VaultDeposit 2025-03-19 16:26:44 +00:00
Bronek Kozicki
d77fc57c6a Do not delete expired MPToken 2025-03-19 12:07:52 +00:00
Bronek Kozicki
1df3ff8d76 Merge branch 'develop' into vault 2025-03-19 11:51:30 +00:00
Bronek Kozicki
8e68838543 Remove lsfMPTDomainCheck flag, delete expired MPToken 2025-03-19 11:51:03 +00:00
Bronek Kozicki
2a8861d1c5 DomainID authorization check moved to doApply 2025-03-18 12:10:59 +00:00
Bronek Kozicki
df8761d9f3 Merge branch 'develop' into vault 2025-03-17 12:48:28 +00:00
Bronek Kozicki
7b5680f536 Fix VaultClawback and unit test 2025-03-13 17:24:05 +00:00
Bronek Kozicki
b397524d85 Remove pointless comment 2025-03-13 16:26:26 +00:00
Bronek Kozicki
e0932635ed Fix formatting 2025-03-13 16:13:19 +00:00
Bronek Kozicki
238db87b7d Add check for lsfMPTCanClawback and lsfMPTCanLock 2025-03-13 16:10:14 +00:00
Bronek Kozicki
840a4644c2 Merge branch 'develop' into vault 2025-03-13 11:30:30 +00:00
Bronek Kozicki
4c586eb4b0 Merge branch 'develop' into vault 2025-03-11 23:23:02 +00:00
Bronek Kozicki
3715d7e2e4 Fix bugs related to perm. domain checks, add unit test 2025-03-11 23:04:29 +00:00
Bronek Kozicki
90fef02164 Factor out static Number getShareTotal() from View.cpp 2025-03-10 15:01:14 +00:00
Bronek Kozicki
7b4e901dd7 Replace assert with XRPL_ASSERT 2025-03-10 14:34:08 +00:00
Bronek Kozicki
8ca6a62b84 Error codes change in accountHolds must be amendment gated 2025-03-10 14:29:01 +00:00
Bronek Kozicki
65fdac09b3 Fix logic error in isVaultPseudoAccountFrozen 2025-03-10 14:22:27 +00:00
Bronek Kozicki
1441c919ad Merge branch 'develop' into vault 2025-03-07 16:51:44 +00:00
Bronek Kozicki
b0c2b97663 Enforce PD is enabled if sfDomainID is set 2025-03-07 16:51:32 +00:00
Bronek Kozicki
1589498ae1 Improve VaultClawback checks 2025-03-07 16:51:21 +00:00
Bronek Kozicki
4dc2025378 Rename maxVaultDataLength to maxDataPayloadLength 2025-03-07 11:17:45 +00:00
Bronek Kozicki
fc2e1a2b5a Remove unused Json::Value operator= 2025-03-06 15:14:01 +00:00
Bronek Kozicki
1756fa7d08 Switch sfAmount in VaultClawback from defaulted to optional 2025-03-06 13:55:07 +00:00
Bronek Kozicki
ac6d26a8b3 Switch error code for non-transferable to tecNO_AUTH 2025-03-06 13:54:44 +00:00
Bronek Kozicki
152da6e078 Use unchecked for negative amount in unit tests 2025-03-06 12:56:54 +00:00
Bronek Kozicki
6370448299 Merge branch 'develop' into vault 2025-03-06 12:43:18 +00:00
Bronek Kozicki
04503c9fa4 Enforce non-negative amounts 2025-02-25 19:37:01 +00:00
Bronek Kozicki
a0632a0cb3 Add WithdrawalPolicy 2025-02-25 19:11:04 +00:00
Bronek Kozicki
3f5df80b47 Merge branch 'develop' into vault 2025-02-24 14:10:46 +00:00
Bronek Kozicki
9d619b9dc5 Merge branch 'develop' into vault 2025-02-07 21:29:25 +00:00
Bronek Kozicki
e9ed80026e Optimise isFrozen check for pair of accounts 2025-02-07 21:25:47 +00:00
Bronek Kozicki
c1d8bc4928 Enforce freeze of pseudo-account 2025-02-07 19:29:33 +00:00
Bronek Kozicki
87d8881c81 Merge branch 'develop' into vault 2025-02-07 14:09:37 +00:00
Bronek Kozicki
b7c9577230 Remove unnecessary check 2025-02-06 16:42:23 +00:00
Bronek Kozicki
ffaa8bd24b Improve checks in Vault 2025-02-06 15:44:59 +00:00
Bronek Kozicki
acaed58d85 Prevent deposit when asset is frozen for depositor 2025-02-04 16:49:28 +00:00
Bronek Kozicki
1884ec5e60 Check for frozen assets in preclaim 2025-02-04 16:44:52 +00:00
Bronek Kozicki
6765c101a8 Check permissioned domain enabled if DomainID is used 2025-02-04 12:52:22 +00:00
Bronek Kozicki
9decc053e3 Rename getSequence to getSeqValue 2025-02-03 13:07:00 +00:00
Bronek Kozicki
8baadd5ec3 Fix clang build error 2025-02-03 11:39:52 +00:00
Bronek Kozicki
d1c7d1ae0f Merge branch 'develop' into vault 2025-02-03 10:11:31 +00:00
Ed Hennis
c3f9a4c6ff Fix MSVC build: Get the intended const& for some fields
- Also make MPTID more consistent
2025-01-31 18:06:53 -05:00
Ed Hennis
eed18d16ce Remove unnecessary ValueProxy friend operator != 2025-01-31 18:06:05 -05:00
Ed Hennis
21e0e7e97b Fix ICE errors by reusing a global static const object 2025-01-31 18:06:05 -05:00
Ed Hennis
a98e59a29a Revert "WIP trying to fix MSVC compilation error"
This reverts commit 06a8a61b23.
2025-01-31 18:06:04 -05:00
Bronek Kozicki
06a8a61b23 WIP trying to fix MSVC compilation error 2025-01-31 20:13:41 +00:00
Bronek Kozicki
ad68074d72 MPT permissioned domain checks 2025-01-31 19:26:52 +00:00
Bronek Kozicki
3eebdae3f0 Implement MPT domain checks 2025-01-30 12:42:26 +00:00
Bronek Kozicki
02dec4f797 Merge branch 'develop' into vault 2025-01-27 11:20:46 +00:00
Bronek Kozicki
65d6c48b4a Unit tests naming fix 2025-01-24 11:17:05 +00:00
Bronek Kozicki
86d249a5bb Fix checo of expired credential 2025-01-24 11:10:34 +00:00
Bronek Kozicki
9bf9a1ef12 Merge branch 'develop' into vault 2025-01-24 11:06:59 +00:00
Bronek Kozicki
2c4a2244e9 Verify credentials in VaultDeposit 2025-01-23 20:49:54 +00:00
Bronek Kozicki
25a20adf39 Add VaultID to account 2025-01-23 17:37:36 +00:00
Bronek Kozicki
c08f86d473 Remove temSTRING_TOO_LARGE, fix authorizedDomain, refactor Vault_test 2025-01-22 18:38:15 +00:00
Bronek Kozicki
580a85f2c8 WIP support adding domainID in VaultSet 2025-01-21 13:38:57 +00:00
Bronek Kozicki
dbaa12aa1c WIP permissioned domain support 2025-01-17 19:16:09 +00:00
Bronek Kozicki
c325b6c7f5 Fix Vault unit tests 2025-01-17 17:05:01 +00:00
Bronek Kozicki
375614d7ec Merge branch 'develop' into vault 2025-01-17 10:49:28 +00:00
Bronek Kozicki
bf8bbffab1 Merge branch 'develop' into vault 2025-01-15 15:49:55 +00:00
Bronek Kozicki
8d5cfb910a Merge branch 'develop' into vault 2025-01-13 16:26:51 +00:00
Bronek Kozicki
241429ba32 Simplify conversions to Json::Value
Also remove potential ODR violation from json_value.h
2024-12-18 17:30:41 +00:00
Bronek Kozicki
b9f1200652 Fix formatting 2024-12-18 17:30:39 +00:00
Bronek Kozicki
526f715f16 Comment out failing test 2024-12-18 17:30:32 +00:00
Bronek Kozicki
eae2cd3328 Fix compilation errors 2024-12-18 13:12:41 +00:00
Bronek Kozicki
ecec6e5d33 Fix failing MPToken payment test 2024-12-17 18:05:09 +00:00
John Freeman
ad581661e3 wip clawback 2024-12-17 11:11:05 +00:00
John Freeman
b5619fbcd6 bless sfAsset to carry MPT 2024-12-17 11:11:00 +00:00
John Freeman
54d511b0db remove blob constants 2024-12-17 11:10:58 +00:00
John Freeman
12646cb89e revise tests 2024-12-17 11:10:56 +00:00
John Freeman
ea30f44247 fix 2024-12-17 11:10:54 +00:00
John Freeman
ea6c040f10 wip 2024-12-17 11:10:52 +00:00
John Freeman
1ff1274ee5 AND_THEN 2024-12-17 11:10:50 +00:00
John Freeman
12552162c9 progress 2024-12-17 11:10:48 +00:00
John Freeman
6046fa239c progress 2024-12-17 11:10:47 +00:00
John Freeman
286612cf19 progress 2024-12-17 11:10:45 +00:00
John Freeman
ebc97aee25 progress 2024-12-17 11:10:44 +00:00
John Freeman
1680477e39 progress 2024-12-17 11:10:42 +00:00
John Freeman
d09e74e548 format 2024-12-17 11:10:40 +00:00
John Freeman
a8ec8e7eaa wip 2024-12-17 11:10:38 +00:00
John Freeman
ff8c6491d7 Start vault implementation 2024-12-17 11:10:36 +00:00
John Freeman
1a032f04e3 Integrate STNumber with STParsedJSON 2024-12-17 11:10:27 +00:00
522 changed files with 13037 additions and 26936 deletions

View File

@@ -94,4 +94,3 @@ SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
QualifierAlignment: Right

View File

@@ -7,13 +7,13 @@ comment:
show_carryforward_flags: false
coverage:
range: "70..85"
range: "60..80"
precision: 1
round: nearest
status:
project:
default:
target: 75%
target: 60%
threshold: 2%
patch:
default:

8
.github/CODEOWNERS vendored
View File

@@ -1,8 +0,0 @@
# Allow anyone to review any change by default.
*
# Require the rpc-reviewers team to review changes to the rpc code.
include/xrpl/protocol/ @xrplf/rpc-reviewers
src/libxrpl/protocol/ @xrplf/rpc-reviewers
src/xrpld/rpc/ @xrplf/rpc-reviewers
src/xrpld/app/misc/ @xrplf/rpc-reviewers

View File

@@ -27,7 +27,6 @@ runs:
- name: build
shell: bash
run: |
echo Running $(nproc) processes
cmake \
--build ${build_dir} \
--config ${{ inputs.configuration }} \

View File

@@ -10,7 +10,7 @@ concurrency:
cancel-in-progress: true
jobs:
documentation:
job:
runs-on: ubuntu-latest
permissions:
contents: write

View File

@@ -71,9 +71,6 @@ jobs:
nproc --version
echo -n "nproc returns: "
nproc
system_profiler SPHardwareDataType
sysctl -n hw.logicalcpu
clang --version
- name: configure Conan
run : |
conan profile new default --detect || true
@@ -92,8 +89,9 @@ jobs:
generator: ${{ matrix.generator }}
configuration: ${{ matrix.configuration }}
cmake-args: "-Dassert=TRUE -Dwerr=TRUE ${{ matrix.cmake-args }}"
- name: test
run: |
n=$(nproc)
echo "Using $n test jobs"
${build_dir}/rippled --unittest --unittest-jobs $n
# TODO: Temporary disabled tests
# - name: test
# run: |
# n=$(nproc)
# echo "Using $n test jobs"
# ${build_dir}/rippled --unittest --unittest-jobs $n

View File

@@ -247,7 +247,7 @@ jobs:
mkdir -p ~/.conan
tar -xzf conan.tar -C ~/.conan
- name: install gcovr
run: pip install "gcovr>=7,<9"
run: pip install "gcovr>=7,<8"
- name: check environment
run: |
echo ${PATH} | tr ':' '\n'

View File

@@ -288,7 +288,7 @@ It fixes some source files to add missing `#include`s.
Single-config generators:
```
cmake --build . -j $(nproc)
cmake --build .
```
Multi-config generators:

View File

@@ -1,5 +1,3 @@
[![codecov](https://codecov.io/gh/XRPLF/rippled/graph/badge.svg?token=WyFr5ajq3O)](https://codecov.io/gh/XRPLF/rippled)
# The XRP Ledger
The [XRP Ledger](https://xrpl.org/) is a decentralized cryptographic ledger powered by a network of peer-to-peer nodes. The XRP Ledger uses a novel Byzantine Fault Tolerant consensus algorithm to settle and record transactions in a secure distributed database without a central operator.

View File

@@ -83,7 +83,7 @@ To report a qualifying bug, please send a detailed report to:
|Long Key ID | `0xCD49A0AFC57929BE` |
|Fingerprint | `24E6 3B02 37E0 FA9C 5E96 8974 CD49 A0AF C579 29BE` |
The full PGP key for this address, which is also available on several key servers (e.g. on [keyserver.ubuntu.com](https://keyserver.ubuntu.com)), is:
The full PGP key for this address, which is also available on several key servers (e.g. on [keys.gnupg.net](https://keys.gnupg.net)), is:
```
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBFUwGHYBEAC0wpGpBPkd8W1UdQjg9+cEFzeIEJRaoZoeuJD8mofwI5Ejnjdt

View File

@@ -26,7 +26,7 @@
#
# Examples:
# https://vl.ripple.com
# https://unl.xrplf.org
# https://vl.xrplf.org
# http://127.0.0.1:8000
# file:///etc/opt/ripple/vl.txt
#

View File

@@ -98,9 +98,6 @@
# 2024-04-03, Bronek Kozicki
# - add support for output formats: jacoco, clover, lcov
#
# 2025-05-12, Jingchen Wu
# - add -fprofile-update=atomic to ensure atomic profile generation
#
# USAGE:
#
# 1. Copy this file into your cmake modules path.
@@ -203,27 +200,15 @@ set(COVERAGE_COMPILER_FLAGS "-g --coverage"
CACHE INTERNAL "")
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
include(CheckCXXCompilerFlag)
include(CheckCCompilerFlag)
check_cxx_compiler_flag(-fprofile-abs-path HAVE_cxx_fprofile_abs_path)
if(HAVE_cxx_fprofile_abs_path)
set(COVERAGE_CXX_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path")
endif()
include(CheckCCompilerFlag)
check_c_compiler_flag(-fprofile-abs-path HAVE_c_fprofile_abs_path)
if(HAVE_c_fprofile_abs_path)
set(COVERAGE_C_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path")
endif()
check_cxx_compiler_flag(-fprofile-update HAVE_cxx_fprofile_update)
if(HAVE_cxx_fprofile_update)
set(COVERAGE_CXX_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-update=atomic")
endif()
check_c_compiler_flag(-fprofile-update HAVE_c_fprofile_update)
if(HAVE_c_fprofile_update)
set(COVERAGE_C_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-update=atomic")
endif()
endif()
set(CMAKE_Fortran_FLAGS_COVERAGE

View File

@@ -53,9 +53,9 @@ set(download_script "${CMAKE_BINARY_DIR}/docs/download-cppreference.cmake")
file(WRITE
"${download_script}"
"file(DOWNLOAD \
https://github.com/PeterFeicht/cppreference-doc/releases/download/v20250209/html-book-20250209.zip \
http://upload.cppreference.com/mwiki/images/b/b2/html_book_20190607.zip \
${CMAKE_BINARY_DIR}/docs/cppreference.zip \
EXPECTED_HASH MD5=bda585f72fbca4b817b29a3d5746567b \
EXPECTED_HASH MD5=82b3a612d7d35a83e3cb1195a63689ab \
)\n \
execute_process( \
COMMAND \"${CMAKE_COMMAND}\" -E tar -xf cppreference.zip \

View File

@@ -1,4 +1,4 @@
from conan import ConanFile, __version__ as conan_version
from conan import ConanFile
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
import re
@@ -24,11 +24,13 @@ class Xrpl(ConanFile):
}
requires = [
'date/3.0.3',
'grpc/1.50.1',
'libarchive/3.7.6',
'nudb/2.0.8',
'openssl/1.1.1v',
'soci/4.0.3',
'xxhash/0.8.2',
'zlib/1.3.1',
]
@@ -97,10 +99,7 @@ class Xrpl(ConanFile):
self.options['boost'].visibility = 'global'
def requirements(self):
# Conan 2 requires transitive headers to be specified
transitive_headers_opt = {'transitive_headers': True} if conan_version.split('.')[0] == '2' else {}
self.requires('boost/1.83.0', force=True, **transitive_headers_opt)
self.requires('date/3.0.3', **transitive_headers_opt)
self.requires('boost/1.83.0', force=True)
self.requires('lz4/1.10.0', force=True)
self.requires('protobuf/3.21.9', force=True)
self.requires('sqlite3/3.47.0', force=True)
@@ -108,7 +107,6 @@ class Xrpl(ConanFile):
self.requires('jemalloc/5.3.0')
if self.options.rocksdb:
self.requires('rocksdb/9.7.3')
self.requires('xxhash/0.8.2', **transitive_headers_opt)
exports_sources = (
'CMakeLists.txt',

View File

@@ -23,7 +23,7 @@ direction.
```
apt update
apt install --yes curl git libssl-dev pipx python3.10-dev python3-pip make g++-11 libprotobuf-dev protobuf-compiler
apt install --yes curl git libssl-dev python3.10-dev python3-pip make g++-11 libprotobuf-dev protobuf-compiler
curl --location --remote-name \
"https://github.com/Kitware/CMake/releases/download/v3.25.1/cmake-3.25.1.tar.gz"
@@ -35,8 +35,7 @@ make --jobs $(nproc)
make install
cd ..
pipx install 'conan<2'
pipx ensurepath
pip3 install 'conan<2'
```
[1]: https://github.com/thejohnfreeman/rippled-docker/blob/master/ubuntu-22.04/install.sh

View File

@@ -367,7 +367,7 @@ get(Section const& section,
}
inline std::string
get(Section const& section, std::string const& name, char const* defaultValue)
get(Section const& section, std::string const& name, const char* defaultValue)
{
try
{

View File

@@ -55,7 +55,7 @@ lz4Compress(void const* in, std::size_t inSize, BufferFactory&& bf)
auto compressed = bf(outCapacity);
auto compressedSize = LZ4_compress_default(
reinterpret_cast<char const*>(in),
reinterpret_cast<const char*>(in),
reinterpret_cast<char*>(compressed),
inSize,
outCapacity);
@@ -89,7 +89,7 @@ lz4Decompress(
Throw<std::runtime_error>("lz4Decompress: integer overflow (output)");
if (LZ4_decompress_safe(
reinterpret_cast<char const*>(in),
reinterpret_cast<const char*>(in),
reinterpret_cast<char*>(decompressed),
inSize,
decompressedSize) != decompressedSize)

View File

@@ -93,7 +93,7 @@ public:
{
}
constexpr E const&
constexpr const E&
value() const&
{
return val_;
@@ -111,7 +111,7 @@ public:
return std::move(val_);
}
constexpr E const&&
constexpr const E&&
value() const&&
{
return std::move(val_);

View File

@@ -115,7 +115,7 @@ public:
sweep();
bool
del(key_type const& key, bool valid);
del(const key_type& key, bool valid);
public:
/** Replace aliased objects with originals.
@@ -134,20 +134,20 @@ public:
template <class R>
bool
canonicalize(
key_type const& key,
const key_type& key,
SharedPointerType& data,
R&& replaceCallback);
bool
canonicalize_replace_cache(
key_type const& key,
const key_type& key,
SharedPointerType const& data);
bool
canonicalize_replace_client(key_type const& key, SharedPointerType& data);
canonicalize_replace_client(const key_type& key, SharedPointerType& data);
SharedPointerType
fetch(key_type const& key);
fetch(const key_type& key);
/** Insert the element into the container.
If the key already exists, nothing happens.
@@ -168,7 +168,7 @@ public:
// simply return an iterator.
//
bool
retrieve(key_type const& key, T& data);
retrieve(const key_type& key, T& data);
mutex_type&
peekMutex();
@@ -322,10 +322,10 @@ private:
std::string m_name;
// Desired number of cache entries (0 = ignore)
int const m_target_size;
const int m_target_size;
// Desired maximum cache age
clock_type::duration const m_target_age;
const clock_type::duration m_target_age;
// Number of items cached
int m_cache_count;

View File

@@ -365,7 +365,7 @@ TaggedCache<
SharedPointerType,
Hash,
KeyEqual,
Mutex>::del(key_type const& key, bool valid)
Mutex>::del(const key_type& key, bool valid)
{
// Remove from cache, if !valid, remove from map too. Returns true if
// removed from cache
@@ -414,7 +414,7 @@ TaggedCache<
KeyEqual,
Mutex>::
canonicalize(
key_type const& key,
const key_type& key,
SharedPointerType& data,
R&& replaceCallback)
{
@@ -509,7 +509,7 @@ TaggedCache<
KeyEqual,
Mutex>::
canonicalize_replace_cache(
key_type const& key,
const key_type& key,
SharedPointerType const& data)
{
return canonicalize(
@@ -535,7 +535,7 @@ TaggedCache<
Hash,
KeyEqual,
Mutex>::
canonicalize_replace_client(key_type const& key, SharedPointerType& data)
canonicalize_replace_client(const key_type& key, SharedPointerType& data)
{
return canonicalize(key, data, []() { return false; });
}
@@ -558,7 +558,7 @@ TaggedCache<
SharedPointerType,
Hash,
KeyEqual,
Mutex>::fetch(key_type const& key)
Mutex>::fetch(const key_type& key)
{
std::lock_guard<mutex_type> l(m_mutex);
auto ret = initialFetch(key, l);
@@ -656,7 +656,7 @@ TaggedCache<
SharedPointerType,
Hash,
KeyEqual,
Mutex>::retrieve(key_type const& key, T& data)
Mutex>::retrieve(const key_type& key, T& data)
{
// retrieve the value of the stored data
auto entry = fetch(key);

View File

@@ -374,7 +374,7 @@ public:
}
base_uint&
operator^=(base_uint const& b)
operator^=(const base_uint& b)
{
for (int i = 0; i < WIDTH; i++)
data_[i] ^= b.data_[i];
@@ -383,7 +383,7 @@ public:
}
base_uint&
operator&=(base_uint const& b)
operator&=(const base_uint& b)
{
for (int i = 0; i < WIDTH; i++)
data_[i] &= b.data_[i];
@@ -392,7 +392,7 @@ public:
}
base_uint&
operator|=(base_uint const& b)
operator|=(const base_uint& b)
{
for (int i = 0; i < WIDTH; i++)
data_[i] |= b.data_[i];
@@ -415,11 +415,11 @@ public:
return *this;
}
base_uint const
const base_uint
operator++(int)
{
// postfix operator
base_uint const ret = *this;
const base_uint ret = *this;
++(*this);
return ret;
@@ -441,11 +441,11 @@ public:
return *this;
}
base_uint const
const base_uint
operator--(int)
{
// postfix operator
base_uint const ret = *this;
const base_uint ret = *this;
--(*this);
return ret;
@@ -466,7 +466,7 @@ public:
}
base_uint&
operator+=(base_uint const& b)
operator+=(const base_uint& b)
{
std::uint64_t carry = 0;
@@ -511,7 +511,7 @@ public:
}
[[nodiscard]] constexpr bool
parseHex(char const* str)
parseHex(const char* str)
{
return parseHex(std::string_view{str});
}
@@ -632,6 +632,13 @@ to_string(base_uint<Bits, Tag> const& a)
return strHex(a.cbegin(), a.cend());
}
template <std::size_t Bits, class Tag>
inline std::string
to_short_string(base_uint<Bits, Tag> const& a)
{
return to_string(a).substr(0, 8) + "...";
}
template <std::size_t Bits, class Tag>
inline std::ostream&
operator<<(std::ostream& out, base_uint<Bits, Tag> const& u)

View File

@@ -43,7 +43,7 @@ struct less
using result_type = bool;
constexpr bool
operator()(T const& left, T const& right) const
operator()(const T& left, const T& right) const
{
return std::less<T>()(left, right);
}
@@ -55,7 +55,7 @@ struct equal_to
using result_type = bool;
constexpr bool
operator()(T const& left, T const& right) const
operator()(const T& left, const T& right) const
{
return std::equal_to<T>()(left, right);
}

View File

@@ -52,7 +52,7 @@ template <
typename Value,
typename Hash,
typename Pred = std::equal_to<Key>,
typename Alloc = std::allocator<std::pair<Key const, Value>>>
typename Alloc = std::allocator<std::pair<const Key, Value>>>
class partitioned_unordered_map
{
std::size_t partitions_;

View File

@@ -76,13 +76,13 @@ public:
}
bool
operator<(tagged_integer const& rhs) const noexcept
operator<(const tagged_integer& rhs) const noexcept
{
return m_value < rhs.m_value;
}
bool
operator==(tagged_integer const& rhs) const noexcept
operator==(const tagged_integer& rhs) const noexcept
{
return m_value == rhs.m_value;
}
@@ -144,14 +144,14 @@ public:
}
tagged_integer&
operator<<=(tagged_integer const& rhs) noexcept
operator<<=(const tagged_integer& rhs) noexcept
{
m_value <<= rhs.m_value;
return *this;
}
tagged_integer&
operator>>=(tagged_integer const& rhs) noexcept
operator>>=(const tagged_integer& rhs) noexcept
{
m_value >>= rhs.m_value;
return *this;

View File

@@ -30,7 +30,7 @@ namespace beast {
template <class Hasher = xxhasher>
struct uhash
{
uhash() = default;
explicit uhash() = default;
using result_type = typename Hasher::result_type;

View File

@@ -215,7 +215,7 @@ namespace std {
template <>
struct hash<::beast::IP::Endpoint>
{
hash() = default;
explicit hash() = default;
std::size_t
operator()(::beast::IP::Endpoint const& endpoint) const
@@ -230,7 +230,7 @@ namespace boost {
template <>
struct hash<::beast::IP::Endpoint>
{
hash() = default;
explicit hash() = default;
std::size_t
operator()(::beast::IP::Endpoint const& endpoint) const

View File

@@ -39,6 +39,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#endif
#define XRPL_ASSERT ALWAYS_OR_UNREACHABLE
#define XRPL_ASSERT2(cond, location, message, ...) \
XRPL_ASSERT(cond, std::string(location) + " : " + message)
// How to use the instrumentation macros:
//

View File

@@ -37,9 +37,9 @@ class temp_dir
public:
#if !GENERATING_DOCS
temp_dir(temp_dir const&) = delete;
temp_dir(const temp_dir&) = delete;
temp_dir&
operator=(temp_dir const&) = delete;
operator=(const temp_dir&) = delete;
#endif
/// Construct a temporary directory.

View File

@@ -39,7 +39,7 @@ class Reader
{
public:
using Char = char;
using Location = Char const*;
using Location = const Char*;
/** \brief Constructs a Reader allowing all features
* for parsing.
@@ -64,7 +64,7 @@ public:
* error occurred.
*/
bool
parse(char const* beginDoc, char const* endDoc, Value& root);
parse(const char* beginDoc, const char* endDoc, Value& root);
/// \brief Parse from input stream.
/// \see Json::operator>>(std::istream&, Json::Value&).
@@ -133,7 +133,7 @@ private:
using Errors = std::deque<ErrorInfo>;
bool
expectToken(TokenType type, Token& token, char const* message);
expectToken(TokenType type, Token& token, const char* message);
bool
readToken(Token& token);
void

View File

@@ -63,24 +63,24 @@ enum ValueType {
class StaticString
{
public:
constexpr explicit StaticString(char const* czstring) : str_(czstring)
constexpr explicit StaticString(const char* czstring) : str_(czstring)
{
}
constexpr
operator char const*() const
operator const char*() const
{
return str_;
}
constexpr char const*
constexpr const char*
c_str() const
{
return str_;
}
private:
char const* str_;
const char* str_;
};
inline bool
@@ -158,10 +158,10 @@ public:
using Int = Json::Int;
using ArrayIndex = UInt;
static Value const null;
static Int const minInt;
static Int const maxInt;
static UInt const maxUInt;
static const Value null;
static const Int minInt;
static const Int maxInt;
static const UInt maxUInt;
private:
class CZString
@@ -173,24 +173,24 @@ private:
duplicateOnCopy
};
CZString(int index);
CZString(char const* cstr, DuplicationPolicy allocate);
CZString(CZString const& other);
CZString(const char* cstr, DuplicationPolicy allocate);
CZString(const CZString& other);
~CZString();
CZString&
operator=(CZString const& other) = delete;
operator=(const CZString& other) = delete;
bool
operator<(CZString const& other) const;
operator<(const CZString& other) const;
bool
operator==(CZString const& other) const;
operator==(const CZString& other) const;
int
index() const;
char const*
const char*
c_str() const;
bool
isStaticString() const;
private:
char const* cstr_;
const char* cstr_;
int index_;
};
@@ -217,7 +217,7 @@ public:
Value(Int value);
Value(UInt value);
Value(double value);
Value(char const* value);
Value(const char* value);
Value(ripple::Number const& value);
/** \brief Constructs a value from a static string.
@@ -230,10 +230,10 @@ public:
* Json::Value aValue( StaticString("some text") );
* \endcode
*/
Value(StaticString const& value);
Value(const StaticString& value);
Value(std::string const& value);
Value(bool value);
Value(Value const& other);
Value(const Value& other);
~Value();
Value&
@@ -250,7 +250,7 @@ public:
ValueType
type() const;
char const*
const char*
asCString() const;
/** Returns the unquoted string value. */
std::string
@@ -320,12 +320,12 @@ public:
/// Access an array element (zero based index )
/// (You may need to say 'value[0u]' to get your compiler to distinguish
/// this from the operator[] which takes a string.)
Value const&
const Value&
operator[](UInt index) const;
/// If the array contains at least index+1 elements, returns the element
/// value, otherwise returns defaultValue.
Value
get(UInt index, Value const& defaultValue) const;
get(UInt index, const Value& defaultValue) const;
/// Return true if index < size().
bool
isValidIndex(UInt index) const;
@@ -333,25 +333,25 @@ public:
///
/// Equivalent to jsonvalue[jsonvalue.size()] = value;
Value&
append(Value const& value);
append(const Value& value);
Value&
append(Value&& value);
/// Access an object value by name, create a null member if it does not
/// exist.
Value&
operator[](char const* key);
operator[](const char* key);
/// Access an object value by name, returns null if there is no member with
/// that name.
Value const&
operator[](char const* key) const;
const Value&
operator[](const char* key) const;
/// Access an object value by name, create a null member if it does not
/// exist.
Value&
operator[](std::string const& key);
/// Access an object value by name, returns null if there is no member with
/// that name.
Value const&
const Value&
operator[](std::string const& key) const;
/** \brief Access an object value by name, create a null member if it does
not exist.
@@ -367,16 +367,16 @@ public:
* \endcode
*/
Value&
operator[](StaticString const& key);
operator[](const StaticString& key);
Value const&
operator[](StaticString const& key) const;
operator[](const StaticString& key) const;
/// Return the member named key if it exist, defaultValue otherwise.
Value
get(char const* key, Value const& defaultValue) const;
get(const char* key, const Value& defaultValue) const;
/// Return the member named key if it exist, defaultValue otherwise.
Value
get(std::string const& key, Value const& defaultValue) const;
get(std::string const& key, const Value& defaultValue) const;
/// \brief Remove and return the named member.
///
@@ -385,14 +385,14 @@ public:
/// \pre type() is objectValue or nullValue
/// \post type() is unchanged
Value
removeMember(char const* key);
removeMember(const char* key);
/// Same as removeMember(const char*)
Value
removeMember(std::string const& key);
/// Return true if the object has a member named key.
bool
isMember(char const* key) const;
isMember(const char* key) const;
/// Return true if the object has a member named key.
bool
isMember(std::string const& key) const;
@@ -419,13 +419,13 @@ public:
end();
friend bool
operator==(Value const&, Value const&);
operator==(const Value&, const Value&);
friend bool
operator<(Value const&, Value const&);
operator<(const Value&, const Value&);
private:
Value&
resolveReference(char const* key, bool isStatic);
resolveReference(const char* key, bool isStatic);
private:
union ValueHolder
@@ -448,31 +448,31 @@ to_json(ripple::Number const& number)
}
bool
operator==(Value const&, Value const&);
operator==(const Value&, const Value&);
inline bool
operator!=(Value const& x, Value const& y)
operator!=(const Value& x, const Value& y)
{
return !(x == y);
}
bool
operator<(Value const&, Value const&);
operator<(const Value&, const Value&);
inline bool
operator<=(Value const& x, Value const& y)
operator<=(const Value& x, const Value& y)
{
return !(y < x);
}
inline bool
operator>(Value const& x, Value const& y)
operator>(const Value& x, const Value& y)
{
return y < x;
}
inline bool
operator>=(Value const& x, Value const& y)
operator>=(const Value& x, const Value& y)
{
return !(x < y);
}
@@ -493,11 +493,11 @@ public:
virtual ~ValueAllocator() = default;
virtual char*
makeMemberName(char const* memberName) = 0;
makeMemberName(const char* memberName) = 0;
virtual void
releaseMemberName(char* memberName) = 0;
virtual char*
duplicateStringValue(char const* value, unsigned int length = unknown) = 0;
duplicateStringValue(const char* value, unsigned int length = unknown) = 0;
virtual void
releaseStringValue(char* value) = 0;
};
@@ -514,16 +514,16 @@ public:
ValueIteratorBase();
explicit ValueIteratorBase(Value::ObjectValues::iterator const& current);
explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
bool
operator==(SelfType const& other) const
operator==(const SelfType& other) const
{
return isEqual(other);
}
bool
operator!=(SelfType const& other) const
operator!=(const SelfType& other) const
{
return !isEqual(other);
}
@@ -539,7 +539,7 @@ public:
/// Return the member name of the referenced Value. "" if it is not an
/// objectValue.
char const*
const char*
memberName() const;
protected:
@@ -553,13 +553,13 @@ protected:
decrement();
difference_type
computeDistance(SelfType const& other) const;
computeDistance(const SelfType& other) const;
bool
isEqual(SelfType const& other) const;
isEqual(const SelfType& other) const;
void
copy(SelfType const& other);
copy(const SelfType& other);
private:
Value::ObjectValues::iterator current_;
@@ -577,8 +577,8 @@ class ValueConstIterator : public ValueIteratorBase
public:
using size_t = unsigned int;
using difference_type = int;
using reference = Value const&;
using pointer = Value const*;
using reference = const Value&;
using pointer = const Value*;
using SelfType = ValueConstIterator;
ValueConstIterator() = default;
@@ -586,11 +586,11 @@ public:
private:
/*! \internal Use by Value to create an iterator.
*/
explicit ValueConstIterator(Value::ObjectValues::iterator const& current);
explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
public:
SelfType&
operator=(ValueIteratorBase const& other);
operator=(const ValueIteratorBase& other);
SelfType
operator++(int)
@@ -643,17 +643,17 @@ public:
using SelfType = ValueIterator;
ValueIterator() = default;
ValueIterator(ValueConstIterator const& other);
ValueIterator(ValueIterator const& other);
ValueIterator(const ValueConstIterator& other);
ValueIterator(const ValueIterator& other);
private:
/*! \internal Use by Value to create an iterator.
*/
explicit ValueIterator(Value::ObjectValues::iterator const& current);
explicit ValueIterator(const Value::ObjectValues::iterator& current);
public:
SelfType&
operator=(SelfType const& other);
operator=(const SelfType& other);
SelfType
operator++(int)

View File

@@ -39,7 +39,7 @@ public:
{
}
virtual std::string
write(Value const& root) = 0;
write(const Value& root) = 0;
};
/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format
@@ -60,11 +60,11 @@ public:
public: // overridden from Writer
std::string
write(Value const& root) override;
write(const Value& root) override;
private:
void
writeValue(Value const& value);
writeValue(const Value& value);
std::string document_;
};
@@ -101,15 +101,15 @@ public: // overridden from Writer
* JSON document that represents the root value.
*/
std::string
write(Value const& root) override;
write(const Value& root) override;
private:
void
writeValue(Value const& value);
writeValue(const Value& value);
void
writeArrayValue(Value const& value);
writeArrayValue(const Value& value);
bool
isMultineArray(Value const& value);
isMultineArray(const Value& value);
void
pushValue(std::string const& value);
void
@@ -168,15 +168,15 @@ public:
* return a value.
*/
void
write(std::ostream& out, Value const& root);
write(std::ostream& out, const Value& root);
private:
void
writeValue(Value const& value);
writeValue(const Value& value);
void
writeArrayValue(Value const& value);
writeArrayValue(const Value& value);
bool
isMultineArray(Value const& value);
isMultineArray(const Value& value);
void
pushValue(std::string const& value);
void
@@ -207,12 +207,12 @@ valueToString(double value);
std::string
valueToString(bool value);
std::string
valueToQuotedString(char const* value);
valueToQuotedString(const char* value);
/// \brief Output using the StyledStreamWriter.
/// \see Json::operator>>()
std::ostream&
operator<<(std::ostream&, Value const& root);
operator<<(std::ostream&, const Value& root);
//------------------------------------------------------------------------------

View File

@@ -37,7 +37,7 @@ pretty(Value const&);
/** Output using the StyledStreamWriter. @see Json::operator>>(). */
std::ostream&
operator<<(std::ostream&, Value const& root);
operator<<(std::ostream&, const Value& root);
} // namespace Json

View File

@@ -149,7 +149,7 @@ namespace std {
template <>
struct hash<ripple::AccountID> : ripple::AccountID::hasher
{
hash() = default;
explicit hash() = default;
};
} // namespace std

View File

@@ -1,37 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2024 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <xrpl/protocol/HashPrefix.h>
#include <xrpl/protocol/STVector256.h>
#include <xrpl/protocol/Serializer.h>
namespace ripple {
inline void
serializeBatch(
Serializer& msg,
std::uint32_t const& flags,
std::vector<uint256> const& txids)
{
msg.add32(HashPrefix::batch);
msg.add32(flags);
msg.add32(std::uint32_t(txids.size()));
for (auto const& txid : txids)
msg.addBitString(txid);
}
} // namespace ripple

View File

@@ -21,7 +21,6 @@
#define RIPPLE_PROTOCOL_BOOK_H_INCLUDED
#include <xrpl/basics/CountedObject.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/protocol/Issue.h>
#include <boost/utility/base_from_member.hpp>
@@ -37,17 +36,12 @@ class Book final : public CountedObject<Book>
public:
Issue in;
Issue out;
std::optional<uint256> domain;
Book()
{
}
Book(
Issue const& in_,
Issue const& out_,
std::optional<uint256> const& domain_)
: in(in_), out(out_), domain(domain_)
Book(Issue const& in_, Issue const& out_) : in(in_), out(out_)
{
}
};
@@ -67,8 +61,6 @@ hash_append(Hasher& h, Book const& b)
{
using beast::hash_append;
hash_append(h, b.in, b.out);
if (b.domain)
hash_append(h, *(b.domain));
}
Book
@@ -79,8 +71,7 @@ reversed(Book const& book);
[[nodiscard]] inline constexpr bool
operator==(Book const& lhs, Book const& rhs)
{
return (lhs.in == rhs.in) && (lhs.out == rhs.out) &&
(lhs.domain == rhs.domain);
return (lhs.in == rhs.in) && (lhs.out == rhs.out);
}
/** @} */
@@ -91,18 +82,7 @@ operator<=>(Book const& lhs, Book const& rhs)
{
if (auto const c{lhs.in <=> rhs.in}; c != 0)
return c;
if (auto const c{lhs.out <=> rhs.out}; c != 0)
return c;
// Manually compare optionals
if (lhs.domain && rhs.domain)
return *lhs.domain <=> *rhs.domain; // Compare values if both exist
if (!lhs.domain && rhs.domain)
return std::weak_ordering::less; // Empty is considered less
if (lhs.domain && !rhs.domain)
return std::weak_ordering::greater; // Non-empty is greater
return std::weak_ordering::equivalent; // Both are empty
return lhs.out <=> rhs.out;
}
/** @} */
@@ -124,7 +104,7 @@ private:
boost::base_from_member<std::hash<ripple::AccountID>, 1>;
public:
hash() = default;
explicit hash() = default;
using value_type = std::size_t;
using argument_type = ripple::Issue;
@@ -146,14 +126,12 @@ template <>
struct hash<ripple::Book>
{
private:
using issue_hasher = std::hash<ripple::Issue>;
using uint256_hasher = ripple::uint256::hasher;
using hasher = std::hash<ripple::Issue>;
issue_hasher m_issue_hasher;
uint256_hasher m_uint256_hasher;
hasher m_hasher;
public:
hash() = default;
explicit hash() = default;
using value_type = std::size_t;
using argument_type = ripple::Book;
@@ -161,12 +139,8 @@ public:
value_type
operator()(argument_type const& value) const
{
value_type result(m_issue_hasher(value.in));
boost::hash_combine(result, m_issue_hasher(value.out));
if (value.domain)
boost::hash_combine(result, m_uint256_hasher(*value.domain));
value_type result(m_hasher(value.in));
boost::hash_combine(result, m_hasher(value.out));
return result;
}
};
@@ -180,7 +154,7 @@ namespace boost {
template <>
struct hash<ripple::Issue> : std::hash<ripple::Issue>
{
hash() = default;
explicit hash() = default;
using Base = std::hash<ripple::Issue>;
// VFALCO NOTE broken in vs2012
@@ -190,7 +164,7 @@ struct hash<ripple::Issue> : std::hash<ripple::Issue>
template <>
struct hash<ripple::Book> : std::hash<ripple::Book>
{
hash() = default;
explicit hash() = default;
using Base = std::hash<ripple::Book>;
// VFALCO NOTE broken in vs2012

View File

@@ -120,7 +120,7 @@ enum error_code_i {
rpcSRC_ACT_MALFORMED = 65,
rpcSRC_ACT_MISSING = 66,
rpcSRC_ACT_NOT_FOUND = 67,
rpcDELEGATE_ACT_NOT_FOUND = 68,
// unused 68,
rpcSRC_CUR_MALFORMED = 69,
rpcSRC_ISR_MALFORMED = 70,
rpcSTREAM_MALFORMED = 71,
@@ -154,10 +154,7 @@ enum error_code_i {
// Simulate
rpcTX_SIGNED = 96,
// Pathfinding
rpcDOMAIN_MALFORMED = 97,
rpcLAST = rpcDOMAIN_MALFORMED // rpcLAST should always equal the last code.
rpcLAST = rpcTX_SIGNED // rpcLAST should always equal the last code.
};
/** Codes returned in the `warnings` array of certain RPC commands.

View File

@@ -88,9 +88,6 @@ enum class HashPrefix : std::uint32_t {
/** Credentials signature */
credential = detail::make_hash_prefix('C', 'R', 'D'),
/** Batch */
batch = detail::make_hash_prefix('B', 'C', 'H'),
};
template <class Hasher>

View File

@@ -98,12 +98,6 @@ public:
static IOUAmount
minPositiveAmount();
friend std::ostream&
operator<<(std::ostream& os, IOUAmount const& x)
{
return os << to_string(x);
}
};
inline IOUAmount::IOUAmount(beast::Zero)

View File

@@ -279,10 +279,6 @@ amm(Asset const& issue1, Asset const& issue2) noexcept;
Keylet
amm(uint256 const& amm) noexcept;
/** A keylet for Delegate object */
Keylet
delegate(AccountID const& account, AccountID const& authorizedAccount) noexcept;
Keylet
bridge(STXChainBridge const& bridge, STXChainBridge::ChainType chainType);
@@ -343,6 +339,24 @@ vault(uint256 const& vaultKey)
return {ltVAULT, vaultKey};
}
Keylet
loanbroker(AccountID const& owner, std::uint32_t seq) noexcept;
inline Keylet
loanbroker(uint256 const& vaultKey)
{
return {ltLOAN_BROKER, vaultKey};
}
Keylet
loan(uint256 const& loanBrokerID, std::uint32_t loanSeq) noexcept;
inline Keylet
loan(uint256 const& vaultKey)
{
return {ltLOAN, vaultKey};
}
Keylet
permissionedDomain(AccountID const& account, std::uint32_t seq) noexcept;

View File

@@ -145,15 +145,13 @@ enum LedgerSpecificFlags {
0x10000000, // True, reject new paychans
lsfDisallowIncomingTrustline =
0x20000000, // True, reject new trustlines (only if no issued assets)
lsfAllowTrustLineLocking =
0x40000000, // True, enable trustline locking
// 0x40000000 is available
lsfAllowTrustLineClawback =
0x80000000, // True, enable clawback
// ltOFFER
lsfPassive = 0x00010000,
lsfSell = 0x00020000, // True, offer was placed as a sell.
lsfHybrid = 0x00040000, // True, offer is hybrid.
// ltRIPPLE_STATE
lsfLowReserve = 0x00010000, // True, if entry counts toward reserve.
@@ -196,6 +194,11 @@ enum LedgerSpecificFlags {
// ltVAULT
lsfVaultPrivate = 0x00010000,
// ltLOAN
lsfLoanDefault = 0x00010000,
lsfLoanImpaired = 0x00020000,
lsfLoanOverpayment = 0x00040000, // True, loan allows overpayments
};
//------------------------------------------------------------------------------

View File

@@ -80,7 +80,7 @@ struct MultiApiJson
}
void
set(char const* key, auto const& v)
set(const char* key, auto const& v)
requires std::constructible_from<Json::Value, decltype(v)>
{
for (auto& a : this->val)
@@ -91,7 +91,7 @@ struct MultiApiJson
enum IsMemberResult : int { none = 0, some, all };
[[nodiscard]] IsMemberResult
isMember(char const* key) const
isMember(const char* key) const
{
int count = 0;
for (auto& a : this->val)

View File

@@ -1,97 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2025 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PROTOCOL_PERMISSION_H_INCLUDED
#define RIPPLE_PROTOCOL_PERMISSION_H_INCLUDED
#include <xrpl/protocol/TxFormats.h>
#include <optional>
#include <string>
#include <unordered_map>
#include <unordered_set>
namespace ripple {
/**
* We have both transaction type permissions and granular type permissions.
* Since we will reuse the TransactionFormats to parse the Transaction
* Permissions, only the GranularPermissionType is defined here. To prevent
* conflicts with TxType, the GranularPermissionType is always set to a value
* greater than the maximum value of uint16.
*/
enum GranularPermissionType : std::uint32_t {
#pragma push_macro("PERMISSION")
#undef PERMISSION
#define PERMISSION(type, txType, value) type = value,
#include <xrpl/protocol/detail/permissions.macro>
#undef PERMISSION
#pragma pop_macro("PERMISSION")
};
enum Delegation { delegatable, notDelegatable };
class Permission
{
private:
Permission();
std::unordered_map<std::uint16_t, Delegation> delegatableTx_;
std::unordered_map<std::string, GranularPermissionType>
granularPermissionMap_;
std::unordered_map<GranularPermissionType, std::string> granularNameMap_;
std::unordered_map<GranularPermissionType, TxType> granularTxTypeMap_;
public:
static Permission const&
getInstance();
Permission(Permission const&) = delete;
Permission&
operator=(Permission const&) = delete;
std::optional<std::uint32_t>
getGranularValue(std::string const& name) const;
std::optional<std::string>
getGranularName(GranularPermissionType const& value) const;
std::optional<TxType>
getGranularTxType(GranularPermissionType const& gpType) const;
bool
isDelegatable(std::uint32_t const& permissionValue) const;
// for tx level permission, permission value is equal to tx type plus one
uint32_t
txToPermissionType(TxType const& type) const;
// tx type value is permission value minus one
TxType
permissionToTxType(uint32_t const& value) const;
};
} // namespace ripple
#endif

View File

@@ -23,6 +23,8 @@
#include <xrpl/basics/ByteUtilities.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/partitioned_unordered_map.h>
#include <xrpl/basics/safe_cast.h>
#include <xrpl/protocol/Units.h>
#include <cstdint>
@@ -82,6 +84,90 @@ std::size_t constexpr maxDeletableTokenOfferEntries = 500;
*/
std::uint16_t constexpr maxTransferFee = 50000;
/** There are 10,000 basis points (bips) in 100%.
*
* Basis points represent 0.01%.
*
* Given a value X, to find the amount for B bps,
* use X * B / bipsPerUnity
*
* Example: If a loan broker has 999 XRP of debt, and must maintain 1,000 bps of
* that debt as cover (10%), then the minimum cover amount is 999,000,000 drops
* * 1000 / bipsPerUnity = 99,900,00 drops or 99.9 XRP.
*
* Given a percentage P, to find the number of bps that percentage represents,
* use P * bipsPerUnity.
*
* Example: 50% is 0.50 * bipsPerUnity = 5,000 bps.
*/
Bips32 constexpr bipsPerUnity(100 * 100);
TenthBips32 constexpr tenthBipsPerUnity(bipsPerUnity.value() * 10);
constexpr Bips32
percentageToBips(std::uint32_t percentage)
{
return Bips32(percentage * bipsPerUnity.value() / 100);
}
constexpr TenthBips32
percentageToTenthBips(std::uint32_t percentage)
{
return TenthBips32(percentage * tenthBipsPerUnity.value() / 100);
}
template <typename T, class TBips>
constexpr T
bipsOfValue(T value, Bips<TBips> bips)
{
return value * bips.value() / bipsPerUnity.value();
}
template <typename T, class TBips>
constexpr T
tenthBipsOfValue(T value, TenthBips<TBips> bips)
{
return value * bips.value() / tenthBipsPerUnity.value();
}
/** The maximum management fee rate allowed by a loan broker in 1/10 bips.
Valid values are between 0 and 10% inclusive.
*/
TenthBips16 constexpr maxManagementFeeRate(
unsafe_cast<std::uint16_t>(percentageToTenthBips(10).value()));
static_assert(maxManagementFeeRate == TenthBips16(std::uint16_t(10'000u)));
/** The maximum coverage rate required of a loan broker in 1/10 bips.
Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxCoverRate = percentageToTenthBips(100);
static_assert(maxCoverRate == TenthBips32(100'000u));
/** The maximum overpayment fee on a loan in 1/10 bips.
*
Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxOverpaymentFee = percentageToTenthBips(100);
/** The maximum premium added to the interest rate for late payments on a loan
* in 1/10 bips.
*
* Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxLateInterestRate = percentageToTenthBips(100);
/** The maximum close interest rate charged for repaying a loan early in 1/10
* bips.
*
* Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxCloseInterestRate = percentageToTenthBips(100);
/** The maximum overpayment interest rate charged on loan overpayments in 1/10
* bips.
*
* Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxOverpaymentInterestRate = percentageToTenthBips(100);
/** The maximum length of a URI inside an NFT */
std::size_t constexpr maxTokenURILength = 256;
@@ -165,13 +251,6 @@ std::size_t constexpr maxPriceScale = 20;
*/
std::size_t constexpr maxTrim = 25;
/** The maximum number of delegate permissions an account can grant
*/
std::size_t constexpr permissionMaxSize = 10;
/** The maximum number of transactions that can be in a batch. */
std::size_t constexpr maxBatchTxCount = 8;
} // namespace ripple
#endif

View File

@@ -113,8 +113,8 @@ public:
// have lower unsigned integer representations.
using value_type = std::uint64_t;
static int const minTickSize = 3;
static int const maxTickSize = 16;
static const int minTickSize = 3;
static const int maxTickSize = 16;
private:
// This has the same representation as STAmount, see the comment on the

View File

@@ -28,9 +28,6 @@
namespace ripple {
bool
isFeatureEnabled(uint256 const& feature);
class DigestAwareReadView;
/** Rules controlling protocol behavior. */

View File

@@ -22,6 +22,7 @@
#include <xrpl/basics/safe_cast.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/Units.h>
#include <cstdint>
#include <map>
@@ -53,6 +54,9 @@ class STXChainBridge;
class STVector256;
class STCurrency;
template <class Integer>
concept HasValue = requires(Integer i) { i.value(); };
#pragma push_macro("XMACRO")
#undef XMACRO
@@ -135,9 +139,9 @@ field_code(int id, int index)
the binary format of the transaction can be canonicalized. All
SFields are created at compile time.
Each SField, once constructed, lives until program termination, and there
is only one instance per fieldType/fieldValue pair which serves the entire
application.
Each SField, once constructed, lives until program termination, and
there is only one instance per fieldType/fieldValue pair which serves the
entire application.
*/
class SField
{
@@ -148,8 +152,11 @@ public:
sMD_ChangeNew = 0x02, // new value when it changes
sMD_DeleteFinal = 0x04, // final value when it is deleted
sMD_Create = 0x08, // value when it's created
sMD_Always = 0x10, // value when node containing it is affected at all
sMD_BaseTen = 0x20,
sMD_Always = 0x10, // value when node containing it is affected at all
sMD_BaseTen = 0x20, // value is treated as base 10, overriding
// default behavior
sMD_PseudoAccount = 0x40, // if this field is set in an ACCOUNT_ROOT
// _only_, then it is a pseudo-account
sMD_Default =
sMD_ChangeOrig | sMD_ChangeNew | sMD_DeleteFinal | sMD_Create
};
@@ -174,29 +181,30 @@ public:
operator=(SField&&) = delete;
public:
struct private_access_tag_t; // public, but still an implementation detail
struct private_access_tag_t; // public, but still an implementation
// detail
// These constructors can only be called from SField.cpp
SField(
private_access_tag_t,
SerializedTypeID tid,
int fv,
char const* fn,
const char* fn,
int meta = sMD_Default,
IsSigning signing = IsSigning::yes);
explicit SField(private_access_tag_t, int fc);
static SField const&
static const SField&
getField(int fieldCode);
static SField const&
static const SField&
getField(std::string const& fieldName);
static SField const&
static const SField&
getField(int type, int value)
{
return getField(field_code(type, value));
}
static SField const&
static const SField&
getField(SerializedTypeID type, int value)
{
return getField(field_code(type, value));
@@ -283,19 +291,19 @@ public:
}
bool
operator==(SField const& f) const
operator==(const SField& f) const
{
return fieldCode == f.fieldCode;
}
bool
operator!=(SField const& f) const
operator!=(const SField& f) const
{
return fieldCode != f.fieldCode;
}
static int
compare(SField const& f1, SField const& f2);
compare(const SField& f1, const SField& f2);
static std::map<int, SField const*> const&
getKnownCodeToField()
@@ -306,6 +314,7 @@ public:
private:
static int num;
static std::map<int, SField const*> knownCodeToField;
static std::map<std::string, SField const*> knownNameToField;
};
/** A field with a type known at compile time. */

View File

@@ -58,7 +58,7 @@ public:
add(Serializer& s) const override;
bool
isEquivalent(STBase const& t) const override;
isEquivalent(const STBase& t) const override;
bool
isDefault() const override;

View File

@@ -62,20 +62,20 @@ private:
public:
using value_type = STAmount;
static int const cMinOffset = -96;
static int const cMaxOffset = 80;
static const int cMinOffset = -96;
static const int cMaxOffset = 80;
// Maximum native value supported by the code
static std::uint64_t const cMinValue = 1000000000000000ull;
static std::uint64_t const cMaxValue = 9999999999999999ull;
static std::uint64_t const cMaxNative = 9000000000000000000ull;
static const std::uint64_t cMinValue = 1000000000000000ull;
static const std::uint64_t cMaxValue = 9999999999999999ull;
static const std::uint64_t cMaxNative = 9000000000000000000ull;
// Max native value on network.
static std::uint64_t const cMaxNativeN = 100000000000000000ull;
static std::uint64_t const cIssuedCurrency = 0x8000000000000000ull;
static std::uint64_t const cPositive = 0x4000000000000000ull;
static std::uint64_t const cMPToken = 0x2000000000000000ull;
static std::uint64_t const cValueMask = ~(cPositive | cMPToken);
static const std::uint64_t cMaxNativeN = 100000000000000000ull;
static const std::uint64_t cIssuedCurrency = 0x8000000000000000ull;
static const std::uint64_t cPositive = 0x4000000000000000ull;
static const std::uint64_t cMPToken = 0x2000000000000000ull;
static const std::uint64_t cValueMask = ~(cPositive | cMPToken);
static std::uint64_t const uRateOne;
@@ -283,7 +283,7 @@ public:
add(Serializer& s) const override;
bool
isEquivalent(STBase const& t) const override;
isEquivalent(const STBase& t) const override;
bool
isDefault() const override;
@@ -695,6 +695,16 @@ divRoundStrict(
std::uint64_t
getRate(STAmount const& offerOut, STAmount const& offerIn);
template <AssetType A>
Number
roundToAsset(A const& asset, Number const& value)
{
STAmount const amount{asset, value};
if (amount != value)
return amount;
return value;
}
//------------------------------------------------------------------------------
inline bool
@@ -703,12 +713,6 @@ isXRP(STAmount const& amount)
return amount.native();
}
bool
canAdd(STAmount const& amt1, STAmount const& amt2);
bool
canSubtract(STAmount const& amt1, STAmount const& amt2);
// Since `canonicalize` does not have access to a ledger, this is needed to put
// the low-level routine stAmountCanonicalize on an amendment switch. Only
// transactions need to use this switchover. Outside of a transaction it's safe

View File

@@ -128,13 +128,13 @@ public:
add(Serializer& s) const override;
void
sort(bool (*compare)(STObject const& o1, STObject const& o2));
sort(bool (*compare)(const STObject& o1, const STObject& o2));
bool
operator==(STArray const& s) const;
operator==(const STArray& s) const;
bool
operator!=(STArray const& s) const;
operator!=(const STArray& s) const;
iterator
erase(iterator pos);
@@ -152,7 +152,7 @@ public:
getSType() const override;
bool
isEquivalent(STBase const& t) const override;
isEquivalent(const STBase& t) const override;
bool
isDefault() const override;
@@ -275,13 +275,13 @@ STArray::swap(STArray& a) noexcept
}
inline bool
STArray::operator==(STArray const& s) const
STArray::operator==(const STArray& s) const
{
return v_ == s.v_;
}
inline bool
STArray::operator!=(STArray const& s) const
STArray::operator!=(const STArray& s) const
{
return v_ != s.v_;
}

View File

@@ -139,16 +139,16 @@ class STBase
public:
virtual ~STBase() = default;
STBase();
STBase(STBase const&) = default;
STBase(const STBase&) = default;
STBase&
operator=(STBase const& t);
operator=(const STBase& t);
explicit STBase(SField const& n);
bool
operator==(STBase const& t) const;
operator==(const STBase& t) const;
bool
operator!=(STBase const& t) const;
operator!=(const STBase& t) const;
template <class D>
D&
@@ -207,7 +207,7 @@ private:
//------------------------------------------------------------------------------
std::ostream&
operator<<(std::ostream& out, STBase const& t);
operator<<(std::ostream& out, const STBase& t);
template <class D>
D&

View File

@@ -45,8 +45,8 @@ public:
STBitString() = default;
STBitString(SField const& n);
STBitString(value_type const& v);
STBitString(SField const& n, value_type const& v);
STBitString(const value_type& v);
STBitString(SField const& n, const value_type& v);
STBitString(SerialIter& sit, SField const& name);
SerializedTypeID
@@ -56,7 +56,7 @@ public:
getText() const override;
bool
isEquivalent(STBase const& t) const override;
isEquivalent(const STBase& t) const override;
void
add(Serializer& s) const override;
@@ -93,12 +93,12 @@ inline STBitString<Bits>::STBitString(SField const& n) : STBase(n)
}
template <int Bits>
inline STBitString<Bits>::STBitString(value_type const& v) : value_(v)
inline STBitString<Bits>::STBitString(const value_type& v) : value_(v)
{
}
template <int Bits>
inline STBitString<Bits>::STBitString(SField const& n, value_type const& v)
inline STBitString<Bits>::STBitString(SField const& n, const value_type& v)
: STBase(n), value_(v)
{
}
@@ -160,9 +160,9 @@ STBitString<Bits>::getText() const
template <int Bits>
bool
STBitString<Bits>::isEquivalent(STBase const& t) const
STBitString<Bits>::isEquivalent(const STBase& t) const
{
STBitString const* v = dynamic_cast<STBitString const*>(&t);
const STBitString* v = dynamic_cast<const STBitString*>(&t);
return v && (value_ == v->value_);
}

View File

@@ -63,7 +63,7 @@ public:
add(Serializer& s) const override;
bool
isEquivalent(STBase const& t) const override;
isEquivalent(const STBase& t) const override;
bool
isDefault() const override;

View File

@@ -65,7 +65,7 @@ public:
add(Serializer& s) const override;
bool
isEquivalent(STBase const& t) const override;
isEquivalent(const STBase& t) const override;
bool
isDefault() const override;

View File

@@ -21,6 +21,7 @@
#define RIPPLE_PROTOCOL_STINTEGER_H_INCLUDED
#include <xrpl/basics/CountedObject.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/STBase.h>
namespace ripple {
@@ -36,7 +37,7 @@ private:
public:
explicit STInteger(Integer v);
STInteger(SField const& n, Integer v = 0);
STInteger(SField const& n, Integer v = {});
STInteger(SerialIter& sit, SField const& name);
SerializedTypeID
@@ -54,7 +55,7 @@ public:
isDefault() const override;
bool
isEquivalent(STBase const& t) const override;
isEquivalent(const STBase& t) const override;
STInteger&
operator=(value_type const& v);
@@ -122,14 +123,14 @@ template <typename Integer>
inline bool
STInteger<Integer>::isDefault() const
{
return value_ == 0;
return value_ == Integer{};
}
template <typename Integer>
inline bool
STInteger<Integer>::isEquivalent(STBase const& t) const
STInteger<Integer>::isEquivalent(const STBase& t) const
{
STInteger const* v = dynamic_cast<STInteger const*>(&t);
const STInteger* v = dynamic_cast<const STInteger*>(&t);
return v && (value_ == v->value_);
}

View File

@@ -48,6 +48,12 @@ public:
STIssue&
operator=(STIssue const& rhs) = default;
STIssue&
operator=(Asset const& rhs)
{
asset_ = rhs;
return *this;
}
template <ValidIssueType TIss>
TIss const&
@@ -75,7 +81,7 @@ public:
add(Serializer& s) const override;
bool
isEquivalent(STBase const& t) const override;
isEquivalent(const STBase& t) const override;
bool
isDefault() const override;

View File

@@ -26,7 +26,9 @@
namespace ripple {
class Rules;
namespace test {
class Invariants_test;
}
class STLedgerEntry final : public STObject, public CountedObject<STLedgerEntry>
{
@@ -35,7 +37,9 @@ class STLedgerEntry final : public STObject, public CountedObject<STLedgerEntry>
public:
using pointer = std::shared_ptr<STLedgerEntry>;
using ref = std::shared_ptr<STLedgerEntry> const&;
using ref = const std::shared_ptr<STLedgerEntry>&;
using const_pointer = std::shared_ptr<STLedgerEntry const>;
using const_ref = const std::shared_ptr<STLedgerEntry const>&;
/** Create an empty object with the given key and type. */
explicit STLedgerEntry(Keylet const& k);
@@ -54,7 +58,7 @@ public:
getText() const override;
Json::Value
getJson(JsonOptions options) const override;
getJson(JsonOptions options = JsonOptions::none) const override;
/** Returns the 'key' (or 'index') of this item.
The key identifies this entry's position in
@@ -84,7 +88,8 @@ private:
void
setSLEType();
friend Invariants_test; // this test wants access to the private type_
friend test::Invariants_test; // this test wants access to the private
// type_
STBase*
copy(std::size_t n, void* buf) const override;

View File

@@ -25,7 +25,6 @@
#include <xrpl/basics/chrono.h>
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/FeeUnits.h>
#include <xrpl/protocol/HashPrefix.h>
#include <xrpl/protocol/SOTemplate.h>
#include <xrpl/protocol/STAmount.h>
@@ -34,6 +33,7 @@
#include <xrpl/protocol/STIssue.h>
#include <xrpl/protocol/STPathSet.h>
#include <xrpl/protocol/STVector256.h>
#include <xrpl/protocol/Units.h>
#include <xrpl/protocol/detail/STVar.h>
#include <boost/iterator/transform_iterator.hpp>
@@ -99,8 +99,8 @@ public:
STObject&
operator=(STObject&& other);
STObject(SOTemplate const& type, SField const& name);
STObject(SOTemplate const& type, SerialIter& sit, SField const& name);
STObject(const SOTemplate& type, SField const& name);
STObject(const SOTemplate& type, SerialIter& sit, SField const& name);
STObject(SerialIter& sit, SField const& name, int depth = 0);
STObject(SerialIter&& sit, SField const& name);
explicit STObject(SField const& name);
@@ -121,7 +121,7 @@ public:
reserve(std::size_t n);
void
applyTemplate(SOTemplate const& type);
applyTemplate(const SOTemplate& type);
void
applyTemplateFromSField(SField const&);
@@ -130,7 +130,7 @@ public:
isFree() const;
void
set(SOTemplate const&);
set(const SOTemplate&);
bool
set(SerialIter& u, int depth = 0);
@@ -139,7 +139,7 @@ public:
getSType() const override;
bool
isEquivalent(STBase const& t) const override;
isEquivalent(const STBase& t) const override;
bool
isDefault() const override;
@@ -182,13 +182,13 @@ public:
uint256
getSigningHash(HashPrefix prefix) const;
STBase const&
const STBase&
peekAtIndex(int offset) const;
STBase&
getIndex(int offset);
STBase const*
const STBase*
peekAtPIndex(int offset) const;
STBase*
@@ -200,13 +200,13 @@ public:
SField const&
getFieldSType(int index) const;
STBase const&
const STBase&
peekAtField(SField const& field) const;
STBase&
getField(SField const& field);
STBase const*
const STBase*
peekAtPField(SField const& field) const;
STBase*
@@ -240,11 +240,14 @@ public:
getFieldAmount(SField const& field) const;
STPathSet const&
getFieldPathSet(SField const& field) const;
STVector256 const&
const STVector256&
getFieldV256(SField const& field) const;
STArray const&
// If not found, returns an object constructed with the given field
STObject
getFieldObject(SField const& field) const;
const STArray&
getFieldArray(SField const& field) const;
STCurrency const&
const STCurrency&
getFieldCurrency(SField const& field) const;
STNumber const&
getFieldNumber(SField const& field) const;
@@ -408,12 +411,12 @@ public:
delField(int index);
bool
hasMatchingEntry(STBase const&);
hasMatchingEntry(const STBase&);
bool
operator==(STObject const& o) const;
operator==(const STObject& o) const;
bool
operator!=(STObject const& o) const;
operator!=(const STObject& o) const;
class FieldErr;
@@ -515,7 +518,26 @@ protected:
// Constraint += and -= ValueProxy operators
// to value types that support arithmetic operations
template <typename U>
concept IsArithmetic = std::is_arithmetic_v<U> || std::is_same_v<U, STAmount>;
concept IsArithmeticNumber = std::is_arithmetic_v<U> ||
std::is_same_v<U, Number> || std::is_same_v<U, STAmount>;
template <
typename U,
typename Value = typename U::value_type,
typename Unit = typename U::unit_type>
concept IsArithmeticValueUnit =
std::is_same_v<U, unit::ValueUnit<Unit, Value>> &&
IsArithmeticNumber<Value> && std::is_class_v<Unit>;
template <typename U, typename Value = typename U::value_type>
concept IsArithmeticST = !IsArithmeticValueUnit<U> && IsArithmeticNumber<Value>;
template <typename U>
concept IsArithmetic =
IsArithmeticNumber<U> || IsArithmeticST<U> || IsArithmeticValueUnit<U>;
template <class T, class U>
concept Addable = requires(T t, U u) { t = t + u; };
template <typename T, typename U>
concept IsArithmeticCompatible =
IsArithmetic<typename T::value_type> && Addable<typename T::value_type, U>;
template <class T>
class STObject::ValueProxy : public Proxy<T>
@@ -535,10 +557,12 @@ public:
// Convenience operators for value types supporting
// arithmetic operations
template <IsArithmetic U>
requires IsArithmeticCompatible<T, U>
ValueProxy&
operator+=(U const& u);
template <IsArithmetic U>
requires IsArithmeticCompatible<T, U>
ValueProxy&
operator-=(U const& u);
@@ -774,6 +798,7 @@ STObject::ValueProxy<T>::operator=(U&& u)
template <typename T>
template <IsArithmetic U>
requires IsArithmeticCompatible<T, U>
STObject::ValueProxy<T>&
STObject::ValueProxy<T>::operator+=(U const& u)
{
@@ -783,6 +808,7 @@ STObject::ValueProxy<T>::operator+=(U const& u)
template <class T>
template <IsArithmetic U>
requires IsArithmeticCompatible<T, U>
STObject::ValueProxy<T>&
STObject::ValueProxy<T>::operator-=(U const& u)
{
@@ -981,7 +1007,7 @@ STObject::getCount() const
return v_.size();
}
inline STBase const&
inline const STBase&
STObject::peekAtIndex(int offset) const
{
return v_[offset].get();
@@ -993,7 +1019,7 @@ STObject::getIndex(int offset)
return v_[offset].get();
}
inline STBase const*
inline const STBase*
STObject::peekAtPIndex(int offset) const
{
return &v_[offset].get();
@@ -1128,7 +1154,7 @@ STObject::setFieldH160(SField const& field, base_uint<160, Tag> const& v)
}
inline bool
STObject::operator!=(STObject const& o) const
STObject::operator!=(const STObject& o) const
{
return !(*this == o);
}
@@ -1137,7 +1163,7 @@ template <typename T, typename V>
V
STObject::getFieldByValue(SField const& field) const
{
STBase const* rf = peekAtPField(field);
const STBase* rf = peekAtPField(field);
if (!rf)
throwFieldNotFound(field);
@@ -1147,7 +1173,7 @@ STObject::getFieldByValue(SField const& field) const
if (id == STI_NOTPRESENT)
return V(); // optional field not present
T const* cf = dynamic_cast<T const*>(rf);
const T* cf = dynamic_cast<const T*>(rf);
if (!cf)
Throw<std::runtime_error>("Wrong field type");
@@ -1164,7 +1190,7 @@ template <typename T, typename V>
V const&
STObject::getFieldByConstRef(SField const& field, V const& empty) const
{
STBase const* rf = peekAtPField(field);
const STBase* rf = peekAtPField(field);
if (!rf)
throwFieldNotFound(field);
@@ -1174,7 +1200,7 @@ STObject::getFieldByConstRef(SField const& field, V const& empty) const
if (id == STI_NOTPRESENT)
return empty; // optional field not present
T const* cf = dynamic_cast<T const*>(rf);
const T* cf = dynamic_cast<const T*>(rf);
if (!cf)
Throw<std::runtime_error>("Wrong field type");

View File

@@ -106,10 +106,10 @@ public:
getIssuerID() const;
bool
operator==(STPathElement const& t) const;
operator==(const STPathElement& t) const;
bool
operator!=(STPathElement const& t) const;
operator!=(const STPathElement& t) const;
private:
static std::size_t
@@ -164,7 +164,7 @@ public:
STPathElement&
operator[](int i);
STPathElement const&
const STPathElement&
operator[](int i) const;
void
@@ -196,7 +196,7 @@ public:
assembleAdd(STPath const& base, STPathElement const& tail);
bool
isEquivalent(STBase const& t) const override;
isEquivalent(const STBase& t) const override;
bool
isDefault() const override;
@@ -375,7 +375,7 @@ STPathElement::getIssuerID() const
}
inline bool
STPathElement::operator==(STPathElement const& t) const
STPathElement::operator==(const STPathElement& t) const
{
return (mType & typeAccount) == (t.mType & typeAccount) &&
hash_value_ == t.hash_value_ && mAccountID == t.mAccountID &&
@@ -383,7 +383,7 @@ STPathElement::operator==(STPathElement const& t) const
}
inline bool
STPathElement::operator!=(STPathElement const& t) const
STPathElement::operator!=(const STPathElement& t) const
{
return !operator==(t);
}
@@ -455,7 +455,7 @@ STPath::operator[](int i)
return mPath[i];
}
inline STPathElement const&
inline const STPathElement&
STPath::operator[](int i) const
{
return mPath[i];

View File

@@ -88,7 +88,13 @@ public:
// Outer transaction functions / signature functions.
Blob
getSignature() const;
getSignature(STObject const& sigObject) const;
Blob
getSignature() const
{
return getSignature(*this);
}
uint256
getSigningHash() const;
@@ -121,20 +127,32 @@ public:
void
sign(PublicKey const& publicKey, SecretKey const& secretKey);
/** Check the signature.
@return `true` if valid signature. If invalid, the error message string.
*/
enum class RequireFullyCanonicalSig : bool { no, yes };
/** Check the signature.
@param requireCanonicalSig If `true`, check that the signature is fully
canonical. If `false`, only check that the signature is valid.
@param rules The current ledger rules.
@param pSig Pointer to object that contains the signature fields, if not
using "this". Will most often be null
@return `true` if valid signature. If invalid, the error message string.
*/
Expected<void, std::string>
checkSign(
RequireFullyCanonicalSig requireCanonicalSig,
Rules const& rules,
STObject const* pSig) const;
/** Check the signature.
@param requireCanonicalSig If `true`, check that the signature is fully
canonical. If `false`, only check that the signature is valid.
@param rules The current ledger rules.
@return `true` if valid signature. If invalid, the error message string.
*/
Expected<void, std::string>
checkSign(RequireFullyCanonicalSig requireCanonicalSig, Rules const& rules)
const;
Expected<void, std::string>
checkBatchSign(
RequireFullyCanonicalSig requireCanonicalSig,
Rules const& rules) const;
// SQL Functions with metadata.
static std::string const&
getMetaSQLInsertReplaceHeader();
@@ -150,28 +168,17 @@ public:
char status,
std::string const& escapedMetaData) const;
std::vector<uint256>
getBatchTransactionIDs() const;
private:
Expected<void, std::string>
checkSingleSign(RequireFullyCanonicalSig requireCanonicalSig) const;
checkSingleSign(
RequireFullyCanonicalSig requireCanonicalSig,
STObject const* pSig) const;
Expected<void, std::string>
checkMultiSign(
RequireFullyCanonicalSig requireCanonicalSig,
Rules const& rules) const;
Expected<void, std::string>
checkBatchSingleSign(
STObject const& batchSigner,
RequireFullyCanonicalSig requireCanonicalSig) const;
Expected<void, std::string>
checkBatchMultiSign(
STObject const& batchSigner,
RequireFullyCanonicalSig requireCanonicalSig,
Rules const& rules) const;
Rules const& rules,
STObject const* pSig) const;
STBase*
copy(std::size_t n, void* buf) const override;
@@ -179,7 +186,6 @@ private:
move(std::size_t n, void* buf) override;
friend class detail::STVar;
mutable std::vector<uint256> batch_txn_ids_;
};
bool

View File

@@ -22,10 +22,10 @@
#include <xrpl/basics/Log.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/FeeUnits.h>
#include <xrpl/protocol/PublicKey.h>
#include <xrpl/protocol/STObject.h>
#include <xrpl/protocol/SecretKey.h>
#include <xrpl/protocol/Units.h>
#include <cstdint>
#include <functional>

View File

@@ -50,7 +50,7 @@ public:
Json::Value getJson(JsonOptions) const override;
bool
isEquivalent(STBase const& t) const override;
isEquivalent(const STBase& t) const override;
bool
isDefault() const override;
@@ -62,7 +62,7 @@ public:
operator=(std::vector<uint256>&& v);
void
setValue(STVector256 const& v);
setValue(const STVector256& v);
/** Retrieve a copy of the vector we contain */
explicit
@@ -153,7 +153,7 @@ STVector256::operator=(std::vector<uint256>&& v)
}
inline void
STVector256::setValue(STVector256 const& v)
STVector256::setValue(const STVector256& v)
{
mValue = v.mValue;
}

View File

@@ -107,7 +107,7 @@ public:
add(Serializer& s) const override;
bool
isEquivalent(STBase const& t) const override;
isEquivalent(const STBase& t) const override;
bool
isDefault() const override;

View File

@@ -125,8 +125,17 @@ public:
}
template <typename Integer>
requires(!HasValue<Integer>)
int addInteger(Integer);
template <typename Integer>
requires HasValue<Integer>
int
addInteger(Integer i)
{
return addInteger(i.value());
}
template <std::size_t Bits, class Tag>
int
addBitString(base_uint<Bits, Tag> const& v)
@@ -139,9 +148,9 @@ public:
int
addRaw(Slice slice);
int
addRaw(void const* ptr, int len);
addRaw(const void* ptr, int len);
int
addRaw(Serializer const& s);
addRaw(const Serializer& s);
int
addVL(Blob const& vector);
@@ -151,7 +160,7 @@ public:
int
addVL(Iter begin, Iter end, int len);
int
addVL(void const* ptr, int len);
addVL(const void* ptr, int len);
// disassemble functions
bool
@@ -161,7 +170,7 @@ public:
bool
getInteger(Integer& number, int offset)
{
static auto const bytes = sizeof(Integer);
static const auto bytes = sizeof(Integer);
if ((offset + bytes) > mData.size())
return false;
number = 0;
@@ -220,7 +229,7 @@ public:
{
return mData.size();
}
void const*
const void*
getDataPtr() const
{
return mData.data();
@@ -238,7 +247,7 @@ public:
std::string
getString() const
{
return std::string(static_cast<char const*>(getDataPtr()), size());
return std::string(static_cast<const char*>(getDataPtr()), size());
}
void
erase()
@@ -296,12 +305,12 @@ public:
return v != mData;
}
bool
operator==(Serializer const& v) const
operator==(const Serializer& v) const
{
return v.mData == mData;
}
bool
operator!=(Serializer const& v) const
operator!=(const Serializer& v) const
{
return v.mData != mData;
}

View File

@@ -139,8 +139,8 @@ enum TEMcodes : TERUnderlyingType {
temARRAY_EMPTY,
temARRAY_TOO_LARGE,
temBAD_TRANSFER_FEE,
temINVALID_INNER_BATCH,
};
//------------------------------------------------------------------------------
@@ -360,8 +360,6 @@ enum TECcodes : TERUnderlyingType {
tecWRONG_ASSET = 194,
tecLIMIT_EXCEEDED = 195,
tecPSEUDO_ACCOUNT = 196,
tecPRECISION_LOSS = 197,
tecNO_DELEGATE_PERMISSION = 198,
};
//------------------------------------------------------------------------------
@@ -647,37 +645,37 @@ using TER = TERSubset<CanCvtToTER>;
//------------------------------------------------------------------------------
inline bool
isTelLocal(TER x) noexcept
isTelLocal(TER x)
{
return (x >= telLOCAL_ERROR && x < temMALFORMED);
return ((x) >= telLOCAL_ERROR && (x) < temMALFORMED);
}
inline bool
isTemMalformed(TER x) noexcept
isTemMalformed(TER x)
{
return (x >= temMALFORMED && x < tefFAILURE);
return ((x) >= temMALFORMED && (x) < tefFAILURE);
}
inline bool
isTefFailure(TER x) noexcept
isTefFailure(TER x)
{
return (x >= tefFAILURE && x < terRETRY);
return ((x) >= tefFAILURE && (x) < terRETRY);
}
inline bool
isTerRetry(TER x) noexcept
isTerRetry(TER x)
{
return (x >= terRETRY && x < tesSUCCESS);
return ((x) >= terRETRY && (x) < tesSUCCESS);
}
inline bool
isTesSuccess(TER x) noexcept
isTesSuccess(TER x)
{
return (x == tesSUCCESS);
return ((x) == tesSUCCESS);
}
inline bool
isTecClaim(TER x) noexcept
isTecClaim(TER x)
{
return ((x) >= tecCLAIM);
}

View File

@@ -58,8 +58,7 @@ namespace ripple {
// clang-format off
// Universal Transaction flags:
constexpr std::uint32_t tfFullyCanonicalSig = 0x80000000;
constexpr std::uint32_t tfInnerBatchTxn = 0x40000000;
constexpr std::uint32_t tfUniversal = tfFullyCanonicalSig | tfInnerBatchTxn;
constexpr std::uint32_t tfUniversal = tfFullyCanonicalSig;
constexpr std::uint32_t tfUniversalMask = ~tfUniversal;
// AccountSet flags:
@@ -92,16 +91,14 @@ constexpr std::uint32_t asfDisallowIncomingCheck = 13;
constexpr std::uint32_t asfDisallowIncomingPayChan = 14;
constexpr std::uint32_t asfDisallowIncomingTrustline = 15;
constexpr std::uint32_t asfAllowTrustLineClawback = 16;
constexpr std::uint32_t asfAllowTrustLineLocking = 17;
// OfferCreate flags:
constexpr std::uint32_t tfPassive = 0x00010000;
constexpr std::uint32_t tfImmediateOrCancel = 0x00020000;
constexpr std::uint32_t tfFillOrKill = 0x00040000;
constexpr std::uint32_t tfSell = 0x00080000;
constexpr std::uint32_t tfHybrid = 0x00100000;
constexpr std::uint32_t tfOfferCreateMask =
~(tfUniversal | tfPassive | tfImmediateOrCancel | tfFillOrKill | tfSell | tfHybrid);
~(tfUniversal | tfPassive | tfImmediateOrCancel | tfFillOrKill | tfSell);
// Payment flags:
constexpr std::uint32_t tfNoRippleDirect = 0x00010000;
@@ -122,11 +119,12 @@ constexpr std::uint32_t tfClearDeepFreeze = 0x00800000;
constexpr std::uint32_t tfTrustSetMask =
~(tfUniversal | tfSetfAuth | tfSetNoRipple | tfClearNoRipple | tfSetFreeze |
tfClearFreeze | tfSetDeepFreeze | tfClearDeepFreeze);
constexpr std::uint32_t tfTrustSetPermissionMask = ~(tfUniversal | tfSetfAuth | tfSetFreeze | tfClearFreeze);
// EnableAmendment flags:
constexpr std::uint32_t tfGotMajority = 0x00010000;
constexpr std::uint32_t tfLostMajority = 0x00020000;
constexpr std::uint32_t tfChangeMask =
~( tfUniversal | tfGotMajority | tfLostMajority);
// PaymentChannelClaim flags:
constexpr std::uint32_t tfRenew = 0x00010000;
@@ -141,7 +139,7 @@ constexpr std::uint32_t const tfTransferable = 0x00000008;
constexpr std::uint32_t const tfMutable = 0x00000010;
// MPTokenIssuanceCreate flags:
// NOTE - there is intentionally no flag here for lsfMPTLocked, which this transaction cannot mutate.
// NOTE - there is intentionally no flag here for lsfMPTLocked, which this transaction cannot mutate.
constexpr std::uint32_t const tfMPTCanLock = lsfMPTCanLock;
constexpr std::uint32_t const tfMPTRequireAuth = lsfMPTRequireAuth;
constexpr std::uint32_t const tfMPTCanEscrow = lsfMPTCanEscrow;
@@ -159,7 +157,6 @@ constexpr std::uint32_t const tfMPTokenAuthorizeMask = ~(tfUniversal | tfMPTUna
constexpr std::uint32_t const tfMPTLock = 0x00000001;
constexpr std::uint32_t const tfMPTUnlock = 0x00000002;
constexpr std::uint32_t const tfMPTokenIssuanceSetMask = ~(tfUniversal | tfMPTLock | tfMPTUnlock);
constexpr std::uint32_t const tfMPTokenIssuanceSetPermissionMask = ~(tfUniversal | tfMPTLock | tfMPTUnlock);
// MPTokenIssuanceDestroy flags:
constexpr std::uint32_t const tfMPTokenIssuanceDestroyMask = ~tfUniversal;
@@ -236,18 +233,16 @@ static_assert(tfVaultPrivate == lsfVaultPrivate);
constexpr std::uint32_t const tfVaultShareNonTransferable = 0x00020000;
constexpr std::uint32_t const tfVaultCreateMask = ~(tfUniversal | tfVaultPrivate | tfVaultShareNonTransferable);
// Batch Flags:
constexpr std::uint32_t tfAllOrNothing = 0x00010000;
constexpr std::uint32_t tfOnlyOne = 0x00020000;
constexpr std::uint32_t tfUntilFailure = 0x00040000;
constexpr std::uint32_t tfIndependent = 0x00080000;
/**
* @note If nested Batch transactions are supported in the future, the tfInnerBatchTxn flag
* will need to be removed from this mask to allow Batch transaction to be inside
* the sfRawTransactions array.
*/
constexpr std::uint32_t const tfBatchMask =
~(tfUniversal | tfAllOrNothing | tfOnlyOne | tfUntilFailure | tfIndependent) | tfInnerBatchTxn;
// LoanSet flags:
// True, indicates the loan supports overpayments
constexpr std::uint32_t const tfLoanOverpayment = 0x00010000;
constexpr std::uint32_t const tfLoanSetMask = ~(tfUniversal | tfLoanOverpayment);
// LoanManage flags:
constexpr std::uint32_t const tfLoanDefault = 0x00010000;
constexpr std::uint32_t const tfLoanImpair = 0x00020000;
constexpr std::uint32_t const tfLoanUnimpair = 0x00040000;
constexpr std::uint32_t const tfLoanManageMask = ~(tfUniversal | tfLoanDefault | tfLoanImpair | tfLoanUnimpair);
// clang-format on

View File

@@ -59,7 +59,7 @@ enum TxType : std::uint16_t
#pragma push_macro("TRANSACTION")
#undef TRANSACTION
#define TRANSACTION(tag, value, name, delegatable, fields) tag = value,
#define TRANSACTION(tag, value, name, privileges, fields) tag = value,
#include <xrpl/protocol/detail/transactions.macro>

View File

@@ -46,10 +46,7 @@ private:
CtorHelper);
public:
TxMeta(
uint256 const& transactionID,
std::uint32_t ledger,
std::optional<uint256> parentBatchId = std::nullopt);
TxMeta(uint256 const& transactionID, std::uint32_t ledger);
TxMeta(uint256 const& txID, std::uint32_t ledger, Blob const&);
TxMeta(uint256 const& txID, std::uint32_t ledger, std::string const&);
TxMeta(uint256 const& txID, std::uint32_t ledger, STObject const&);
@@ -133,27 +130,6 @@ public:
return static_cast<bool>(mDelivered);
}
void
setParentBatchId(uint256 const& parentBatchId)
{
mParentBatchId = parentBatchId;
}
uint256
getParentBatchId() const
{
XRPL_ASSERT(
hasParentBatchId(),
"ripple::TxMeta::getParentBatchId : non-null batch id");
return *mParentBatchId;
}
bool
hasParentBatchId() const
{
return static_cast<bool>(mParentBatchId);
}
private:
uint256 mTransactionID;
std::uint32_t mLedger;
@@ -161,7 +137,6 @@ private:
int mResult;
std::optional<STAmount> mDelivered;
std::optional<uint256> mParentBatchId;
STArray mNodes;
};

View File

@@ -63,9 +63,6 @@ using NodeID = base_uint<160, detail::NodeIDTag>;
* and a 160-bit account */
using MPTID = base_uint<192>;
/** Domain is a 256-bit hash representing a specific domain. */
using Domain = base_uint<256>;
/** XRP currency. */
Currency const&
xrpCurrency();
@@ -122,25 +119,25 @@ namespace std {
template <>
struct hash<ripple::Currency> : ripple::Currency::hasher
{
hash() = default;
explicit hash() = default;
};
template <>
struct hash<ripple::NodeID> : ripple::NodeID::hasher
{
hash() = default;
explicit hash() = default;
};
template <>
struct hash<ripple::Directory> : ripple::Directory::hasher
{
hash() = default;
explicit hash() = default;
};
template <>
struct hash<ripple::uint256> : ripple::uint256::hasher
{
hash() = default;
explicit hash() = default;
};
} // namespace std

View File

@@ -16,8 +16,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef BASICS_FEES_H_INCLUDED
#define BASICS_FEES_H_INCLUDED
#ifndef PROTOCOL_UNITS_H_INCLUDED
#define PROTOCOL_UNITS_H_INCLUDED
#include <xrpl/basics/safe_cast.h>
#include <xrpl/beast/utility/Zero.h>
@@ -38,23 +38,23 @@
namespace ripple {
namespace feeunit {
namespace unit {
/** "drops" are the smallest divisible amount of XRP. This is what most
of the code uses. */
struct dropTag;
/** "fee units" calculations are a not-really-unitless value that is used
to express the cost of a given transaction vs. a reference transaction.
They are primarily used by the Transactor classes. */
struct feeunitTag;
/** "fee levels" are used by the transaction queue to compare the relative
cost of transactions that require different levels of effort to process.
See also: src/ripple/app/misc/FeeEscalation.md#fee-level */
struct feelevelTag;
/** unitless values are plain scalars wrapped in a TaggedFee. They are
/** unitless values are plain scalars wrapped in a ValueUnit. They are
used for calculations in this header. */
struct unitlessTag;
/** Units to represent basis points (bips) and 1/10 basis points */
class BipsTag;
class TenthBipsTag;
template <class T>
using enable_if_unit_t = typename std::enable_if_t<
std::is_class_v<T> && std::is_object_v<typename T::unit_type> &&
@@ -62,32 +62,33 @@ using enable_if_unit_t = typename std::enable_if_t<
/** `is_usable_unit_v` is checked to ensure that only values with
known valid type tags can be used (sometimes transparently) in
non-fee contexts. At the time of implementation, this includes
non-unit contexts. At the time of implementation, this includes
all known tags, but more may be added in the future, and they
should not be added automatically unless determined to be
appropriate.
*/
template <class T, class = enable_if_unit_t<T>>
constexpr bool is_usable_unit_v =
std::is_same_v<typename T::unit_type, feeunitTag> ||
std::is_same_v<typename T::unit_type, feelevelTag> ||
std::is_same_v<typename T::unit_type, unitlessTag> ||
std::is_same_v<typename T::unit_type, dropTag>;
std::is_same_v<typename T::unit_type, dropTag> ||
std::is_same_v<typename T::unit_type, BipsTag> ||
std::is_same_v<typename T::unit_type, TenthBipsTag>;
template <class UnitTag, class T>
class TaggedFee : private boost::totally_ordered<TaggedFee<UnitTag, T>>,
private boost::additive<TaggedFee<UnitTag, T>>,
private boost::equality_comparable<TaggedFee<UnitTag, T>, T>,
private boost::dividable<TaggedFee<UnitTag, T>, T>,
private boost::modable<TaggedFee<UnitTag, T>, T>,
private boost::unit_steppable<TaggedFee<UnitTag, T>>
class ValueUnit : private boost::totally_ordered<ValueUnit<UnitTag, T>>,
private boost::additive<ValueUnit<UnitTag, T>>,
private boost::equality_comparable<ValueUnit<UnitTag, T>, T>,
private boost::dividable<ValueUnit<UnitTag, T>, T>,
private boost::modable<ValueUnit<UnitTag, T>, T>,
private boost::unit_steppable<ValueUnit<UnitTag, T>>
{
public:
using unit_type = UnitTag;
using value_type = T;
private:
value_type fee_;
value_type value_;
protected:
template <class Other>
@@ -95,44 +96,44 @@ protected:
std::is_arithmetic_v<Other> && std::is_arithmetic_v<value_type> &&
std::is_convertible_v<Other, value_type>;
template <class OtherFee, class = enable_if_unit_t<OtherFee>>
static constexpr bool is_compatiblefee_v =
is_compatible_v<typename OtherFee::value_type> &&
std::is_same_v<UnitTag, typename OtherFee::unit_type>;
template <class OtherValue, class = enable_if_unit_t<OtherValue>>
static constexpr bool is_compatiblevalue_v =
is_compatible_v<typename OtherValue::value_type> &&
std::is_same_v<UnitTag, typename OtherValue::unit_type>;
template <class Other>
using enable_if_compatible_t =
typename std::enable_if_t<is_compatible_v<Other>>;
template <class OtherFee>
using enable_if_compatiblefee_t =
typename std::enable_if_t<is_compatiblefee_v<OtherFee>>;
template <class OtherValue>
using enable_if_compatiblevalue_t =
typename std::enable_if_t<is_compatiblevalue_v<OtherValue>>;
public:
TaggedFee() = default;
constexpr TaggedFee(TaggedFee const& other) = default;
constexpr TaggedFee&
operator=(TaggedFee const& other) = default;
ValueUnit() = default;
constexpr ValueUnit(ValueUnit const& other) = default;
constexpr ValueUnit&
operator=(ValueUnit const& other) = default;
constexpr explicit TaggedFee(beast::Zero) : fee_(0)
constexpr explicit ValueUnit(beast::Zero) : value_(0)
{
}
constexpr TaggedFee&
constexpr ValueUnit&
operator=(beast::Zero)
{
fee_ = 0;
value_ = 0;
return *this;
}
constexpr explicit TaggedFee(value_type fee) : fee_(fee)
constexpr explicit ValueUnit(value_type value) : value_(value)
{
}
TaggedFee&
operator=(value_type fee)
constexpr ValueUnit&
operator=(value_type value)
{
fee_ = fee;
value_ = value;
return *this;
}
@@ -144,153 +145,181 @@ public:
class = std::enable_if_t<
is_compatible_v<Other> &&
is_safetocasttovalue_v<value_type, Other>>>
constexpr TaggedFee(TaggedFee<unit_type, Other> const& fee)
: TaggedFee(safe_cast<value_type>(fee.fee()))
constexpr ValueUnit(ValueUnit<unit_type, Other> const& value)
: ValueUnit(safe_cast<value_type>(value.value()))
{
}
constexpr TaggedFee
constexpr ValueUnit
operator+(value_type const& rhs) const
{
return ValueUnit{value_ + rhs};
}
friend constexpr ValueUnit
operator+(value_type lhs, ValueUnit const& rhs)
{
// addition is commutative
return rhs + lhs;
}
constexpr ValueUnit
operator-(value_type const& rhs) const
{
return ValueUnit{value_ - rhs};
}
friend constexpr ValueUnit
operator-(value_type lhs, ValueUnit const& rhs)
{
// subtraction is NOT commutative, but (lhs + (-rhs)) is addition, which
// is
return -rhs + lhs;
}
constexpr ValueUnit
operator*(value_type const& rhs) const
{
return TaggedFee{fee_ * rhs};
return ValueUnit{value_ * rhs};
}
friend constexpr TaggedFee
operator*(value_type lhs, TaggedFee const& rhs)
friend constexpr ValueUnit
operator*(value_type lhs, ValueUnit const& rhs)
{
// multiplication is commutative
return rhs * lhs;
}
constexpr value_type
operator/(TaggedFee const& rhs) const
operator/(ValueUnit const& rhs) const
{
return fee_ / rhs.fee_;
return value_ / rhs.value_;
}
TaggedFee&
operator+=(TaggedFee const& other)
ValueUnit&
operator+=(ValueUnit const& other)
{
fee_ += other.fee();
value_ += other.value();
return *this;
}
TaggedFee&
operator-=(TaggedFee const& other)
ValueUnit&
operator-=(ValueUnit const& other)
{
fee_ -= other.fee();
value_ -= other.value();
return *this;
}
TaggedFee&
ValueUnit&
operator++()
{
++fee_;
++value_;
return *this;
}
TaggedFee&
ValueUnit&
operator--()
{
--fee_;
--value_;
return *this;
}
TaggedFee&
ValueUnit&
operator*=(value_type const& rhs)
{
fee_ *= rhs;
value_ *= rhs;
return *this;
}
TaggedFee&
ValueUnit&
operator/=(value_type const& rhs)
{
fee_ /= rhs;
value_ /= rhs;
return *this;
}
template <class transparent = value_type>
std::enable_if_t<std::is_integral_v<transparent>, TaggedFee&>
std::enable_if_t<std::is_integral_v<transparent>, ValueUnit&>
operator%=(value_type const& rhs)
{
fee_ %= rhs;
value_ %= rhs;
return *this;
}
TaggedFee
ValueUnit
operator-() const
{
static_assert(
std::is_signed_v<T>, "- operator illegal on unsigned fee types");
return TaggedFee{-fee_};
std::is_signed_v<T>, "- operator illegal on unsigned value types");
return ValueUnit{-value_};
}
bool
operator==(TaggedFee const& other) const
constexpr bool
operator==(ValueUnit const& other) const
{
return fee_ == other.fee_;
return value_ == other.value_;
}
template <class Other, class = enable_if_compatible_t<Other>>
bool
operator==(TaggedFee<unit_type, Other> const& other) const
constexpr bool
operator==(ValueUnit<unit_type, Other> const& other) const
{
return fee_ == other.fee();
return value_ == other.value();
}
bool
constexpr bool
operator==(value_type other) const
{
return fee_ == other;
return value_ == other;
}
template <class Other, class = enable_if_compatible_t<Other>>
bool
operator!=(TaggedFee<unit_type, Other> const& other) const
constexpr bool
operator!=(ValueUnit<unit_type, Other> const& other) const
{
return !operator==(other);
}
bool
operator<(TaggedFee const& other) const
constexpr bool
operator<(ValueUnit const& other) const
{
return fee_ < other.fee_;
return value_ < other.value_;
}
/** Returns true if the amount is not zero */
explicit constexpr
operator bool() const noexcept
{
return fee_ != 0;
return value_ != 0;
}
/** Return the sign of the amount */
constexpr int
signum() const noexcept
{
return (fee_ < 0) ? -1 : (fee_ ? 1 : 0);
return (value_ < 0) ? -1 : (value_ ? 1 : 0);
}
/** Returns the number of drops */
// TODO: Move this to a new class, maybe with the old "TaggedFee" name
constexpr value_type
fee() const
{
return fee_;
return value_;
}
template <class Other>
constexpr double
decimalFromReference(TaggedFee<unit_type, Other> reference) const
decimalFromReference(ValueUnit<unit_type, Other> reference) const
{
return static_cast<double>(fee_) / reference.fee();
return static_cast<double>(value_) / reference.value();
}
// `is_usable_unit_v` is checked to ensure that only values with
// known valid type tags can be converted to JSON. At the time
// of implementation, that includes all known tags, but more may
// be added in the future.
std::enable_if_t<is_usable_unit_v<TaggedFee>, Json::Value>
std::enable_if_t<is_usable_unit_v<ValueUnit>, Json::Value>
jsonClipped() const
{
if constexpr (std::is_integral_v<value_type>)
@@ -303,15 +332,15 @@ public:
constexpr auto min = std::numeric_limits<jsontype>::min();
constexpr auto max = std::numeric_limits<jsontype>::max();
if (fee_ < min)
if (value_ < min)
return min;
if (fee_ > max)
if (value_ > max)
return max;
return static_cast<jsontype>(fee_);
return static_cast<jsontype>(value_);
}
else
{
return fee_;
return value_;
}
}
@@ -322,30 +351,30 @@ public:
constexpr value_type
value() const
{
return fee_;
return value_;
}
friend std::istream&
operator>>(std::istream& s, TaggedFee& val)
operator>>(std::istream& s, ValueUnit& val)
{
s >> val.fee_;
s >> val.value_;
return s;
}
};
// Output Fees as just their numeric value.
// Output Values as just their numeric value.
template <class Char, class Traits, class UnitTag, class T>
std::basic_ostream<Char, Traits>&
operator<<(std::basic_ostream<Char, Traits>& os, TaggedFee<UnitTag, T> const& q)
operator<<(std::basic_ostream<Char, Traits>& os, const ValueUnit<UnitTag, T>& q)
{
return os << q.value();
}
template <class UnitTag, class T>
std::string
to_string(TaggedFee<UnitTag, T> const& amount)
to_string(ValueUnit<UnitTag, T> const& amount)
{
return std::to_string(amount.fee());
return std::to_string(amount.value());
}
template <class Source, class = enable_if_unit_t<Source>>
@@ -408,10 +437,10 @@ using enable_muldiv_commute_t =
typename std::enable_if_t<can_muldiv_commute_v<Source1, Source2, Dest>>;
template <class T>
TaggedFee<unitlessTag, T>
ValueUnit<unitlessTag, T>
scalar(T value)
{
return TaggedFee<unitlessTag, T>{value};
return ValueUnit<unitlessTag, T>{value};
}
template <
@@ -422,18 +451,17 @@ template <
std::optional<Dest>
mulDivU(Source1 value, Dest mul, Source2 div)
{
// Fees can never be negative in any context.
// values can never be negative in any context.
if (value.value() < 0 || mul.value() < 0 || div.value() < 0)
{
// split the asserts so if one hits, the user can tell which
// without a debugger.
XRPL_ASSERT(
value.value() >= 0,
"ripple::feeunit::mulDivU : minimum value input");
value.value() >= 0, "ripple::unit::mulDivU : minimum value input");
XRPL_ASSERT(
mul.value() >= 0, "ripple::feeunit::mulDivU : minimum mul input");
mul.value() >= 0, "ripple::unit::mulDivU : minimum mul input");
XRPL_ASSERT(
div.value() >= 0, "ripple::feeunit::mulDivU : minimum div input");
div.value() >= 0, "ripple::unit::mulDivU : minimum div input");
return std::nullopt;
}
@@ -466,46 +494,57 @@ mulDivU(Source1 value, Dest mul, Source2 div)
return Dest{static_cast<desttype>(quotient)};
}
} // namespace feeunit
} // namespace unit
// Fee Levels
template <class T>
using FeeLevel = feeunit::TaggedFee<feeunit::feelevelTag, T>;
using FeeLevel = unit::ValueUnit<unit::feelevelTag, T>;
using FeeLevel64 = FeeLevel<std::uint64_t>;
using FeeLevelDouble = FeeLevel<double>;
// Basis points (Bips)
template <class T>
using Bips = unit::ValueUnit<unit::BipsTag, T>;
using Bips16 = Bips<std::uint16_t>;
using Bips32 = Bips<std::uint32_t>;
template <class T>
using TenthBips = unit::ValueUnit<unit::TenthBipsTag, T>;
using TenthBips16 = TenthBips<std::uint16_t>;
using TenthBips32 = TenthBips<std::uint32_t>;
template <
class Source1,
class Source2,
class Dest,
class = feeunit::enable_muldiv_t<Source1, Source2, Dest>>
class = unit::enable_muldiv_t<Source1, Source2, Dest>>
std::optional<Dest>
mulDiv(Source1 value, Dest mul, Source2 div)
{
return feeunit::mulDivU(value, mul, div);
return unit::mulDivU(value, mul, div);
}
template <
class Source1,
class Source2,
class Dest,
class = feeunit::enable_muldiv_commute_t<Source1, Source2, Dest>>
class = unit::enable_muldiv_commute_t<Source1, Source2, Dest>>
std::optional<Dest>
mulDiv(Dest value, Source1 mul, Source2 div)
{
// Multiplication is commutative
return feeunit::mulDivU(mul, value, div);
return unit::mulDivU(mul, value, div);
}
template <class Dest, class = feeunit::enable_muldiv_dest_t<Dest>>
template <class Dest, class = unit::enable_muldiv_dest_t<Dest>>
std::optional<Dest>
mulDiv(std::uint64_t value, Dest mul, std::uint64_t div)
{
// Give the scalars a non-tag so the
// unit-handling version gets called.
return feeunit::mulDivU(feeunit::scalar(value), mul, feeunit::scalar(div));
return unit::mulDivU(unit::scalar(value), mul, unit::scalar(div));
}
template <class Dest, class = feeunit::enable_muldiv_dest_t<Dest>>
template <class Dest, class = unit::enable_muldiv_dest_t<Dest>>
std::optional<Dest>
mulDiv(Dest value, std::uint64_t mul, std::uint64_t div)
{
@@ -516,13 +555,13 @@ mulDiv(Dest value, std::uint64_t mul, std::uint64_t div)
template <
class Source1,
class Source2,
class = feeunit::enable_muldiv_sources_t<Source1, Source2>>
class = unit::enable_muldiv_sources_t<Source1, Source2>>
std::optional<std::uint64_t>
mulDiv(Source1 value, std::uint64_t mul, Source2 div)
{
// Give the scalars a dimensionless unit so the
// unit-handling version gets called.
auto unitresult = feeunit::mulDivU(value, feeunit::scalar(mul), div);
auto unitresult = unit::mulDivU(value, unit::scalar(mul), div);
if (!unitresult)
return std::nullopt;
@@ -533,7 +572,7 @@ mulDiv(Source1 value, std::uint64_t mul, Source2 div)
template <
class Source1,
class Source2,
class = feeunit::enable_muldiv_sources_t<Source1, Source2>>
class = unit::enable_muldiv_sources_t<Source1, Source2>>
std::optional<std::uint64_t>
mulDiv(std::uint64_t value, Source1 mul, Source2 div)
{
@@ -553,6 +592,16 @@ safe_cast(Src s) noexcept
return Dest{safe_cast<typename Dest::value_type>(s.value())};
}
template <class Dest, class Src>
constexpr std::enable_if_t<
std::is_integral_v<typename Dest::value_type> && std::is_integral_v<Src>,
Dest>
safe_cast(Src s) noexcept
{
// Dest may not have an explicit value constructor
return Dest{safe_cast<typename Dest::value_type>(s)};
}
template <class Dest, class Src>
constexpr std::enable_if_t<
std::is_same_v<typename Dest::unit_type, typename Src::unit_type> &&
@@ -565,6 +614,16 @@ unsafe_cast(Src s) noexcept
return Dest{unsafe_cast<typename Dest::value_type>(s.value())};
}
template <class Dest, class Src>
constexpr std::enable_if_t<
std::is_integral_v<typename Dest::value_type> && std::is_integral_v<Src>,
Dest>
unsafe_cast(Src s) noexcept
{
// Dest may not have an explicit value constructor
return Dest{unsafe_cast<typename Dest::value_type>(s)};
}
} // namespace ripple
#endif // BASICS_FEES_H_INCLUDED
#endif // PROTOCOL_UNITS_H_INCLUDED

View File

@@ -24,7 +24,7 @@
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/Zero.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/FeeUnits.h>
#include <xrpl/protocol/Units.h>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/operators.hpp>
@@ -42,7 +42,7 @@ class XRPAmount : private boost::totally_ordered<XRPAmount>,
private boost::additive<XRPAmount, std::int64_t>
{
public:
using unit_type = feeunit::dropTag;
using unit_type = unit::dropTag;
using value_type = std::int64_t;
private:
@@ -267,7 +267,7 @@ XRPAmount::decimalXRP() const
// Output XRPAmount as just the drops value.
template <class Char, class Traits>
std::basic_ostream<Char, Traits>&
operator<<(std::basic_ostream<Char, Traits>& os, XRPAmount const& q)
operator<<(std::basic_ostream<Char, Traits>& os, const XRPAmount& q)
{
return os << q.drops();
}

View File

@@ -27,18 +27,13 @@
#error "undefined macro: XRPL_RETIRE"
#endif
// clang-format off
// Add new amendments to the top of this list.
// Keep it sorted in reverse chronological order.
// If you add an amendment here, then do not forget to increment `numFeatures`
// in include/xrpl/protocol/Feature.h.
XRPL_FEATURE(TokenEscrow, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (EnforceNFTokenTrustlineV2, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (AMMv1_3, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionedDEX, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(Batch, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(LendingProtocol, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(SingleAssetVault, Supported::no, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionDelegation, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (PayChanCancelAfter, Supported::yes, VoteBehavior::DefaultNo)
// Check flags in Credential transactions
XRPL_FIX (InvalidTxFlags, Supported::yes, VoteBehavior::DefaultNo)
@@ -151,3 +146,5 @@ XRPL_RETIRE(fix1201)
XRPL_RETIRE(fix1512)
XRPL_RETIRE(fix1523)
XRPL_RETIRE(fix1528)
// clang-format on

View File

@@ -167,6 +167,7 @@ LEDGER_ENTRY(ltACCOUNT_ROOT, 0x0061, AccountRoot, account, ({
{sfFirstNFTokenSequence, soeOPTIONAL},
{sfAMMID, soeOPTIONAL}, // pseudo-account designator
{sfVaultID, soeOPTIONAL}, // pseudo-account designator
{sfLoanBrokerID, soeOPTIONAL}, // pseudo-account designator
}))
/** A ledger object which contains a list of object identifiers.
@@ -188,7 +189,6 @@ LEDGER_ENTRY(ltDIR_NODE, 0x0064, DirectoryNode, directory, ({
{sfNFTokenID, soeOPTIONAL},
{sfPreviousTxnID, soeOPTIONAL},
{sfPreviousTxnLgrSeq, soeOPTIONAL},
{sfDomainID, soeOPTIONAL}
}))
/** The ledger object which lists details about amendments on the network.
@@ -250,8 +250,6 @@ LEDGER_ENTRY(ltOFFER, 0x006f, Offer, offer, ({
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
{sfDomainID, soeOPTIONAL},
{sfAdditionalBooks, soeOPTIONAL},
}))
/** A ledger object which describes a deposit preauthorization.
@@ -354,8 +352,6 @@ LEDGER_ENTRY(ltESCROW, 0x0075, Escrow, escrow, ({
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfDestinationNode, soeOPTIONAL},
{sfTransferRate, soeOPTIONAL},
{sfIssuerNode, soeOPTIONAL},
}))
/** A ledger object describing a single unidirectional XRP payment channel.
@@ -407,7 +403,6 @@ LEDGER_ENTRY(ltMPTOKEN_ISSUANCE, 0x007e, MPTokenIssuance, mpt_issuance, ({
{sfAssetScale, soeDEFAULT},
{sfMaximumAmount, soeOPTIONAL},
{sfOutstandingAmount, soeREQUIRED},
{sfLockedAmount, soeOPTIONAL},
{sfMPTokenMetadata, soeOPTIONAL},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
@@ -421,7 +416,6 @@ LEDGER_ENTRY(ltMPTOKEN, 0x007f, MPToken, mptoken, ({
{sfAccount, soeREQUIRED},
{sfMPTokenIssuanceID, soeREQUIRED},
{sfMPTAmount, soeDEFAULT},
{sfLockedAmount, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
@@ -469,23 +463,11 @@ LEDGER_ENTRY(ltPERMISSIONED_DOMAIN, 0x0082, PermissionedDomain, permissioned_dom
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
/** A ledger object representing permissions an account has delegated to another account.
\sa keylet::delegate
*/
LEDGER_ENTRY(ltDELEGATE, 0x0083, Delegate, delegate, ({
{sfAccount, soeREQUIRED},
{sfAuthorize, soeREQUIRED},
{sfPermissions, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
}))
/** A ledger object representing a single asset vault.
\sa keylet::mptoken
*/
LEDGER_ENTRY(ltVAULT, 0x0084, Vault, vault, ({
LEDGER_ENTRY(ltVAULT, 0x0083, Vault, vault, ({
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfSequence, soeREQUIRED},
@@ -504,6 +486,63 @@ LEDGER_ENTRY(ltVAULT, 0x0084, Vault, vault, ({
// no PermissionedDomainID ever (use MPTIssuance.sfDomainID)
}))
/** Reserve 0x0084-0x0087 for future Vault-related objects. */
/** A ledger object representing a loan broker
\sa keylet::loanbroker
*/
LEDGER_ENTRY(ltLOAN_BROKER, 0x0088, LoanBroker, loan_broker, ({
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfVaultNode, soeREQUIRED},
{sfVaultID, soeREQUIRED},
{sfAccount, soeREQUIRED},
{sfOwner, soeREQUIRED},
{sfLoanSequence, soeREQUIRED},
{sfData, soeDEFAULT},
{sfManagementFeeRate, soeDEFAULT},
{sfOwnerCount, soeDEFAULT},
{sfDebtTotal, soeDEFAULT},
{sfDebtMaximum, soeDEFAULT},
{sfCoverAvailable, soeDEFAULT},
{sfCoverRateMinimum, soeDEFAULT},
{sfCoverRateLiquidation, soeDEFAULT},
}))
/** A ledger object representing a loan between a Borrower and a Loan Broker
\sa keylet::loan
*/
LEDGER_ENTRY(ltLOAN, 0x0089, Loan, loan, ({
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfOwnerNode, soeREQUIRED},
{sfLoanBrokerNode, soeREQUIRED},
{sfLoanBrokerID, soeREQUIRED},
{sfLoanSequence, soeREQUIRED},
{sfBorrower, soeREQUIRED},
{sfLoanOriginationFee, soeREQUIRED},
{sfLoanServiceFee, soeREQUIRED},
{sfLatePaymentFee, soeREQUIRED},
{sfClosePaymentFee, soeREQUIRED},
{sfOverpaymentFee, soeREQUIRED},
{sfInterestRate, soeREQUIRED},
{sfLateInterestRate, soeREQUIRED},
{sfCloseInterestRate, soeREQUIRED},
{sfOverpaymentInterestRate, soeREQUIRED},
{sfStartDate, soeREQUIRED},
{sfPaymentInterval, soeREQUIRED},
{sfGracePeriod, soeREQUIRED},
{sfPreviousPaymentDate, soeREQUIRED},
{sfNextPaymentDueDate, soeREQUIRED},
{sfPaymentRemaining, soeREQUIRED},
{sfAssetsAvailable, soeREQUIRED},
{sfPrincipalOutstanding, soeREQUIRED},
}))
#undef EXPAND
#undef LEDGER_ENTRY_DUPLICATE

View File

@@ -1,68 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2025 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#if !defined(PERMISSION)
#error "undefined macro: PERMISSION"
#endif
/**
* PERMISSION(name, type, txType, value)
*
* This macro defines a permission:
* name: the name of the permission.
* type: the GranularPermissionType enum.
* txType: the corresponding TxType for this permission.
* value: the uint32 numeric value for the enum type.
*/
/** This permission grants the delegated account the ability to authorize a trustline. */
PERMISSION(TrustlineAuthorize, ttTRUST_SET, 65537)
/** This permission grants the delegated account the ability to freeze a trustline. */
PERMISSION(TrustlineFreeze, ttTRUST_SET, 65538)
/** This permission grants the delegated account the ability to unfreeze a trustline. */
PERMISSION(TrustlineUnfreeze, ttTRUST_SET, 65539)
/** This permission grants the delegated account the ability to set Domain. */
PERMISSION(AccountDomainSet, ttACCOUNT_SET, 65540)
/** This permission grants the delegated account the ability to set EmailHashSet. */
PERMISSION(AccountEmailHashSet, ttACCOUNT_SET, 65541)
/** This permission grants the delegated account the ability to set MessageKey. */
PERMISSION(AccountMessageKeySet, ttACCOUNT_SET, 65542)
/** This permission grants the delegated account the ability to set TransferRate. */
PERMISSION(AccountTransferRateSet, ttACCOUNT_SET, 65543)
/** This permission grants the delegated account the ability to set TickSize. */
PERMISSION(AccountTickSizeSet, ttACCOUNT_SET, 65544)
/** This permission grants the delegated account the ability to mint payment, which means sending a payment for a currency where the sending account is the issuer. */
PERMISSION(PaymentMint, ttPAYMENT, 65545)
/** This permission grants the delegated account the ability to burn payment, which means sending a payment for a currency where the destination account is the issuer */
PERMISSION(PaymentBurn, ttPAYMENT, 65546)
/** This permission grants the delegated account the ability to lock MPToken. */
PERMISSION(MPTokenIssuanceLock, ttMPTOKEN_ISSUANCE_SET, 65547)
/** This permission grants the delegated account the ability to unlock MPToken. */
PERMISSION(MPTokenIssuanceUnlock, ttMPTOKEN_ISSUANCE_SET, 65548)

View File

@@ -24,6 +24,8 @@
#error "undefined macro: TYPED_SFIELD"
#endif
// clang-format off
// untyped
UNTYPED_SFIELD(sfLedgerEntry, LEDGERENTRY, 257)
UNTYPED_SFIELD(sfTransaction, TRANSACTION, 257)
@@ -59,6 +61,7 @@ TYPED_SFIELD(sfHookEmitCount, UINT16, 18)
TYPED_SFIELD(sfHookExecutionIndex, UINT16, 19)
TYPED_SFIELD(sfHookApiVersion, UINT16, 20)
TYPED_SFIELD(sfLedgerFixType, UINT16, 21)
TYPED_SFIELD(sfManagementFeeRate, UINT16, 22) // 1/10 basis points (bips)
// 32-bit integers (common)
TYPED_SFIELD(sfNetworkID, UINT32, 1)
@@ -113,7 +116,21 @@ TYPED_SFIELD(sfEmitGeneration, UINT32, 46)
TYPED_SFIELD(sfVoteWeight, UINT32, 48)
TYPED_SFIELD(sfFirstNFTokenSequence, UINT32, 50)
TYPED_SFIELD(sfOracleDocumentID, UINT32, 51)
TYPED_SFIELD(sfPermissionValue, UINT32, 52)
TYPED_SFIELD(sfStartDate, UINT32, 52)
TYPED_SFIELD(sfPaymentInterval, UINT32, 53)
TYPED_SFIELD(sfGracePeriod, UINT32, 54)
TYPED_SFIELD(sfPreviousPaymentDate, UINT32, 55)
TYPED_SFIELD(sfNextPaymentDueDate, UINT32, 56)
TYPED_SFIELD(sfPaymentRemaining, UINT32, 57)
TYPED_SFIELD(sfPaymentTotal, UINT32, 58)
TYPED_SFIELD(sfLoanSequence, UINT32, 59)
TYPED_SFIELD(sfCoverRateMinimum, UINT32, 60) // 1/10 basis points (bips)
TYPED_SFIELD(sfCoverRateLiquidation, UINT32, 61) // 1/10 basis points (bips)
TYPED_SFIELD(sfOverpaymentFee, UINT32, 62) // 1/10 basis points (bips)
TYPED_SFIELD(sfInterestRate, UINT32, 63) // 1/10 basis points (bips)
TYPED_SFIELD(sfLateInterestRate, UINT32, 64) // 1/10 basis points (bips)
TYPED_SFIELD(sfCloseInterestRate, UINT32, 65) // 1/10 basis points (bips)
TYPED_SFIELD(sfOverpaymentInterestRate, UINT32, 66) // 1/10 basis points (bips)
// 64-bit integers (common)
TYPED_SFIELD(sfIndexNext, UINT64, 1)
@@ -144,7 +161,8 @@ TYPED_SFIELD(sfOutstandingAmount, UINT64, 25, SField::sMD_BaseTen|SFie
TYPED_SFIELD(sfMPTAmount, UINT64, 26, SField::sMD_BaseTen|SField::sMD_Default)
TYPED_SFIELD(sfIssuerNode, UINT64, 27)
TYPED_SFIELD(sfSubjectNode, UINT64, 28)
TYPED_SFIELD(sfLockedAmount, UINT64, 29, SField::sMD_BaseTen|SField::sMD_Default)
TYPED_SFIELD(sfVaultNode, UINT64, 29)
TYPED_SFIELD(sfLoanBrokerNode, UINT64, 30)
// 128-bit
TYPED_SFIELD(sfEmailHash, UINT128, 1)
@@ -173,7 +191,8 @@ TYPED_SFIELD(sfNFTokenID, UINT256, 10)
TYPED_SFIELD(sfEmitParentTxnID, UINT256, 11)
TYPED_SFIELD(sfEmitNonce, UINT256, 12)
TYPED_SFIELD(sfEmitHookHash, UINT256, 13)
TYPED_SFIELD(sfAMMID, UINT256, 14)
TYPED_SFIELD(sfAMMID, UINT256, 14,
SField::sMD_PseudoAccount |SField::sMD_Default)
// 256-bit (uncommon)
TYPED_SFIELD(sfBookDirectory, UINT256, 16)
@@ -195,8 +214,11 @@ TYPED_SFIELD(sfHookHash, UINT256, 31)
TYPED_SFIELD(sfHookNamespace, UINT256, 32)
TYPED_SFIELD(sfHookSetTxnID, UINT256, 33)
TYPED_SFIELD(sfDomainID, UINT256, 34)
TYPED_SFIELD(sfVaultID, UINT256, 35)
TYPED_SFIELD(sfParentBatchID, UINT256, 36)
TYPED_SFIELD(sfVaultID, UINT256, 35,
SField::sMD_PseudoAccount | SField::sMD_Default)
TYPED_SFIELD(sfLoanBrokerID, UINT256, 36,
SField::sMD_PseudoAccount | SField::sMD_Default)
TYPED_SFIELD(sfLoanID, UINT256, 37)
// number (common)
TYPED_SFIELD(sfNumber, NUMBER, 1)
@@ -204,6 +226,15 @@ TYPED_SFIELD(sfAssetsAvailable, NUMBER, 2)
TYPED_SFIELD(sfAssetsMaximum, NUMBER, 3)
TYPED_SFIELD(sfAssetsTotal, NUMBER, 4)
TYPED_SFIELD(sfLossUnrealized, NUMBER, 5)
TYPED_SFIELD(sfDebtTotal, NUMBER, 6)
TYPED_SFIELD(sfDebtMaximum, NUMBER, 7)
TYPED_SFIELD(sfCoverAvailable, NUMBER, 8)
TYPED_SFIELD(sfLoanOriginationFee, NUMBER, 9)
TYPED_SFIELD(sfLoanServiceFee, NUMBER, 10)
TYPED_SFIELD(sfLatePaymentFee, NUMBER, 11)
TYPED_SFIELD(sfClosePaymentFee, NUMBER, 12)
TYPED_SFIELD(sfPrincipalOutstanding, NUMBER, 13)
TYPED_SFIELD(sfPrincipalRequested, NUMBER, 14)
// currency amount (common)
TYPED_SFIELD(sfAmount, AMOUNT, 1)
@@ -288,7 +319,6 @@ TYPED_SFIELD(sfRegularKey, ACCOUNT, 8)
TYPED_SFIELD(sfNFTokenMinter, ACCOUNT, 9)
TYPED_SFIELD(sfEmitCallback, ACCOUNT, 10)
TYPED_SFIELD(sfHolder, ACCOUNT, 11)
TYPED_SFIELD(sfDelegate, ACCOUNT, 12)
// account (uncommon)
TYPED_SFIELD(sfHookAccount, ACCOUNT, 16)
@@ -299,6 +329,8 @@ TYPED_SFIELD(sfAttestationRewardAccount, ACCOUNT, 21)
TYPED_SFIELD(sfLockingChainDoor, ACCOUNT, 22)
TYPED_SFIELD(sfIssuingChainDoor, ACCOUNT, 23)
TYPED_SFIELD(sfSubject, ACCOUNT, 24)
TYPED_SFIELD(sfBorrower, ACCOUNT, 25)
TYPED_SFIELD(sfCounterparty, ACCOUNT, 26)
// vector of 256-bit
TYPED_SFIELD(sfIndexes, VECTOR256, 1, SField::sMD_Never)
@@ -338,7 +370,6 @@ UNTYPED_SFIELD(sfSignerEntry, OBJECT, 11)
UNTYPED_SFIELD(sfNFToken, OBJECT, 12)
UNTYPED_SFIELD(sfEmitDetails, OBJECT, 13)
UNTYPED_SFIELD(sfHook, OBJECT, 14)
UNTYPED_SFIELD(sfPermission, OBJECT, 15)
// inner object (uncommon)
UNTYPED_SFIELD(sfSigner, OBJECT, 16)
@@ -359,9 +390,7 @@ UNTYPED_SFIELD(sfXChainClaimAttestationCollectionElement, OBJECT, 30)
UNTYPED_SFIELD(sfXChainCreateAccountAttestationCollectionElement, OBJECT, 31)
UNTYPED_SFIELD(sfPriceData, OBJECT, 32)
UNTYPED_SFIELD(sfCredential, OBJECT, 33)
UNTYPED_SFIELD(sfRawTransaction, OBJECT, 34)
UNTYPED_SFIELD(sfBatchSigner, OBJECT, 35)
UNTYPED_SFIELD(sfBook, OBJECT, 36)
UNTYPED_SFIELD(sfCounterpartySignature, OBJECT, 34, SField::sMD_Default, SField::notSigning)
// array of objects (common)
// ARRAY/1 is reserved for end of array
@@ -377,7 +406,6 @@ UNTYPED_SFIELD(sfMemos, ARRAY, 9)
UNTYPED_SFIELD(sfNFTokens, ARRAY, 10)
UNTYPED_SFIELD(sfHooks, ARRAY, 11)
UNTYPED_SFIELD(sfVoteSlots, ARRAY, 12)
UNTYPED_SFIELD(sfAdditionalBooks, ARRAY, 13)
// array of objects (uncommon)
UNTYPED_SFIELD(sfMajorities, ARRAY, 16)
@@ -393,6 +421,5 @@ UNTYPED_SFIELD(sfAuthAccounts, ARRAY, 25)
UNTYPED_SFIELD(sfAuthorizeCredentials, ARRAY, 26)
UNTYPED_SFIELD(sfUnauthorizeCredentials, ARRAY, 27)
UNTYPED_SFIELD(sfAcceptedCredentials, ARRAY, 28)
UNTYPED_SFIELD(sfPermissions, ARRAY, 29)
UNTYPED_SFIELD(sfRawTransactions, ARRAY, 30)
UNTYPED_SFIELD(sfBatchSigners, ARRAY, 31, SField::sMD_Default, SField::notSigning)
// clang-format on

View File

@@ -50,7 +50,7 @@ class TokenCodecErrcCategory : public std::error_category
{
public:
// Return a short descriptive name for the category
virtual char const*
virtual const char*
name() const noexcept override final
{
return "TokenCodecError";
@@ -86,7 +86,7 @@ public:
};
} // namespace detail
inline ripple::detail::TokenCodecErrcCategory const&
inline const ripple::detail::TokenCodecErrcCategory&
TokenCodecErrcCategory()
{
static ripple::detail::TokenCodecErrcCategory c;

View File

@@ -22,14 +22,42 @@
#endif
/**
* TRANSACTION(tag, value, name, delegatable, fields)
* TRANSACTION(tag, value, name, privileges, fields)
*
* You must define a transactor class in the `ripple` namespace named `name`,
* and include its header in `src/xrpld/app/tx/detail/applySteps.cpp`.
* and include its header alongside the TRANSACTOR definition using this
* format:
* #if TRANSACTION_INCLUDE
* # include <xrpld/app/tx/detail/HEADER.h>
* #endif
*
* The `privileges` parameter of the TRANSACTION macro is a bitfield
* defining which operations the transaction can perform.
*
* The values are only used in InvariantCheck.cpp
* Valid values are
noPriv - The transaction can not do any of the enumerated operations
createAcct - The transaction can create a new ACCOUNT_ROOT object.
createPseudoAcct - The transaction can create a pseudo account,
which implies createAcct
mustDeleteAcct - The transaction must delete an ACCOUNT_ROOT object
mayDeleteAcct - The transaction may delete an ACCOUNT_ROOT object,
but does not have to
overrideFreeze - The transaction can override some freeze rules
changeNFTCounts - The transaction can mint or burn an NFT
createMPTIssuance - The transaction can create a new MPT issuance
destroyMPTIssuance - The transaction can destroy an MPT issuance
mustAuthorizeMPT - The transaction MUST create or delete an MPT
object (except by issuer)
mayAuthorizeMPT - The transaction MAY create or delete an MPT
object (except by issuer)
*/
/** This transaction type executes a payment. */
TRANSACTION(ttPAYMENT, 0, Payment, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Payment.h>
#endif
TRANSACTION(ttPAYMENT, 0, Payment, createAcct, ({
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
{sfSendMax, soeOPTIONAL, soeMPTSupported},
@@ -38,13 +66,15 @@ TRANSACTION(ttPAYMENT, 0, Payment, Delegation::delegatable, ({
{sfDestinationTag, soeOPTIONAL},
{sfDeliverMin, soeOPTIONAL, soeMPTSupported},
{sfCredentialIDs, soeOPTIONAL},
{sfDomainID, soeOPTIONAL},
}))
/** This transaction type creates an escrow object. */
TRANSACTION(ttESCROW_CREATE, 1, EscrowCreate, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Escrow.h>
#endif
TRANSACTION(ttESCROW_CREATE, 1, EscrowCreate, noPriv, ({
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
{sfAmount, soeREQUIRED},
{sfCondition, soeOPTIONAL},
{sfCancelAfter, soeOPTIONAL},
{sfFinishAfter, soeOPTIONAL},
@@ -52,7 +82,7 @@ TRANSACTION(ttESCROW_CREATE, 1, EscrowCreate, Delegation::delegatable, ({
}))
/** This transaction type completes an existing escrow. */
TRANSACTION(ttESCROW_FINISH, 2, EscrowFinish, Delegation::delegatable, ({
TRANSACTION(ttESCROW_FINISH, 2, EscrowFinish, noPriv, ({
{sfOwner, soeREQUIRED},
{sfOfferSequence, soeREQUIRED},
{sfFulfillment, soeOPTIONAL},
@@ -62,7 +92,10 @@ TRANSACTION(ttESCROW_FINISH, 2, EscrowFinish, Delegation::delegatable, ({
/** This transaction type adjusts various account settings. */
TRANSACTION(ttACCOUNT_SET, 3, AccountSet, Delegation::notDelegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/SetAccount.h>
#endif
TRANSACTION(ttACCOUNT_SET, 3, AccountSet, noPriv, ({
{sfEmailHash, soeOPTIONAL},
{sfWalletLocator, soeOPTIONAL},
{sfWalletSize, soeOPTIONAL},
@@ -76,36 +109,50 @@ TRANSACTION(ttACCOUNT_SET, 3, AccountSet, Delegation::notDelegatable, ({
}))
/** This transaction type cancels an existing escrow. */
TRANSACTION(ttESCROW_CANCEL, 4, EscrowCancel, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Escrow.h>
#endif
TRANSACTION(ttESCROW_CANCEL, 4, EscrowCancel, noPriv, ({
{sfOwner, soeREQUIRED},
{sfOfferSequence, soeREQUIRED},
}))
/** This transaction type sets or clears an account's "regular key". */
TRANSACTION(ttREGULAR_KEY_SET, 5, SetRegularKey, Delegation::notDelegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/SetRegularKey.h>
#endif
TRANSACTION(ttREGULAR_KEY_SET, 5, SetRegularKey, noPriv, ({
{sfRegularKey, soeOPTIONAL},
}))
// 6 deprecated
/** This transaction type creates an offer to trade one asset for another. */
TRANSACTION(ttOFFER_CREATE, 7, OfferCreate, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CreateOffer.h>
#endif
TRANSACTION(ttOFFER_CREATE, 7, OfferCreate, noPriv, ({
{sfTakerPays, soeREQUIRED},
{sfTakerGets, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
{sfOfferSequence, soeOPTIONAL},
{sfDomainID, soeOPTIONAL},
}))
/** This transaction type cancels existing offers to trade one asset for another. */
TRANSACTION(ttOFFER_CANCEL, 8, OfferCancel, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CancelOffer.h>
#endif
TRANSACTION(ttOFFER_CANCEL, 8, OfferCancel, noPriv, ({
{sfOfferSequence, soeREQUIRED},
}))
// 9 deprecated
/** This transaction type creates a new set of tickets. */
TRANSACTION(ttTICKET_CREATE, 10, TicketCreate, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CreateTicket.h>
#endif
TRANSACTION(ttTICKET_CREATE, 10, TicketCreate, noPriv, ({
{sfTicketCount, soeREQUIRED},
}))
@@ -114,13 +161,19 @@ TRANSACTION(ttTICKET_CREATE, 10, TicketCreate, Delegation::delegatable, ({
/** This transaction type modifies the signer list associated with an account. */
// The SignerEntries are optional because a SignerList is deleted by
// setting the SignerQuorum to zero and omitting SignerEntries.
TRANSACTION(ttSIGNER_LIST_SET, 12, SignerListSet, Delegation::notDelegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/SetSignerList.h>
#endif
TRANSACTION(ttSIGNER_LIST_SET, 12, SignerListSet, noPriv, ({
{sfSignerQuorum, soeREQUIRED},
{sfSignerEntries, soeOPTIONAL},
}))
/** This transaction type creates a new unidirectional XRP payment channel. */
TRANSACTION(ttPAYCHAN_CREATE, 13, PaymentChannelCreate, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/PayChan.h>
#endif
TRANSACTION(ttPAYCHAN_CREATE, 13, PaymentChannelCreate, noPriv, ({
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfSettleDelay, soeREQUIRED},
@@ -130,14 +183,14 @@ TRANSACTION(ttPAYCHAN_CREATE, 13, PaymentChannelCreate, Delegation::delegatable,
}))
/** This transaction type funds an existing unidirectional XRP payment channel. */
TRANSACTION(ttPAYCHAN_FUND, 14, PaymentChannelFund, Delegation::delegatable, ({
TRANSACTION(ttPAYCHAN_FUND, 14, PaymentChannelFund, noPriv, ({
{sfChannel, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
}))
/** This transaction type submits a claim against an existing unidirectional payment channel. */
TRANSACTION(ttPAYCHAN_CLAIM, 15, PaymentChannelClaim, Delegation::delegatable, ({
TRANSACTION(ttPAYCHAN_CLAIM, 15, PaymentChannelClaim, noPriv, ({
{sfChannel, soeREQUIRED},
{sfAmount, soeOPTIONAL},
{sfBalance, soeOPTIONAL},
@@ -147,7 +200,10 @@ TRANSACTION(ttPAYCHAN_CLAIM, 15, PaymentChannelClaim, Delegation::delegatable, (
}))
/** This transaction type creates a new check. */
TRANSACTION(ttCHECK_CREATE, 16, CheckCreate, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CreateCheck.h>
#endif
TRANSACTION(ttCHECK_CREATE, 16, CheckCreate, noPriv, ({
{sfDestination, soeREQUIRED},
{sfSendMax, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
@@ -156,19 +212,28 @@ TRANSACTION(ttCHECK_CREATE, 16, CheckCreate, Delegation::delegatable, ({
}))
/** This transaction type cashes an existing check. */
TRANSACTION(ttCHECK_CASH, 17, CheckCash, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CashCheck.h>
#endif
TRANSACTION(ttCHECK_CASH, 17, CheckCash, noPriv, ({
{sfCheckID, soeREQUIRED},
{sfAmount, soeOPTIONAL},
{sfDeliverMin, soeOPTIONAL},
}))
/** This transaction type cancels an existing check. */
TRANSACTION(ttCHECK_CANCEL, 18, CheckCancel, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CancelCheck.h>
#endif
TRANSACTION(ttCHECK_CANCEL, 18, CheckCancel, noPriv, ({
{sfCheckID, soeREQUIRED},
}))
/** This transaction type grants or revokes authorization to transfer funds. */
TRANSACTION(ttDEPOSIT_PREAUTH, 19, DepositPreauth, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/DepositPreauth.h>
#endif
TRANSACTION(ttDEPOSIT_PREAUTH, 19, DepositPreauth, noPriv, ({
{sfAuthorize, soeOPTIONAL},
{sfUnauthorize, soeOPTIONAL},
{sfAuthorizeCredentials, soeOPTIONAL},
@@ -176,14 +241,20 @@ TRANSACTION(ttDEPOSIT_PREAUTH, 19, DepositPreauth, Delegation::delegatable, ({
}))
/** This transaction type modifies a trustline between two accounts. */
TRANSACTION(ttTRUST_SET, 20, TrustSet, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/SetTrust.h>
#endif
TRANSACTION(ttTRUST_SET, 20, TrustSet, noPriv, ({
{sfLimitAmount, soeOPTIONAL},
{sfQualityIn, soeOPTIONAL},
{sfQualityOut, soeOPTIONAL},
}))
/** This transaction type deletes an existing account. */
TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete, Delegation::notDelegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/DeleteAccount.h>
#endif
TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete, mustDeleteAcct, ({
{sfDestination, soeREQUIRED},
{sfDestinationTag, soeOPTIONAL},
{sfCredentialIDs, soeOPTIONAL},
@@ -192,7 +263,10 @@ TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete, Delegation::notDelegatable, ({
// 22 reserved
/** This transaction mints a new NFT. */
TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenMint.h>
#endif
TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint, changeNFTCounts, ({
{sfNFTokenTaxon, soeREQUIRED},
{sfTransferFee, soeOPTIONAL},
{sfIssuer, soeOPTIONAL},
@@ -203,13 +277,19 @@ TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint, Delegation::delegatable, ({
}))
/** This transaction burns (i.e. destroys) an existing NFT. */
TRANSACTION(ttNFTOKEN_BURN, 26, NFTokenBurn, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenBurn.h>
#endif
TRANSACTION(ttNFTOKEN_BURN, 26, NFTokenBurn, changeNFTCounts, ({
{sfNFTokenID, soeREQUIRED},
{sfOwner, soeOPTIONAL},
}))
/** This transaction creates a new offer to buy or sell an NFT. */
TRANSACTION(ttNFTOKEN_CREATE_OFFER, 27, NFTokenCreateOffer, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenCreateOffer.h>
#endif
TRANSACTION(ttNFTOKEN_CREATE_OFFER, 27, NFTokenCreateOffer, noPriv, ({
{sfNFTokenID, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfDestination, soeOPTIONAL},
@@ -218,25 +298,38 @@ TRANSACTION(ttNFTOKEN_CREATE_OFFER, 27, NFTokenCreateOffer, Delegation::delegata
}))
/** This transaction cancels an existing offer to buy or sell an existing NFT. */
TRANSACTION(ttNFTOKEN_CANCEL_OFFER, 28, NFTokenCancelOffer, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenCancelOffer.h>
#endif
TRANSACTION(ttNFTOKEN_CANCEL_OFFER, 28, NFTokenCancelOffer, noPriv, ({
{sfNFTokenOffers, soeREQUIRED},
}))
/** This transaction accepts an existing offer to buy or sell an existing NFT. */
TRANSACTION(ttNFTOKEN_ACCEPT_OFFER, 29, NFTokenAcceptOffer, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenAcceptOffer.h>
#endif
TRANSACTION(ttNFTOKEN_ACCEPT_OFFER, 29, NFTokenAcceptOffer, noPriv, ({
{sfNFTokenBuyOffer, soeOPTIONAL},
{sfNFTokenSellOffer, soeOPTIONAL},
{sfNFTokenBrokerFee, soeOPTIONAL},
}))
/** This transaction claws back issued tokens. */
TRANSACTION(ttCLAWBACK, 30, Clawback, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Clawback.h>
#endif
TRANSACTION(ttCLAWBACK, 30, Clawback, noPriv, ({
{sfAmount, soeREQUIRED, soeMPTSupported},
{sfHolder, soeOPTIONAL},
}))
/** This transaction claws back tokens from an AMM pool. */
TRANSACTION(ttAMM_CLAWBACK, 31, AMMClawback, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMClawback.h>
#endif
TRANSACTION(ttAMM_CLAWBACK, 31, AMMClawback,
mayDeleteAcct | overrideFreeze, ({
{sfHolder, soeREQUIRED},
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
@@ -244,14 +337,20 @@ TRANSACTION(ttAMM_CLAWBACK, 31, AMMClawback, Delegation::delegatable, ({
}))
/** This transaction type creates an AMM instance */
TRANSACTION(ttAMM_CREATE, 35, AMMCreate, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMCreate.h>
#endif
TRANSACTION(ttAMM_CREATE, 35, AMMCreate, createPseudoAcct, ({
{sfAmount, soeREQUIRED},
{sfAmount2, soeREQUIRED},
{sfTradingFee, soeREQUIRED},
}))
/** This transaction type deposits into an AMM instance */
TRANSACTION(ttAMM_DEPOSIT, 36, AMMDeposit, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMDeposit.h>
#endif
TRANSACTION(ttAMM_DEPOSIT, 36, AMMDeposit, noPriv, ({
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
{sfAmount, soeOPTIONAL},
@@ -262,7 +361,10 @@ TRANSACTION(ttAMM_DEPOSIT, 36, AMMDeposit, Delegation::delegatable, ({
}))
/** This transaction type withdraws from an AMM instance */
TRANSACTION(ttAMM_WITHDRAW, 37, AMMWithdraw, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMWithdraw.h>
#endif
TRANSACTION(ttAMM_WITHDRAW, 37, AMMWithdraw, mayDeleteAcct, ({
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
{sfAmount, soeOPTIONAL},
@@ -272,14 +374,20 @@ TRANSACTION(ttAMM_WITHDRAW, 37, AMMWithdraw, Delegation::delegatable, ({
}))
/** This transaction type votes for the trading fee */
TRANSACTION(ttAMM_VOTE, 38, AMMVote, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMVote.h>
#endif
TRANSACTION(ttAMM_VOTE, 38, AMMVote, noPriv, ({
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
{sfTradingFee, soeREQUIRED},
}))
/** This transaction type bids for the auction slot */
TRANSACTION(ttAMM_BID, 39, AMMBid, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMBid.h>
#endif
TRANSACTION(ttAMM_BID, 39, AMMBid, noPriv, ({
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
{sfBidMin, soeOPTIONAL},
@@ -288,20 +396,26 @@ TRANSACTION(ttAMM_BID, 39, AMMBid, Delegation::delegatable, ({
}))
/** This transaction type deletes AMM in the empty state */
TRANSACTION(ttAMM_DELETE, 40, AMMDelete, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMDelete.h>
#endif
TRANSACTION(ttAMM_DELETE, 40, AMMDelete, mustDeleteAcct, ({
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
}))
/** This transactions creates a crosschain sequence number */
TRANSACTION(ttXCHAIN_CREATE_CLAIM_ID, 41, XChainCreateClaimID, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/XChainBridge.h>
#endif
TRANSACTION(ttXCHAIN_CREATE_CLAIM_ID, 41, XChainCreateClaimID, noPriv, ({
{sfXChainBridge, soeREQUIRED},
{sfSignatureReward, soeREQUIRED},
{sfOtherChainSource, soeREQUIRED},
}))
/** This transactions initiates a crosschain transaction */
TRANSACTION(ttXCHAIN_COMMIT, 42, XChainCommit, Delegation::delegatable, ({
TRANSACTION(ttXCHAIN_COMMIT, 42, XChainCommit, noPriv, ({
{sfXChainBridge, soeREQUIRED},
{sfXChainClaimID, soeREQUIRED},
{sfAmount, soeREQUIRED},
@@ -309,7 +423,7 @@ TRANSACTION(ttXCHAIN_COMMIT, 42, XChainCommit, Delegation::delegatable, ({
}))
/** This transaction completes a crosschain transaction */
TRANSACTION(ttXCHAIN_CLAIM, 43, XChainClaim, Delegation::delegatable, ({
TRANSACTION(ttXCHAIN_CLAIM, 43, XChainClaim, noPriv, ({
{sfXChainBridge, soeREQUIRED},
{sfXChainClaimID, soeREQUIRED},
{sfDestination, soeREQUIRED},
@@ -318,7 +432,7 @@ TRANSACTION(ttXCHAIN_CLAIM, 43, XChainClaim, Delegation::delegatable, ({
}))
/** This transaction initiates a crosschain account create transaction */
TRANSACTION(ttXCHAIN_ACCOUNT_CREATE_COMMIT, 44, XChainAccountCreateCommit, Delegation::delegatable, ({
TRANSACTION(ttXCHAIN_ACCOUNT_CREATE_COMMIT, 44, XChainAccountCreateCommit, noPriv, ({
{sfXChainBridge, soeREQUIRED},
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED},
@@ -326,7 +440,7 @@ TRANSACTION(ttXCHAIN_ACCOUNT_CREATE_COMMIT, 44, XChainAccountCreateCommit, Deleg
}))
/** This transaction adds an attestation to a claim */
TRANSACTION(ttXCHAIN_ADD_CLAIM_ATTESTATION, 45, XChainAddClaimAttestation, Delegation::delegatable, ({
TRANSACTION(ttXCHAIN_ADD_CLAIM_ATTESTATION, 45, XChainAddClaimAttestation, createAcct, ({
{sfXChainBridge, soeREQUIRED},
{sfAttestationSignerAccount, soeREQUIRED},
@@ -342,7 +456,7 @@ TRANSACTION(ttXCHAIN_ADD_CLAIM_ATTESTATION, 45, XChainAddClaimAttestation, Deleg
}))
/** This transaction adds an attestation to an account */
TRANSACTION(ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION, 46, XChainAddAccountCreateAttestation, Delegation::delegatable, ({
TRANSACTION(ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION, 46, XChainAddAccountCreateAttestation, createAcct, ({
{sfXChainBridge, soeREQUIRED},
{sfAttestationSignerAccount, soeREQUIRED},
@@ -359,31 +473,37 @@ TRANSACTION(ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION, 46, XChainAddAccountCreateA
}))
/** This transaction modifies a sidechain */
TRANSACTION(ttXCHAIN_MODIFY_BRIDGE, 47, XChainModifyBridge, Delegation::delegatable, ({
TRANSACTION(ttXCHAIN_MODIFY_BRIDGE, 47, XChainModifyBridge, noPriv, ({
{sfXChainBridge, soeREQUIRED},
{sfSignatureReward, soeOPTIONAL},
{sfMinAccountCreateAmount, soeOPTIONAL},
}))
/** This transactions creates a sidechain */
TRANSACTION(ttXCHAIN_CREATE_BRIDGE, 48, XChainCreateBridge, Delegation::delegatable, ({
TRANSACTION(ttXCHAIN_CREATE_BRIDGE, 48, XChainCreateBridge, noPriv, ({
{sfXChainBridge, soeREQUIRED},
{sfSignatureReward, soeREQUIRED},
{sfMinAccountCreateAmount, soeOPTIONAL},
}))
/** This transaction type creates or updates a DID */
TRANSACTION(ttDID_SET, 49, DIDSet, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/DID.h>
#endif
TRANSACTION(ttDID_SET, 49, DIDSet, noPriv, ({
{sfDIDDocument, soeOPTIONAL},
{sfURI, soeOPTIONAL},
{sfData, soeOPTIONAL},
}))
/** This transaction type deletes a DID */
TRANSACTION(ttDID_DELETE, 50, DIDDelete, Delegation::delegatable, ({}))
TRANSACTION(ttDID_DELETE, 50, DIDDelete, noPriv, ({}))
/** This transaction type creates an Oracle instance */
TRANSACTION(ttORACLE_SET, 51, OracleSet, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/SetOracle.h>
#endif
TRANSACTION(ttORACLE_SET, 51, OracleSet, noPriv, ({
{sfOracleDocumentID, soeREQUIRED},
{sfProvider, soeOPTIONAL},
{sfURI, soeOPTIONAL},
@@ -393,18 +513,28 @@ TRANSACTION(ttORACLE_SET, 51, OracleSet, Delegation::delegatable, ({
}))
/** This transaction type deletes an Oracle instance */
TRANSACTION(ttORACLE_DELETE, 52, OracleDelete, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/DeleteOracle.h>
#endif
TRANSACTION(ttORACLE_DELETE, 52, OracleDelete, noPriv, ({
{sfOracleDocumentID, soeREQUIRED},
}))
/** This transaction type fixes a problem in the ledger state */
TRANSACTION(ttLEDGER_STATE_FIX, 53, LedgerStateFix, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LedgerStateFix.h>
#endif
TRANSACTION(ttLEDGER_STATE_FIX, 53, LedgerStateFix, noPriv, ({
{sfLedgerFixType, soeREQUIRED},
{sfOwner, soeOPTIONAL},
}))
/** This transaction type creates a MPTokensIssuance instance */
TRANSACTION(ttMPTOKEN_ISSUANCE_CREATE, 54, MPTokenIssuanceCreate, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/MPTokenIssuanceCreate.h>
#endif
TRANSACTION(ttMPTOKEN_ISSUANCE_CREATE, 54, MPTokenIssuanceCreate,
createMPTIssuance, ({
{sfAssetScale, soeOPTIONAL},
{sfTransferFee, soeOPTIONAL},
{sfMaximumAmount, soeOPTIONAL},
@@ -412,24 +542,37 @@ TRANSACTION(ttMPTOKEN_ISSUANCE_CREATE, 54, MPTokenIssuanceCreate, Delegation::de
}))
/** This transaction type destroys a MPTokensIssuance instance */
TRANSACTION(ttMPTOKEN_ISSUANCE_DESTROY, 55, MPTokenIssuanceDestroy, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/MPTokenIssuanceDestroy.h>
#endif
TRANSACTION(ttMPTOKEN_ISSUANCE_DESTROY, 55, MPTokenIssuanceDestroy,
destroyMPTIssuance, ({
{sfMPTokenIssuanceID, soeREQUIRED},
}))
/** This transaction type sets flags on a MPTokensIssuance or MPToken instance */
TRANSACTION(ttMPTOKEN_ISSUANCE_SET, 56, MPTokenIssuanceSet, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/MPTokenIssuanceSet.h>
#endif
TRANSACTION(ttMPTOKEN_ISSUANCE_SET, 56, MPTokenIssuanceSet, noPriv, ({
{sfMPTokenIssuanceID, soeREQUIRED},
{sfHolder, soeOPTIONAL},
}))
/** This transaction type authorizes a MPToken instance */
TRANSACTION(ttMPTOKEN_AUTHORIZE, 57, MPTokenAuthorize, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/MPTokenAuthorize.h>
#endif
TRANSACTION(ttMPTOKEN_AUTHORIZE, 57, MPTokenAuthorize, mustAuthorizeMPT, ({
{sfMPTokenIssuanceID, soeREQUIRED},
{sfHolder, soeOPTIONAL},
}))
/** This transaction type create an Credential instance */
TRANSACTION(ttCREDENTIAL_CREATE, 58, CredentialCreate, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Credentials.h>
#endif
TRANSACTION(ttCREDENTIAL_CREATE, 58, CredentialCreate, noPriv, ({
{sfSubject, soeREQUIRED},
{sfCredentialType, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
@@ -437,44 +580,51 @@ TRANSACTION(ttCREDENTIAL_CREATE, 58, CredentialCreate, Delegation::delegatable,
}))
/** This transaction type accept an Credential object */
TRANSACTION(ttCREDENTIAL_ACCEPT, 59, CredentialAccept, Delegation::delegatable, ({
TRANSACTION(ttCREDENTIAL_ACCEPT, 59, CredentialAccept, noPriv, ({
{sfIssuer, soeREQUIRED},
{sfCredentialType, soeREQUIRED},
}))
/** This transaction type delete an Credential object */
TRANSACTION(ttCREDENTIAL_DELETE, 60, CredentialDelete, Delegation::delegatable, ({
TRANSACTION(ttCREDENTIAL_DELETE, 60, CredentialDelete, noPriv, ({
{sfSubject, soeOPTIONAL},
{sfIssuer, soeOPTIONAL},
{sfCredentialType, soeREQUIRED},
}))
/** This transaction type modify a NFToken */
TRANSACTION(ttNFTOKEN_MODIFY, 61, NFTokenModify, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenModify.h>
#endif
TRANSACTION(ttNFTOKEN_MODIFY, 61, NFTokenModify, noPriv, ({
{sfNFTokenID, soeREQUIRED},
{sfOwner, soeOPTIONAL},
{sfURI, soeOPTIONAL},
}))
/** This transaction type creates or modifies a Permissioned Domain */
TRANSACTION(ttPERMISSIONED_DOMAIN_SET, 62, PermissionedDomainSet, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/PermissionedDomainSet.h>
#endif
TRANSACTION(ttPERMISSIONED_DOMAIN_SET, 62, PermissionedDomainSet, noPriv, ({
{sfDomainID, soeOPTIONAL},
{sfAcceptedCredentials, soeREQUIRED},
}))
/** This transaction type deletes a Permissioned Domain */
TRANSACTION(ttPERMISSIONED_DOMAIN_DELETE, 63, PermissionedDomainDelete, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/PermissionedDomainDelete.h>
#endif
TRANSACTION(ttPERMISSIONED_DOMAIN_DELETE, 63, PermissionedDomainDelete, noPriv, ({
{sfDomainID, soeREQUIRED},
}))
/** This transaction type delegates authorized account specified permissions */
TRANSACTION(ttDELEGATE_SET, 64, DelegateSet, Delegation::notDelegatable, ({
{sfAuthorize, soeREQUIRED},
{sfPermissions, soeREQUIRED},
}))
/** This transaction creates a single asset vault. */
TRANSACTION(ttVAULT_CREATE, 65, VaultCreate, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultCreate.h>
#endif
TRANSACTION(ttVAULT_CREATE, 64, VaultCreate,
createPseudoAcct | createMPTIssuance, ({
{sfAsset, soeREQUIRED, soeMPTSupported},
{sfAssetsMaximum, soeOPTIONAL},
{sfMPTokenMetadata, soeOPTIONAL},
@@ -484,7 +634,10 @@ TRANSACTION(ttVAULT_CREATE, 65, VaultCreate, Delegation::delegatable, ({
}))
/** This transaction updates a single asset vault. */
TRANSACTION(ttVAULT_SET, 66, VaultSet, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultSet.h>
#endif
TRANSACTION(ttVAULT_SET, 65, VaultSet, noPriv, ({
{sfVaultID, soeREQUIRED},
{sfAssetsMaximum, soeOPTIONAL},
{sfDomainID, soeOPTIONAL}, // PermissionedDomainID
@@ -492,41 +645,154 @@ TRANSACTION(ttVAULT_SET, 66, VaultSet, Delegation::delegatable, ({
}))
/** This transaction deletes a single asset vault. */
TRANSACTION(ttVAULT_DELETE, 67, VaultDelete, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultDelete.h>
#endif
TRANSACTION(ttVAULT_DELETE, 66, VaultDelete,
mustDeleteAcct | destroyMPTIssuance, ({
{sfVaultID, soeREQUIRED},
}))
/** This transaction trades assets for shares with a vault. */
TRANSACTION(ttVAULT_DEPOSIT, 68, VaultDeposit, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultDeposit.h>
#endif
TRANSACTION(ttVAULT_DEPOSIT, 67, VaultDeposit, mayAuthorizeMPT, ({
{sfVaultID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
}))
/** This transaction trades shares for assets with a vault. */
TRANSACTION(ttVAULT_WITHDRAW, 69, VaultWithdraw, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultWithdraw.h>
#endif
TRANSACTION(ttVAULT_WITHDRAW, 68, VaultWithdraw, noPriv, ({
{sfVaultID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
{sfDestination, soeOPTIONAL},
}))
/** This transaction claws back tokens from a vault. */
TRANSACTION(ttVAULT_CLAWBACK, 70, VaultClawback, Delegation::delegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultClawback.h>
#endif
TRANSACTION(ttVAULT_CLAWBACK, 69, VaultClawback, noPriv, ({
{sfVaultID, soeREQUIRED},
{sfHolder, soeREQUIRED},
{sfAmount, soeOPTIONAL, soeMPTSupported},
}))
/** This transaction type batches together transactions. */
TRANSACTION(ttBATCH, 71, Batch, Delegation::notDelegatable, ({
{sfRawTransactions, soeREQUIRED},
{sfBatchSigners, soeOPTIONAL},
/** Reserve 70-73 for future Vault-related transactions */
/** This transaction creates and updates a Loan Broker */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanBrokerSet.h>
#endif
TRANSACTION(ttLOAN_BROKER_SET, 74, LoanBrokerSet,
createPseudoAcct | mayAuthorizeMPT, ({
{sfVaultID, soeREQUIRED},
{sfLoanBrokerID, soeOPTIONAL},
{sfData, soeOPTIONAL},
{sfManagementFeeRate, soeOPTIONAL},
{sfDebtMaximum, soeOPTIONAL},
{sfCoverRateMinimum, soeOPTIONAL},
{sfCoverRateLiquidation, soeOPTIONAL},
}))
/** This transaction deletes a Loan Broker */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanBrokerDelete.h>
#endif
TRANSACTION(ttLOAN_BROKER_DELETE, 75, LoanBrokerDelete,
mustDeleteAcct | mayAuthorizeMPT, ({
{sfLoanBrokerID, soeREQUIRED},
}))
/** This transaction deposits First Loss Capital into a Loan Broker */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanBrokerCoverDeposit.h>
#endif
TRANSACTION(ttLOAN_BROKER_COVER_DEPOSIT, 76, LoanBrokerCoverDeposit, noPriv, ({
{sfLoanBrokerID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
}))
/** This transaction withdraws First Loss Capital from a Loan Broker */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanBrokerCoverWithdraw.h>
#endif
TRANSACTION(ttLOAN_BROKER_COVER_WITHDRAW, 77, LoanBrokerCoverWithdraw, noPriv, ({
{sfLoanBrokerID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
}))
/** This transaction creates a Loan */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanSet.h>
#endif
TRANSACTION(ttLOAN_SET, 78, LoanSet, noPriv, ({
{sfLoanBrokerID, soeREQUIRED},
{sfData, soeOPTIONAL},
{sfCounterparty, soeOPTIONAL},
{sfCounterpartySignature, soeREQUIRED},
{sfLoanOriginationFee, soeOPTIONAL},
{sfLoanServiceFee, soeOPTIONAL},
{sfLatePaymentFee, soeOPTIONAL},
{sfClosePaymentFee, soeOPTIONAL},
{sfOverpaymentFee, soeOPTIONAL},
{sfInterestRate, soeOPTIONAL},
{sfLateInterestRate, soeOPTIONAL},
{sfCloseInterestRate, soeOPTIONAL},
{sfOverpaymentInterestRate, soeOPTIONAL},
{sfPrincipalRequested, soeREQUIRED},
{sfStartDate, soeREQUIRED},
{sfPaymentTotal, soeOPTIONAL},
{sfPaymentInterval, soeOPTIONAL},
{sfGracePeriod, soeOPTIONAL},
}))
/** This transaction deletes an existing Loan */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanDelete.h>
#endif
TRANSACTION(ttLOAN_DELETE, 79, LoanDelete, noPriv, ({
{sfLoanID, soeREQUIRED},
}))
/** This transaction is used to change the delinquency status of an existing Loan */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanManage.h>
#endif
TRANSACTION(ttLOAN_MANAGE, 80, LoanManage, noPriv, ({
{sfLoanID, soeREQUIRED},
}))
/** The Borrower uses this transaction to draws funds from the Loan. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanDraw.h>
#endif
TRANSACTION(ttLOAN_DRAW, 81, LoanDraw, noPriv, ({
{sfLoanID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
}))
/** The Borrower uses this transaction to make a Payment on the Loan. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanPay.h>
#endif
TRANSACTION(ttLOAN_PAY, 82, LoanPay, noPriv, ({
{sfLoanID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
}))
/** This system-generated transaction type is used to update the status of the various amendments.
For details, see: https://xrpl.org/amendments.html
*/
TRANSACTION(ttAMENDMENT, 100, EnableAmendment, Delegation::notDelegatable, ({
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Change.h>
#endif
TRANSACTION(ttAMENDMENT, 100, EnableAmendment, noPriv, ({
{sfLedgerSequence, soeREQUIRED},
{sfAmendment, soeREQUIRED},
}))
@@ -534,7 +800,7 @@ TRANSACTION(ttAMENDMENT, 100, EnableAmendment, Delegation::notDelegatable, ({
/** This system-generated transaction type is used to update the network's fee settings.
For details, see: https://xrpl.org/fee-voting.html
*/
TRANSACTION(ttFEE, 101, SetFee, Delegation::notDelegatable, ({
TRANSACTION(ttFEE, 101, SetFee, noPriv, ({
{sfLedgerSequence, soeOPTIONAL},
// Old version uses raw numbers
{sfBaseFee, soeOPTIONAL},
@@ -551,8 +817,9 @@ TRANSACTION(ttFEE, 101, SetFee, Delegation::notDelegatable, ({
For details, see: https://xrpl.org/negative-unl.html
*/
TRANSACTION(ttUNL_MODIFY, 102, UNLModify, Delegation::notDelegatable, ({
TRANSACTION(ttUNL_MODIFY, 102, UNLModify, noPriv, ({
{sfUNLModifyDisabling, soeREQUIRED},
{sfLedgerSequence, soeREQUIRED},
{sfUNLModifyValidator, soeREQUIRED},
}))

View File

@@ -20,7 +20,7 @@ struct JsonMissingKeyError : std::exception
JsonMissingKeyError(Json::StaticString const& k) : key{k.c_str()}
{
}
char const*
const char*
what() const noexcept override
{
if (msg.empty())
@@ -40,7 +40,7 @@ struct JsonTypeMismatchError : std::exception
: key{k.c_str()}, expectedType{std::move(et)}
{
}
char const*
const char*
what() const noexcept override
{
if (msg.empty())

View File

@@ -83,8 +83,6 @@ JSS(PriceDataSeries); // field.
JSS(PriceData); // field.
JSS(Provider); // field.
JSS(QuoteAsset); // in: Oracle.
JSS(RawTransaction); // in: Batch
JSS(RawTransactions); // in: Batch
JSS(SLE_hit_rate); // out: GetCounts.
JSS(Scale); // field.
JSS(SettleDelay); // in: TransactionSign
@@ -147,7 +145,6 @@ JSS(attestations);
JSS(attestation_reward_account);
JSS(auction_slot); // out: amm_info
JSS(authorized); // out: AccountLines
JSS(authorize); // out: delegate
JSS(authorized_credentials); // in: ledger_entry DepositPreauth
JSS(auth_accounts); // out: amm_info
JSS(auth_change); // out: AccountInfo
@@ -391,7 +388,6 @@ JSS(load_fee); // out: LoadFeeTrackImp, NetworkOPs
JSS(local); // out: resource/Logic.h
JSS(local_txs); // out: GetCounts
JSS(local_static_keys); // out: ValidatorList
JSS(locked); // out: GatewayBalances
JSS(low); // out: BookChanges
JSS(lowest_sequence); // out: AccountInfo
JSS(lowest_ticket); // out: AccountInfo
@@ -706,7 +702,7 @@ JSS(write_load); // out: GetCounts
#pragma push_macro("TRANSACTION")
#undef TRANSACTION
#define TRANSACTION(tag, value, name, delegatable, fields) JSS(name);
#define TRANSACTION(tag, value, name, privileges, fields) JSS(name);
#include <xrpl/protocol/detail/transactions.macro>

View File

@@ -53,7 +53,7 @@ struct Key
struct key_equal
{
key_equal() = default;
explicit key_equal() = default;
bool
operator()(Key const& lhs, Key const& rhs) const

View File

@@ -94,7 +94,7 @@ extractTarLz4(
if (archive_entry_size(entry) > 0)
{
void const* buf;
const void* buf;
size_t sz;
la_int64_t offset;
while (true)

View File

@@ -63,7 +63,7 @@ getFileContents(
return {};
}
std::string const result{
const std::string result{
std::istreambuf_iterator<char>{fileStream},
std::istreambuf_iterator<char>{}};

View File

@@ -20,6 +20,8 @@
#include <xrpl/basics/Number.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/predef.h>
#include <algorithm>
#include <cstddef>
#include <cstdint>
@@ -469,7 +471,7 @@ Number::operator/=(Number const& y)
}
// Shift by 10^17 gives greatest precision while not overflowing uint128_t
// or the cast back to int64_t
uint128_t const f = 100'000'000'000'000'000;
const uint128_t f = 100'000'000'000'000'000;
mantissa_ = static_cast<std::int64_t>(uint128_t(nm) * f / uint128_t(dm));
exponent_ = ne - de - 17;
mantissa_ *= np * dp;

View File

@@ -89,13 +89,13 @@ parseUrl(parsedURL& pUrl, std::string const& strUrl)
boost::algorithm::to_lower(pUrl.scheme);
pUrl.username = smMatch[2];
pUrl.password = smMatch[3];
std::string const domain = smMatch[4];
const std::string domain = smMatch[4];
// We need to use Endpoint to parse the domain to
// strip surrounding brackets from IPv6 addresses,
// e.g. [::1] => ::1.
auto const result = beast::IP::Endpoint::from_string_checked(domain);
const auto result = beast::IP::Endpoint::from_string_checked(domain);
pUrl.domain = result ? result->address().to_string() : domain;
std::string const port = smMatch[5];
const std::string port = smMatch[5];
if (!port.empty())
{
pUrl.port = beast::lexicalCast<std::uint16_t>(port);

View File

@@ -67,7 +67,7 @@ UptimeClock::time_point
UptimeClock::now()
{
// start the update thread on first use
static auto const init = start_clock();
static const auto init = start_clock();
// Return the number of seconds since rippled start
return time_point{duration{now_}};

View File

@@ -34,7 +34,7 @@ namespace Json {
namespace {
std::map<char, char const*> jsonSpecialCharacterEscape = {
std::map<char, const char*> jsonSpecialCharacterEscape = {
{'"', "\\\""},
{'\\', "\\\\"},
{'/', "\\/"},
@@ -47,13 +47,13 @@ std::map<char, char const*> jsonSpecialCharacterEscape = {
static size_t const jsonEscapeLength = 2;
// All other JSON punctuation.
char const closeBrace = '}';
char const closeBracket = ']';
char const colon = ':';
char const comma = ',';
char const openBrace = '{';
char const openBracket = '[';
char const quote = '"';
const char closeBrace = '}';
const char closeBracket = ']';
const char colon = ':';
const char comma = ',';
const char openBrace = '{';
const char openBracket = '[';
const char quote = '"';
static auto const integralFloatsBecomeInts = false;

View File

@@ -78,8 +78,8 @@ bool
Reader::parse(std::string const& document, Value& root)
{
document_ = document;
char const* begin = document_.c_str();
char const* end = begin + document_.length();
const char* begin = document_.c_str();
const char* end = begin + document_.length();
return parse(begin, end, root);
}
@@ -99,7 +99,7 @@ Reader::parse(std::istream& sin, Value& root)
}
bool
Reader::parse(char const* beginDoc, char const* endDoc, Value& root)
Reader::parse(const char* beginDoc, const char* endDoc, Value& root)
{
begin_ = beginDoc;
end_ = endDoc;
@@ -193,7 +193,7 @@ Reader::skipCommentTokens(Token& token)
}
bool
Reader::expectToken(TokenType type, Token& token, char const* message)
Reader::expectToken(TokenType type, Token& token, const char* message)
{
readToken(token);
@@ -629,7 +629,7 @@ bool
Reader::decodeDouble(Token& token)
{
double value = 0;
int const bufferSize = 32;
const int bufferSize = 32;
int count;
int length = int(token.end_ - token.start_);
// Sanity check to avoid buffer overflow exploits.
@@ -939,7 +939,7 @@ Reader::getFormatedErrorMessages() const
itError != errors_.end();
++itError)
{
ErrorInfo const& error = *itError;
const ErrorInfo& error = *itError;
formattedMessage +=
"* " + getLocationLineAndColumn(error.token_.start_) + "\n";
formattedMessage += " " + error.message_ + "\n";

View File

@@ -31,10 +31,10 @@
namespace Json {
Value const Value::null;
Int const Value::minInt = Int(~(UInt(-1) / 2));
Int const Value::maxInt = Int(UInt(-1) / 2);
UInt const Value::maxUInt = UInt(-1);
const Value Value::null;
const Int Value::minInt = Int(~(UInt(-1) / 2));
const Int Value::maxInt = Int(UInt(-1) / 2);
const UInt Value::maxUInt = UInt(-1);
class DefaultValueAllocator : public ValueAllocator
{
@@ -42,7 +42,7 @@ public:
virtual ~DefaultValueAllocator() = default;
char*
makeMemberName(char const* memberName) override
makeMemberName(const char* memberName) override
{
return duplicateStringValue(memberName);
}
@@ -54,7 +54,7 @@ public:
}
char*
duplicateStringValue(char const* value, unsigned int length = unknown)
duplicateStringValue(const char* value, unsigned int length = unknown)
override
{
//@todo investigate this old optimization
@@ -110,14 +110,14 @@ Value::CZString::CZString(int index) : cstr_(0), index_(index)
{
}
Value::CZString::CZString(char const* cstr, DuplicationPolicy allocate)
Value::CZString::CZString(const char* cstr, DuplicationPolicy allocate)
: cstr_(
allocate == duplicate ? valueAllocator()->makeMemberName(cstr) : cstr)
, index_(allocate)
{
}
Value::CZString::CZString(CZString const& other)
Value::CZString::CZString(const CZString& other)
: cstr_(
other.index_ != noDuplication && other.cstr_ != 0
? valueAllocator()->makeMemberName(other.cstr_)
@@ -136,7 +136,7 @@ Value::CZString::~CZString()
}
bool
Value::CZString::operator<(CZString const& other) const
Value::CZString::operator<(const CZString& other) const
{
if (cstr_ && other.cstr_)
return strcmp(cstr_, other.cstr_) < 0;
@@ -145,7 +145,7 @@ Value::CZString::operator<(CZString const& other) const
}
bool
Value::CZString::operator==(CZString const& other) const
Value::CZString::operator==(const CZString& other) const
{
if (cstr_ && other.cstr_)
return strcmp(cstr_, other.cstr_) == 0;
@@ -159,7 +159,7 @@ Value::CZString::index() const
return index_;
}
char const*
const char*
Value::CZString::c_str() const
{
return cstr_;
@@ -232,7 +232,7 @@ Value::Value(double value) : type_(realValue)
value_.real_ = value;
}
Value::Value(char const* value) : type_(stringValue), allocated_(true)
Value::Value(const char* value) : type_(stringValue), allocated_(true)
{
value_.string_ = valueAllocator()->duplicateStringValue(value);
}
@@ -250,7 +250,7 @@ Value::Value(std::string const& value) : type_(stringValue), allocated_(true)
value.c_str(), (unsigned int)value.length());
}
Value::Value(StaticString const& value) : type_(stringValue), allocated_(false)
Value::Value(const StaticString& value) : type_(stringValue), allocated_(false)
{
value_.string_ = const_cast<char*>(value.c_str());
}
@@ -260,7 +260,7 @@ Value::Value(bool value) : type_(booleanValue)
value_.bool_ = value;
}
Value::Value(Value const& other) : type_(other.type_)
Value::Value(const Value& other) : type_(other.type_)
{
switch (type_)
{
@@ -377,7 +377,7 @@ integerCmp(Int i, UInt ui)
}
bool
operator<(Value const& x, Value const& y)
operator<(const Value& x, const Value& y)
{
if (auto signum = x.type_ - y.type_)
{
@@ -426,7 +426,7 @@ operator<(Value const& x, Value const& y)
}
bool
operator==(Value const& x, Value const& y)
operator==(const Value& x, const Value& y)
{
if (x.type_ != y.type_)
{
@@ -471,7 +471,7 @@ operator==(Value const& x, Value const& y)
return 0; // unreachable
}
char const*
const char*
Value::asCString() const
{
XRPL_ASSERT(type_ == stringValue, "Json::Value::asCString : valid type");
@@ -802,7 +802,7 @@ Value::operator[](UInt index)
return (*it).second;
}
Value const&
const Value&
Value::operator[](UInt index) const
{
XRPL_ASSERT(
@@ -822,13 +822,13 @@ Value::operator[](UInt index) const
}
Value&
Value::operator[](char const* key)
Value::operator[](const char* key)
{
return resolveReference(key, false);
}
Value&
Value::resolveReference(char const* key, bool isStatic)
Value::resolveReference(const char* key, bool isStatic)
{
XRPL_ASSERT(
type_ == nullValue || type_ == objectValue,
@@ -851,9 +851,9 @@ Value::resolveReference(char const* key, bool isStatic)
}
Value
Value::get(UInt index, Value const& defaultValue) const
Value::get(UInt index, const Value& defaultValue) const
{
Value const* value = &((*this)[index]);
const Value* value = &((*this)[index]);
return value == &null ? defaultValue : *value;
}
@@ -863,8 +863,8 @@ Value::isValidIndex(UInt index) const
return index < size();
}
Value const&
Value::operator[](char const* key) const
const Value&
Value::operator[](const char* key) const
{
XRPL_ASSERT(
type_ == nullValue || type_ == objectValue,
@@ -888,26 +888,26 @@ Value::operator[](std::string const& key)
return (*this)[key.c_str()];
}
Value const&
const Value&
Value::operator[](std::string const& key) const
{
return (*this)[key.c_str()];
}
Value&
Value::operator[](StaticString const& key)
Value::operator[](const StaticString& key)
{
return resolveReference(key, true);
}
Value const&
Value::operator[](StaticString const& key) const
Value::operator[](const StaticString& key) const
{
return (*this)[key.c_str()];
}
Value&
Value::append(Value const& value)
Value::append(const Value& value)
{
return (*this)[size()] = value;
}
@@ -919,20 +919,20 @@ Value::append(Value&& value)
}
Value
Value::get(char const* key, Value const& defaultValue) const
Value::get(const char* key, const Value& defaultValue) const
{
Value const* value = &((*this)[key]);
const Value* value = &((*this)[key]);
return value == &null ? defaultValue : *value;
}
Value
Value::get(std::string const& key, Value const& defaultValue) const
Value::get(std::string const& key, const Value& defaultValue) const
{
return get(key.c_str(), defaultValue);
}
Value
Value::removeMember(char const* key)
Value::removeMember(const char* key)
{
XRPL_ASSERT(
type_ == nullValue || type_ == objectValue,
@@ -959,12 +959,12 @@ Value::removeMember(std::string const& key)
}
bool
Value::isMember(char const* key) const
Value::isMember(const char* key) const
{
if (type_ != objectValue)
return false;
Value const* value = &((*this)[key]);
const Value* value = &((*this)[key]);
return value != &null;
}

View File

@@ -37,7 +37,7 @@ ValueIteratorBase::ValueIteratorBase() : current_(), isNull_(true)
}
ValueIteratorBase::ValueIteratorBase(
Value::ObjectValues::iterator const& current)
const Value::ObjectValues::iterator& current)
: current_(current), isNull_(false)
{
}
@@ -61,7 +61,7 @@ ValueIteratorBase::decrement()
}
ValueIteratorBase::difference_type
ValueIteratorBase::computeDistance(SelfType const& other) const
ValueIteratorBase::computeDistance(const SelfType& other) const
{
// Iterator for null value are initialized using the default
// constructor, which initialize current_ to the default
@@ -89,7 +89,7 @@ ValueIteratorBase::computeDistance(SelfType const& other) const
}
bool
ValueIteratorBase::isEqual(SelfType const& other) const
ValueIteratorBase::isEqual(const SelfType& other) const
{
if (isNull_)
{
@@ -100,7 +100,7 @@ ValueIteratorBase::isEqual(SelfType const& other) const
}
void
ValueIteratorBase::copy(SelfType const& other)
ValueIteratorBase::copy(const SelfType& other)
{
current_ = other.current_;
}
@@ -108,7 +108,7 @@ ValueIteratorBase::copy(SelfType const& other)
Value
ValueIteratorBase::key() const
{
Value::CZString const czstring = (*current_).first;
const Value::CZString czstring = (*current_).first;
if (czstring.c_str())
{
@@ -124,7 +124,7 @@ ValueIteratorBase::key() const
UInt
ValueIteratorBase::index() const
{
Value::CZString const czstring = (*current_).first;
const Value::CZString czstring = (*current_).first;
if (!czstring.c_str())
return czstring.index();
@@ -132,10 +132,10 @@ ValueIteratorBase::index() const
return Value::UInt(-1);
}
char const*
const char*
ValueIteratorBase::memberName() const
{
char const* name = (*current_).first.c_str();
const char* name = (*current_).first.c_str();
return name ? name : "";
}
@@ -148,13 +148,13 @@ ValueIteratorBase::memberName() const
// //////////////////////////////////////////////////////////////////
ValueConstIterator::ValueConstIterator(
Value::ObjectValues::iterator const& current)
const Value::ObjectValues::iterator& current)
: ValueIteratorBase(current)
{
}
ValueConstIterator&
ValueConstIterator::operator=(ValueIteratorBase const& other)
ValueConstIterator::operator=(const ValueIteratorBase& other)
{
copy(other);
return *this;
@@ -168,23 +168,23 @@ ValueConstIterator::operator=(ValueIteratorBase const& other)
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
ValueIterator::ValueIterator(Value::ObjectValues::iterator const& current)
ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current)
: ValueIteratorBase(current)
{
}
ValueIterator::ValueIterator(ValueConstIterator const& other)
ValueIterator::ValueIterator(const ValueConstIterator& other)
: ValueIteratorBase(other)
{
}
ValueIterator::ValueIterator(ValueIterator const& other)
ValueIterator::ValueIterator(const ValueIterator& other)
: ValueIteratorBase(other)
{
}
ValueIterator&
ValueIterator::operator=(SelfType const& other)
ValueIterator::operator=(const SelfType& other)
{
copy(other);
return *this;

View File

@@ -40,7 +40,7 @@ isControlCharacter(char ch)
}
static bool
containsControlCharacter(char const* str)
containsControlCharacter(const char* str)
{
while (*str)
{
@@ -117,7 +117,7 @@ valueToString(bool value)
}
std::string
valueToQuotedString(char const* value)
valueToQuotedString(const char* value)
{
// Not sure how to handle unicode...
if (strpbrk(value, "\"\\\b\f\n\r\t") == nullptr &&
@@ -132,7 +132,7 @@ valueToQuotedString(char const* value)
result.reserve(maxsize); // to avoid lots of mallocs
result += "\"";
for (char const* c = value; *c != 0; ++c)
for (const char* c = value; *c != 0; ++c)
{
switch (*c)
{
@@ -197,7 +197,7 @@ valueToQuotedString(char const* value)
// //////////////////////////////////////////////////////////////////
std::string
FastWriter::write(Value const& root)
FastWriter::write(const Value& root)
{
document_ = "";
writeValue(root);
@@ -205,7 +205,7 @@ FastWriter::write(Value const& root)
}
void
FastWriter::writeValue(Value const& value)
FastWriter::writeValue(const Value& value)
{
switch (value.type())
{
@@ -281,7 +281,7 @@ StyledWriter::StyledWriter() : rightMargin_(74), indentSize_(3)
}
std::string
StyledWriter::write(Value const& root)
StyledWriter::write(const Value& root)
{
document_ = "";
addChildValues_ = false;
@@ -292,7 +292,7 @@ StyledWriter::write(Value const& root)
}
void
StyledWriter::writeValue(Value const& value)
StyledWriter::writeValue(const Value& value)
{
switch (value.type())
{
@@ -338,7 +338,7 @@ StyledWriter::writeValue(Value const& value)
while (true)
{
std::string const& name = *it;
Value const& childValue = value[name];
const Value& childValue = value[name];
writeWithIndent(valueToQuotedString(name.c_str()));
document_ += " : ";
writeValue(childValue);
@@ -358,7 +358,7 @@ StyledWriter::writeValue(Value const& value)
}
void
StyledWriter::writeArrayValue(Value const& value)
StyledWriter::writeArrayValue(const Value& value)
{
unsigned size = value.size();
@@ -377,7 +377,7 @@ StyledWriter::writeArrayValue(Value const& value)
while (true)
{
Value const& childValue = value[index];
const Value& childValue = value[index];
if (hasChildValue)
writeWithIndent(childValues_[index]);
@@ -417,7 +417,7 @@ StyledWriter::writeArrayValue(Value const& value)
}
bool
StyledWriter::isMultineArray(Value const& value)
StyledWriter::isMultineArray(const Value& value)
{
int size = value.size();
bool isMultiLine = size * 3 >= rightMargin_;
@@ -425,7 +425,7 @@ StyledWriter::isMultineArray(Value const& value)
for (int index = 0; index < size && !isMultiLine; ++index)
{
Value const& childValue = value[index];
const Value& childValue = value[index];
isMultiLine = isMultiLine ||
((childValue.isArray() || childValue.isObject()) &&
childValue.size() > 0);
@@ -507,7 +507,7 @@ StyledStreamWriter::StyledStreamWriter(std::string indentation)
}
void
StyledStreamWriter::write(std::ostream& out, Value const& root)
StyledStreamWriter::write(std::ostream& out, const Value& root)
{
document_ = &out;
addChildValues_ = false;
@@ -518,7 +518,7 @@ StyledStreamWriter::write(std::ostream& out, Value const& root)
}
void
StyledStreamWriter::writeValue(Value const& value)
StyledStreamWriter::writeValue(const Value& value)
{
switch (value.type())
{
@@ -564,7 +564,7 @@ StyledStreamWriter::writeValue(Value const& value)
while (true)
{
std::string const& name = *it;
Value const& childValue = value[name];
const Value& childValue = value[name];
writeWithIndent(valueToQuotedString(name.c_str()));
*document_ << " : ";
writeValue(childValue);
@@ -584,7 +584,7 @@ StyledStreamWriter::writeValue(Value const& value)
}
void
StyledStreamWriter::writeArrayValue(Value const& value)
StyledStreamWriter::writeArrayValue(const Value& value)
{
unsigned size = value.size();
@@ -603,7 +603,7 @@ StyledStreamWriter::writeArrayValue(Value const& value)
while (true)
{
Value const& childValue = value[index];
const Value& childValue = value[index];
if (hasChildValue)
writeWithIndent(childValues_[index]);
@@ -643,7 +643,7 @@ StyledStreamWriter::writeArrayValue(Value const& value)
}
bool
StyledStreamWriter::isMultineArray(Value const& value)
StyledStreamWriter::isMultineArray(const Value& value)
{
int size = value.size();
bool isMultiLine = size * 3 >= rightMargin_;
@@ -651,7 +651,7 @@ StyledStreamWriter::isMultineArray(Value const& value)
for (int index = 0; index < size && !isMultiLine; ++index)
{
Value const& childValue = value[index];
const Value& childValue = value[index];
isMultiLine = isMultiLine ||
((childValue.isArray() || childValue.isObject()) &&
childValue.size() > 0);
@@ -726,7 +726,7 @@ StyledStreamWriter::unindent()
}
std::ostream&
operator<<(std::ostream& sout, Value const& root)
operator<<(std::ostream& sout, const Value& root)
{
Json::StyledStreamWriter writer;
writer.write(sout, root);

View File

@@ -48,7 +48,7 @@ operator<<(std::ostream& os, Book const& x)
Book
reversed(Book const& book)
{
return Book(book.out, book.in, book.domain);
return Book(book.out, book.in);
}
} // namespace ripple

View File

@@ -36,7 +36,7 @@ namespace BuildInfo {
// and follow the format described at http://semver.org/
//------------------------------------------------------------------------------
// clang-format off
char const* const versionString = "2.5.0-rc1"
char const* const versionString = "2.4.0"
// clang-format on
#if defined(DEBUG) || defined(SANITIZER)

View File

@@ -107,7 +107,6 @@ constexpr static ErrorInfo unorderedErrorInfos[]{
{rpcSRC_ACT_MALFORMED, "srcActMalformed", "Source account is malformed.", 400},
{rpcSRC_ACT_MISSING, "srcActMissing", "Source account not provided.", 400},
{rpcSRC_ACT_NOT_FOUND, "srcActNotFound", "Source account not found.", 404},
{rpcDELEGATE_ACT_NOT_FOUND, "delegateActNotFound", "Delegate account not found.", 404},
{rpcSRC_CUR_MALFORMED, "srcCurMalformed", "Source currency is malformed.", 400},
{rpcSRC_ISR_MALFORMED, "srcIsrMalformed", "Source issuer is malformed.", 400},
{rpcSTREAM_MALFORMED, "malformedStream", "Stream malformed.", 400},
@@ -116,8 +115,7 @@ constexpr static ErrorInfo unorderedErrorInfos[]{
{rpcUNKNOWN_COMMAND, "unknownCmd", "Unknown method.", 405},
{rpcORACLE_MALFORMED, "oracleMalformed", "Oracle request is malformed.", 400},
{rpcBAD_CREDENTIALS, "badCredentials", "Credentials do not exist, are not accepted, or have expired.", 400},
{rpcTX_SIGNED, "transactionSigned", "Transaction should not be signed.", 400},
{rpcDOMAIN_MALFORMED, "domainMalformed", "Domain is malformed.", 400}};
{rpcTX_SIGNED, "transactionSigned", "Transaction should not be signed.", 400}};
// clang-format on
// Sort and validate unorderedErrorInfos at compile time. Should be

View File

@@ -139,27 +139,27 @@ class FeatureCollections
{
if (i >= features.size())
LogicError("Invalid FeatureBitset index");
auto const& sequence = features.get<Feature::byIndex>();
const auto& sequence = features.get<Feature::byIndex>();
return sequence[i];
}
size_t
getIndex(Feature const& feature) const
{
auto const& sequence = features.get<Feature::byIndex>();
const auto& sequence = features.get<Feature::byIndex>();
auto const it_to = sequence.iterator_to(feature);
return it_to - sequence.begin();
}
Feature const*
getByFeature(uint256 const& feature) const
{
auto const& feature_index = features.get<Feature::byFeature>();
const auto& feature_index = features.get<Feature::byFeature>();
auto const feature_it = feature_index.find(feature);
return feature_it == feature_index.end() ? nullptr : &*feature_it;
}
Feature const*
getByName(std::string const& name) const
{
auto const& name_index = features.get<Feature::byName>();
const auto& name_index = features.get<Feature::byName>();
auto const name_it = name_index.find(name);
return name_it == name_index.end() ? nullptr : &*name_it;
}
@@ -240,7 +240,7 @@ FeatureCollections::getRegisteredFeature(std::string const& name) const
}
void
check(bool condition, char const* logicErrorMessage)
check(bool condition, const char* logicErrorMessage)
{
if (!condition)
LogicError(logicErrorMessage);
@@ -437,13 +437,9 @@ featureToName(uint256 const& f)
uint256 const feature##name = registerFeature(#name, supported, vote);
#define XRPL_FIX(name, supported, vote) \
uint256 const fix##name = registerFeature("fix" #name, supported, vote);
// clang-format off
#define XRPL_RETIRE(name) \
[[deprecated("The referenced amendment has been retired")]] \
[[maybe_unused]] \
#define XRPL_RETIRE(name) \
[[deprecated("The referenced amendment has been retired"), maybe_unused]] \
uint256 const retired##name = retireFeature(#name);
// clang-format on
#include <xrpl/protocol/detail/features.macro>
@@ -459,7 +455,7 @@ featureToName(uint256 const& f)
//
// Use initialization of one final static variable to set
// featureCollections::readOnly.
[[maybe_unused]] static bool const readOnlySet =
[[maybe_unused]] static const bool readOnlySet =
featureCollections.registrationIsDone();
} // namespace ripple

View File

@@ -94,8 +94,9 @@ enum class LedgerNameSpace : std::uint16_t {
MPTOKEN = 't',
CREDENTIAL = 'D',
PERMISSIONED_DOMAIN = 'm',
DELEGATE = 'E',
VAULT = 'V',
LOAN_BROKER = 'l', // lower-case L
LOAN = 'L',
// No longer used or supported. Left here to reserve the space
// to avoid accidental reuse.
@@ -117,19 +118,12 @@ getBookBase(Book const& book)
XRPL_ASSERT(
isConsistent(book), "ripple::getBookBase : input is consistent");
auto const index = book.domain ? indexHash(
LedgerNameSpace::BOOK_DIR,
book.in.currency,
book.out.currency,
book.in.account,
book.out.account,
*(book.domain))
: indexHash(
LedgerNameSpace::BOOK_DIR,
book.in.currency,
book.out.currency,
book.in.account,
book.out.account);
auto const index = indexHash(
LedgerNameSpace::BOOK_DIR,
book.in.currency,
book.out.currency,
book.in.account,
book.out.account);
// Return with quality 0.
auto k = keylet::quality({ltDIR_NODE, index}, 0);
@@ -461,14 +455,6 @@ amm(uint256 const& id) noexcept
return {ltAMM, id};
}
Keylet
delegate(AccountID const& account, AccountID const& authorizedAccount) noexcept
{
return {
ltDELEGATE,
indexHash(LedgerNameSpace::DELEGATE, account, authorizedAccount)};
}
Keylet
bridge(STXChainBridge const& bridge, STXChainBridge::ChainType chainType)
{
@@ -566,6 +552,18 @@ vault(AccountID const& owner, std::uint32_t seq) noexcept
return vault(indexHash(LedgerNameSpace::VAULT, owner, seq));
}
Keylet
loanbroker(AccountID const& owner, std::uint32_t seq) noexcept
{
return loanbroker(indexHash(LedgerNameSpace::LOAN_BROKER, owner, seq));
}
Keylet
loan(uint256 const& loanBrokerID, std::uint32_t loanSeq) noexcept
{
return loan(indexHash(LedgerNameSpace::LOAN, loanBrokerID, loanSeq));
}
Keylet
permissionedDomain(AccountID const& account, std::uint32_t seq) noexcept
{

View File

@@ -155,22 +155,12 @@ InnerObjectFormats::InnerObjectFormats()
{sfCredentialType, soeREQUIRED},
});
add(sfPermission.jsonName.c_str(),
sfPermission.getCode(),
{{sfPermissionValue, soeREQUIRED}});
add(sfBatchSigner.jsonName.c_str(),
sfBatchSigner.getCode(),
{{sfAccount, soeREQUIRED},
{sfSigningPubKey, soeOPTIONAL},
{sfTxnSignature, soeOPTIONAL},
{sfSigners, soeOPTIONAL}});
add(sfBook.jsonName,
sfBook.getCode(),
add(sfCounterpartySignature.jsonName,
sfCounterpartySignature.getCode(),
{
{sfBookDirectory, soeREQUIRED},
{sfBookNode, soeREQUIRED},
{sfSigningPubKey, soeOPTIONAL},
{sfTxnSignature, soeOPTIONAL},
{sfSigners, soeOPTIONAL},
});
}

View File

@@ -29,7 +29,7 @@ namespace ripple {
LedgerFormats::LedgerFormats()
{
// Fields shared by all ledger formats:
static std::initializer_list<SOElement> const commonFields{
static const std::initializer_list<SOElement> commonFields{
{sfLedgerIndex, soeOPTIONAL},
{sfLedgerEntryType, soeREQUIRED},
{sfFlags, soeREQUIRED},

View File

@@ -1,148 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2025 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/Permissions.h>
#include <xrpl/protocol/jss.h>
namespace ripple {
Permission::Permission()
{
delegatableTx_ = {
#pragma push_macro("TRANSACTION")
#undef TRANSACTION
#define TRANSACTION(tag, value, name, delegatable, fields) {value, delegatable},
#include <xrpl/protocol/detail/transactions.macro>
#undef TRANSACTION
#pragma pop_macro("TRANSACTION")
};
granularPermissionMap_ = {
#pragma push_macro("PERMISSION")
#undef PERMISSION
#define PERMISSION(type, txType, value) {#type, type},
#include <xrpl/protocol/detail/permissions.macro>
#undef PERMISSION
#pragma pop_macro("PERMISSION")
};
granularNameMap_ = {
#pragma push_macro("PERMISSION")
#undef PERMISSION
#define PERMISSION(type, txType, value) {type, #type},
#include <xrpl/protocol/detail/permissions.macro>
#undef PERMISSION
#pragma pop_macro("PERMISSION")
};
granularTxTypeMap_ = {
#pragma push_macro("PERMISSION")
#undef PERMISSION
#define PERMISSION(type, txType, value) {type, txType},
#include <xrpl/protocol/detail/permissions.macro>
#undef PERMISSION
#pragma pop_macro("PERMISSION")
};
for ([[maybe_unused]] auto const& permission : granularPermissionMap_)
XRPL_ASSERT(
permission.second > UINT16_MAX,
"ripple::Permission::granularPermissionMap_ : granular permission "
"value must not exceed the maximum uint16_t value.");
}
Permission const&
Permission::getInstance()
{
static Permission const instance;
return instance;
}
std::optional<std::uint32_t>
Permission::getGranularValue(std::string const& name) const
{
auto const it = granularPermissionMap_.find(name);
if (it != granularPermissionMap_.end())
return static_cast<uint32_t>(it->second);
return std::nullopt;
}
std::optional<std::string>
Permission::getGranularName(GranularPermissionType const& value) const
{
auto const it = granularNameMap_.find(value);
if (it != granularNameMap_.end())
return it->second;
return std::nullopt;
}
std::optional<TxType>
Permission::getGranularTxType(GranularPermissionType const& gpType) const
{
auto const it = granularTxTypeMap_.find(gpType);
if (it != granularTxTypeMap_.end())
return it->second;
return std::nullopt;
}
bool
Permission::isDelegatable(std::uint32_t const& permissionValue) const
{
auto const granularPermission =
getGranularName(static_cast<GranularPermissionType>(permissionValue));
if (granularPermission)
// granular permissions are always allowed to be delegated
return true;
auto const it = delegatableTx_.find(permissionValue - 1);
if (it != delegatableTx_.end() && it->second == Delegation::notDelegatable)
return false;
return true;
}
uint32_t
Permission::txToPermissionType(TxType const& type) const
{
return static_cast<uint32_t>(type) + 1;
}
TxType
Permission::permissionToTxType(uint32_t const& value) const
{
return static_cast<TxType>(value - 1);
}
} // namespace ripple

View File

@@ -183,7 +183,7 @@ Quality
Quality::round(int digits) const
{
// Modulus for mantissa
static std::uint64_t const mod[17] = {
static const std::uint64_t mod[17] = {
/* 0 */ 10000000000000000,
/* 1 */ 1000000000000000,
/* 2 */ 100000000000000,

View File

@@ -161,12 +161,4 @@ Rules::operator!=(Rules const& other) const
{
return !(*this == other);
}
bool
isFeatureEnabled(uint256 const& feature)
{
auto const& rules = getCurrentTransactionRules();
return rules && rules->enabled(feature);
}
} // namespace ripple

View File

@@ -17,6 +17,7 @@
*/
//==============================================================================
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/SField.h>
#include <map>
@@ -28,6 +29,7 @@ namespace ripple {
SField::IsSigning const SField::notSigning;
int SField::num = 0;
std::map<int, SField const*> SField::knownCodeToField;
std::map<std::string, SField const*> SField::knownNameToField;
// Give only this translation unit permission to construct SFields
struct SField::private_access_tag_t
@@ -45,7 +47,7 @@ TypedField<T>::TypedField(private_access_tag_t pat, Args&&... args)
}
// Construct all compile-time SFields, and register them in the knownCodeToField
// database:
// and knownNameToField databases:
// Use macros for most SField construction to enforce naming conventions.
#pragma push_macro("UNTYPED_SFIELD")
@@ -87,7 +89,7 @@ SField::SField(
private_access_tag_t,
SerializedTypeID tid,
int fv,
char const* fn,
const char* fn,
int meta,
IsSigning signing)
: fieldCode(field_code(tid, fv))
@@ -99,7 +101,14 @@ SField::SField(
, signingField(signing)
, jsonName(fieldName.c_str())
{
XRPL_ASSERT(
!knownCodeToField.contains(fieldCode),
"ripple::SField::SField(tid,fv,fn,meta,signing) : fieldCode is unique");
XRPL_ASSERT(
!knownNameToField.contains(fieldName),
"ripple::SField::SField(tid,fv,fn,meta,signing) : fieldName is unique");
knownCodeToField[fieldCode] = this;
knownNameToField[fieldName] = this;
}
SField::SField(private_access_tag_t, int fc)
@@ -111,6 +120,9 @@ SField::SField(private_access_tag_t, int fc)
, signingField(IsSigning::yes)
, jsonName(fieldName.c_str())
{
XRPL_ASSERT(
!knownCodeToField.contains(fieldCode),
"ripple::SField::SField(fc) : fieldCode is unique");
knownCodeToField[fieldCode] = this;
}
@@ -145,11 +157,11 @@ SField::compare(SField const& f1, SField const& f2)
SField const&
SField::getField(std::string const& fieldName)
{
for (auto const& [_, f] : knownCodeToField)
auto it = knownNameToField.find(fieldName);
if (it != knownNameToField.end())
{
(void)_;
if (f->fieldName == fieldName)
return *f;
return *(it->second);
}
return sfInvalid;
}

Some files were not shown because too many files have changed in this diff Show More