Compare commits

..

402 Commits

Author SHA1 Message Date
Bronek Kozicki
b4388f3341 Add invariants for LoanManage 2025-10-15 14:07:41 +01:00
Bronek Kozicki
3f1f37f323 Add invariants for LoanPay 2025-10-15 13:30:39 +01:00
Bronek Kozicki
2d37254504 Initial implementation of Vault invariants for Loan operations 2025-10-10 15:14:32 +01:00
Ed Hennis
8152bcb1f3 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  refactor: Update Conan dependencies: OpenSSL (5873)
  Add vault invariants (5518)
  test: Add more tests for Simulate RPC metadata (5827)
  chore: Fix release build error (5864)
  refactor: Update CI strategy matrix to use new RHEL 9 and RHEL 10 images (5856)
  chore: exclude all `UNREACHABLE` blocks from codecov (5846)
  Set version to 3.0.0-b1 (5859)
2025-10-09 16:15:22 -04:00
Ed Hennis
c179135e15 Fix the build and test errors introduced by the previous merge:
** Vault Invariants for Loan txs need to be fleshed out. **

- Give the appropriate Loan transactions vault modification privileges.
- Give the appropriate Loan transactions the ability to authorize
  (create in this case) MPTokens.
- Check that LoanManage does not leave Vault in an inconsistent state
  (AssetsAvailable > AssetsTotal). For IOU vaults, if the difference is
  dust, "round up".
2025-10-09 15:09:49 -04:00
Ed Hennis
5117ef831e Merge branch 'develop' into ximinez/lending-XLS-66 2025-10-09 14:15:26 -04:00
Bart
46ba8a28fe refactor: Update Conan dependencies: OpenSSL (#5873)
This change bumps OpenSSL from 1.1.1w to 3.6.0.
2025-10-09 13:27:26 -04:00
Gregory Tsipenyuk
f35d0dc829 Add convenience functions to MPT test-framework. (#5870) 2025-10-09 04:22:38 +00:00
Bronek Kozicki
5ecde3cf39 Add vault invariants (#5518)
This change adds invariants for SingleAssetVault #5224 (XLS-065), which had been intentionally skipped earlier to keep the SAV PR size manageable.
2025-10-08 15:04:02 +00:00
tequ
620fb26823 test: Add more tests for Simulate RPC metadata (#5827) 2025-10-08 14:36:09 +00:00
Bronek Kozicki
6b6b213cf5 chore: Fix release build error (#5864)
This change fixes a release build error with GCC 15.2.

The `fields` variable is only used in `XRPL_ASSERT`, which evaluates to nothing in a Release build, leaving the variable unused. This change silences the build warning.

Co-authored-by: Bart Thomee <11445373+bthomee@users.noreply.github.com>
2025-10-08 13:45:44 +00:00
Bart
f61086b43c refactor: Update CI strategy matrix to use new RHEL 9 and RHEL 10 images (#5856)
This change uses the new RHEL 9 and 10 images to build and test the binary, and adds support for having different Docker image SHAs per distro-compiler combination.

Instead of supporting RHEL each minor version, we are simplifying our pipelines by only supporting RHEL major versions. Our CI Docker images have already been updated accordingly, and we recently added support for RHEL 10 as well. Up until now, the CI Docker images had all been rebuilt at the same time, but that is not necessarily true as the most recent push to the CI repo has shown where the RHEL images now have a different SHA than the Debian and Ubuntu ones.

Co-authored-by: Bart Thomee <11445373+bthomee@users.noreply.github.com>
2025-10-08 13:15:24 +00:00
Mayukha Vadari
176fd2b6e4 chore: exclude all UNREACHABLE blocks from codecov (#5846) 2025-10-08 09:25:51 +01:00
Bart
2df730438d Set version to 3.0.0-b1 (#5859) 2025-10-07 20:28:19 +00:00
Ed Hennis
d576e9d214 Include exception messages in multi signature check result 2025-10-02 22:08:03 -04:00
Ed Hennis
5863f05343 Merge branch 'develop' into ximinez/lending-XLS-66 2025-10-02 11:03:17 -04:00
Bronek Kozicki
5d79bfc531 Remove bogus coverage warning (#5838) 2025-10-02 11:54:09 +01:00
Ed Hennis
ce23d0aa54 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  fix: Transaction sig checking functions do not get a full context (5829)
2025-10-01 18:13:53 -04:00
Ed Hennis
51ef35ab55 fix: Transaction sig checking functions do not get a full context (#5829)
Fixes a (currently harmless) bug introduced by PR #5594
2025-10-01 20:58:43 +00:00
Ed Hennis
aac25e8c79 fixup! Review feedback from @Bronek: Add an assert 2025-10-01 15:56:06 -04:00
Ed Hennis
1888784e8e Review feedback from @Bronek: Add an assert 2025-10-01 14:15:45 -04:00
Ed Hennis
681c179174 Merge branch 'develop' into ximinez/lending-XLS-66 2025-10-01 13:14:33 -04:00
Valentin Balaschenko
330a3215bc fix: FD/handle guarding + exponential backoff (#5823) 2025-10-01 12:57:33 +01:00
Ed Hennis
05739c59cf Merge branch 'develop' into ximinez/lending-XLS-66 2025-09-30 22:29:07 -04:00
Ed Hennis
b127b24dae Addressed review feedback from @gregtatcam:
- All current items are done
- Mostly comments
- Restructured PaymentParts (formerly PeriodicPaymentParts) to bring
  along fees, and removed the computed / combined PeriodicPayment from
  places that should be using PaymentParts instead.
2025-09-30 22:25:53 -04:00
Ed Hennis
85c2ceacde Merge tag '2.6.1' into ximinez/merge261
2.6.1

* tag '2.6.1':
  Set version to 2.6.1
  Set version to 2.6.1-rc2
  Mark PermissionDelegation as unsupported
2025-09-30 19:10:51 -04:00
Ed Hennis
c2a0824da0 Merge remote-tracking branch 'mywork/ximinez/lending-tx-fix' into ximinez/lending-XLS-66
* mywork/ximinez/lending-tx-fix:
  fix: Transaction sig checking functions do not get a full context
  ci: Upload artifacts during build and test in a separate job (5817)
2025-09-30 16:28:10 -04:00
Ed Hennis
70d5c624e8 Set version to 2.6.1 2025-09-30 16:09:11 -04:00
yinyiqian1
8e4fda160d Rename flags for DynamicMPT (#5820) 2025-09-30 18:49:53 +00:00
Ed Hennis
e1b234cc51 fix: Transaction sig checking functions do not get a full context
- Fixes a bug introduced by PR #5594, commit 550f90a75e, which
  introduced the concept of a "sigObject", in which the signature is
  checked without necessarily being the transaction.
- Fortunately, no code uses the "sigObject" as anything other than the
  transactor yet, so the bug is harmless for now.
- This fix removes the "PreclaimContext" from the parameter list, and
  adds only the individual parts needed by the function, none of which
  are the transaction.
2025-09-30 14:39:08 -04:00
Bart
072b1c442c chore: Set free-form CI inputs as env vars (#5822)
This change moves CI values that could be user-provided into environment variables.
2025-09-30 19:46:10 +02:00
Ayaz Salikhov
294e03ecf5 ci: Upload artifacts during build and test in a separate job (#5817) 2025-09-30 16:15:24 +00:00
Ed Hennis
03d8cf2c12 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  refactor: Add support for extra transaction signatures (5594)
  refactor: Restructure Transactor::preflight to reduce boilerplate (5592)
2025-09-29 21:49:58 -04:00
Ed Hennis
7a3f7aebcf Review feedback from @gregtatcam
* Write more comments explaining what's going on.
* Rename some variables.
* Do a final safety check for valid values in `LoanPay`.
2025-09-29 21:42:03 -04:00
Ed Hennis
550f90a75e refactor: Add support for extra transaction signatures (#5594)
* Restructures Transactor signature checking code to be able to handle a `sigObject`, which may be the full transaction, or may be an object field containing a separate signature. Either way, the `sigObject` can be a single- or multi-sign signature.
2025-09-29 22:11:53 +00:00
Ed Hennis
d67dcfe3c4 refactor: Restructure Transactor::preflight to reduce boilerplate (#5592)
* Restructures `Transactor::preflight` to create several functions that will remove the need for error-prone boilerplate code in derived classes' implementations of `preflight`.
2025-09-29 17:31:42 -04:00
Ed Hennis
f78d27e9b3 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  switch `fixIncludeKeyletFields` to `Supported::yes` (5819)
2025-09-29 13:38:43 -04:00
Ed Hennis
e38e911190 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-29 13:32:12 -04:00
Ed Hennis
44313d9a30 Merge branch 'develop' into ximinez/lending-refactoring-3 2025-09-29 13:32:08 -04:00
Ed Hennis
a3365545df Review feedback from @Bronek
- Exclude impossible logging from code coverage, too.
2025-09-28 19:10:12 -04:00
Mayukha Vadari
0fd2f715bb switch fixIncludeKeyletFields to Supported::yes (#5819) 2025-09-27 09:04:04 +02:00
Ed Hennis
1d85727675 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-26 19:26:13 -04:00
Ed Hennis
da3c2beae0 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-26 19:26:06 -04:00
Ed Hennis
6b7136906f Merge branch 'develop' into ximinez/lending-refactoring-3 2025-09-26 19:26:02 -04:00
Ed Hennis
7612fd0ba6 Review feedback from @gregtatcam
- Amendment checking correctness.
- Sync some changes between LoanBrokerCoverWithdraw and CoverDeposit.
- Check for nulls.
- Add documentation.
2025-09-26 19:23:13 -04:00
Mayukha Vadari
807462b191 Add STInt32 as a new SType (#5788)
This change adds `STInt32` as a new `SType` under the `STInteger` umbrella, with `SType` value `12`. This is the first and only `STInteger` type that supports negative values.
2025-09-26 20:13:15 +00:00
Ed Hennis
0bd6b1ae49 Review feedback from @mvadari
- Clarify the purpose of the assert in calculateOwnerReserveFee
2025-09-26 16:05:15 -04:00
Ed Hennis
66216a3d41 Review feedback from @mvadari
- Add a test for preflightCheckSigningKey
2025-09-26 15:36:12 -04:00
Ayaz Salikhov
19c4226d3d ci: Call all reusable workflows reusable (#5818) 2025-09-26 18:33:42 +00:00
Ed Hennis
4b90f97e52 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-26 13:41:43 -04:00
Ed Hennis
f1a2fe3d0a Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-26 13:41:35 -04:00
Ed Hennis
d76f31cb7c Merge branch 'develop' into ximinez/lending-refactoring-3 2025-09-26 13:41:31 -04:00
Mayukha Vadari
d02c306f1e test: add more comprehensive tests for FeeVote (#5746)
This change adds more comprehensive tests for the `FeeVote` module, which previously only checked the basics, and not the more comprehensive flows in that class.
2025-09-26 17:40:19 +00:00
Ed Hennis
b5caa9c63d Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-26 12:09:25 -04:00
Ed Hennis
3931eb39d5 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-26 12:09:17 -04:00
Ed Hennis
322308f7d1 Merge branch 'develop' into ximinez/lending-refactoring-3 2025-09-26 12:09:13 -04:00
Jingchen
cfd26f444c fix: Address http header case sensitivity (#5767)
This change makes the regex in `HttpClient.cpp` that matches the content-length http header case insensitive to improve compatibility, as http headers are case insensitive.
2025-09-26 11:40:43 +00:00
tequ
2c3024716b change fixPriceOracleOrder to Supported::yes (#5749) 2025-09-26 12:07:48 +01:00
Ed Hennis
4c8f7968c4 Tweak payment rounding 2025-09-25 16:11:02 -04:00
Ed Hennis
6e2965f01a Add test cases for Vault prereq amendments being disabled 2025-09-25 15:26:30 -04:00
Ed Hennis
dba3af9318 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-25 13:27:17 -04:00
Ed Hennis
7304ee68d5 Merge branch 'develop' into ximinez/lending-refactoring-3 2025-09-25 13:27:13 -04:00
Bart
a12f5de68d chore: Pin all CI Docker tags (#5813)
To avoid surprises and ensure reproducibility, this change pins all CI Docker image tags to the latest version in the XRPLF/CI repo.
2025-09-25 16:08:07 +00:00
Bronek Kozicki
51c5f2bfc9 Improve ValidatorList invalid UNL manifest logging (#5804)
This change raises logging severity from `INFO` to `WARN` when handling UNL manifest signed with an unexpected / invalid key. It also changes the internal error code for an invalid format of UNL manifest to `invalid` (from `untrusted`).

This is a follow up to problems experienced by an UNL node due to old manifest key configured in `validators.txt`, which would be easier to diagnose with improved logging.

It also replaces a log line with `UNREACHABLE` for an impossible situation when we match UNL manifest key against a configured key which has an invalid type (we cannot configure such a key because of checks when loading configured keys).
2025-09-25 16:14:29 +02:00
Ed Hennis
759d114ab8 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  docs: Add warning about using std::counting_semaphore (#5595)
  Revert "Update Conan dependencies: OpenSSL" (#5807)
  test: Add STInteger and STParsedJSON tests (#5726)
  Review feedback from @mvadari
2025-09-24 16:10:16 -04:00
Ed Hennis
3c93dbbc7c Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-24 15:49:59 -04:00
Ed Hennis
97819b23ba Merge branch 'develop' into ximinez/lending-refactoring-3 2025-09-24 15:49:56 -04:00
Ed Hennis
9bfa88cd86 Fix build error
- New code referenced `isEnabled`, which was renamed in an updated prereq PR
2025-09-24 15:38:53 -04:00
Valentin Balaschenko
73ff54143d docs: Add warning about using std::counting_semaphore (#5595)
This adds a comment to avoid using `std::counting_semaphore` until the minimum compiler versions of GCC and Clang have been updated to no longer contain the bug that is present in older compilers.
2025-09-23 13:26:26 +02:00
Bart
08b136528e Revert "Update Conan dependencies: OpenSSL" (#5807)
This change reverts #5617, because it will require extensive testing that will take up more time than we have before the next scheduled release.

Reverting this change does not mean we are abandoning it. We aim to pick it back up once there's a sufficient time window to allow for testing on multiple distros running a mixture of OpenSSL 1.x and 3.x.
2025-09-22 18:27:02 +00:00
Mayukha Vadari
6b8a589447 test: Add STInteger and STParsedJSON tests (#5726)
This change is to improve code coverage (and to simplify #5720 and #5725); there is otherwise no change in functionality. The change adds basic tests for `STInteger` and `STParsedJSON`, so it becomes easier to test smaller changes to the types, as well as removes `STParsedJSONArray`, since it is not used anywhere (including in Clio).
2025-09-22 20:00:31 +02:00
Ed Hennis
de5af71cb6 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-22 11:26:20 -04:00
Ed Hennis
67578b8f50 Review feedback from @mvadari
- Clean up some of the flag and extra feature checks for readability
2025-09-22 11:17:13 -04:00
Ed Hennis
e72a9d4bf2 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-20 17:12:32 -04:00
Ed Hennis
5b576b841c Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-20 17:12:26 -04:00
Ed Hennis
267b537a13 Review feedback from @Bronek
- Fix a moved assert message
- Rename `Transactor::isEnabled` to `checkExtraFeatures`, and finish
  cleaning up a few classes I missed on the first pass (Vault*
  & XChainBridge*).
2025-09-20 17:09:48 -04:00
Ed Hennis
543f1e702f Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-20 15:44:46 -04:00
Ed Hennis
f9dcce2d7e Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-20 15:44:39 -04:00
Ed Hennis
928af9633f Merge branch 'develop' into ximinez/lending-refactoring-3 2025-09-20 15:44:36 -04:00
Ed Hennis
ffeabc9642 refactor: Simplify STParsedJSON with some helper functions (#5591)
- Add code coverage for STParsedJSON edge cases

Co-authored-by: Denis Angell <dangell@transia.co>
2025-09-18 19:04:40 +00:00
Ed Hennis
9e84c37306 Refactor full payment into a function, and update some formatting 2025-09-18 14:54:49 -04:00
Ed Hennis
2aa626c205 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-18 14:08:42 -04:00
Ed Hennis
36c2fa1e56 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-18 14:08:35 -04:00
Ed Hennis
886b0a487c Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-18 14:08:31 -04:00
Ed Hennis
7849df5feb Merge branch 'develop' into ximinez/lending-refactoring-2 2025-09-18 14:08:27 -04:00
Ed Hennis
3cbdf818a7 Miscellaneous refactors and updates (#5590)
- Added a new Invariant: `ValidPseudoAccounts` which checks that all pseudo-accounts behave consistently through creation and updates, and that no "real" accounts look like pseudo-accounts (which means they don't have a 0 sequence). 
- `to_short_string(base_uint)`. Like `to_string`, but only returns the first 8 characters. (Similar to how a git commit ID can be abbreviated.) Used as a wrapped sink to prefix most transaction-related messages. More can be added later.
- `XRPL_ASSERT_PARTS`. Convenience wrapper for `XRPL_ASSERT`, which takes the `function` and `description` as separate parameters.
- `SField::sMD_PseudoAccount`. Metadata option for `SField` definitions to indicate that the field, if set in an `AccountRoot` indicates that account is a pseudo-account. Removes the need for hard-coded field lists all over the place. Added the flag to `AMMID` and `VaultID`.
- Added functionality to `SField` ctor to detect both code and name collisions using asserts. And require all SFields to have a name
- Convenience type aliases `STLedgerEntry::const_pointer` and `STLedgerEntry::const_ref`. (`SLE` is an alias to `STLedgerEntry`.)
- Generalized `feeunit.h` (`TaggedFee`) into `unit.h` (`ValueUnit`) and added new "BIPS"-related tags for future use. Also refactored the type restrictions to use Concepts.
- Restructured `transactions.macro` to do two big things
	1. Include the `#include` directives for transactor header files directly in the macro file. Removes the need to update `applySteps.cpp` and the resulting conflicts.
	2. Added a `privileges` parameter to the `TRANSACTION` macro, which specifies some of the operations a transaction is allowed to do. These `privileges` are enforced by invariant checks. Again, removed the need to update scattered lists of transaction types in various checks.
- Unit tests:
	1.  Moved more helper functions into `TestHelpers.h` and `.cpp`. 
	2. Cleaned up the namespaces to prevent / mitigate random collisions and ambiguous symbols, particularly in unity builds.
	3. Generalized `Env::balance` to add support for `MPTIssue` and `Asset`.
	4. Added a set of helper classes to simplify `Env` transaction parameter classes: `JTxField`, `JTxFieldWrapper`, and a bunch of classes derived or aliased from it. For an example of how awesome it is, check the changes `src/test/jtx/escrow.h` for how much simpler the definitions are for `finish_time`, `cancel_time`, `condition`, and `fulfillment`. 
	5. Generalized several of the amount-related helper classes to understand `Asset`s.
     6. `env.balance` for an MPT issuer will return a negative number (or 0) for consistency with IOUs.
2025-09-18 17:55:49 +00:00
Ed Hennis
55baf35d9c Fix build errors due to private type access 2025-09-18 13:30:50 -04:00
Ed Hennis
90ca9ea71a Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  refactor: Modularise ledger (5493)
  chore: Add unit tests dir to code coverage excludes (5803)
  chore: Build and test all configs for daily scheduled run (5801)
  chore: Limits CI build and test parallelism to reduce resource contention (5799)
  fix(amendment): Add missing fields for keylets to ledger objects (5646)
  Rename mutable flags (5797)
  Set version to 2.6.1-rc1
  Downgrade to boost 1.83
  Set version to 2.5.1
  Fix: Don't flag consensus as stalled prematurely (5658)
2025-09-18 13:17:29 -04:00
Bronek Kozicki
c46888f8f7 Set version to 2.6.1-rc2 2025-09-18 18:09:04 +01:00
Bronek Kozicki
2ae65d2fdb Mark PermissionDelegation as unsupported 2025-09-18 18:04:12 +01:00
Ed Hennis
47eb1e8db2 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-18 12:26:50 -04:00
Ed Hennis
540b76fe42 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-18 12:26:46 -04:00
Ed Hennis
d4135a9115 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-18 12:26:42 -04:00
Ed Hennis
4c6a34d3c1 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-18 12:26:38 -04:00
Ed Hennis
be5390b8c7 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-refactoring-1
* XRPLF/develop:
  refactor: Modularise ledger (5493)
  chore: Add unit tests dir to code coverage excludes (5803)
  chore: Build and test all configs for daily scheduled run (5801)
  chore: Limits CI build and test parallelism to reduce resource contention (5799)
  fix(amendment): Add missing fields for keylets to ledger objects (5646)
  Rename mutable flags (5797)
  Set version to 2.5.1
  Fix: Don't flag consensus as stalled prematurely (5658)
2025-09-18 12:03:29 -04:00
Ed Hennis
bd834c87e0 Merge tag '2.6.1-rc1' into ximinez/merge-261rc1
2.6.1-rc1

* tag '2.6.1-rc1':
  Set version to 2.6.1-rc1
  Downgrade to boost 1.83
2025-09-18 11:46:22 -04:00
Jingchen
dc8b37a524 refactor: Modularise ledger (#5493)
This change moves the ledger code to libxrpl.
2025-09-18 11:12:24 -04:00
Bronek Kozicki
617a895af5 chore: Add unit tests dir to code coverage excludes (#5803)
This change excludes unit test code from code coverage reporting.
2025-09-18 06:30:34 -04:00
Ed Hennis
b5ddc812ea Review feedback from @gregtatcam:
- In progress
- Add explanatory comments, and start refactoring
  loanComputePaymentParts into functions for readability.
2025-09-17 19:37:59 -04:00
Bart
1af1048c58 chore: Build and test all configs for daily scheduled run (#5801)
This change re-enables building and testing all configurations, but only for the daily scheduled run. Previously all configurations were run for each merge into the develop branch, but that overwhelmed both the GitHub runners and the Conan remote, and thus they were limited to just a subset of configurations. Now that the number of jobs is limited via `max-parallel: 10`, we should be able to safely enable building all configurations again. However, building them all once a day instead of for each PR merge should be sufficient.
2025-09-17 19:17:48 -04:00
Ed Hennis
f07ba87e51 Merge tag '2.5.1' into upstream--develop
- Ensures the commits don't get orphaned, even though the relevant code
  changes are already included.

* tag '2.5.1':
  Set version to 2.5.1
  Fix: Don't flag consensus as stalled prematurely (#5658)
2025-09-17 19:05:14 -04:00
Bart
e66558a883 chore: Limits CI build and test parallelism to reduce resource contention (#5799)
GitHub runners have a limit on how many concurrent jobs they can actually process (even though they will try to run them all at the same time), and similarly the Conan remote cannot handle hundreds of concurrent requests. Previously, the Conan dependency uploading was already limited to max 10 jobs running in parallel, and this change makes the same change to the build+test workflow.
2025-09-17 22:55:00 +00:00
Mayukha Vadari
510314d344 fix(amendment): Add missing fields for keylets to ledger objects (#5646)
This change adds a fix amendment (`fixIncludeKeyletFields`) that adds:
* `sfSequence` to `Escrow` and `PayChannel`
* `sfOwner` to `SignerList`
* `sfOracleDocumentID` to `Oracle`

This ensures that all ledger entries hold all the information needed to determine their keylet.
2025-09-17 21:34:47 +00:00
Ed Hennis
b9a2eb3399 Review feedback from @gregtatcam
- Remove a redundant struct LoanPaymentParts declaration.
- Add pointers to the XLS-66 spec for all of the LendingHeler formulas.
- Changed if/else if in LoanManage.
2025-09-17 16:54:50 -04:00
yinyiqian1
37b951859c Rename mutable flags (#5797)
This is a minor change on top of #5705
2025-09-17 21:43:04 +01:00
Ed Hennis
2c0c4567f4 Rewrite LoanManage flag check to skip if field not set or 0 2025-09-17 15:41:03 -04:00
Ed Hennis
d1c708ca01 Remove A BUNCH of unnecessary includes from the Loan/Lending files 2025-09-17 13:31:56 -04:00
Ed Hennis
ae27376863 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-17 10:49:29 -04:00
Ed Hennis
e237f968c7 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-17 10:49:20 -04:00
Ed Hennis
b02b58e3b5 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-17 10:49:15 -04:00
Ed Hennis
d10ac3b169 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-17 10:49:11 -04:00
Ed Hennis
c37f863201 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-17 10:49:07 -04:00
Jingchen
9494fc9668 chore: Use self hosted windows runners (#5780)
This changes switches from the GitHub-managed Windows runners to self-hosted runners to significantly reduce build time.
2025-09-17 09:29:15 -04:00
Ed Hennis
1fbd3fcfa4 Handle Flags not present in LoanManage
- Addresses RIPD-3418
2025-09-16 19:31:01 -04:00
Ed Hennis
70755ed1d3 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-16 19:04:59 -04:00
Ed Hennis
6926c511cb Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-16 19:04:53 -04:00
Ed Hennis
e01dd6d5b0 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-16 19:04:49 -04:00
Ed Hennis
0bfd404111 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-16 19:04:45 -04:00
Ed Hennis
5c072579d7 Review feedback from @yinyiqian1 and @Bronek
- Rewrite all of the templates in Units.h to use concepts.
- Restrict to_short_string to reasonably sized values.
- Rephrase some comments, and fix some typos.
2025-09-16 18:50:24 -04:00
Ed Hennis
c118121337 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-16 17:19:54 -04:00
Ed Hennis
8a4c607af9 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-16 17:19:47 -04:00
Ed Hennis
f85ce9c742 Remove or simplify Transactor::isEnabled overrides
- Remove the ones where the only condition was the required amendment
  specified in transactor.macro.
- Simplify the one that had other conditions, removing the required
  amendment from the conditions.
2025-09-16 17:15:57 -04:00
Ed Hennis
49e1f97476 Fix formatting 2025-09-16 17:10:28 -04:00
Bronek Kozicki
8d01f35eb9 Set version to 2.6.1-rc1 2025-09-16 15:35:54 -04:00
Bronek Kozicki
1020a32d76 Downgrade to boost 1.83 2025-09-16 15:35:47 -04:00
Ed Hennis
47aa95fcc4 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-16 15:07:11 -04:00
Ed Hennis
dc5b0918da Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-16 15:07:04 -04:00
Ed Hennis
cb991523f8 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-16 15:07:00 -04:00
Ed Hennis
9683344940 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-16 15:06:55 -04:00
Ed Hennis
5ac905be01 Fix issuer MPT balance sign on tests introduced by 5571 2025-09-16 14:51:18 -04:00
Ed Hennis
4d5afbea3a Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  Bugfix: Adds graceful peer disconnection (5669)
  Support DynamicMPT XLS-94d (5705)
  Only notify clio for PRs targeting the release and master branches (5794)
  refactor: Wrap GitHub CI conditionals in curly braces (5796)
2025-09-16 11:26:18 -04:00
Ed Hennis
9d08fe9a03 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-16 11:15:04 -04:00
Ed Hennis
84e97f0ef5 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3
* XRPLF/ximinez/lending-refactoring-2:
  Bugfix: Adds graceful peer disconnection (5669)
  Support DynamicMPT XLS-94d (5705)
  Only notify clio for PRs targeting the release and master branches (5794)
  refactor: Wrap GitHub CI conditionals in curly braces (5796)
2025-09-16 11:14:06 -04:00
Ed Hennis
4d24b5eac2 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-16 10:46:45 -04:00
Ed Hennis
935749fe1f Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-16 10:46:41 -04:00
Ed Hennis
49eb1cc54e Remove LoanDraw transaction (#5792) 2025-09-16 00:30:02 +00:00
Ed Hennis
dee972e9cd Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  Fix: EscrowTokenV1 (5571)
  fix: Skip processing transaction batch if the batch is empty (5670)
  ci: Fix conan secrets in `upload-conan-deps` (5785)
  Fix code coverage error (5765)
  docs: Add remote to `conan lock create` command (5770)
  refactor: clean up `CTID.h` (5681)
2025-09-15 11:25:13 -04:00
Ed Hennis
bdeed43304 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-15 11:13:45 -04:00
Ed Hennis
7eff303160 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-15 11:13:40 -04:00
Ed Hennis
aa1341f42e Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-15 11:13:36 -04:00
Ed Hennis
91031dbec4 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-15 11:13:32 -04:00
Ed Hennis
03da5da815 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-11 10:33:38 -04:00
Ed Hennis
fc860c1a1d Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-11 10:33:30 -04:00
Ed Hennis
2545bc5936 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-11 10:33:26 -04:00
Ed Hennis
9a9588eaf6 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-11 10:33:22 -04:00
Ed Hennis
abee3dd55c Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-11 10:33:17 -04:00
Ed Hennis
22d9ade2b0 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-10 20:36:49 -04:00
Ed Hennis
3ea0fa67cb Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-10 20:36:43 -04:00
Ed Hennis
1b295c7c00 Use Permission to check if a Transactor is enabled
- Adds a Permission::getTxFeature lookup function to find the
  controlling amendment for a Transactor, if any.
- Returns temDISABLED from preflight if there is an amendment and it's
  not enabled.
- Still need to go through and remove all the now-redundant isEnabled
  functions.
2025-09-10 20:33:01 -04:00
Ed Hennis
dd52a50acc Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  fixup! Make a few tweaks to the changes in 43fe49e7
  Fix Vault tests broken by negative MPT issuer balance
  Make a few tweaks to the changes in 43fe49e7
  fix: Add restrictions to Permission Delegation: fixDelegateV1_1 (5650)
  ci: Add missing dependencies to workflows (5783)
  ci: Use default conan install format (5784)
  Switch CI pipeline bookworm:gcc-13 from arm64 to amd64 (5779)
2025-09-10 20:01:15 -04:00
Ed Hennis
80a2d8f789 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-10 19:39:58 -04:00
Ed Hennis
e5f99e8ee7 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-10 19:39:55 -04:00
Ed Hennis
b925ed44a0 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-10 19:39:51 -04:00
Ed Hennis
14ff03821c Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-refactoring-1
* XRPLF/develop:
  fix: Add restrictions to Permission Delegation: fixDelegateV1_1 (5650)
  ci: Add missing dependencies to workflows (5783)
  ci: Use default conan install format (5784)
  Switch CI pipeline bookworm:gcc-13 from arm64 to amd64 (5779)
2025-09-10 19:34:05 -04:00
Ed Hennis
5ff6bc496a fixup! Make a few tweaks to the changes in 43fe49e7 2025-09-10 18:20:47 -04:00
Ed Hennis
7aaad4a8ef Fix Vault tests broken by negative MPT issuer balance 2025-09-10 17:00:05 -04:00
Ed Hennis
1897ac5ee7 Make a few tweaks to the changes in 43fe49e7
- This was the first merge after I got back from sabbatical. I made
  these same changes in "ximinez/lending-XLS-66" commit 9d052dc, but
  after seeing some test failures, I think they belong here.
2025-09-10 16:49:13 -04:00
Ed Hennis
5894cd2103 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-09 17:14:41 -04:00
Ed Hennis
2f89182fd3 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-09 17:14:34 -04:00
Ed Hennis
4191ddd702 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-09 17:14:30 -04:00
Ed Hennis
37888b97ba Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-09 17:14:27 -04:00
Ed Hennis
10f7e4a02a Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-09 17:14:23 -04:00
Ed Hennis
e5941d5b23 Simplify flag exclusion check in LoanManage 2025-09-09 16:29:35 -04:00
Ed Hennis
3f1a0f3a3d Fix some build errors from yesterday 2025-09-09 15:25:51 -04:00
Ed Hennis
fa2c595a59 Add more value validation in LoanSet
- Don't allow negative numbers.
- Don't send the origination fee if it's defined, but 0.
2025-09-08 17:57:56 -04:00
Ed Hennis
fc6fe9802e Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-08 11:42:09 -04:00
Ed Hennis
b3c40ad408 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-08 11:42:01 -04:00
Ed Hennis
779e94bc03 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-08 11:41:57 -04:00
Ed Hennis
f653ca03d9 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-08 11:41:53 -04:00
Ed Hennis
d46e477092 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-08 11:41:50 -04:00
Ed Hennis
24f58a2e94 Fix test loop 2025-09-05 23:46:48 -04:00
Ed Hennis
e3358ad124 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-05 20:29:04 -04:00
Ed Hennis
5102147709 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-05 20:28:58 -04:00
Ed Hennis
0a54c09de1 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-05 20:28:54 -04:00
Ed Hennis
d594ca1401 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-05 20:28:50 -04:00
Ed Hennis
5335c04616 Fix constexpr expression 2025-09-05 20:28:12 -04:00
Ed Hennis
6db14ccb13 More review feedback from @gregtatcam
- Also fix a few build errors that I missed earlier.
- Updated freeze check rules for LoanSet.
- Fixed the debt total calculation and check in LoanSet.
- Removed _some_ unnecessary includes.
2025-09-05 20:00:10 -04:00
Ed Hennis
582f56487d Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-05 17:44:28 -04:00
Ed Hennis
d47c039941 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-05 17:44:20 -04:00
Ed Hennis
bf4ae57da4 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-05 17:44:17 -04:00
Ed Hennis
83702e79bf Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-05 17:44:13 -04:00
Ed Hennis
6379363bad Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-05 17:44:10 -04:00
Ed Hennis
f0c96ccfe6 Review feedback from @yinyiqian1
- Rewrite to_short_string to call strHex directly instead of building
  the whole hex string first.
- Change PrettyAsset::scale_ back to a uint32 since the Number
  conversion elides any potential multiplication overflow.
- Clean ups.
2025-09-05 17:41:06 -04:00
Ed Hennis
4c726838d1 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-04 20:25:16 -04:00
Ed Hennis
47bcc67d56 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-04 20:25:09 -04:00
Ed Hennis
4b48f9612b Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-04 20:25:05 -04:00
Ed Hennis
7bba34832b Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-04 20:25:02 -04:00
Ed Hennis
76ae61feb5 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-04 20:24:58 -04:00
Ed Hennis
adb260fe17 Review feedback from @dangell7 and @gregtatcam
- Mostly adding comments.
- Fixed some function parameter names that weren't updated after
  a copy/paste.
- LoanBrokerCoverWithdraw does not need to check for freeze when sending
  to the issuer.
- Reorder the fund transfer cases in LoanBrokerCoverWithdraw to make it
  clearer that some transfers are direct, and some use the payment
  engine.
- Only look up the vault ID once in LoanBrokerSet
2025-09-04 20:21:30 -04:00
Ed Hennis
8444a944af Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-04 16:44:10 -04:00
Ed Hennis
6d20e59212 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-04 16:44:03 -04:00
Ed Hennis
c49cf6cec6 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-04 16:43:59 -04:00
Ed Hennis
e24f034b17 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-04 16:43:56 -04:00
Ed Hennis
72733b57e4 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-04 16:43:52 -04:00
Ed Hennis
7a78449f6d Fix minor review feedback from @Bronek
- Clean up assert, log, and comments
2025-09-04 15:53:04 -04:00
Ed Hennis
0d500343ed New invariant privilege "mayDeleteMPT", used by VauleDeposit & Clawback 2025-09-04 14:08:54 -04:00
Ed Hennis
f15e88c009 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-04 13:15:41 -04:00
Ed Hennis
0069c0c5fa Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-04 13:15:35 -04:00
Ed Hennis
450d38293d Remove unused variable 2025-09-04 13:14:19 -04:00
Ed Hennis
6d9001edac Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-04 12:37:00 -04:00
Ed Hennis
3dc14e7430 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4
* XRPLF/ximinez/lending-refactoring-3:
  ci: Use cleanup-workspace action (5763)
  Add `Scale` to SingleAssetVault (5652)
2025-09-04 12:35:39 -04:00
Ed Hennis
9a8c2523ae Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3
* XRPLF/ximinez/lending-refactoring-2:
  ci: Use cleanup-workspace action (5763)
  Add `Scale` to SingleAssetVault (5652)
2025-09-04 12:29:41 -04:00
Ed Hennis
115161f7d2 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-04 12:27:02 -04:00
Ed Hennis
77fcb9b9b3 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-04 12:26:58 -04:00
Ed Hennis
d2e8144c53 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-refactoring-1
* XRPLF/develop:
  Add `Scale` to SingleAssetVault (5652)
2025-09-04 12:25:49 -04:00
Ed Hennis
9d45fd1873 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-03 21:01:09 -04:00
Ed Hennis
4c43a0bca4 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-03 21:01:01 -04:00
Ed Hennis
bb491431bd Review feedback from @dangell7 and @mvadari
- Rewrite isTesSuccess to use TERSubset::operator bool
- Add Transactor::preflightSigValidated for expensive operations that
  should be done after signature validation. These things would have
  been done after preflight2 before this refactor.
- Split Batch and EscrowFinish preflight to use preflightSigValidated, too.
2025-09-03 20:51:40 -04:00
Ed Hennis
f090434c2d Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-03 19:21:10 -04:00
Ed Hennis
5f7b4a5e13 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-03 19:21:00 -04:00
Ed Hennis
11b8f9978e Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-03 19:20:57 -04:00
Ed Hennis
58551da698 Review feedback from @dangell7 and @Bronek
- Added more `STParsedJSON` test cases.
- Add a `safe_cast` conversion in `parseUint32`.
2025-09-03 19:18:24 -04:00
Ed Hennis
5ade8756f6 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  Review feedback from @Bronek
  Rewrite Units.h and same safe_cast.h restrictions to use concepts
* Also add required support for LoanBroker and Loan ledger entries
2025-09-03 18:41:24 -04:00
Ed Hennis
ac4c4905df Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-03 18:10:26 -04:00
Ed Hennis
a5f1879afb Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-03 18:10:23 -04:00
Ed Hennis
8a77ac71ed Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-03 18:10:19 -04:00
Ed Hennis
a72c237373 Review feedback from @Bronek
- Remove unnecessary #include
- Explanatory comments
- Make the MPT InvariantCheck related to EscrowFinish amendment safe
- Convert SField maps to unordered_maps
- Make jtx::fee::operator() clearer
- Rename checkMyPrivilege to hasPrivilege
2025-09-03 18:04:05 -04:00
Ed Hennis
faae2514b9 Rewrite Units.h and same safe_cast.h restrictions to use concepts 2025-09-03 16:14:28 -04:00
Ed Hennis
bcbbf71f29 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-09-03 14:04:25 -04:00
Ed Hennis
12994d4251 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-09-03 14:04:15 -04:00
Ed Hennis
22679673f6 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-09-03 14:04:12 -04:00
Ed Hennis
a14cbf117c Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-09-03 14:04:08 -04:00
Ed Hennis
5ce07e769f Merge branch 'develop' into ximinez/lending-refactoring-1 2025-09-03 14:04:05 -04:00
Ed Hennis
16c2ff97cc Set version to 2.5.1 2025-09-03 10:20:12 -04:00
Ed Hennis
32043463a8 Fix: Don't flag consensus as stalled prematurely (#5658)
Fix stalled consensus detection to prevent false positives in situations where there are no disputed transactions.

Stalled consensus detection was added to 2.5.0 in response to a network consensus halt that caused a round to run for over an hour. However, it has a flaw that makes it very easy to have false positives. Those false positives are usually mitigated by other checks that prevent them from having an effect, but there have been several instances of validators "running ahead" because there are circumstances where the other checks are "successful", allowing the stall state to be checked.
2025-09-03 10:12:30 -04:00
Ed Hennis
08a5e8428a Require all SFields to have a name
- From @bronek https://github.com/XRPLF/rippled/pull/5590#discussion_r2290589770
- Adds consistency, and ensures sfInvalid and sfGeneric are handled the
  same as all other SFields
2025-08-29 20:11:28 -04:00
Ed Hennis
a8e35f8399 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-29 17:58:21 -04:00
Ed Hennis
1f85888ae8 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-29 15:53:07 -04:00
Ed Hennis
183450db46 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-29 15:53:04 -04:00
Ed Hennis
64959b980f Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-29 15:53:00 -04:00
Ed Hennis
0b833e17ae Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-29 15:52:57 -04:00
Ed Hennis
2e3c5543f2 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-29 10:43:01 -04:00
Ed Hennis
0475398a17 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-29 10:42:57 -04:00
Ed Hennis
bf483a2e94 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-29 10:42:54 -04:00
Ed Hennis
5e3539d6bb Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-28 18:17:49 -04:00
Ed Hennis
a90265dd2a Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-28 18:17:40 -04:00
Ed Hennis
8498ed9df4 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-28 18:17:36 -04:00
Ed Hennis
4169b0a6b7 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-28 18:17:33 -04:00
Ed Hennis
024339c99b Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-28 18:17:29 -04:00
Ed Hennis
044697c438 fix: Allow the borrower to delete a completed / inactive loan, too. 2025-08-27 15:26:45 -04:00
Ed Hennis
2aebeeb966 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-27 11:15:23 -04:00
Ed Hennis
4c79fe46c9 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-27 11:15:14 -04:00
Ed Hennis
51abafea26 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-27 11:15:10 -04:00
Ed Hennis
f1f1117b08 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-27 11:15:06 -04:00
Ed Hennis
5bb12ac1db Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-27 11:15:03 -04:00
Ed Hennis
dbd9a05e10 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-25 19:51:13 -04:00
Ed Hennis
8981885196 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-25 19:51:04 -04:00
Ed Hennis
a7390c070f Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-25 19:51:01 -04:00
Ed Hennis
4d0f895cda Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-25 19:50:57 -04:00
Ed Hennis
48162219ac Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-25 19:50:54 -04:00
Ed Hennis
1cb4a49ad3 Make a note about PR #5650 integration 2025-08-25 19:48:31 -04:00
Ed Hennis
18ffbbd42d Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-22 20:34:42 -04:00
Ed Hennis
7f1c0e55d6 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-22 19:31:36 -04:00
Ed Hennis
1876ffcd71 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-22 19:31:24 -04:00
Ed Hennis
3ef1e4269b Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-22 19:31:20 -04:00
Ed Hennis
ae25e0f058 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-22 19:31:17 -04:00
Ed Hennis
7d634c1e62 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-22 19:31:14 -04:00
Ed Hennis
f713208d89 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-22 19:09:07 -04:00
Ed Hennis
5d98799205 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-22 19:08:55 -04:00
Ed Hennis
9086c678a9 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-22 19:08:52 -04:00
Ed Hennis
e434563e2e Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-22 19:08:48 -04:00
Ed Hennis
29300fc972 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-refactoring-1
* XRPLF/develop:
  chore: Update clang-format and prettier with pre-commit (5709)
  fix(test): handle null metadata for unvalidated tx in Env::meta (5715)
  chore: Workaround for CI build errors on arm64 (5717)
  chore: Fix file formatting (5718)
  fix: Skip notify-clio when running in a fork, reorder config fields (5712)
  chore: Reverts formatting changes to external files, adds formatting changes to proto files (5711)
2025-08-22 19:07:28 -04:00
Ed Hennis
a88aceb846 Reformat transactions.macro 2025-08-22 16:02:59 -04:00
Ed Hennis
9986346d60 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-21 11:39:20 -04:00
Ed Hennis
7c642783f4 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-21 11:39:09 -04:00
Ed Hennis
0f1a2324bc Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-21 11:39:05 -04:00
Ed Hennis
2d570267de Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-21 11:39:01 -04:00
Ed Hennis
97849b6e70 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-21 11:38:57 -04:00
Ed Hennis
5d2a7d651e Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  Review feedback from @dangell7
2025-08-19 20:22:54 -04:00
Ed Hennis
b26477a21e Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-19 20:11:45 -04:00
Ed Hennis
422a99bb26 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-19 20:11:42 -04:00
Ed Hennis
b447fc54c8 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-19 20:11:38 -04:00
Ed Hennis
9920037d13 Review feedback from @dangell7
- Cleaned up some of the `LEDGER_ENTRY` macros by eliding unnecessary
  parameters.
- Define the transaction privileges in one place (InvariantCheck.cpp).
- Give `EscrowFinish` the `mayAuthorizeMPT` privilege.
- Rename the test helper `expectLine` to `expectHolding` since
  it handles both trust lines and MPTs.
- Restructure the ""pseudo-account has 2 pseudo-account fields set"
  invariant test to loop over all defined pseudo-account fields.
- Fix `operator<<` for `PrettyAmount` to handle `MPTIssue`s.
- Add enforcement of the `AccountRootsDeletedClean` invariant if SAV is
  enabled, and clarify the comment for the pseudo-account field check.
- Delete the 100% redundant `ttMPTOKEN_ISSUANCE_SET` check in
  `ValidMPTIssuance`.
2025-08-19 19:52:30 -04:00
Ed Hennis
714e12f44f Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-19 16:14:20 -04:00
Ed Hennis
fba91487ec Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-19 16:05:34 -04:00
Ed Hennis
49ea5cc152 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-19 16:05:30 -04:00
Ed Hennis
87e0c25a34 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-19 16:05:26 -04:00
Ed Hennis
a648249b90 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-19 16:05:21 -04:00
Ed Hennis
083ab7b054 Prevent Vault unrealized loss from exceeding "unavailable" assets 2025-08-19 15:15:10 -04:00
Ed Hennis
b6ef337e45 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  fix: Modify jobs to use '>>' instead of 'tee' for GITHUB_OUTPUT (5699)
  refactor: Revamp CI workflows (5661)
  refactor: Decouple net from xrpld and move rpc-related classes to the rpc folder (5477)
  Set version to 2.6.0-rc2
  docs: Updates list of maintainers and reviewers (5687)
  fix: Change log to debug level for AMM offer retrieval and IOU payment check (5686)
  fix: Add -Wno-deprecated-declarations for Clang only (5680)
  Update .git-blame-ignore-revs for 5657 (5675)
  Fix BUILD.md instruction (5676)
  Set version to 2.6.0-rc1
  fix: Improve logging of the reason to refuse a peer connection (5664)
  fix: Make test suite names match the directory name (5597)
  chore: Run prettier on all files (5657)
  chore: Set CONAN_REMOTE_URL also for forks (5662)
  chore: Cleanup bin/ directory (5660)
  perf: Optimize hash performance by avoiding allocating hash state object (5469)
2025-08-18 20:36:35 -04:00
Ed Hennis
e62efa2a90 Fix unit tests broken by the addition of signature_target
- Specifically some of the tests for sign and submit
2025-08-18 20:32:53 -04:00
Ed Hennis
3867945b46 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-18 12:44:41 -04:00
Ed Hennis
084896189d Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-18 12:25:55 -04:00
Ed Hennis
e9033898da Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-18 12:25:51 -04:00
Ed Hennis
d952e9de1a Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-refactoring-1
* XRPLF/develop:
  fix: Modify jobs to use '>>' instead of 'tee' for GITHUB_OUTPUT (#5699)
  refactor: Revamp CI workflows (#5661)
  refactor: Decouple net from xrpld and move rpc-related classes to the rpc folder (#5477)
  Set version to 2.6.0-rc2
  docs: Updates list of maintainers and reviewers (#5687)
  fix: Change log to debug level for AMM offer retrieval and IOU payment check (#5686)
  fix: Add -Wno-deprecated-declarations for Clang only (#5680)
  Update .git-blame-ignore-revs for #5657 (#5675)
  Fix BUILD.md instruction (#5676)
  Set version to 2.6.0-rc1
  fix: Improve logging of the reason to refuse a peer connection (#5664)
  fix: Make test suite names match the directory name (#5597)
  chore: Run prettier on all files (#5657)
  chore: Set CONAN_REMOTE_URL also for forks (#5662)
  chore: Cleanup bin/ directory (#5660)
  perf: Optimize hash performance by avoiding allocating hash state object (#5469)
2025-08-18 12:22:43 -04:00
Ed Hennis
bc3c9e1534 fixup! Add Counterparty signing support 2025-08-09 01:19:38 -04:00
Ed Hennis
6d137e44dc Add Counterparty signing support
- Add a new parameter "signature_target" to "sign". Supports single and
  multisign, but I haven't written tests for multisign yet.
- Skip account validation if this field is set, like multisigning.
- Unit tests demonstrating examples.
2025-08-09 00:55:00 -04:00
Ed Hennis
6778521f12 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-08 18:30:40 -04:00
Ed Hennis
b0f3ef4969 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-08 18:23:37 -04:00
Ed Hennis
c01ef3f155 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-08 18:23:34 -04:00
Ed Hennis
241f22bab7 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-08 18:23:30 -04:00
Ed Hennis
a387a7aadf Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-08 18:23:27 -04:00
Ed Hennis
d5e137de82 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-refactoring-1
* XRPLF/develop:
  Switch Conan 1 commands to Conan 2 and fix credentials (#5655)
  perf: Move mutex to the partition level (#5486)
  Upload Conan dependencies upon merge into develop (#5654)
2025-08-08 11:31:44 -04:00
Ed Hennis
e0cdd65352 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-06 21:08:14 -04:00
Ed Hennis
2c1ccdbc84 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-06 21:03:14 -04:00
Ed Hennis
36204d2ce9 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-06 21:03:10 -04:00
Ed Hennis
4639c1c351 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-06 21:03:07 -04:00
Ed Hennis
c863bd25e0 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-06 21:03:04 -04:00
Ed Hennis
7dcc682e29 Make LoanSet.CounterpartySignature optional in the Tx layout
- Still required for the transaction to succeed (except inside a Batch,
  because the batch signers take care of that).
- Started adding tests for Loan-related RPC and low-level math checks.
  Currently only implemented "sign" on a LoanSet to verify it can be
  done.
2025-08-06 20:48:13 -04:00
Ed Hennis
162875616d Correct more issues related to 0-interest loans and some rounding issues
- Addresses FIND-012 from audit.
- If computePeriodicPaymentParts rounds the principal part to 0, add
  a small amount so that some principal is paid regardless of how
  extreme the loan parameters are. For XRP and MPTs, this just adds 1.
  For IOUs, compute an epsilon based on the scale of the original loan.
  (IOUs untested.)
  - Also move this function out of the detail namespace so direct unit
    tests can be written. (Pending.)
- Adds the testLoanPayComputePeriodicPaymentValidRateInvariant from
  auditors with some minor modifications.
- Fixes an assert that the periodic rate > 0, which won't be true if the
  loan interest rate is 0.
2025-08-06 11:47:42 -04:00
Ed Hennis
9847025099 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  Fix formatting
  fix: Ensures canonical order for `PriceDataSeries` upon `PriceOracle` creation (#5485)
  Add code coverage for STParsedJSON edge cases
  refactor: Decouple ledger from xrpld/app (#5492)
2025-08-05 21:30:31 -04:00
Ed Hennis
bb183ea09a Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-05 21:16:57 -04:00
Ed Hennis
9fd45e7aa7 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-05 21:16:54 -04:00
Ed Hennis
924b05ea9f Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-05 21:16:50 -04:00
Ed Hennis
a0a0916108 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-05 21:16:47 -04:00
Ed Hennis
c78b9aedac Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-08-05 21:16:34 -04:00
Ed Hennis
b07087f10b Fix formatting 2025-08-05 13:20:29 -04:00
Ed Hennis
f89c88dbb8 Add code coverage for STParsedJSON edge cases
- Move several tests from `STObject_test` to new `STParsedJSON_test`
  unchanged.
- Add 3 test cases to cover edge cases for UInt16 values.

Co-authored-by: Denis Angell <dangell@transia.co>
2025-08-05 12:45:05 -04:00
Ed Hennis
0c76153b2c Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-08-04 13:05:06 -04:00
Ed Hennis
70a23bcca3 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-08-04 13:05:02 -04:00
Ed Hennis
a66ef800bc Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-08-04 13:04:59 -04:00
Ed Hennis
5f5f60a024 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-08-04 13:04:55 -04:00
Ed Hennis
d58399d417 Correct handling of LoanBroker.DebtMaximum zero values
- Addresses FIND-003 from audit.
- Behavior changed to treat a DebtMaximum value of 0 to mean "no limit",
  as defined in spec.
- No need to add unit tests, because the previous commit covers 0, and
  tests already exist for non-zero limits.
2025-07-30 18:08:05 -04:00
Ed Hennis
a1e9091f1e Add the "testBatchBypassCounterparty" test from auditors
- (With some minor modifications)
2025-07-30 17:25:58 -04:00
Ed Hennis
84acebeb7f Enforce valid range of LoanSet.InterestRate
- Addresses FIND-002 from audit.
- Enforces a range of 0-100% in 1/10 bips.
- Also add a couple of unit test checks.
2025-07-30 13:56:50 -04:00
Ed Hennis
83ba11d505 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  fix `DeliveredAmount` and `delivered_amount` in transaction metadata for direct MPT transfer (#5569)
2025-07-30 11:07:03 -04:00
Ed Hennis
97469a1c02 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-07-29 20:33:43 -04:00
Ed Hennis
c74dc6baf2 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-07-29 20:33:40 -04:00
Ed Hennis
1d90ae7c25 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-07-29 20:33:36 -04:00
Ed Hennis
39db7381b2 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-07-29 20:33:32 -04:00
Ed Hennis
ec8eaf0d73 fixup! Ensure Counterparty Signatures are properly handled by Batch tx 2025-07-29 20:31:31 -04:00
Ed Hennis
9d1a23a811 Ensure Counterparty Signatures are properly handled by Batch tx
- Addresses FIND-001 from audit
- LoanSet::preflight will require Counterparty to be set (it's normally
  optional) for an inner batch transaction, because the checks are done
  before the LoanBroker object can be accessed.
- Adjust LoanSet::calculateBaseFee to not charge extra if an inner
  transaction.
- Adds a Loan-specific test to Batch_test.
2025-07-29 19:46:01 -04:00
Ed Hennis
421cbb9abd Add the "testBatchBypassCounterparty" test from auditors
- (With some minor modifications)
2025-07-29 19:34:02 -04:00
Ed Hennis
bba9119a75 Fix a couple of errors
- Mark variable only used in asserts as [[maybe_unused]].
- Restore commented out line that I think I resolved wrong in an earlier
  merge to fix Vault tests.
2025-07-29 14:58:36 -04:00
Ed Hennis
6f00f296c8 Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-07-29 12:31:48 -04:00
Ed Hennis
aee4719df4 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-07-29 11:54:30 -04:00
Ed Hennis
5f2402479d Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-07-29 11:54:26 -04:00
Ed Hennis
c3fa4fb71c Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-07-29 11:54:23 -04:00
Ed Hennis
a8d0d763b0 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-07-29 11:54:19 -04:00
Ed Hennis
6310b2544c Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  Build options cleanup (#5581)
  Updates Conan dependencies: Boost 1.86 (#5264)
  VaultWithdraw destination account bugfix (#5572)
2025-07-28 21:10:12 -04:00
Ed Hennis
3c0ef8f8d3 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-07-28 20:57:29 -04:00
Ed Hennis
ebe39e9320 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-07-28 20:57:24 -04:00
Ed Hennis
1b8da176bf Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-07-28 20:57:21 -04:00
Ed Hennis
66dd0de019 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-07-28 20:57:17 -04:00
Ed Hennis
a2be55fbc9 Check LoanBrokerCoverWithdraw Destination and DestinationTag fields
- See also #5572 / e7a7bb8
2025-07-28 19:04:55 -04:00
Ed Hennis
41c24094eb Merge branch 'ximinez/lending-refactoring-4' into ximinez/lending-XLS-66 2025-07-24 17:00:57 -04:00
Ed Hennis
3b446f144f Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-07-24 16:13:47 -04:00
Ed Hennis
760a9aad83 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3
* XRPLF/ximinez/lending-refactoring-2:
  refactor: Update rocksdb (#5568)
  Switch instrumentation workflow to use dependencies (#5607)
  chore: Rename conan profile to `default` (#5599)
  Include `network_id` in validations and subscription stream responses (#5579)
  Add support for `DomainID` in `MPTokenIssuance` transactions (#5509)
  chore: Remove unused code after flow cross retirement (#5575)
  Remove obsolete owner pays fee feature and XRPL_ABANDON stanza (#5550)
  refactor: Makes HashRouter flags more type-safe (#5371)
  Fix clang-format CI job (#5598)
2025-07-24 16:12:48 -04:00
Ed Hennis
c73372297c Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-07-24 15:50:17 -04:00
Ed Hennis
1f331bf8d8 Merge branch 'develop' into ximinez/lending-refactoring-1 2025-07-24 15:50:13 -04:00
Ed Hennis
57c78c56ba fixup! fixup! Fix divide by 0 error on 0-interest loans; allow broker to self-lend 2025-07-24 15:08:18 -04:00
Ed Hennis
1adb410e8e fixup! Fix divide by 0 error on 0-interest loans; allow broker to self-lend 2025-07-24 13:58:05 -04:00
Ed Hennis
6444ad4393 Merge remote-tracking branch 'XRPLF/ximinez/lending-refactoring-4' into ximinez/lending-XLS-66
* XRPLF/ximinez/lending-refactoring-4:
  fixup! Rename Transactor preflight functions
  Rename Transactor preflight functions
  fixup! Make preflight1 and preflight2 private static Transactor functions
  Make preflight1 and preflight2 private static Transactor functions
  Fix formatting
2025-07-23 17:45:51 -04:00
Ed Hennis
1e7462606c Fix divide by 0 error on 0-interest loans; allow broker to self-lend
* Unit tests for self lending
2025-07-23 17:24:53 -04:00
Ed Hennis
68aecfe8a2 Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4 2025-07-22 14:09:47 -04:00
Ed Hennis
8ffe1838d4 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3 2025-07-22 14:09:43 -04:00
Ed Hennis
30becab0b6 Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2 2025-07-22 14:09:40 -04:00
Ed Hennis
e037ae3d3a Merge branch 'develop' into ximinez/lending-refactoring-1 2025-07-22 14:09:37 -04:00
Ed Hennis
2f3c79837e Merge branch 'develop' into ximinez/lending-XLS-66 2025-07-22 14:09:23 -04:00
Ed Hennis
4550d2bfba Fix build error 2025-07-22 14:06:17 -04:00
Ed Hennis
5edaad41af Merge branch 'ximinez/lending-refactoring-3' into ximinez/lending-refactoring-4
* ximinez/lending-refactoring-3: (61 commits)
  fixup! Rename Transactor preflight functions
  Rename Transactor preflight functions
  fixup! Make preflight1 and preflight2 private static Transactor functions
  Make preflight1 and preflight2 private static Transactor functions
  Fix formatting
  Remove `include(default)` from libxrpl profile (#5587)
  refactor: Change boost::shared_mutex to std::shared_mutex (#5576)
  Fix macos runner (#5585)
  Remove the type filter from "ledger" RPC command (#4934)
  refactor: Update date, libarchive, nudb, openssl, sqlite3, xxhash packages (#5567)
  test: Run unit tests regardless of 'Supported' amendment status (#5537)
  Retire Flow Cross amendment (#5562)
  chore: Update CI to use Conan 2 (#5556)
  fixAMMClawbackRounding: adjust last holder's LPToken balance (#5513)
  chore: Add gcc-12 workaround (#5554)
  Add MPT related txns into issuer's account history  (#5530)
  chore: Remove unused headers (#5526)
  fix: add allowTrustLineLocking flag for account_info (#5525)
  Downgrade required CMake version for Antithesis SDK (#5548)
  fix: Link with boost libraries explicitly (#5546)
  ...

Co-authored-by: Bronek Kozicki <brok@incorrekt.com>
2025-07-22 13:34:43 -04:00
Ed Hennis
24447969be fixup! Rename Transactor preflight functions 2025-07-22 12:43:54 -04:00
Ed Hennis
c76e485d01 Rename Transactor preflight functions
- Rename Transactor::preflight to invokePreflight.
- Rename doPreflight back to preflight.
- Update instructions.
- With preflight1 & 2 now uncallable, in-flight code in other
  branches should be easier to convert.
2025-07-22 12:11:00 -04:00
Ed Hennis
021bee8dd4 fixup! Make preflight1 and preflight2 private static Transactor functions 2025-07-22 12:10:58 -04:00
Ed Hennis
6c5945f9e8 Make preflight1 and preflight2 private static Transactor functions
- They should never be called by derived classes.
2025-07-21 23:26:29 -04:00
Ed Hennis
96ad348fb0 Merge branch 'ximinez/lending-refactoring-2' into ximinez/lending-refactoring-3
* ximinez/lending-refactoring-2: (57 commits)
  Fix formatting
  Remove `include(default)` from libxrpl profile (#5587)
  refactor: Change boost::shared_mutex to std::shared_mutex (#5576)
  Fix macos runner (#5585)
  Remove the type filter from "ledger" RPC command (#4934)
  refactor: Update date, libarchive, nudb, openssl, sqlite3, xxhash packages (#5567)
  test: Run unit tests regardless of 'Supported' amendment status (#5537)
  Retire Flow Cross amendment (#5562)
  chore: Update CI to use Conan 2 (#5556)
  fixAMMClawbackRounding: adjust last holder's LPToken balance (#5513)
  chore: Add gcc-12 workaround (#5554)
  Add MPT related txns into issuer's account history  (#5530)
  chore: Remove unused headers (#5526)
  fix: add allowTrustLineLocking flag for account_info (#5525)
  Downgrade required CMake version for Antithesis SDK (#5548)
  fix: Link with boost libraries explicitly (#5546)
  chore: Fix compilation error with clang-20 and cleanup (#5543)
  test: Remove circular jtx.h dependencies (#5544)
  Decouple CredentialHelpers from xrpld/app/tx (#5487)
  fix: crash when trace-logging in tests (#5529)
  ...
2025-07-21 23:26:23 -04:00
Ed Hennis
72f33d8f3b Merge branch 'ximinez/lending-refactoring-1' into ximinez/lending-refactoring-2
* ximinez/lending-refactoring-1: (57 commits)
  Fix formatting
  Remove `include(default)` from libxrpl profile (#5587)
  refactor: Change boost::shared_mutex to std::shared_mutex (#5576)
  Fix macos runner (#5585)
  Remove the type filter from "ledger" RPC command (#4934)
  refactor: Update date, libarchive, nudb, openssl, sqlite3, xxhash packages (#5567)
  test: Run unit tests regardless of 'Supported' amendment status (#5537)
  Retire Flow Cross amendment (#5562)
  chore: Update CI to use Conan 2 (#5556)
  fixAMMClawbackRounding: adjust last holder's LPToken balance (#5513)
  chore: Add gcc-12 workaround (#5554)
  Add MPT related txns into issuer's account history  (#5530)
  chore: Remove unused headers (#5526)
  fix: add allowTrustLineLocking flag for account_info (#5525)
  Downgrade required CMake version for Antithesis SDK (#5548)
  fix: Link with boost libraries explicitly (#5546)
  chore: Fix compilation error with clang-20 and cleanup (#5543)
  test: Remove circular jtx.h dependencies (#5544)
  Decouple CredentialHelpers from xrpld/app/tx (#5487)
  fix: crash when trace-logging in tests (#5529)
  ...
2025-07-21 20:48:44 -04:00
Ed Hennis
96f2a65f64 Fix formatting 2025-07-21 20:37:16 -04:00
Ed Hennis
43fe49e756 Merge remote-tracking branch 'upstream/develop' into ximinez/lending-refactoring-1
* upstream/develop: (56 commits)
  Remove `include(default)` from libxrpl profile (#5587)
  refactor: Change boost::shared_mutex to std::shared_mutex (#5576)
  Fix macos runner (#5585)
  Remove the type filter from "ledger" RPC command (#4934)
  refactor: Update date, libarchive, nudb, openssl, sqlite3, xxhash packages (#5567)
  test: Run unit tests regardless of 'Supported' amendment status (#5537)
  Retire Flow Cross amendment (#5562)
  chore: Update CI to use Conan 2 (#5556)
  fixAMMClawbackRounding: adjust last holder's LPToken balance (#5513)
  chore: Add gcc-12 workaround (#5554)
  Add MPT related txns into issuer's account history  (#5530)
  chore: Remove unused headers (#5526)
  fix: add allowTrustLineLocking flag for account_info (#5525)
  Downgrade required CMake version for Antithesis SDK (#5548)
  fix: Link with boost libraries explicitly (#5546)
  chore: Fix compilation error with clang-20 and cleanup (#5543)
  test: Remove circular jtx.h dependencies (#5544)
  Decouple CredentialHelpers from xrpld/app/tx (#5487)
  fix: crash when trace-logging in tests (#5529)
  test: switch some unit tests to doctest (#5383)
  ...
2025-07-21 19:53:20 -04:00
Ed Hennis
e14ca4c438 Merge branch 'develop' into ximinez/lending-XLS-66 2025-07-21 18:20:32 -04:00
Ed Hennis
ed00018adc fixup! Add pseudo account type to injected data in RPC account_info result 2025-07-18 20:42:00 -04:00
Ed Hennis
f7aef49509 Add pseudo account type to injected data in RPC account_info result
- Low hanging fruit
2025-07-18 20:32:07 -04:00
Ed Hennis
e1edd43205 fixup! Fix LoanBrokerCoverClawback tests? 2025-07-18 19:19:08 -04:00
Ed Hennis
03d253ae20 Fix LoanBrokerCoverClawback tests? 2025-07-18 18:58:58 -04:00
Ed Hennis
577b047cc1 Merge branch 'develop' into ximinez/lending-XLS-66 2025-07-18 18:33:00 -04:00
Ed Hennis
c46d894192 Implement LoanBrokerCoverClawback and many test cases
- Not all tests are passing yet
2025-07-17 20:41:55 -04:00
Ed Hennis
e4480569f7 TEMP: Change VaultWithdraw back so tests pass 2025-07-16 18:58:25 -04:00
Ed Hennis
e6e6360c1a Support MPT payments via Payment tx for LBCoverWithdraw.Destination 2025-07-16 18:31:10 -04:00
Ed Hennis
6b4236343a Get CoverWithdraw IOU payments working
- Clean up some of the payment parameters
- Also factor out Payment::makeMPTDirectPayment for future use
2025-07-16 17:41:23 -04:00
Ed Hennis
45abab3a78 Add missing headers 2025-07-16 15:29:59 -04:00
Ed Hennis
4d7492a00d Use new "testable_amendments" function in new tests 2025-07-16 14:03:50 -04:00
Ed Hennis
b83af2d54a Fix formatting 2025-07-16 13:49:23 -04:00
Ed Hennis
10b73525be fixup! Start implementing LoanBrokerCoverWithdraw.Destination field 2025-07-16 12:55:23 -04:00
Ed Hennis
89dbb48860 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  test: Run unit tests regardless of 'Supported' amendment status (#5537)
  Retire Flow Cross amendment (#5562)
2025-07-16 12:53:36 -04:00
Ed Hennis
16854fff1a Merge branch 'develop' into ximinez/lending-XLS-66 2025-07-15 19:36:14 -04:00
Ed Hennis
b34f59eafc Start implementing LoanBrokerCoverWithdraw.Destination field
- Refactor the IOU payment code out of the Payment transactor and use it
  for different destinations. This should enforce all of the trust line
  rules without having to reinvent a dozen wheels.
- TODO: Same for MPTs.
2025-07-15 19:30:58 -04:00
Ed Hennis
38cb371c72 Make requireAuth work more similarly between IOUs and MPTs
- Unfortunately, to not change behavior, a new "Legacy" authorization
  type was created. It acts like "StrongAuth" for MPTs and "WeakAuth"
  for IOUs.
2025-07-15 17:48:14 -04:00
Ed Hennis
5199c5e073 Improve / add freeze checking helper functions
- Add an override of isDeepFrozen that can take an Asset, and thus an
  MPTIssue. The MPT version just calls isFrozen, since they're
  equivalent for MPTs.
- Add wrappers checkFrozen and checkDeepFrozen that return the
  appropriate TER code, so the Asset type doesn't have to be checked
  at every #*%@ing caller.
- Convert the Loan* transactors to use these functions.
2025-07-15 15:32:21 -04:00
Ed Hennis
3ef72d28bd fixup! Make a few tweaks to the changes in 907cc19a 2025-07-15 14:20:44 -04:00
Ed Hennis
06906a8bd3 Refactor the bulk of testLifecycle into a function
- Allows tweaking loan properties
2025-07-14 18:54:48 -04:00
Ed Hennis
0a3c728a96 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-XLS-66
* XRPLF/develop:
  fixAMMClawbackRounding: adjust last holder's LPToken balance (#5513)
  chore: Add gcc-12 workaround (#5554)
  Add MPT related txns into issuer's account history  (#5530)
  chore: Remove unused headers (#5526)
2025-07-11 19:21:03 -04:00
Ed Hennis
37745cb5b2 Rename Transactor preflight functions
- Rename Transactor::preflight to invokePreflight.
- Rename doPreflight back to preflight.
- Update instructions.
- With preflight1 & 2 now uncallable, in-flight code in other
  branches should be easier to convert.
2025-07-11 19:17:11 -04:00
Ed Hennis
269eac9a15 Mark the LendingProtocol amendment as unsupported 2025-07-11 18:55:08 -04:00
Ed Hennis
d82461ea70 Make preflight1 and preflight2 private static Transactor functions
- They should never be called by derived classes.
2025-07-11 18:42:39 -04:00
Ed Hennis
e9d2dfe329 fixup! Make a few tweaks to the changes in merge cc83ea8 2025-07-11 17:14:53 -04:00
Ed Hennis
9d052dc86c Make a few tweaks to the changes in 907cc19a 2025-07-11 17:06:26 -04:00
Ed Hennis
ad5d28bc48 Make a few tweaks to the changes in merge cc83ea8
- Not necessarily wrong, just not how I want it.
- Fixes a build error in LoanBroker_test
- In CreateOffer, fixes a logic error where _no_ offers will work if
  PermissionedDex amendment is enabled, and FlowCross is not
2025-07-11 16:14:10 -04:00
Ed Hennis
2b5a8ebf2f Merge branch 'develop' into ximinez/lending-XLS-66 2025-07-10 12:30:06 -04:00
Ed Hennis
28999a242c Merge branch 'develop' into ximinez/lending-XLS-66 2025-07-03 15:51:14 -04:00
Ed Hennis
186821f971 Merge branch 'develop' into ximinez/lending-XLS-66 2025-07-02 19:04:56 -04:00
Bronek Kozicki
1c8e4c346b Merge branch 'develop' into ximinez/lending-XLS-66 2025-06-27 10:45:37 +01:00
Bronek Kozicki
6bcd037264 Merge branch 'develop' into ximinez/lending-XLS-66 2025-06-23 10:33:05 +01:00
Bronek Kozicki
439e2d4934 Merge branch 'release' into ximinez/lending-XLS-66 2025-06-23 10:04:20 +01:00
Bronek Kozicki
f812774637 Merge branch 'develop' into ximinez/lending-XLS-66 2025-06-10 23:03:43 +08:00
Bronek Kozicki
d82693c2d3 Merge branch 'develop' into ximinez/lending-XLS-66 2025-06-10 21:51:58 +08:00
Bronek Kozicki
907cc19a41 Merge branch 'develop' into ximinez/lending-XLS-66 2025-06-05 13:04:15 +01:00
Bronek Kozicki
cc83ea8eb6 Merge branch 'develop' into ximinez/lending-XLS-66 2025-06-04 19:35:45 +01:00
Ed Hennis
527e0c916f Lending protocol implementation (XLS-0066)
- Add the LendingProtocol amendment
- Add Loan Broker and Loan ledger objects:
- Also add new SFields, Keylet functions, and an Invariant to verify no
  illegal field modification
- Update list of "constant" fields from spec
- Also add a general check for all object types for the type and index
  fields
- 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.
- refactor: Generalize Transactor preflight:
- Derived classes no longer need to explicitly check amendments, nor
  call into preflight1 or preflight2.
- implemeng LoanBrokerSet
- Transactions: LoanDelete, LoanManage, LoanDraw, LoanPay
- LoanBrokerSet creation mostly done. Need update.
- Also added a lookup table for pseudo account fields.
- 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.
- Create some helper classes for transaction fields
- Test that they work by converting some of the existing classes
- Finish creating helper classes for JTx fields
- Also change the pseudo account field lookup to a function that uses
  a switch
- Update tests, update pseudo-account checking
- Generalize some of the Invariant checks using macro files
  - Valid ledger entry type
  - Valid new account root and pseudo account check
- 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.
- Reserve a few values between Vault and Lending for future use
- Pseudo-account improvements
  - Define pseudo-account fields with an sfield flag
  - Pseudo-account invariant checks rules whenever a pseudo-account is
    created or modified.
- 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.
- Fix account creation to check both amendments
- Add a validity range for sfDebtMaximum
- Change more "failed" messages. The goal here is to be able to search
  the log for "failed" and ONLY get test failures.
- NoModifiedUnmodifiableFields and ValidPseudoAccounts
- Move the Invariants_test class into the test namespace
- Clang wants an explicit ctor to emplace in a vector
- 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.
- Initial implementation of LoanBrokerDelete
- Generalize the LoanBroker lifecycle test
- Refactor ApplyView::dirAdd to give access to low-level operations
  - Takes a page from #5362, which may turn out to be useful!
- Start writing Loan Broker invariants and tests
  - Specifically those mentioned for LoanBrokerDelete
- 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.
- Add LoanBrokerCoverDeposit transaction
- Add LoanBrokerCoverWithdraw transaction
- Start writing tests for LoanBrokerCover*
- 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.
- 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.
- Ensure that an account is not deleted with an XRP balance
  - Updates the AccountRootsDeletedClean invariant
- Finish up the Loan Broker tests
- Move inclusion of Transactor headers to transactions.macro
  - Only need to update in one place when adding a new transaction.
- 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.
- Generalize the check*Sign functions to support CounterParty
  - checkSign, checkSingleSign, and checkMultiSign in STTx and Transactor
- Start writing Loan tests
  - Required adding support for counterparty signature to jtx framework:
    arbitrary signature field destination, multiple signer callbacks
- Get Counterparty signing working
- Add more LoanSet unit tests, added LoanBroker LoanSequence field
  - LoanSequence will prevent loan key collisions
- 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.
- Ensure that an account is not deleted with a non-zero owner count
  - Updates the AccountRootsDeletedClean invariant
- Add unit tests to create a Loan successfully
  - Fix a few field initializations in LoanSet
- Refactor issuance validity check in VaultCreate
  - Utility function: canAddHolding
  - Call canAddHolding from any transactor that call addEmptyHolding
    (LoanBrokerSet, LoanSet)
- Start implementing LoanManage transaction
  - Also add a ValidLoan invariant
- Finish `LoanManage` functionality and tests, modulo LoanDraw/Pay
- Allow existing trust lines to loan brokers to be managed (by issuer)
- Implement LoanDelete, and fix a bunch of math errors in LoanManage
- Update to match latest spec: compute interest, LoanBroker reserves
- refactor: Define getFlagsMask in the base Transactor class
  - Returns tfUniversalMask for most transactors
  - Only transactors that use other flags need to override
- Implement LoanDraw, and made good progress on related tests
- Start implementing LoanPay transaction
- Implement LoanPay & most tests
- Also add an XRPL_ASSERT_PARTS, which splits the parts of the assert message
    so I don't have to remember the proper formatting.
Start writing LoanPay transaction tests
2025-05-21 11:39:55 +01:00
Ed Hennis
fb5d94bbef Refactor 4: Transactor extra signing support 2025-05-21 11:39:37 +01:00
Ed Hennis
4fe3ec8a08 Refactor 3: Transactors 2025-05-21 11:39:35 +01:00
Ed Hennis
937b67cbc0 Refactor 2: STParsed Json 2025-05-21 11:39:34 +01:00
Ed Hennis
4e50087612 Refactoring 1 2025-05-21 11:39:26 +01:00
396 changed files with 22735 additions and 4533 deletions

View File

@@ -33,5 +33,6 @@ slack_app: false
ignore:
- "src/test/"
- "src/tests/"
- "include/xrpl/beast/test/"
- "include/xrpl/beast/unit_test/"

View File

@@ -20,14 +20,18 @@ runs:
steps:
- name: Install Conan dependencies
shell: bash
env:
BUILD_DIR: ${{ inputs.build_dir }}
BUILD_OPTION: ${{ inputs.force_build == 'true' && '*' || 'missing' }}
BUILD_TYPE: ${{ inputs.build_type }}
run: |
echo 'Installing dependencies.'
mkdir -p ${{ inputs.build_dir }}
cd ${{ inputs.build_dir }}
mkdir -p '${{ env.BUILD_DIR }}'
cd '${{ env.BUILD_DIR }}'
conan install \
--output-folder . \
--build ${{ inputs.force_build == 'true' && '"*"' || 'missing' }} \
--options:host '&:tests=True' \
--options:host '&:xrpld=True' \
--settings:all build_type=${{ inputs.build_type }} \
--build=${{ env.BUILD_OPTION }} \
--options:host='&:tests=True' \
--options:host='&:xrpld=True' \
--settings:all build_type='${{ env.BUILD_TYPE }}' \
..

View File

@@ -1,96 +0,0 @@
# This action build and tests the binary. The Conan dependencies must have
# already been installed (see the build-deps action).
name: Build and Test
description: "Build and test the binary."
# Note that actions do not support 'type' and all inputs are strings, see
# https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax#inputs.
inputs:
build_dir:
description: "The directory where to build."
required: true
build_only:
description: 'Whether to only build or to build and test the code ("true", "false").'
required: false
default: "false"
build_type:
description: 'The build type to use ("Debug", "Release").'
required: true
cmake_args:
description: "Additional arguments to pass to CMake."
required: false
default: ""
cmake_target:
description: "The CMake target to build."
required: true
codecov_token:
description: "The Codecov token to use for uploading coverage reports."
required: false
default: ""
os:
description: 'The operating system to use for the build ("linux", "macos", "windows").'
required: true
runs:
using: composite
steps:
- name: Configure CMake
shell: bash
working-directory: ${{ inputs.build_dir }}
run: |
echo 'Configuring CMake.'
cmake \
-G '${{ inputs.os == 'windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \
${{ inputs.cmake_args }} \
..
- name: Build the binary
shell: bash
working-directory: ${{ inputs.build_dir }}
run: |
echo 'Building binary.'
cmake \
--build . \
--config ${{ inputs.build_type }} \
--parallel $(nproc) \
--target ${{ inputs.cmake_target }}
- name: Check linking
if: ${{ inputs.os == 'linux' }}
shell: bash
working-directory: ${{ inputs.build_dir }}
run: |
echo 'Checking linking.'
ldd ./rippled
if [ "$(ldd ./rippled | grep -E '(libstdc\+\+|libgcc)' | wc -l)" -eq 0 ]; then
echo 'The binary is statically linked.'
else
echo 'The binary is dynamically linked.'
exit 1
fi
- name: Verify voidstar
if: ${{ contains(inputs.cmake_args, '-Dvoidstar=ON') }}
shell: bash
working-directory: ${{ inputs.build_dir }}
run: |
echo 'Verifying presence of instrumentation.'
./rippled --version | grep libvoidstar
- name: Test the binary
if: ${{ inputs.build_only == 'false' }}
shell: bash
working-directory: ${{ inputs.build_dir }}/${{ inputs.os == 'windows' && inputs.build_type || '' }}
run: |
echo 'Testing binary.'
./rippled --unittest --unittest-jobs $(nproc)
ctest -j $(nproc) --output-on-failure
- name: Upload coverage report
if: ${{ inputs.cmake_target == 'coverage' }}
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
with:
disable_search: true
disable_telem: true
fail_ci_if_error: true
files: ${{ inputs.build_dir }}/coverage.xml
plugins: noop
token: ${{ inputs.codecov_token }}
verbose: true

43
.github/actions/print-env/action.yml vendored Normal file
View File

@@ -0,0 +1,43 @@
name: Print build environment
description: "Print environment and some tooling versions"
runs:
using: composite
steps:
- name: Check configuration (Windows)
if: ${{ runner.os == 'Windows' }}
shell: bash
run: |
echo 'Checking environment variables.'
set
echo 'Checking CMake version.'
cmake --version
echo 'Checking Conan version.'
conan --version
- name: Check configuration (Linux and macOS)
if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }}
shell: bash
run: |
echo 'Checking path.'
echo ${PATH} | tr ':' '\n'
echo 'Checking environment variables.'
env | sort
echo 'Checking CMake version.'
cmake --version
echo 'Checking compiler version.'
${{ runner.os == 'Linux' && '${CC}' || 'clang' }} --version
echo 'Checking Conan version.'
conan --version
echo 'Checking Ninja version.'
ninja --version
echo 'Checking nproc version.'
nproc --version

View File

@@ -35,9 +35,12 @@ runs:
- name: Set up Conan remote
shell: bash
env:
CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
CONAN_REMOTE_URL: ${{ inputs.conan_remote_url }}
run: |
echo "Adding Conan remote '${{ inputs.conan_remote_name }}' at ${{ inputs.conan_remote_url }}."
conan remote add --index 0 --force ${{ inputs.conan_remote_name }} ${{ inputs.conan_remote_url }}
echo "Adding Conan remote '${{ env.CONAN_REMOTE_NAME }}' at '${{ env.CONAN_REMOTE_URL }}'."
conan remote add --index 0 --force '${{ env.CONAN_REMOTE_NAME }}' '${{ env.CONAN_REMOTE_URL }}'
echo 'Listing Conan remotes.'
conan remote list

View File

@@ -72,15 +72,15 @@ It generates many files of [results](results):
desired as described above. In a perfect repo, this file will be
empty.
This file is committed to the repo, and is used by the [levelization
Github workflow](../../workflows/check-levelization.yml) to validate
Github workflow](../../workflows/reusable-check-levelization.yml) to validate
that nothing changed.
- [`ordering.txt`](results/ordering.txt): A list showing relationships
between modules where there are no loops as they actually exist, as
opposed to how they are desired as described above.
This file is committed to the repo, and is used by the [levelization
Github workflow](../../workflows/check-levelization.yml) to validate
Github workflow](../../workflows/reusable-check-levelization.yml) to validate
that nothing changed.
- [`levelization.yml`](../../workflows/check-levelization.yml)
- [`levelization.yml`](../../workflows/reusable-check-levelization.yml)
Github Actions workflow to test that levelization loops haven't
changed. Unfortunately, if changes are detected, it can't tell if
they are improvements or not, so if you have resolved any issues or

View File

@@ -7,9 +7,6 @@ Loop: test.jtx test.unit_test
Loop: xrpld.app xrpld.core
xrpld.app > xrpld.core
Loop: xrpld.app xrpld.ledger
xrpld.app > xrpld.ledger
Loop: xrpld.app xrpld.overlay
xrpld.overlay > xrpld.app

View File

@@ -2,6 +2,10 @@ libxrpl.basics > xrpl.basics
libxrpl.crypto > xrpl.basics
libxrpl.json > xrpl.basics
libxrpl.json > xrpl.json
libxrpl.ledger > xrpl.basics
libxrpl.ledger > xrpl.json
libxrpl.ledger > xrpl.ledger
libxrpl.ledger > xrpl.protocol
libxrpl.net > xrpl.basics
libxrpl.net > xrpl.net
libxrpl.protocol > xrpl.basics
@@ -21,11 +25,11 @@ test.app > test.unit_test
test.app > xrpl.basics
test.app > xrpld.app
test.app > xrpld.core
test.app > xrpld.ledger
test.app > xrpld.nodestore
test.app > xrpld.overlay
test.app > xrpld.rpc
test.app > xrpl.json
test.app > xrpl.ledger
test.app > xrpl.protocol
test.app > xrpl.resource
test.basics > test.jtx
@@ -44,8 +48,8 @@ test.consensus > test.unit_test
test.consensus > xrpl.basics
test.consensus > xrpld.app
test.consensus > xrpld.consensus
test.consensus > xrpld.ledger
test.consensus > xrpl.json
test.consensus > xrpl.ledger
test.core > test.jtx
test.core > test.toplevel
test.core > test.unit_test
@@ -63,9 +67,9 @@ test.json > xrpl.json
test.jtx > xrpl.basics
test.jtx > xrpld.app
test.jtx > xrpld.core
test.jtx > xrpld.ledger
test.jtx > xrpld.rpc
test.jtx > xrpl.json
test.jtx > xrpl.ledger
test.jtx > xrpl.net
test.jtx > xrpl.protocol
test.jtx > xrpl.resource
@@ -75,7 +79,7 @@ test.ledger > test.toplevel
test.ledger > xrpl.basics
test.ledger > xrpld.app
test.ledger > xrpld.core
test.ledger > xrpld.ledger
test.ledger > xrpl.ledger
test.ledger > xrpl.protocol
test.nodestore > test.jtx
test.nodestore > test.toplevel
@@ -134,7 +138,10 @@ test.toplevel > test.csf
test.toplevel > xrpl.json
test.unit_test > xrpl.basics
tests.libxrpl > xrpl.basics
tests.libxrpl > xrpl.net
xrpl.json > xrpl.basics
xrpl.ledger > xrpl.basics
xrpl.ledger > xrpl.protocol
xrpl.net > xrpl.basics
xrpl.protocol > xrpl.basics
xrpl.protocol > xrpl.json
@@ -151,6 +158,7 @@ xrpld.app > xrpld.consensus
xrpld.app > xrpld.nodestore
xrpld.app > xrpld.perflog
xrpld.app > xrpl.json
xrpld.app > xrpl.ledger
xrpld.app > xrpl.net
xrpld.app > xrpl.protocol
xrpld.app > xrpl.resource
@@ -163,9 +171,6 @@ xrpld.core > xrpl.basics
xrpld.core > xrpl.json
xrpld.core > xrpl.net
xrpld.core > xrpl.protocol
xrpld.ledger > xrpl.basics
xrpld.ledger > xrpl.json
xrpld.ledger > xrpl.protocol
xrpld.nodestore > xrpl.basics
xrpld.nodestore > xrpld.core
xrpld.nodestore > xrpld.unity
@@ -186,9 +191,9 @@ xrpld.perflog > xrpl.basics
xrpld.perflog > xrpl.json
xrpld.rpc > xrpl.basics
xrpld.rpc > xrpld.core
xrpld.rpc > xrpld.ledger
xrpld.rpc > xrpld.nodestore
xrpld.rpc > xrpl.json
xrpld.rpc > xrpl.ledger
xrpld.rpc > xrpl.net
xrpld.rpc > xrpl.protocol
xrpld.rpc > xrpl.resource

View File

@@ -74,14 +74,14 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
continue
# RHEL:
# - 9.4 using GCC 12: Debug and Unity on linux/amd64.
# - 9.6 using Clang: Release and no Unity on linux/amd64.
# - 9 using GCC 12: Debug and Unity on linux/amd64.
# - 10 using Clang: Release and no Unity on linux/amd64.
if os['distro_name'] == 'rhel':
skip = True
if os['distro_version'] == '9.4':
if os['distro_version'] == '9':
if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-12' and build_type == 'Debug' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64':
skip = False
elif os['distro_version'] == '9.6':
elif os['distro_version'] == '10':
if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-any' and build_type == 'Release' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64':
skip = False
if skip:
@@ -162,7 +162,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
'config_name': config_name,
'cmake_args': cmake_args,
'cmake_target': cmake_target,
'build_only': 'true' if build_only else 'false',
'build_only': build_only,
'build_type': build_type,
'os': os,
'architecture': architecture,

View File

@@ -14,139 +14,155 @@
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "12"
"compiler_version": "12",
"image_sha": "6f723eb"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "13"
"compiler_version": "13",
"image_sha": "6f723eb"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "14"
"compiler_version": "14",
"image_sha": "6f723eb"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "15"
"compiler_version": "15",
"image_sha": "6f723eb"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "16"
"compiler_version": "16",
"image_sha": "6f723eb"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "17"
"compiler_version": "17",
"image_sha": "6f723eb"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "18"
"compiler_version": "18",
"image_sha": "6f723eb"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "19"
"compiler_version": "19",
"image_sha": "6f723eb"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "20"
"compiler_version": "20",
"image_sha": "6f723eb"
},
{
"distro_name": "rhel",
"distro_version": "9.4",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "12"
"compiler_version": "12",
"image_sha": "d133ce3"
},
{
"distro_name": "rhel",
"distro_version": "9.4",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "13"
"compiler_version": "13",
"image_sha": "d133ce3"
},
{
"distro_name": "rhel",
"distro_version": "9.4",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "14"
"compiler_version": "14",
"image_sha": "d133ce3"
},
{
"distro_name": "rhel",
"distro_version": "9.6",
"compiler_name": "gcc",
"compiler_version": "13"
},
{
"distro_name": "rhel",
"distro_version": "9.6",
"compiler_name": "gcc",
"compiler_version": "14"
},
{
"distro_name": "rhel",
"distro_version": "9.4",
"distro_version": "9",
"compiler_name": "clang",
"compiler_version": "any"
"compiler_version": "any",
"image_sha": "d133ce3"
},
{
"distro_name": "rhel",
"distro_version": "9.6",
"distro_version": "10",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "d133ce3"
},
{
"distro_name": "rhel",
"distro_version": "10",
"compiler_name": "clang",
"compiler_version": "any"
"compiler_version": "any",
"image_sha": "d133ce3"
},
{
"distro_name": "ubuntu",
"distro_version": "jammy",
"compiler_name": "gcc",
"compiler_version": "12"
"compiler_version": "12",
"image_sha": "6f723eb"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "gcc",
"compiler_version": "13"
"compiler_version": "13",
"image_sha": "6f723eb"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "gcc",
"compiler_version": "14"
"compiler_version": "14",
"image_sha": "6f723eb"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "16"
"compiler_version": "16",
"image_sha": "6f723eb"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "17"
"compiler_version": "17",
"image_sha": "6f723eb"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "18"
"compiler_version": "18",
"image_sha": "6f723eb"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "19"
"compiler_version": "19",
"image_sha": "6f723eb"
}
],
"build_type": ["Debug", "Release"],

View File

@@ -10,7 +10,8 @@
"distro_name": "macos",
"distro_version": "",
"compiler_name": "",
"compiler_version": ""
"compiler_version": "",
"image_sha": ""
}
],
"build_type": ["Debug", "Release"],

View File

@@ -2,7 +2,7 @@
"architecture": [
{
"platform": "windows/amd64",
"runner": ["windows-latest"]
"runner": ["self-hosted", "Windows", "devbox"]
}
],
"os": [
@@ -10,7 +10,8 @@
"distro_name": "windows",
"distro_version": "",
"compiler_name": "",
"compiler_version": ""
"compiler_version": "",
"image_sha": ""
}
],
"build_type": ["Debug", "Release"],

View File

@@ -1,146 +0,0 @@
# This workflow builds and tests the binary for various configurations.
name: Build and test
# This workflow can only be triggered by other workflows. Note that the
# workflow_call event does not support the 'choice' input type, see
# https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#onworkflow_callinputsinput_idtype,
# so we use 'string' instead.
on:
workflow_call:
inputs:
build_dir:
description: "The directory where to build."
required: false
type: string
default: ".build"
dependencies_force_build:
description: "Force building of all dependencies."
required: false
type: boolean
default: false
dependencies_force_upload:
description: "Force uploading of all dependencies."
required: false
type: boolean
default: false
os:
description: 'The operating system to use for the build ("linux", "macos", "windows").'
required: true
type: string
strategy_matrix:
# TODO: Support additional strategies, e.g. "ubuntu" for generating all Ubuntu configurations.
description: 'The strategy matrix to use for generating the configurations ("minimal", "all").'
required: false
type: string
default: "minimal"
secrets:
codecov_token:
description: "The Codecov token to use for uploading coverage reports."
required: false
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.os }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
# Generate the strategy matrix to be used by the following job.
generate-matrix:
uses: ./.github/workflows/reusable-strategy-matrix.yml
with:
os: ${{ inputs.os }}
strategy_matrix: ${{ inputs.strategy_matrix }}
# Build and test the binary.
build-test:
needs:
- generate-matrix
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
runs-on: ${{ matrix.architecture.runner }}
container: ${{ inputs.os == 'linux' && format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version) || null }}
steps:
- name: Check strategy matrix
run: |
echo 'Operating system distro name: ${{ matrix.os.distro_name }}'
echo 'Operating system distro version: ${{ matrix.os.distro_version }}'
echo 'Operating system compiler name: ${{ matrix.os.compiler_name }}'
echo 'Operating system compiler version: ${{ matrix.os.compiler_version }}'
echo 'Architecture platform: ${{ matrix.architecture.platform }}'
echo 'Architecture runner: ${{ toJson(matrix.architecture.runner) }}'
echo 'Build type: ${{ matrix.build_type }}'
echo 'Build only: ${{ matrix.build_only }}'
echo 'CMake arguments: ${{ matrix.cmake_args }}'
echo 'CMake target: ${{ matrix.cmake_target }}'
echo 'Config name: ${{ matrix.config_name }}'
- name: Cleanup workspace
if: ${{ runner.os == 'macOS' }}
uses: XRPLF/actions/.github/actions/cleanup-workspace@3f044c7478548e3c32ff68980eeb36ece02b364e
- name: Checkout repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Prepare runner
uses: XRPLF/actions/.github/actions/prepare-runner@638e0dc11ea230f91bd26622fb542116bb5254d5
with:
disable_ccache: false
- name: Check configuration (Windows)
if: ${{ inputs.os == 'windows' }}
run: |
echo 'Checking environment variables.'
set
echo 'Checking CMake version.'
cmake --version
echo 'Checking Conan version.'
conan --version
- name: Check configuration (Linux and MacOS)
if: ${{ inputs.os == 'linux' || inputs.os == 'macos' }}
run: |
echo 'Checking path.'
echo ${PATH} | tr ':' '\n'
echo 'Checking environment variables.'
env | sort
echo 'Checking CMake version.'
cmake --version
echo 'Checking compiler version.'
${{ inputs.os == 'linux' && '${CC}' || 'clang' }} --version
echo 'Checking Conan version.'
conan --version
echo 'Checking Ninja version.'
ninja --version
echo 'Checking nproc version.'
nproc --version
- name: Setup Conan
uses: ./.github/actions/setup-conan
- name: Build dependencies
uses: ./.github/actions/build-deps
with:
build_dir: ${{ inputs.build_dir }}
build_type: ${{ matrix.build_type }}
force_build: ${{ inputs.dependencies_force_build }}
- name: Build and test binary
uses: ./.github/actions/build-test
with:
build_dir: ${{ inputs.build_dir }}
build_only: ${{ matrix.build_only }}
build_type: ${{ matrix.build_type }}
cmake_args: ${{ matrix.cmake_args }}
cmake_target: ${{ matrix.cmake_target }}
codecov_token: ${{ secrets.codecov_token }}
os: ${{ inputs.os }}

View File

@@ -50,8 +50,8 @@ jobs:
files: |
# These paths are unique to `on-pr.yml`.
.github/scripts/levelization/**
.github/workflows/check-levelization.yml
.github/workflows/notify-clio.yml
.github/workflows/reusable-check-levelization.yml
.github/workflows/reusable-notify-clio.yml
.github/workflows/on-pr.yml
# Keep the paths below in sync with those in `on-trigger.yml`.
@@ -59,8 +59,11 @@ jobs:
.github/actions/build-test/**
.github/actions/setup-conan/**
.github/scripts/strategy-matrix/**
.github/workflows/build-test.yml
.github/workflows/reusable-build.yml
.github/workflows/reusable-build-test-config.yml
.github/workflows/reusable-build-test.yml
.github/workflows/reusable-strategy-matrix.yml
.github/workflows/reusable-test.yml
.codecov.yml
cmake/**
conan/**
@@ -93,26 +96,26 @@ jobs:
check-levelization:
needs: should-run
if: ${{ needs.should-run.outputs.go == 'true' }}
uses: ./.github/workflows/check-levelization.yml
uses: ./.github/workflows/reusable-check-levelization.yml
build-test:
needs: should-run
if: ${{ needs.should-run.outputs.go == 'true' }}
uses: ./.github/workflows/build-test.yml
uses: ./.github/workflows/reusable-build-test.yml
strategy:
matrix:
os: [linux, macos, windows]
with:
os: ${{ matrix.os }}
secrets:
codecov_token: ${{ secrets.CODECOV_TOKEN }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
notify-clio:
needs:
- should-run
- build-test
if: ${{ needs.should-run.outputs.go == 'true' && contains(fromJSON('["release", "master"]'), github.ref_name) }}
uses: ./.github/workflows/notify-clio.yml
uses: ./.github/workflows/reusable-notify-clio.yml
secrets:
clio_notify_token: ${{ secrets.CLIO_NOTIFY_TOKEN }}
conan_remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}

View File

@@ -14,7 +14,7 @@ on:
- master
paths:
# These paths are unique to `on-trigger.yml`.
- ".github/workflows/check-missing-commits.yml"
- ".github/workflows/reusable-check-missing-commits.yml"
- ".github/workflows/on-trigger.yml"
- ".github/workflows/publish-docs.yml"
@@ -23,8 +23,11 @@ on:
- ".github/actions/build-test/**"
- ".github/actions/setup-conan/**"
- ".github/scripts/strategy-matrix/**"
- ".github/workflows/build-test.yml"
- ".github/workflows/reusable-build.yml"
- ".github/workflows/reusable-build-test-config.yml"
- ".github/workflows/reusable-build-test.yml"
- ".github/workflows/reusable-strategy-matrix.yml"
- ".github/workflows/reusable-test.yml"
- ".codecov.yml"
- "cmake/**"
- "conan/**"
@@ -43,22 +46,8 @@ on:
schedule:
- cron: "32 6 * * 1-5"
# Run when manually triggered via the GitHub UI or API. If `force_upload` is
# true, then the dependencies that were missing (`force_rebuild` is false) or
# rebuilt (`force_rebuild` is true) will be uploaded, overwriting existing
# dependencies if needed.
# Run when manually triggered via the GitHub UI or API.
workflow_dispatch:
inputs:
dependencies_force_build:
description: "Force building of all dependencies."
required: false
type: boolean
default: false
dependencies_force_upload:
description: "Force uploading of all dependencies."
required: false
type: boolean
default: false
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -71,15 +60,15 @@ defaults:
jobs:
check-missing-commits:
if: ${{ github.event_name == 'push' && github.ref_type == 'branch' && contains(fromJSON('["develop", "release"]'), github.ref_name) }}
uses: ./.github/workflows/check-missing-commits.yml
uses: ./.github/workflows/reusable-check-missing-commits.yml
build-test:
uses: ./.github/workflows/build-test.yml
uses: ./.github/workflows/reusable-build-test.yml
strategy:
matrix:
os: [linux, macos, windows]
with:
os: ${{ matrix.os }}
strategy_matrix: "minimal"
strategy_matrix: ${{ github.event_name == 'schedule' && 'all' || 'minimal' }}
secrets:
codecov_token: ${{ secrets.CODECOV_TOKEN }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -7,8 +7,9 @@ on:
workflow_dispatch:
jobs:
# Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks.
run-hooks:
uses: XRPLF/actions/.github/workflows/pre-commit.yml@af1b0f0d764cda2e5435f5ac97b240d4bd4d95d3
with:
runs_on: ubuntu-latest
container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit" }'
container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-d1496b8" }'

View File

@@ -27,7 +27,7 @@ env:
jobs:
publish:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/ci/tools-rippled-documentation
container: ghcr.io/xrplf/ci/tools-rippled-documentation:sha-d1496b8
permissions:
contents: write
steps:

View File

@@ -0,0 +1,69 @@
name: Build and test configuration
on:
workflow_call:
inputs:
build_dir:
description: "The directory where to build."
required: true
type: string
build_only:
description: 'Whether to only build or to build and test the code ("true", "false").'
required: true
type: boolean
build_type:
description: 'The build type to use ("Debug", "Release").'
type: string
required: true
cmake_args:
description: "Additional arguments to pass to CMake."
required: false
type: string
default: ""
cmake_target:
description: "The CMake target to build."
type: string
required: true
runs_on:
description: Runner to run the job on as a JSON string
required: true
type: string
image:
description: "The image to run in (leave empty to run natively)"
required: true
type: string
config_name:
description: "The configuration string (used for naming artifacts and such)."
required: true
type: string
secrets:
CODECOV_TOKEN:
description: "The Codecov token to use for uploading coverage reports."
required: true
jobs:
build:
uses: ./.github/workflows/reusable-build.yml
with:
build_dir: ${{ inputs.build_dir }}
build_type: ${{ inputs.build_type }}
cmake_args: ${{ inputs.cmake_args }}
cmake_target: ${{ inputs.cmake_target }}
runs_on: ${{ inputs.runs_on }}
image: ${{ inputs.image }}
config_name: ${{ inputs.config_name }}
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
test:
needs: build
uses: ./.github/workflows/reusable-test.yml
with:
run_tests: ${{ !inputs.build_only }}
verify_voidstar: ${{ contains(inputs.cmake_args, '-Dvoidstar=ON') }}
runs_on: ${{ inputs.runs_on }}
image: ${{ inputs.image }}
config_name: ${{ inputs.config_name }}

View File

@@ -0,0 +1,58 @@
# This workflow builds and tests the binary for various configurations.
name: Build and test
# This workflow can only be triggered by other workflows. Note that the
# workflow_call event does not support the 'choice' input type, see
# https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#onworkflow_callinputsinput_idtype,
# so we use 'string' instead.
on:
workflow_call:
inputs:
build_dir:
description: "The directory where to build."
required: false
type: string
default: ".build"
os:
description: 'The operating system to use for the build ("linux", "macos", "windows").'
required: true
type: string
strategy_matrix:
# TODO: Support additional strategies, e.g. "ubuntu" for generating all Ubuntu configurations.
description: 'The strategy matrix to use for generating the configurations ("minimal", "all").'
required: false
type: string
default: "minimal"
secrets:
CODECOV_TOKEN:
description: "The Codecov token to use for uploading coverage reports."
required: true
jobs:
# Generate the strategy matrix to be used by the following job.
generate-matrix:
uses: ./.github/workflows/reusable-strategy-matrix.yml
with:
os: ${{ inputs.os }}
strategy_matrix: ${{ inputs.strategy_matrix }}
# Build and test the binary for each configuration.
build-test-config:
needs:
- generate-matrix
uses: ./.github/workflows/reusable-build-test-config.yml
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
max-parallel: 10
with:
build_dir: ${{ inputs.build_dir }}
build_only: ${{ matrix.build_only }}
build_type: ${{ matrix.build_type }}
cmake_args: ${{ matrix.cmake_args }}
cmake_target: ${{ matrix.cmake_target }}
runs_on: ${{ toJSON(matrix.architecture.runner) }}
image: ${{ contains(matrix.architecture.platform, 'linux') && format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}-sha-{4}', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version, matrix.os.image_sha) || '' }}
config_name: ${{ matrix.config_name }}
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

121
.github/workflows/reusable-build.yml vendored Normal file
View File

@@ -0,0 +1,121 @@
name: Build rippled
on:
workflow_call:
inputs:
build_dir:
description: "The directory where to build."
required: true
type: string
build_type:
description: 'The build type to use ("Debug", "Release").'
required: true
type: string
cmake_args:
description: "Additional arguments to pass to CMake."
required: true
type: string
cmake_target:
description: "The CMake target to build."
required: true
type: string
runs_on:
description: Runner to run the job on as a JSON string
required: true
type: string
image:
description: "The image to run in (leave empty to run natively)"
required: true
type: string
config_name:
description: "The name of the configuration."
required: true
type: string
secrets:
CODECOV_TOKEN:
description: "The Codecov token to use for uploading coverage reports."
required: true
defaults:
run:
shell: bash
jobs:
build:
name: Build ${{ inputs.config_name }}
runs-on: ${{ fromJSON(inputs.runs_on) }}
container: ${{ inputs.image != '' && inputs.image || null }}
steps:
- name: Cleanup workspace
if: ${{ runner.os == 'macOS' }}
uses: XRPLF/actions/.github/actions/cleanup-workspace@3f044c7478548e3c32ff68980eeb36ece02b364e
- name: Checkout repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Prepare runner
uses: XRPLF/actions/.github/actions/prepare-runner@638e0dc11ea230f91bd26622fb542116bb5254d5
with:
disable_ccache: false
- name: Print build environment
uses: ./.github/actions/print-env
- name: Setup Conan
uses: ./.github/actions/setup-conan
- name: Build dependencies
uses: ./.github/actions/build-deps
with:
build_dir: ${{ inputs.build_dir }}
build_type: ${{ inputs.build_type }}
- name: Configure CMake
shell: bash
working-directory: ${{ inputs.build_dir }}
env:
BUILD_TYPE: ${{ inputs.build_type }}
CMAKE_ARGS: ${{ inputs.cmake_args }}
run: |
cmake \
-G '${{ runner.os == 'Windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
${{ env.CMAKE_ARGS }} \
..
- name: Build the binary
shell: bash
working-directory: ${{ inputs.build_dir }}
env:
BUILD_TYPE: ${{ inputs.build_type }}
CMAKE_TARGET: ${{ inputs.cmake_target }}
run: |
cmake \
--build . \
--config ${{ env.BUILD_TYPE }} \
--parallel $(nproc) \
--target ${{ env.CMAKE_TARGET }}
- name: Upload rippled artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: rippled-${{ inputs.config_name }}
path: ${{ inputs.build_dir }}/${{ runner.os == 'Windows' && inputs.build_type || '' }}/rippled${{ runner.os == 'Windows' && '.exe' || '' }}
retention-days: 3
if-no-files-found: error
- name: Upload coverage report
if: ${{ inputs.cmake_target == 'coverage' }}
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
with:
disable_search: true
disable_telem: true
fail_ci_if_error: true
files: ${{ inputs.build_dir }}/coverage.xml
plugins: noop
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true

View File

@@ -40,47 +40,50 @@ jobs:
upload:
if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
runs-on: ubuntu-latest
container: ghcr.io/xrplf/ci/ubuntu-noble:gcc-13
container: ghcr.io/xrplf/ci/ubuntu-noble:gcc-13-sha-5dd7158
steps:
- name: Checkout repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Generate outputs
id: generate
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
echo 'Generating user and channel.'
echo "user=clio" >> "${GITHUB_OUTPUT}"
echo "channel=pr_${{ github.event.pull_request.number }}" >> "${GITHUB_OUTPUT}"
echo "channel=pr_${{ env.PR_NUMBER }}" >> "${GITHUB_OUTPUT}"
echo 'Extracting version.'
echo "version=$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')" >> "${GITHUB_OUTPUT}"
- name: Calculate conan reference
id: conan_ref
run: |
echo "conan_ref=${{ steps.generate.outputs.version }}@${{ steps.generate.outputs.user }}/${{ steps.generate.outputs.channel }}" >> "${GITHUB_OUTPUT}"
- name: Set up Conan
uses: ./.github/actions/setup-conan
with:
conan_remote_name: ${{ inputs.conan_remote_name }}
conan_remote_url: ${{ inputs.conan_remote_url }}
- name: Log into Conan remote
run: conan remote login ${{ inputs.conan_remote_name }} "${{ secrets.conan_remote_username }}" --password "${{ secrets.conan_remote_password }}"
- name: Upload package
env:
CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
run: |
conan export --user=${{ steps.generate.outputs.user }} --channel=${{ steps.generate.outputs.channel }} .
conan upload --confirm --check --remote=${{ inputs.conan_remote_name }} xrpl/${{ steps.conan_ref.outputs.conan_ref }}
conan upload --confirm --check --remote=${{ env.CONAN_REMOTE_NAME }} xrpl/${{ steps.conan_ref.outputs.conan_ref }}
outputs:
conan_ref: ${{ steps.conan_ref.outputs.conan_ref }}
notify:
needs: upload
runs-on: ubuntu-latest
env:
GH_TOKEN: ${{ secrets.clio_notify_token }}
steps:
- name: Notify Clio
env:
GH_TOKEN: ${{ secrets.clio_notify_token }}
PR_URL: ${{ github.event.pull_request.html_url }}
run: |
gh api --method POST -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \
/repos/xrplf/clio/dispatches -f "event_type=check_libxrpl" \
-F "client_payload[conan_ref]=${{ needs.upload.outputs.conan_ref }}" \
-F "client_payload[pr_url]=${{ github.event.pull_request.html_url }}"
-F "client_payload[pr_url]=${{ env.PR_URL }}"

View File

@@ -35,4 +35,7 @@ jobs:
- name: Generate strategy matrix
working-directory: .github/scripts/strategy-matrix
id: generate
run: ./generate.py ${{ inputs.strategy_matrix == 'all' && '--all' || '' }} ${{ inputs.os != '' && format('--config={0}.json', inputs.os) || '' }} >> "${GITHUB_OUTPUT}"
env:
GENERATE_CONFIG: ${{ inputs.os != '' && format('--config={0}.json', inputs.os) || '' }}
GENERATE_OPTION: ${{ inputs.strategy_matrix == 'all' && '--all' || '' }}
run: ./generate.py ${{ env.GENERATE_OPTION }} ${{ env.GENERATE_CONFIG }} >> "${GITHUB_OUTPUT}"

69
.github/workflows/reusable-test.yml vendored Normal file
View File

@@ -0,0 +1,69 @@
name: Test rippled
on:
workflow_call:
inputs:
verify_voidstar:
description: "Whether to verify the presence of voidstar instrumentation."
required: true
type: boolean
run_tests:
description: "Whether to run unit tests"
required: true
type: boolean
runs_on:
description: Runner to run the job on as a JSON string
required: true
type: string
image:
description: "The image to run in (leave empty to run natively)"
required: true
type: string
config_name:
description: "The name of the configuration."
required: true
type: string
jobs:
test:
name: Test ${{ inputs.config_name }}
runs-on: ${{ fromJSON(inputs.runs_on) }}
container: ${{ inputs.image != '' && inputs.image || null }}
steps:
- name: Download rippled artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: rippled-${{ inputs.config_name }}
- name: Make binary executable (Linux and macOS)
shell: bash
if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }}
run: |
chmod +x ./rippled
- name: Check linking (Linux)
if: ${{ runner.os == 'Linux' }}
shell: bash
run: |
ldd ./rippled
if [ "$(ldd ./rippled | grep -E '(libstdc\+\+|libgcc)' | wc -l)" -eq 0 ]; then
echo 'The binary is statically linked.'
else
echo 'The binary is dynamically linked.'
exit 1
fi
- name: Verifying presence of instrumentation
if: ${{ inputs.verify_voidstar }}
shell: bash
run: |
./rippled --version | grep libvoidstar
- name: Test the binary
if: ${{ inputs.run_tests }}
shell: bash
run: |
./rippled --unittest --unittest-jobs $(nproc)
ctest -j $(nproc) --output-on-failure

View File

@@ -24,13 +24,10 @@ on:
branches: [develop]
paths:
- .github/workflows/upload-conan-deps.yml
- .github/workflows/reusable-strategy-matrix.yml
- .github/actions/build-deps/action.yml
- .github/actions/setup-conan/action.yml
- ".github/scripts/strategy-matrix/**"
- conanfile.py
- conan.lock
@@ -43,11 +40,13 @@ concurrency:
cancel-in-progress: true
jobs:
# Generate the strategy matrix to be used by the following job.
generate-matrix:
uses: ./.github/workflows/reusable-strategy-matrix.yml
with:
strategy_matrix: ${{ github.event_name == 'pull_request' && 'minimal' || 'all' }}
# Build and upload the dependencies for each configuration.
run-upload-conan-deps:
needs:
- generate-matrix
@@ -56,8 +55,7 @@ jobs:
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
max-parallel: 10
runs-on: ${{ matrix.architecture.runner }}
container: ${{ contains(matrix.architecture.platform, 'linux') && format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version) || null }}
container: ${{ contains(matrix.architecture.platform, 'linux') && format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}-sha-{4}', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version, matrix.os.image_sha) || null }}
steps:
- name: Cleanup workspace
if: ${{ runner.os == 'macOS' }}
@@ -88,4 +86,6 @@ jobs:
- name: Upload Conan packages
if: ${{ github.repository_owner == 'XRPLF' && github.event_name != 'pull_request' && github.event_name != 'schedule' }}
run: conan upload "*" -r=${{ env.CONAN_REMOTE_NAME }} --confirm ${{ github.event.inputs.force_upload == 'true' && '--force' || '' }}
env:
FORCE_OPTION: ${{ github.event.inputs.force_upload == 'true' && '--force' || '' }}
run: conan upload "*" --remote='${{ env.CONAN_REMOTE_NAME }}' --confirm ${{ env.FORCE_OPTION }}

2
.gitignore vendored
View File

@@ -111,5 +111,3 @@ bld.rippled/
# Suggested in-tree build directory
/.build*/
cmake-build-debug-event-trace/*

View File

@@ -119,7 +119,6 @@ endif()
find_package(nudb REQUIRED)
find_package(date REQUIRED)
find_package(BLAKE3 REQUIRED)
find_package(xxHash REQUIRED)
target_link_libraries(ripple_libs INTERFACE

View File

@@ -61,7 +61,6 @@ target_link_libraries(xrpl.imports.main
absl::random_random
date::date
ed25519::ed25519
BLAKE3::blake3
secp256k1::secp256k1
xrpl.libpb
xxHash::xxhash
@@ -112,6 +111,12 @@ target_link_libraries(xrpl.libxrpl.net PUBLIC
add_module(xrpl server)
target_link_libraries(xrpl.libxrpl.server PUBLIC xrpl.libxrpl.protocol)
add_module(xrpl ledger)
target_link_libraries(xrpl.libxrpl.ledger PUBLIC
xrpl.libxrpl.basics
xrpl.libxrpl.json
xrpl.libxrpl.protocol
)
add_library(xrpl.libxrpl)
set_target_properties(xrpl.libxrpl PROPERTIES OUTPUT_NAME xrpl)
@@ -132,6 +137,7 @@ target_link_modules(xrpl PUBLIC
resource
server
net
ledger
)
# All headers in libxrpl are in modules.

View File

@@ -33,7 +33,7 @@ setup_target_for_coverage_gcovr(
FORMAT ${coverage_format}
EXECUTABLE rippled
EXECUTABLE_ARGS --unittest$<$<BOOL:${coverage_test}>:=${coverage_test}> --unittest-jobs ${coverage_test_parallelism} --quiet --unittest-log
EXCLUDE "src/test" "include/xrpl/beast/test" "include/xrpl/beast/unit_test" "${CMAKE_BINARY_DIR}/pb-xrpl.libpb"
EXCLUDE "src/test" "src/tests" "include/xrpl/beast/test" "include/xrpl/beast/unit_test" "${CMAKE_BINARY_DIR}/pb-xrpl.libpb"
DEPENDENCIES rippled
)

View File

@@ -18,6 +18,7 @@ install (
xrpl.libxrpl.json
xrpl.libxrpl.protocol
xrpl.libxrpl.resource
xrpl.libxrpl.ledger
xrpl.libxrpl.server
xrpl.libxrpl.net
xrpl.libxrpl

View File

@@ -2,14 +2,14 @@
"version": "0.5",
"requires": [
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1756234269.497",
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1743678659.187",
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1756234289.683",
"sqlite3/3.49.1#8631739a4c9b93bd3d6b753bac548a63%1756234266.869",
"soci/4.0.3#a9f8d773cd33e356b5879a4b0564f287%1756234262.318",
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1756234314.246",
"rocksdb/10.0.1#85537f46e538974d67da0c3977de48ac%1744110653.645",
"rocksdb/10.0.1#85537f46e538974d67da0c3977de48ac%1756234304.347",
"re2/20230301#dfd6e2bf050eb90ddd8729cfb4c844a4%1756234257.976",
"protobuf/3.21.12#d927114e28de9f4691a6bbcdd9a529d1%1756234251.614",
"openssl/3.5.2#0c5a5e15ae569f45dff57adcf1770cf7%1756234259.61",
"openssl/3.6.0#89e8af1d4a21afcac0557079d23d8890%1759746682.365",
"nudb/2.0.9#c62cfd501e57055a7e0d8ee3d5e5427d%1756234237.107",
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1756234228.999",
"libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1756223727.64",
@@ -17,12 +17,11 @@
"libarchive/3.8.1#5cf685686322e906cb42706ab7e099a8%1756234256.696",
"jemalloc/5.3.0#e951da9cf599e956cebc117880d2d9f8%1729241615.244",
"grpc/1.50.1#02291451d1e17200293a409410d1c4e1%1756234248.958",
"doctest/2.4.11#a4211dfc329a16ba9f280f9574025659%1681601797.282",
"date/3.0.4#f74bbba5a08fa388256688743136cb6f%1748457219.54",
"doctest/2.4.11#a4211dfc329a16ba9f280f9574025659%1756234220.819",
"date/3.0.4#f74bbba5a08fa388256688743136cb6f%1756234217.493",
"c-ares/1.34.5#b78b91e7cfb1f11ce777a285bbf169c6%1756234217.915",
"bzip2/1.0.8#00b4a4658791c1f06914e087f0e792f5%1756234261.716",
"boost/1.88.0#8852c0b72ce8271fb8ff7c53456d4983%1756223752.326",
"blake3/1.5.0#af8dc8cf8dc55bfca24686b52dc137db%1758046610.912948",
"abseil/20230802.1#f0f91485b111dc9837a68972cb19ca7b%1756234220.907"
],
"build_requires": [

View File

@@ -27,10 +27,9 @@ class Xrpl(ConanFile):
'grpc/1.50.1',
'libarchive/3.8.1',
'nudb/2.0.9',
'openssl/3.5.2',
'openssl/3.6.0',
'soci/4.0.3',
'zlib/1.3.1',
'blake3/1.5.0',
]
test_requires = [

View File

@@ -1,10 +0,0 @@
sources:
"1.5.0":
url: "https://github.com/BLAKE3-team/BLAKE3/archive/refs/tags/1.5.0.tar.gz"
sha256: "f506140bc3af41d3432a4ce18b3b83b08eaa240e94ef161eb72b2e57cdc94c69"
"1.4.1":
url: "https://github.com/BLAKE3-team/BLAKE3/archive/refs/tags/1.4.1.tar.gz"
sha256: "33020ac83a8169b2e847cc6fb1dd38806ffab6efe79fe6c320e322154a3bea2c"
"1.4.0":
url: "https://github.com/BLAKE3-team/BLAKE3/archive/refs/tags/1.4.0.tar.gz"
sha256: "658e1c75e2d9bbed9f426385f02d2a188dc19978a39e067ba93e837861e5fe58"

View File

@@ -1,102 +0,0 @@
from conan import ConanFile
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
from conan.tools.files import copy, get
from conan.tools.scm import Version
import os
required_conan_version = ">=1.54.0"
class Blake3Conan(ConanFile):
name = "blake3"
version = "1.5.0"
description = "BLAKE3 cryptographic hash function"
topics = ("blake3", "hash", "cryptography")
url = "https://github.com/BLAKE3-team/BLAKE3"
homepage = "https://github.com/BLAKE3-team/BLAKE3"
license = "CC0-1.0 OR Apache-2.0"
package_type = "library"
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
"fPIC": [True, False],
"simd": [True, False],
}
default_options = {
"shared": False,
"fPIC": True,
"simd": True,
}
def config_options(self):
if self.settings.os == 'Windows':
del self.options.fPIC
def configure(self):
if self.options.shared:
self.options.rm_safe("fPIC")
# BLAKE3 is C code
self.settings.rm_safe("compiler.cppstd")
self.settings.rm_safe("compiler.libcxx")
def layout(self):
cmake_layout(self, src_folder="src")
def source(self):
get(self, **self.conan_data["sources"][self.version], strip_root=True)
def generate(self):
tc = CMakeToolchain(self)
# BLAKE3's CMake options
tc.variables["BUILD_SHARED_LIBS"] = self.options.shared
if not self.options.simd:
tc.variables["BLAKE3_NO_SSE2"] = True
tc.variables["BLAKE3_NO_SSE41"] = True
tc.variables["BLAKE3_NO_AVX2"] = True
tc.variables["BLAKE3_NO_AVX512"] = True
tc.variables["BLAKE3_NO_NEON"] = True
tc.generate()
def build(self):
cmake = CMake(self)
# BLAKE3's C implementation has its CMakeLists.txt in the c/ subdirectory
cmake.configure(build_script_folder=os.path.join(self.source_folder, "c"))
cmake.build()
def package(self):
# Copy license files
copy(self, "LICENSE*", src=self.source_folder,
dst=os.path.join(self.package_folder, "licenses"))
# Copy header
copy(self, "blake3.h",
src=os.path.join(self.source_folder, "c"),
dst=os.path.join(self.package_folder, "include"))
# Copy library
copy(self, "*.a", src=self.build_folder,
dst=os.path.join(self.package_folder, "lib"), keep_path=False)
copy(self, "*.lib", src=self.build_folder,
dst=os.path.join(self.package_folder, "lib"), keep_path=False)
copy(self, "*.dylib", src=self.build_folder,
dst=os.path.join(self.package_folder, "lib"), keep_path=False)
copy(self, "*.so*", src=self.build_folder,
dst=os.path.join(self.package_folder, "lib"), keep_path=False)
copy(self, "*.dll", src=self.build_folder,
dst=os.path.join(self.package_folder, "bin"), keep_path=False)
def package_info(self):
self.cpp_info.set_property("cmake_file_name", "BLAKE3")
self.cpp_info.set_property("cmake_target_name", "BLAKE3::blake3")
# IMPORTANT: Explicitly set include directories to fix Conan CMakeDeps generation
self.cpp_info.includedirs = ["include"]
self.cpp_info.libs = ["blake3"]
# System libraries
if self.settings.os in ["Linux", "FreeBSD"]:
self.cpp_info.system_libs.append("m")
self.cpp_info.system_libs.append("pthread")
# TODO: to remove in conan v2 once cmake_find_package* generators removed
self.cpp_info.names["cmake_find_package"] = "BLAKE3"
self.cpp_info.names["cmake_find_package_multi"] = "BLAKE3"

View File

@@ -654,12 +654,14 @@ SharedWeakUnion<T>::convertToWeak()
break;
case destroy:
// We just added a weak ref. How could we destroy?
// LCOV_EXCL_START
UNREACHABLE(
"ripple::SharedWeakUnion::convertToWeak : destroying freshly "
"added ref");
delete p;
unsafeSetRawPtr(nullptr);
return true; // Should never happen
// LCOV_EXCL_STOP
case partialDestroy:
// This is a weird case. We just converted the last strong
// pointer to a weak pointer.

View File

@@ -632,6 +632,16 @@ 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)
{
static_assert(
base_uint<Bits, Tag>::bytes > 4,
"For 4 bytes or less, use a native type");
return strHex(a.cbegin(), a.cbegin() + 4) + "...";
}
template <std::size_t Bits, class Tag>
inline std::ostream&
operator<<(std::ostream& out, base_uint<Bits, Tag> const& u)

View File

@@ -28,9 +28,8 @@ namespace ripple {
// the destination can hold all values of the source. This is particularly
// handy when the source or destination is an enumeration type.
template <class Dest, class Src>
static constexpr bool is_safetocasttovalue_v =
(std::is_integral_v<Src> && std::is_integral_v<Dest>) &&
template <class Src, class Dest>
concept SafeToCast = (std::is_integral_v<Src> && std::is_integral_v<Dest>) &&
(std::is_signed<Src>::value || std::is_unsigned<Dest>::value) &&
(std::is_signed<Src>::value != std::is_signed<Dest>::value
? sizeof(Dest) > sizeof(Src)
@@ -78,7 +77,7 @@ inline constexpr std::
unsafe_cast(Src s) noexcept
{
static_assert(
!is_safetocasttovalue_v<Dest, Src>,
!SafeToCast<Src, Dest>,
"Only unsafe if casting signed to unsigned or "
"destination is too small");
return static_cast<Dest>(s);

View File

@@ -94,7 +94,11 @@ hash_append(Hasher& h, beast::IP::Address const& addr) noexcept
else if (addr.is_v6())
hash_append(h, addr.to_v6().to_bytes());
else
{
// LCOV_EXCL_START
UNREACHABLE("beast::hash_append : invalid address type");
// LCOV_EXCL_STOP
}
}
} // namespace beast

View File

@@ -39,11 +39,16 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#endif
#define XRPL_ASSERT ALWAYS_OR_UNREACHABLE
#define XRPL_ASSERT_PARTS(cond, function, description, ...) \
XRPL_ASSERT(cond, function " : " description)
// How to use the instrumentation macros:
//
// * XRPL_ASSERT if cond must be true but the line might not be reached during
// fuzzing. Same like `assert` in normal use.
// * XRPL_ASSERT_PARTS is for convenience, and works like XRPL_ASSERT, but
// splits the message param into "function" and "description", then joins
// them with " : " before passing to XRPL_ASSERT.
// * ALWAYS if cond must be true _and_ the line must be reached during fuzzing.
// Same like `assert` in normal use.
// * REACHABLE if the line must be reached during fuzzing

View File

@@ -20,11 +20,10 @@
#ifndef RIPPLE_LEDGER_APPLYVIEW_H_INCLUDED
#define RIPPLE_LEDGER_APPLYVIEW_H_INCLUDED
#include <xrpld/ledger/RawView.h>
#include <xrpld/ledger/ReadView.h>
#include <xrpl/basics/safe_cast.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/ledger/RawView.h>
#include <xrpl/ledger/ReadView.h>
namespace ripple {
@@ -285,12 +284,14 @@ public:
{
if (key.type != ltOFFER)
{
// LCOV_EXCL_START
UNREACHABLE(
"ripple::ApplyView::dirAppend : only Offers are appended to "
"book directories");
// Only Offers are appended to book directories. Call dirInsert()
// instead
return std::nullopt;
// LCOV_EXCL_STOP
}
return dirAdd(true, directory, key.key, describe);
}
@@ -386,6 +387,45 @@ public:
emptyDirDelete(Keylet const& directory);
};
namespace directory {
/** Helper functions for managing low-level directory operations.
These are not part of the ApplyView interface.
Don't use them unless you really, really know what you're doing.
Instead use dirAdd, dirInsert, etc.
*/
std::uint64_t
createRoot(
ApplyView& view,
Keylet const& directory,
uint256 const& key,
std::function<void(std::shared_ptr<SLE> const&)> const& describe);
auto
findPreviousPage(ApplyView& view, Keylet const& directory, SLE::ref start);
std::uint64_t
insertKey(
ApplyView& view,
SLE::ref node,
std::uint64_t page,
bool preserveOrder,
STVector256& indexes,
uint256 const& key);
std::optional<std::uint64_t>
insertPage(
ApplyView& view,
std::uint64_t page,
SLE::pointer node,
std::uint64_t nextPage,
SLE::ref next,
uint256 const& key,
Keylet const& directory,
std::function<void(std::shared_ptr<SLE> const&)> const& describe);
} // namespace directory
} // namespace ripple
#endif

View File

@@ -20,9 +20,8 @@
#ifndef RIPPLE_LEDGER_APPLYVIEWIMPL_H_INCLUDED
#define RIPPLE_LEDGER_APPLYVIEWIMPL_H_INCLUDED
#include <xrpld/ledger/OpenView.h>
#include <xrpld/ledger/detail/ApplyViewBase.h>
#include <xrpl/ledger/OpenView.h>
#include <xrpl/ledger/detail/ApplyViewBase.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/TER.h>

View File

@@ -20,9 +20,8 @@
#ifndef RIPPLE_LEDGER_BOOK_DIRS_H_INCLUDED
#define RIPPLE_LEDGER_BOOK_DIRS_H_INCLUDED
#include <xrpld/ledger/ReadView.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/ledger/ReadView.h>
namespace ripple {

View File

@@ -20,10 +20,9 @@
#ifndef RIPPLE_LEDGER_CACHEDVIEW_H_INCLUDED
#define RIPPLE_LEDGER_CACHEDVIEW_H_INCLUDED
#include <xrpld/ledger/CachedSLEs.h>
#include <xrpld/ledger/ReadView.h>
#include <xrpl/basics/hardened_hash.h>
#include <xrpl/ledger/CachedSLEs.h>
#include <xrpl/ledger/ReadView.h>
#include <mutex>
#include <type_traits>

View File

@@ -20,12 +20,11 @@
#ifndef RIPPLE_APP_MISC_CREDENTIALHELPERS_H_INCLUDED
#define RIPPLE_APP_MISC_CREDENTIALHELPERS_H_INCLUDED
#include <xrpld/ledger/ApplyView.h>
#include <xrpld/ledger/ReadView.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/STArray.h>
#include <xrpl/protocol/STTx.h>

View File

@@ -20,8 +20,7 @@
#ifndef RIPPLE_LEDGER_DIR_H_INCLUDED
#define RIPPLE_LEDGER_DIR_H_INCLUDED
#include <xrpld/ledger/ReadView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/Indexes.h>
namespace ripple {

View File

@@ -20,10 +20,9 @@
#ifndef RIPPLE_LEDGER_OPENVIEW_H_INCLUDED
#define RIPPLE_LEDGER_OPENVIEW_H_INCLUDED
#include <xrpld/ledger/RawView.h>
#include <xrpld/ledger/ReadView.h>
#include <xrpld/ledger/detail/RawStateTable.h>
#include <xrpl/ledger/RawView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/ledger/detail/RawStateTable.h>
#include <xrpl/protocol/STArray.h>
#include <xrpl/protocol/XRPAmount.h>

View File

@@ -20,10 +20,9 @@
#ifndef RIPPLE_LEDGER_PAYMENTSANDBOX_H_INCLUDED
#define RIPPLE_LEDGER_PAYMENTSANDBOX_H_INCLUDED
#include <xrpld/ledger/RawView.h>
#include <xrpld/ledger/Sandbox.h>
#include <xrpld/ledger/detail/ApplyViewBase.h>
#include <xrpl/ledger/RawView.h>
#include <xrpl/ledger/Sandbox.h>
#include <xrpl/ledger/detail/ApplyViewBase.h>
#include <xrpl/protocol/AccountID.h>
#include <map>

View File

@@ -20,8 +20,7 @@
#ifndef RIPPLE_LEDGER_RAWVIEW_H_INCLUDED
#define RIPPLE_LEDGER_RAWVIEW_H_INCLUDED
#include <xrpld/ledger/ReadView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/Serializer.h>

View File

@@ -20,10 +20,9 @@
#ifndef RIPPLE_LEDGER_READVIEW_H_INCLUDED
#define RIPPLE_LEDGER_READVIEW_H_INCLUDED
#include <xrpld/ledger/detail/ReadViewFwdRange.h>
#include <xrpl/basics/chrono.h>
#include <xrpl/beast/hash/uhash.h>
#include <xrpl/ledger/detail/ReadViewFwdRange.h>
#include <xrpl/protocol/Fees.h>
#include <xrpl/protocol/IOUAmount.h>
#include <xrpl/protocol/Indexes.h>
@@ -280,6 +279,6 @@ makeRulesGivenLedger(
} // namespace ripple
#include <xrpld/ledger/detail/ReadViewFwdRange.ipp>
#include <xrpl/ledger/detail/ReadViewFwdRange.ipp>
#endif

View File

@@ -20,8 +20,8 @@
#ifndef RIPPLE_LEDGER_SANDBOX_H_INCLUDED
#define RIPPLE_LEDGER_SANDBOX_H_INCLUDED
#include <xrpld/ledger/RawView.h>
#include <xrpld/ledger/detail/ApplyViewBase.h>
#include <xrpl/ledger/RawView.h>
#include <xrpl/ledger/detail/ApplyViewBase.h>
namespace ripple {

View File

@@ -20,11 +20,10 @@
#ifndef RIPPLE_LEDGER_VIEW_H_INCLUDED
#define RIPPLE_LEDGER_VIEW_H_INCLUDED
#include <xrpld/ledger/ApplyView.h>
#include <xrpld/ledger/OpenView.h>
#include <xrpld/ledger/ReadView.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/OpenView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/MPTIssue.h>
#include <xrpl/protocol/Protocol.h>
@@ -243,6 +242,80 @@ isDeepFrozen(
Currency const& currency,
AccountID const& issuer);
[[nodiscard]] inline bool
isDeepFrozen(
ReadView const& view,
AccountID const& account,
Issue const& issue,
int = 0 /*ignored*/)
{
return isDeepFrozen(view, account, issue.currency, issue.account);
}
[[nodiscard]] inline bool
isDeepFrozen(
ReadView const& view,
AccountID const& account,
MPTIssue const& mptIssue,
int depth = 0)
{
// Unlike IOUs, frozen / locked MPTs are not allowed to send or receive
// funds, so checking "deep frozen" is the same as checking "frozen".
return isFrozen(view, account, mptIssue, depth);
}
/**
* isFrozen check is recursive for MPT shares in a vault, descending to
* assets in the vault, up to maxAssetCheckDepth recursion depth. This is
* purely defensive, as we currently do not allow such vaults to be created.
*/
[[nodiscard]] inline bool
isDeepFrozen(
ReadView const& view,
AccountID const& account,
Asset const& asset,
int depth = 0)
{
return std::visit(
[&](auto const& issue) {
return isDeepFrozen(view, account, issue, depth);
},
asset.value());
}
[[nodiscard]] inline TER
checkDeepFrozen(
ReadView const& view,
AccountID const& account,
Issue const& issue)
{
return isDeepFrozen(view, account, issue) ? (TER)tecFROZEN
: (TER)tesSUCCESS;
}
[[nodiscard]] inline TER
checkDeepFrozen(
ReadView const& view,
AccountID const& account,
MPTIssue const& mptIssue)
{
return isDeepFrozen(view, account, mptIssue) ? (TER)tecLOCKED
: (TER)tesSUCCESS;
}
[[nodiscard]] inline TER
checkDeepFrozen(
ReadView const& view,
AccountID const& account,
Asset const& asset)
{
return std::visit(
[&](auto const& issue) {
return checkDeepFrozen(view, account, issue);
},
asset.value());
}
[[nodiscard]] bool
isLPTokenFrozen(
ReadView const& view,
@@ -534,7 +607,11 @@ dirNext(
describeOwnerDir(AccountID const& account);
[[nodiscard]] TER
dirLink(ApplyView& view, AccountID const& owner, std::shared_ptr<SLE>& object);
dirLink(
ApplyView& view,
AccountID const& owner,
std::shared_ptr<SLE>& object,
SF_UINT64 const& node = sfOwnerNode);
AccountID
pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey);
@@ -562,12 +639,28 @@ createPseudoAccount(
[[nodiscard]] bool
isPseudoAccount(std::shared_ptr<SLE const> sleAcct);
// Returns the list of fields that define an ACCOUNT_ROOT as a pseudo-account if
// set
// Pseudo-account designator fields MUST be maintained by including the
// SField::sMD_PseudoAccount flag in the SField definition. (Don't forget to
// "| SField::sMD_Default"!) The fields do NOT need to be amendment-gated,
// since a non-active amendment will not set any field, by definition.
// Specific properties of a pseudo-account are NOT checked here, that's what
// InvariantCheck is for.
[[nodiscard]] std::vector<SField const*> const&
getPseudoAccountFields();
[[nodiscard]] inline bool
isPseudoAccount(ReadView const& view, AccountID accountId)
{
return isPseudoAccount(view.read(keylet::account(accountId)));
}
[[nodiscard]] TER
canAddHolding(ReadView const& view, Asset const& asset);
/// Any transactors that call addEmptyHolding() in doApply must call
/// canAddHolding() in preflight with the same View and Asset
[[nodiscard]] TER
addEmptyHolding(
ApplyView& view,

View File

@@ -20,11 +20,10 @@
#ifndef RIPPLE_LEDGER_APPLYSTATETABLE_H_INCLUDED
#define RIPPLE_LEDGER_APPLYSTATETABLE_H_INCLUDED
#include <xrpld/ledger/OpenView.h>
#include <xrpld/ledger/RawView.h>
#include <xrpld/ledger/ReadView.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/ledger/OpenView.h>
#include <xrpl/ledger/RawView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxMeta.h>
#include <xrpl/protocol/XRPAmount.h>

View File

@@ -20,10 +20,9 @@
#ifndef RIPPLE_LEDGER_APPLYVIEWBASE_H_INCLUDED
#define RIPPLE_LEDGER_APPLYVIEWBASE_H_INCLUDED
#include <xrpld/ledger/ApplyView.h>
#include <xrpld/ledger/ReadView.h>
#include <xrpld/ledger/detail/ApplyStateTable.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/ledger/detail/ApplyStateTable.h>
#include <xrpl/protocol/XRPAmount.h>
namespace ripple {

View File

@@ -20,8 +20,8 @@
#ifndef RIPPLE_LEDGER_RAWSTATETABLE_H_INCLUDED
#define RIPPLE_LEDGER_RAWSTATETABLE_H_INCLUDED
#include <xrpld/ledger/RawView.h>
#include <xrpld/ledger/ReadView.h>
#include <xrpl/ledger/RawView.h>
#include <xrpl/ledger/ReadView.h>
#include <boost/container/pmr/monotonic_buffer_resource.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>

View File

@@ -1,565 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2019 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 BASICS_FEES_H_INCLUDED
#define BASICS_FEES_H_INCLUDED
#include <xrpl/basics/safe_cast.h>
#include <xrpl/beast/utility/Zero.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/json/json_value.h>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/operators.hpp>
#include <iosfwd>
#include <limits>
#include <optional>
namespace ripple {
namespace feeunit {
/** "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
used for calculations in this header. */
struct unitlessTag;
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> &&
std::is_object_v<typename T::value_type>>;
/** `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
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>;
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>>
{
public:
using unit_type = UnitTag;
using value_type = T;
private:
value_type fee_;
protected:
template <class Other>
static constexpr bool is_compatible_v =
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 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>>;
public:
TaggedFee() = default;
constexpr TaggedFee(TaggedFee const& other) = default;
constexpr TaggedFee&
operator=(TaggedFee const& other) = default;
constexpr explicit TaggedFee(beast::Zero) : fee_(0)
{
}
constexpr TaggedFee&
operator=(beast::Zero)
{
fee_ = 0;
return *this;
}
constexpr explicit TaggedFee(value_type fee) : fee_(fee)
{
}
TaggedFee&
operator=(value_type fee)
{
fee_ = fee;
return *this;
}
/** Instances with the same unit, and a type that is
"safe" to convert to this one can be converted
implicitly */
template <
class Other,
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 TaggedFee
operator*(value_type const& rhs) const
{
return TaggedFee{fee_ * rhs};
}
friend constexpr TaggedFee
operator*(value_type lhs, TaggedFee const& rhs)
{
// multiplication is commutative
return rhs * lhs;
}
constexpr value_type
operator/(TaggedFee const& rhs) const
{
return fee_ / rhs.fee_;
}
TaggedFee&
operator+=(TaggedFee const& other)
{
fee_ += other.fee();
return *this;
}
TaggedFee&
operator-=(TaggedFee const& other)
{
fee_ -= other.fee();
return *this;
}
TaggedFee&
operator++()
{
++fee_;
return *this;
}
TaggedFee&
operator--()
{
--fee_;
return *this;
}
TaggedFee&
operator*=(value_type const& rhs)
{
fee_ *= rhs;
return *this;
}
TaggedFee&
operator/=(value_type const& rhs)
{
fee_ /= rhs;
return *this;
}
template <class transparent = value_type>
std::enable_if_t<std::is_integral_v<transparent>, TaggedFee&>
operator%=(value_type const& rhs)
{
fee_ %= rhs;
return *this;
}
TaggedFee
operator-() const
{
static_assert(
std::is_signed_v<T>, "- operator illegal on unsigned fee types");
return TaggedFee{-fee_};
}
bool
operator==(TaggedFee const& other) const
{
return fee_ == other.fee_;
}
template <class Other, class = enable_if_compatible_t<Other>>
bool
operator==(TaggedFee<unit_type, Other> const& other) const
{
return fee_ == other.fee();
}
bool
operator==(value_type other) const
{
return fee_ == other;
}
template <class Other, class = enable_if_compatible_t<Other>>
bool
operator!=(TaggedFee<unit_type, Other> const& other) const
{
return !operator==(other);
}
bool
operator<(TaggedFee const& other) const
{
return fee_ < other.fee_;
}
/** Returns true if the amount is not zero */
explicit constexpr
operator bool() const noexcept
{
return fee_ != 0;
}
/** Return the sign of the amount */
constexpr int
signum() const noexcept
{
return (fee_ < 0) ? -1 : (fee_ ? 1 : 0);
}
/** Returns the number of drops */
constexpr value_type
fee() const
{
return fee_;
}
template <class Other>
constexpr double
decimalFromReference(TaggedFee<unit_type, Other> reference) const
{
return static_cast<double>(fee_) / reference.fee();
}
// `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>
jsonClipped() const
{
if constexpr (std::is_integral_v<value_type>)
{
using jsontype = std::conditional_t<
std::is_signed_v<value_type>,
Json::Int,
Json::UInt>;
constexpr auto min = std::numeric_limits<jsontype>::min();
constexpr auto max = std::numeric_limits<jsontype>::max();
if (fee_ < min)
return min;
if (fee_ > max)
return max;
return static_cast<jsontype>(fee_);
}
else
{
return fee_;
}
}
/** Returns the underlying value. Code SHOULD NOT call this
function unless the type has been abstracted away,
e.g. in a templated function.
*/
constexpr value_type
value() const
{
return fee_;
}
friend std::istream&
operator>>(std::istream& s, TaggedFee& val)
{
s >> val.fee_;
return s;
}
};
// Output Fees 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)
{
return os << q.value();
}
template <class UnitTag, class T>
std::string
to_string(TaggedFee<UnitTag, T> const& amount)
{
return std::to_string(amount.fee());
}
template <class Source, class = enable_if_unit_t<Source>>
constexpr bool can_muldiv_source_v =
std::is_convertible_v<typename Source::value_type, std::uint64_t>;
template <class Dest, class = enable_if_unit_t<Dest>>
constexpr bool can_muldiv_dest_v =
can_muldiv_source_v<Dest> && // Dest is also a source
std::is_convertible_v<std::uint64_t, typename Dest::value_type> &&
sizeof(typename Dest::value_type) >= sizeof(std::uint64_t);
template <
class Source1,
class Source2,
class = enable_if_unit_t<Source1>,
class = enable_if_unit_t<Source2>>
constexpr bool can_muldiv_sources_v =
can_muldiv_source_v<Source1> && can_muldiv_source_v<Source2> &&
std::is_same_v<typename Source1::unit_type, typename Source2::unit_type>;
template <
class Source1,
class Source2,
class Dest,
class = enable_if_unit_t<Source1>,
class = enable_if_unit_t<Source2>,
class = enable_if_unit_t<Dest>>
constexpr bool can_muldiv_v =
can_muldiv_sources_v<Source1, Source2> && can_muldiv_dest_v<Dest>;
// Source and Dest can be the same by default
template <
class Source1,
class Source2,
class Dest,
class = enable_if_unit_t<Source1>,
class = enable_if_unit_t<Source2>,
class = enable_if_unit_t<Dest>>
constexpr bool can_muldiv_commute_v = can_muldiv_v<Source1, Source2, Dest> &&
!std::is_same_v<typename Source1::unit_type, typename Dest::unit_type>;
template <class T>
using enable_muldiv_source_t =
typename std::enable_if_t<can_muldiv_source_v<T>>;
template <class T>
using enable_muldiv_dest_t = typename std::enable_if_t<can_muldiv_dest_v<T>>;
template <class Source1, class Source2>
using enable_muldiv_sources_t =
typename std::enable_if_t<can_muldiv_sources_v<Source1, Source2>>;
template <class Source1, class Source2, class Dest>
using enable_muldiv_t =
typename std::enable_if_t<can_muldiv_v<Source1, Source2, Dest>>;
template <class Source1, class Source2, class Dest>
using enable_muldiv_commute_t =
typename std::enable_if_t<can_muldiv_commute_v<Source1, Source2, Dest>>;
template <class T>
TaggedFee<unitlessTag, T>
scalar(T value)
{
return TaggedFee<unitlessTag, T>{value};
}
template <
class Source1,
class Source2,
class Dest,
class = enable_muldiv_t<Source1, Source2, Dest>>
std::optional<Dest>
mulDivU(Source1 value, Dest mul, Source2 div)
{
// Fees 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");
XRPL_ASSERT(
mul.value() >= 0, "ripple::feeunit::mulDivU : minimum mul input");
XRPL_ASSERT(
div.value() >= 0, "ripple::feeunit::mulDivU : minimum div input");
return std::nullopt;
}
using desttype = typename Dest::value_type;
constexpr auto max = std::numeric_limits<desttype>::max();
// Shortcuts, since these happen a lot in the real world
if (value == div)
return mul;
if (mul.value() == div.value())
{
if (value.value() > max)
return std::nullopt;
return Dest{static_cast<desttype>(value.value())};
}
using namespace boost::multiprecision;
uint128_t product;
product = multiply(
product,
static_cast<std::uint64_t>(value.value()),
static_cast<std::uint64_t>(mul.value()));
auto quotient = product / div.value();
if (quotient > max)
return std::nullopt;
return Dest{static_cast<desttype>(quotient)};
}
} // namespace feeunit
template <class T>
using FeeLevel = feeunit::TaggedFee<feeunit::feelevelTag, T>;
using FeeLevel64 = FeeLevel<std::uint64_t>;
using FeeLevelDouble = FeeLevel<double>;
template <
class Source1,
class Source2,
class Dest,
class = feeunit::enable_muldiv_t<Source1, Source2, Dest>>
std::optional<Dest>
mulDiv(Source1 value, Dest mul, Source2 div)
{
return feeunit::mulDivU(value, mul, div);
}
template <
class Source1,
class Source2,
class Dest,
class = feeunit::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);
}
template <class Dest, class = feeunit::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));
}
template <class Dest, class = feeunit::enable_muldiv_dest_t<Dest>>
std::optional<Dest>
mulDiv(Dest value, std::uint64_t mul, std::uint64_t div)
{
// Multiplication is commutative
return mulDiv(mul, value, div);
}
template <
class Source1,
class Source2,
class = feeunit::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);
if (!unitresult)
return std::nullopt;
return unitresult->value();
}
template <
class Source1,
class Source2,
class = feeunit::enable_muldiv_sources_t<Source1, Source2>>
std::optional<std::uint64_t>
mulDiv(std::uint64_t value, Source1 mul, Source2 div)
{
// Multiplication is commutative
return mulDiv(mul, value, div);
}
template <class Dest, class Src>
constexpr std::enable_if_t<
std::is_same_v<typename Dest::unit_type, typename Src::unit_type> &&
std::is_integral_v<typename Dest::value_type> &&
std::is_integral_v<typename Src::value_type>,
Dest>
safe_cast(Src s) noexcept
{
// Dest may not have an explicit value constructor
return Dest{safe_cast<typename Dest::value_type>(s.value())};
}
template <class Dest, class Src>
constexpr std::enable_if_t<
std::is_same_v<typename Dest::unit_type, typename Src::unit_type> &&
std::is_integral_v<typename Dest::value_type> &&
std::is_integral_v<typename Src::value_type>,
Dest>
unsafe_cast(Src s) noexcept
{
// Dest may not have an explicit value constructor
return Dest{unsafe_cast<typename Dest::value_type>(s.value())};
}
} // namespace ripple
#endif // BASICS_FEES_H_INCLUDED

View File

@@ -287,9 +287,11 @@ delegate(AccountID const& account, AccountID const& authorizedAccount) noexcept;
Keylet
bridge(STXChainBridge const& bridge, STXChainBridge::ChainType chainType);
// `seq` is stored as `sfXChainClaimID` in the object
Keylet
xChainClaimID(STXChainBridge const& bridge, std::uint64_t seq);
// `seq` is stored as `sfXChainAccountCreateCount` in the object
Keylet
xChainCreateAccountClaimID(STXChainBridge const& bridge, std::uint64_t seq);
@@ -344,6 +346,24 @@ vault(uint256 const& vaultKey)
return {ltVAULT, vaultKey};
}
Keylet
loanbroker(AccountID const& owner, std::uint32_t seq) noexcept;
inline Keylet
loanbroker(uint256 const& key)
{
return {ltLOAN_BROKER, key};
}
Keylet
loan(uint256 const& loanBrokerID, std::uint32_t loanSeq) noexcept;
inline Keylet
loan(uint256 const& key)
{
return {ltLOAN, key};
}
Keylet
permissionedDomain(AccountID const& account, std::uint32_t seq) noexcept;

View File

@@ -56,7 +56,7 @@ enum LedgerEntryType : std::uint16_t
#pragma push_macro("LEDGER_ENTRY")
#undef LEDGER_ENTRY
#define LEDGER_ENTRY(tag, value, name, rpcName, fields) tag = value,
#define LEDGER_ENTRY(tag, value, ...) tag = value,
#include <xrpl/protocol/detail/ledger_entries.macro>
@@ -188,14 +188,14 @@ enum LedgerSpecificFlags {
lsfMPTCanTransfer = 0x00000020,
lsfMPTCanClawback = 0x00000040,
lsfMPTCanMutateCanLock = 0x00000002,
lsfMPTCanMutateRequireAuth = 0x00000004,
lsfMPTCanMutateCanEscrow = 0x00000008,
lsfMPTCanMutateCanTrade = 0x00000010,
lsfMPTCanMutateCanTransfer = 0x00000020,
lsfMPTCanMutateCanClawback = 0x00000040,
lsfMPTCanMutateMetadata = 0x00010000,
lsfMPTCanMutateTransferFee = 0x00020000,
lsmfMPTCanMutateCanLock = 0x00000002,
lsmfMPTCanMutateRequireAuth = 0x00000004,
lsmfMPTCanMutateCanEscrow = 0x00000008,
lsmfMPTCanMutateCanTrade = 0x00000010,
lsmfMPTCanMutateCanTransfer = 0x00000020,
lsmfMPTCanMutateCanClawback = 0x00000040,
lsmfMPTCanMutateMetadata = 0x00010000,
lsmfMPTCanMutateTransferFee = 0x00020000,
// ltMPTOKEN
lsfMPTAuthorized = 0x00000002,
@@ -205,6 +205,11 @@ enum LedgerSpecificFlags {
// ltVAULT
lsfVaultPrivate = 0x00010000,
// ltLOAN
lsfLoanDefault = 0x00010000,
lsfLoanImpaired = 0x00020000,
lsfLoanOverpayment = 0x00040000, // True, loan allows overpayments
};
//------------------------------------------------------------------------------

View File

@@ -74,6 +74,9 @@ public:
Permission&
operator=(Permission const&) = delete;
std::optional<std::string>
getPermissionName(std::uint32_t const value) const;
std::optional<std::uint32_t>
getGranularValue(std::string const& name) const;
@@ -83,6 +86,9 @@ public:
std::optional<TxType>
getGranularTxType(GranularPermissionType const& gpType) const;
std::optional<std::reference_wrapper<uint256 const>> const
getTxFeature(TxType txType) const;
bool
isDelegatable(std::uint32_t const& permissionValue, Rules const& rules)
const;

View File

@@ -22,7 +22,7 @@
#include <xrpl/basics/ByteUtilities.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/partitioned_unordered_map.h>
#include <xrpl/protocol/Units.h>
#include <cstdint>
@@ -82,6 +82,101 @@ 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);
static_assert(maxOverpaymentFee == TenthBips32(100'000u));
/** Annualized interest rate of the Loan in 1/10 bips.
*
* Valid values are between 0 and 100% inclusive.
*/
TenthBips32 constexpr maxInterestRate = percentageToTenthBips(100);
static_assert(maxInterestRate == TenthBips32(100'000u));
/** 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);
static_assert(maxLateInterestRate == TenthBips32(100'000u));
/** 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);
static_assert(maxCloseInterestRate == TenthBips32(100'000u));
/** 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);
static_assert(maxOverpaymentInterestRate == TenthBips32(100'000u));
/** The maximum length of a URI inside an NFT */
std::size_t constexpr maxTokenURILength = 256;

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>
@@ -71,8 +72,10 @@ class STCurrency;
STYPE(STI_VL, 7) \
STYPE(STI_ACCOUNT, 8) \
STYPE(STI_NUMBER, 9) \
STYPE(STI_INT32, 10) \
STYPE(STI_INT64, 11) \
\
/* 10-13 are reserved */ \
/* 12-13 are reserved */ \
STYPE(STI_OBJECT, 14) \
STYPE(STI_ARRAY, 15) \
\
@@ -136,8 +139,8 @@ field_code(int id, int index)
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.
is only one instance per fieldType/fieldValue pair which serves the
entire application.
*/
class SField
{
@@ -148,8 +151,10 @@ 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 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
};
@@ -184,7 +189,7 @@ public:
char const* fn,
int meta = sMD_Default,
IsSigning signing = IsSigning::yes);
explicit SField(private_access_tag_t, int fc);
explicit SField(private_access_tag_t, int fc, char const* fn);
static SField const&
getField(int fieldCode);
@@ -297,7 +302,7 @@ public:
static int
compare(SField const& f1, SField const& f2);
static std::map<int, SField const*> const&
static std::unordered_map<int, SField const*> const&
getKnownCodeToField()
{
return knownCodeToField;
@@ -305,7 +310,8 @@ public:
private:
static int num;
static std::map<int, SField const*> knownCodeToField;
static std::unordered_map<int, SField const*> knownCodeToField;
static std::unordered_map<std::string, SField const*> knownNameToField;
};
/** A field with a type known at compile time. */
@@ -352,6 +358,9 @@ using SF_UINT256 = TypedField<STBitString<256>>;
using SF_UINT384 = TypedField<STBitString<384>>;
using SF_UINT512 = TypedField<STBitString<512>>;
using SF_INT32 = TypedField<STInteger<std::int32_t>>;
using SF_INT64 = TypedField<STInteger<std::int64_t>>;
using SF_ACCOUNT = TypedField<STAccount>;
using SF_AMOUNT = TypedField<STAmount>;
using SF_ISSUE = TypedField<STIssue>;

View File

@@ -695,6 +695,53 @@ divRoundStrict(
std::uint64_t
getRate(STAmount const& offerOut, STAmount const& offerIn);
/** Round an arbitrary precision Amount to the precision of a reference Amount.
*
* This is used to ensure that calculations involving IOU amounts do not collect
* dust beyond the precision of the reference value.
*
* @param value The value to be rounded
* @param referenceValue A reference value to establish the precision limit of
* `value`. Should be larger than `value`.
* @param rounding Optional Number rounding mode
*
*/
STAmount
roundToReference(
STAmount const value,
STAmount referenceValue,
Number::rounding_mode rounding = Number::getround());
/** Round an arbitrary precision Number to the precision of a given Asset.
*
* This is used to ensure that calculations do not collect dust beyond the
* precision of the reference value for IOUs, or fractional amounts for the
* integral types XRP and MPT.
*
* @param asset The relevant asset
* @param value The value to be rounded
* @param referenceValue Only relevant to IOU assets. A reference value to
* establish the precision limit of `value`. Should be larger than
* `value`.
* @param rounding Optional Number rounding mode
*/
template <AssetType A>
Number
roundToAsset(
A const& asset,
Number const& value,
Number const& referenceValue,
Number::rounding_mode rounding = Number::getround())
{
NumberRoundModeGuard mg(rounding);
STAmount const ret{asset, value};
if (ret.asset().native() || !ret.asset().holds<Issue>())
return ret;
// Not that the ctor will round integral types (XRP, MPT) via canonicalize,
// so no extra work is needed for those.
return roundToReference(ret, STAmount{asset, referenceValue});
}
//------------------------------------------------------------------------------
inline bool
@@ -709,10 +756,10 @@ 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
// to unconditionally use the new behavior.
// 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 to unconditionally use the new behavior.
bool
getSTAmountCanonicalizeSwitchover();

View File

@@ -81,6 +81,8 @@ using STUInt16 = STInteger<std::uint16_t>;
using STUInt32 = STInteger<std::uint32_t>;
using STUInt64 = STInteger<std::uint64_t>;
using STInt32 = STInteger<std::int32_t>;
template <typename Integer>
inline STInteger<Integer>::STInteger(Integer v) : value_(v)
{

View File

@@ -26,7 +26,9 @@
namespace ripple {
class Rules;
namespace test {
class Invariants_test;
}
class STLedgerEntry final : public STObject, public CountedObject<STLedgerEntry>
{
@@ -36,6 +38,8 @@ class STLedgerEntry final : public STObject, public CountedObject<STLedgerEntry>
public:
using pointer = std::shared_ptr<STLedgerEntry>;
using ref = std::shared_ptr<STLedgerEntry> const&;
using const_pointer = std::shared_ptr<STLedgerEntry const>;
using const_ref = std::shared_ptr<STLedgerEntry const> 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>
@@ -231,6 +231,8 @@ public:
getFieldH192(SField const& field) const;
uint256
getFieldH256(SField const& field) const;
std::int32_t
getFieldI32(SField const& field) const;
AccountID
getAccountID(SField const& field) const;
@@ -242,6 +244,9 @@ public:
getFieldPathSet(SField const& field) const;
STVector256 const&
getFieldV256(SField const& field) const;
// If not found, returns an object constructed with the given field
STObject
getFieldObject(SField const& field) const;
STArray const&
getFieldArray(SField const& field) const;
STCurrency const&
@@ -365,6 +370,8 @@ public:
void
setFieldH256(SField const& field, uint256 const&);
void
setFieldI32(SField const& field, std::int32_t);
void
setFieldVL(SField const& field, Blob const&);
void
setFieldVL(SField const& field, Slice const&);
@@ -386,6 +393,8 @@ public:
setFieldV256(SField const& field, STVector256 const& v);
void
setFieldArray(SField const& field, STArray const& v);
void
setFieldObject(SField const& field, STObject const& v);
template <class Tag>
void
@@ -515,7 +524,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 +563,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 +804,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 +814,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)
{

View File

@@ -54,34 +54,6 @@ public:
Json::Value error;
};
/** Holds the serialized result of parsing an input JSON array.
This does validation and checking on the provided JSON.
*/
class STParsedJSONArray
{
public:
/** Parses and creates an STParsedJSON array.
The result of the parsing is stored in array and error.
Exceptions:
Does not throw.
@param name The name of the JSON field, used in diagnostics.
@param json The JSON-RPC to parse.
*/
STParsedJSONArray(std::string const& name, Json::Value const& json);
STParsedJSONArray() = delete;
STParsedJSONArray(STParsedJSONArray const&) = delete;
STParsedJSONArray&
operator=(STParsedJSONArray const&) = delete;
~STParsedJSONArray() = default;
/** The STArray if the parse was successful. */
std::optional<STArray> array;
/** On failure, an appropriate set of error values. */
Json::Value error;
};
} // namespace ripple
#endif

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;
@@ -119,13 +125,34 @@ public:
getJson(JsonOptions options, bool binary) const;
void
sign(PublicKey const& publicKey, SecretKey const& secretKey);
sign(
PublicKey const& publicKey,
SecretKey const& secretKey,
std::optional<std::reference_wrapper<SField const>> signatureTarget =
{});
/** 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;
@@ -155,12 +182,15 @@ public:
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;
Rules const& rules,
STObject const* pSig) const;
Expected<void, std::string>
checkBatchSingleSign(

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 <optional>

View File

@@ -673,7 +673,8 @@ isTerRetry(TER x) noexcept
inline bool
isTesSuccess(TER x) noexcept
{
return (x == tesSUCCESS);
// Makes use of TERSubset::operator bool()
return !(x);
}
inline bool

View File

@@ -127,6 +127,8 @@ constexpr std::uint32_t tfTrustSetPermissionMask = ~(tfUniversal | tfSetfAuth |
// 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 +143,8 @@ 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: tf/lsfMPTLocked is intentionally omitted, since this transaction
// is not allowed to modify it.
constexpr std::uint32_t const tfMPTCanLock = lsfMPTCanLock;
constexpr std::uint32_t const tfMPTRequireAuth = lsfMPTRequireAuth;
constexpr std::uint32_t const tfMPTCanEscrow = lsfMPTCanEscrow;
@@ -153,17 +156,17 @@ constexpr std::uint32_t const tfMPTokenIssuanceCreateMask =
// MPTokenIssuanceCreate MutableFlags:
// Indicating specific fields or flags may be changed after issuance.
constexpr std::uint32_t const tfMPTCanMutateCanLock = lsfMPTCanMutateCanLock;
constexpr std::uint32_t const tfMPTCanMutateRequireAuth = lsfMPTCanMutateRequireAuth;
constexpr std::uint32_t const tfMPTCanMutateCanEscrow = lsfMPTCanMutateCanEscrow;
constexpr std::uint32_t const tfMPTCanMutateCanTrade = lsfMPTCanMutateCanTrade;
constexpr std::uint32_t const tfMPTCanMutateCanTransfer = lsfMPTCanMutateCanTransfer;
constexpr std::uint32_t const tfMPTCanMutateCanClawback = lsfMPTCanMutateCanClawback;
constexpr std::uint32_t const tfMPTCanMutateMetadata = lsfMPTCanMutateMetadata;
constexpr std::uint32_t const tfMPTCanMutateTransferFee = lsfMPTCanMutateTransferFee;
constexpr std::uint32_t const tfMPTokenIssuanceCreateMutableMask =
~(tfMPTCanMutateCanLock | tfMPTCanMutateRequireAuth | tfMPTCanMutateCanEscrow | tfMPTCanMutateCanTrade
| tfMPTCanMutateCanTransfer | tfMPTCanMutateCanClawback | tfMPTCanMutateMetadata | tfMPTCanMutateTransferFee);
constexpr std::uint32_t const tmfMPTCanMutateCanLock = lsmfMPTCanMutateCanLock;
constexpr std::uint32_t const tmfMPTCanMutateRequireAuth = lsmfMPTCanMutateRequireAuth;
constexpr std::uint32_t const tmfMPTCanMutateCanEscrow = lsmfMPTCanMutateCanEscrow;
constexpr std::uint32_t const tmfMPTCanMutateCanTrade = lsmfMPTCanMutateCanTrade;
constexpr std::uint32_t const tmfMPTCanMutateCanTransfer = lsmfMPTCanMutateCanTransfer;
constexpr std::uint32_t const tmfMPTCanMutateCanClawback = lsmfMPTCanMutateCanClawback;
constexpr std::uint32_t const tmfMPTCanMutateMetadata = lsmfMPTCanMutateMetadata;
constexpr std::uint32_t const tmfMPTCanMutateTransferFee = lsmfMPTCanMutateTransferFee;
constexpr std::uint32_t const tmfMPTokenIssuanceCreateMutableMask =
~(tmfMPTCanMutateCanLock | tmfMPTCanMutateRequireAuth | tmfMPTCanMutateCanEscrow | tmfMPTCanMutateCanTrade
| tmfMPTCanMutateCanTransfer | tmfMPTCanMutateCanClawback | tmfMPTCanMutateMetadata | tmfMPTCanMutateTransferFee);
// MPTokenAuthorize flags:
constexpr std::uint32_t const tfMPTUnauthorize = 0x00000001;
@@ -177,22 +180,22 @@ constexpr std::uint32_t const tfMPTokenIssuanceSetPermissionMask = ~(tfUniversal
// MPTokenIssuanceSet MutableFlags:
// Set or Clear flags.
constexpr std::uint32_t const tfMPTSetCanLock = 0x00000001;
constexpr std::uint32_t const tfMPTClearCanLock = 0x00000002;
constexpr std::uint32_t const tfMPTSetRequireAuth = 0x00000004;
constexpr std::uint32_t const tfMPTClearRequireAuth = 0x00000008;
constexpr std::uint32_t const tfMPTSetCanEscrow = 0x00000010;
constexpr std::uint32_t const tfMPTClearCanEscrow = 0x00000020;
constexpr std::uint32_t const tfMPTSetCanTrade = 0x00000040;
constexpr std::uint32_t const tfMPTClearCanTrade = 0x00000080;
constexpr std::uint32_t const tfMPTSetCanTransfer = 0x00000100;
constexpr std::uint32_t const tfMPTClearCanTransfer = 0x00000200;
constexpr std::uint32_t const tfMPTSetCanClawback = 0x00000400;
constexpr std::uint32_t const tfMPTClearCanClawback = 0x00000800;
constexpr std::uint32_t const tfMPTokenIssuanceSetMutableMask = ~(tfMPTSetCanLock | tfMPTClearCanLock |
tfMPTSetRequireAuth | tfMPTClearRequireAuth | tfMPTSetCanEscrow | tfMPTClearCanEscrow |
tfMPTSetCanTrade | tfMPTClearCanTrade | tfMPTSetCanTransfer | tfMPTClearCanTransfer |
tfMPTSetCanClawback | tfMPTClearCanClawback);
constexpr std::uint32_t const tmfMPTSetCanLock = 0x00000001;
constexpr std::uint32_t const tmfMPTClearCanLock = 0x00000002;
constexpr std::uint32_t const tmfMPTSetRequireAuth = 0x00000004;
constexpr std::uint32_t const tmfMPTClearRequireAuth = 0x00000008;
constexpr std::uint32_t const tmfMPTSetCanEscrow = 0x00000010;
constexpr std::uint32_t const tmfMPTClearCanEscrow = 0x00000020;
constexpr std::uint32_t const tmfMPTSetCanTrade = 0x00000040;
constexpr std::uint32_t const tmfMPTClearCanTrade = 0x00000080;
constexpr std::uint32_t const tmfMPTSetCanTransfer = 0x00000100;
constexpr std::uint32_t const tmfMPTClearCanTransfer = 0x00000200;
constexpr std::uint32_t const tmfMPTSetCanClawback = 0x00000400;
constexpr std::uint32_t const tmfMPTClearCanClawback = 0x00000800;
constexpr std::uint32_t const tmfMPTokenIssuanceSetMutableMask = ~(tmfMPTSetCanLock | tmfMPTClearCanLock |
tmfMPTSetRequireAuth | tmfMPTClearRequireAuth | tmfMPTSetCanEscrow | tmfMPTClearCanEscrow |
tmfMPTSetCanTrade | tmfMPTClearCanTrade | tmfMPTSetCanTransfer | tmfMPTClearCanTransfer |
tmfMPTSetCanClawback | tmfMPTClearCanClawback);
// MPTokenIssuanceDestroy flags:
constexpr std::uint32_t const tfMPTokenIssuanceDestroyMask = ~tfUniversal;
@@ -282,6 +285,17 @@ constexpr std::uint32_t tfIndependent = 0x00080000;
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
} // namespace ripple

View File

@@ -0,0 +1,555 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2019 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 PROTOCOL_UNITS_H_INCLUDED
#define PROTOCOL_UNITS_H_INCLUDED
#include <xrpl/basics/safe_cast.h>
#include <xrpl/beast/utility/Zero.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/json/json_value.h>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/operators.hpp>
#include <iosfwd>
#include <limits>
#include <optional>
namespace ripple {
namespace unit {
/** "drops" are the smallest divisible amount of XRP. This is what most
of the code uses. */
struct dropTag;
/** "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 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;
// These names don't have to be too descriptive, because we're in the "unit"
// namespace.
template <class T>
concept Valid = std::is_class_v<T> && std::is_object_v<typename T::unit_type> &&
std::is_object_v<typename T::value_type>;
/** `Usable` is checked to ensure that only values with
known valid type tags can be used (sometimes transparently) in
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>
concept Usable = Valid<T> &&
(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, BipsTag> ||
std::is_same_v<typename T::unit_type, TenthBipsTag>);
template <class Other, class VU>
concept Compatible = Valid<VU> && std::is_arithmetic_v<Other> &&
std::is_arithmetic_v<typename VU::value_type> &&
std::is_convertible_v<Other, typename VU::value_type>;
template <class T>
concept Integral = std::is_integral_v<T>;
template <class VU>
concept IntegralValue = Integral<typename VU::value_type>;
template <class VU1, class VU2>
concept CastableValue = IntegralValue<VU1> && IntegralValue<VU2> &&
std::is_same_v<typename VU1::unit_type, typename VU2::unit_type>;
template <class UnitTag, class 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 value_;
public:
ValueUnit() = default;
constexpr ValueUnit(ValueUnit const& other) = default;
constexpr ValueUnit&
operator=(ValueUnit const& other) = default;
constexpr explicit ValueUnit(beast::Zero) : value_(0)
{
}
constexpr ValueUnit&
operator=(beast::Zero)
{
value_ = 0;
return *this;
}
constexpr explicit ValueUnit(value_type value) : value_(value)
{
}
constexpr ValueUnit&
operator=(value_type value)
{
value_ = value;
return *this;
}
/** Instances with the same unit, and a type that is
"safe" to convert to this one can be converted
implicitly */
template <Compatible<ValueUnit> Other>
constexpr ValueUnit(ValueUnit<unit_type, Other> const& value)
requires SafeToCast<Other, value_type>
: ValueUnit(safe_cast<value_type>(value.value()))
{
}
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 ValueUnit{value_ * rhs};
}
friend constexpr ValueUnit
operator*(value_type lhs, ValueUnit const& rhs)
{
// multiplication is commutative
return rhs * lhs;
}
constexpr value_type
operator/(ValueUnit const& rhs) const
{
return value_ / rhs.value_;
}
ValueUnit&
operator+=(ValueUnit const& other)
{
value_ += other.value();
return *this;
}
ValueUnit&
operator-=(ValueUnit const& other)
{
value_ -= other.value();
return *this;
}
ValueUnit&
operator++()
{
++value_;
return *this;
}
ValueUnit&
operator--()
{
--value_;
return *this;
}
ValueUnit&
operator*=(value_type const& rhs)
{
value_ *= rhs;
return *this;
}
ValueUnit&
operator/=(value_type const& rhs)
{
value_ /= rhs;
return *this;
}
template <Integral transparent = value_type>
ValueUnit&
operator%=(value_type const& rhs)
{
value_ %= rhs;
return *this;
}
ValueUnit
operator-() const
{
static_assert(
std::is_signed_v<T>, "- operator illegal on unsigned value types");
return ValueUnit{-value_};
}
constexpr bool
operator==(ValueUnit const& other) const
{
return value_ == other.value_;
}
template <Compatible<ValueUnit> Other>
constexpr bool
operator==(ValueUnit<unit_type, Other> const& other) const
{
return value_ == other.value();
}
constexpr bool
operator==(value_type other) const
{
return value_ == other;
}
template <Compatible<ValueUnit> Other>
constexpr bool
operator!=(ValueUnit<unit_type, Other> const& other) const
{
return !operator==(other);
}
constexpr bool
operator<(ValueUnit const& other) const
{
return value_ < other.value_;
}
/** Returns true if the amount is not zero */
explicit constexpr
operator bool() const noexcept
{
return value_ != 0;
}
/** Return the sign of the amount */
constexpr int
signum() const noexcept
{
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 value_;
}
template <class Other>
constexpr double
decimalFromReference(ValueUnit<unit_type, Other> reference) const
{
return static_cast<double>(value_) / reference.value();
}
// `Usable` 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.
Json::Value
jsonClipped() const
requires Usable<ValueUnit>
{
if constexpr (std::is_integral_v<value_type>)
{
using jsontype = std::conditional_t<
std::is_signed_v<value_type>,
Json::Int,
Json::UInt>;
constexpr auto min = std::numeric_limits<jsontype>::min();
constexpr auto max = std::numeric_limits<jsontype>::max();
if (value_ < min)
return min;
if (value_ > max)
return max;
return static_cast<jsontype>(value_);
}
else
{
return value_;
}
}
/** Returns the underlying value. Code SHOULD NOT call this
function unless the type has been abstracted away,
e.g. in a templated function.
*/
constexpr value_type
value() const
{
return value_;
}
friend std::istream&
operator>>(std::istream& s, ValueUnit& val)
{
s >> val.value_;
return s;
}
};
// 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, ValueUnit<UnitTag, T> const& q)
{
return os << q.value();
}
template <class UnitTag, class T>
std::string
to_string(ValueUnit<UnitTag, T> const& amount)
{
return std::to_string(amount.value());
}
template <class Source>
concept muldivSource = Valid<Source> &&
std::is_convertible_v<typename Source::value_type, std::uint64_t>;
template <class Dest>
concept muldivDest = muldivSource<Dest> && // Dest is also a source
std::is_convertible_v<std::uint64_t, typename Dest::value_type> &&
sizeof(typename Dest::value_type) >= sizeof(std::uint64_t);
template <class Source2, class Source1>
concept muldivSources = muldivSource<Source1> && muldivSource<Source2> &&
std::is_same_v<typename Source1::unit_type, typename Source2::unit_type>;
template <class Dest, class Source1, class Source2>
concept muldivable = muldivSources<Source1, Source2> && muldivDest<Dest>;
// Source and Dest can be the same by default
template <class Dest, class Source1, class Source2>
concept muldivCommutable = muldivable<Dest, Source1, Source2> &&
!std::is_same_v<typename Source1::unit_type, typename Dest::unit_type>;
template <class T>
ValueUnit<unitlessTag, T>
scalar(T value)
{
return ValueUnit<unitlessTag, T>{value};
}
template <class Source1, class Source2, unit::muldivable<Source1, Source2> Dest>
std::optional<Dest>
mulDivU(Source1 value, Dest mul, Source2 div)
{
// 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::unit::mulDivU : minimum value input");
XRPL_ASSERT(
mul.value() >= 0, "ripple::unit::mulDivU : minimum mul input");
XRPL_ASSERT(
div.value() > 0, "ripple::unit::mulDivU : minimum div input");
return std::nullopt;
}
using desttype = typename Dest::value_type;
constexpr auto max = std::numeric_limits<desttype>::max();
// Shortcuts, since these happen a lot in the real world
if (value == div)
return mul;
if (mul.value() == div.value())
{
if (value.value() > max)
return std::nullopt;
return Dest{static_cast<desttype>(value.value())};
}
using namespace boost::multiprecision;
uint128_t product;
product = multiply(
product,
static_cast<std::uint64_t>(value.value()),
static_cast<std::uint64_t>(mul.value()));
auto quotient = product / div.value();
if (quotient > max)
return std::nullopt;
return Dest{static_cast<desttype>(quotient)};
}
} // namespace unit
// Fee Levels
template <class 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, unit::muldivable<Source1, Source2> Dest>
std::optional<Dest>
mulDiv(Source1 value, Dest mul, Source2 div)
{
return unit::mulDivU(value, mul, div);
}
template <
class Source1,
class Source2,
unit::muldivCommutable<Source1, Source2> Dest>
std::optional<Dest>
mulDiv(Dest value, Source1 mul, Source2 div)
{
// Multiplication is commutative
return unit::mulDivU(mul, value, div);
}
template <unit::muldivDest 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 unit::mulDivU(unit::scalar(value), mul, unit::scalar(div));
}
template <unit::muldivDest Dest>
std::optional<Dest>
mulDiv(Dest value, std::uint64_t mul, std::uint64_t div)
{
// Multiplication is commutative
return mulDiv(mul, value, div);
}
template <unit::muldivSource Source1, unit::muldivSources<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 = unit::mulDivU(value, unit::scalar(mul), div);
if (!unitresult)
return std::nullopt;
return unitresult->value();
}
template <unit::muldivSource Source1, unit::muldivSources<Source1> Source2>
std::optional<std::uint64_t>
mulDiv(std::uint64_t value, Source1 mul, Source2 div)
{
// Multiplication is commutative
return mulDiv(mul, value, div);
}
template <unit::IntegralValue Dest, unit::CastableValue<Dest> Src>
constexpr Dest
safe_cast(Src s) noexcept
{
// Dest may not have an explicit value constructor
return Dest{safe_cast<typename Dest::value_type>(s.value())};
}
template <unit::IntegralValue Dest, unit::Integral Src>
constexpr Dest
safe_cast(Src s) noexcept
{
// Dest may not have an explicit value constructor
return Dest{safe_cast<typename Dest::value_type>(s)};
}
template <unit::IntegralValue Dest, unit::CastableValue<Dest> Src>
constexpr Dest
unsafe_cast(Src s) noexcept
{
// Dest may not have an explicit value constructor
return Dest{unsafe_cast<typename Dest::value_type>(s.value())};
}
template <unit::IntegralValue Dest, unit::Integral Src>
constexpr 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 // 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:

View File

@@ -129,10 +129,12 @@ inplace_bigint_div_rem(std::span<uint64_t> numerator, std::uint64_t divisor)
{
// should never happen, but if it does then it seems natural to define
// the a null set of numbers to be zero, so the remainder is also zero.
// LCOV_EXCL_START
UNREACHABLE(
"ripple::b58_fast::detail::inplace_bigint_div_rem : empty "
"numerator");
return 0;
// LCOV_EXCL_STOP
}
auto to_u128 = [](std::uint64_t high,

View File

@@ -27,16 +27,17 @@
#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_FIX (CanonicalTxSet, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(LendingProtocol, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (IncludeKeyletFields, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(DynamicMPT, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (TokenEscrowV1, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (DelegateV1_1, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (PriceOracleOrder, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (PriceOracleOrder, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (MPTDeliveredAmount, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (AMMClawbackRounding, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(TokenEscrow, Supported::yes, VoteBehavior::DefaultNo)
@@ -45,7 +46,7 @@ XRPL_FIX (AMMv1_3, Supported::yes, VoteBehavior::DefaultNo
XRPL_FEATURE(PermissionedDEX, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(Batch, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(SingleAssetVault, Supported::no, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionDelegation, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionDelegation, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (PayChanCancelAfter, Supported::yes, VoteBehavior::DefaultNo)
// Check flags in Credential transactions
XRPL_FIX (InvalidTxFlags, Supported::yes, VoteBehavior::DefaultNo)
@@ -156,3 +157,5 @@ XRPL_RETIRE(fix1512)
XRPL_RETIRE(fix1523)
XRPL_RETIRE(fix1528)
XRPL_RETIRE(FlowCross)
// clang-format on

View File

@@ -120,6 +120,7 @@ LEDGER_ENTRY(ltNFTOKEN_PAGE, 0x0050, NFTokenPage, nft_page, ({
// All fields are soeREQUIRED because there is always a SignerEntries.
// If there are no SignerEntries the node is deleted.
LEDGER_ENTRY(ltSIGNER_LIST, 0x0053, SignerList, signer_list, ({
{sfOwner, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfSignerQuorum, soeREQUIRED},
{sfSignerEntries, soeREQUIRED},
@@ -167,6 +168,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 +190,7 @@ LEDGER_ENTRY(ltDIR_NODE, 0x0064, DirectoryNode, directory, ({
{sfNFTokenID, soeOPTIONAL},
{sfPreviousTxnID, soeOPTIONAL},
{sfPreviousTxnLgrSeq, soeOPTIONAL},
{sfDomainID, soeOPTIONAL}
{sfDomainID, soeOPTIONAL} // order book directories
}))
/** The ledger object which lists details about amendments on the network.
@@ -343,6 +345,7 @@ LEDGER_ENTRY(ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID, 0x0074, XChainOwnedCreateAc
*/
LEDGER_ENTRY(ltESCROW, 0x0075, Escrow, escrow, ({
{sfAccount, soeREQUIRED},
{sfSequence, soeOPTIONAL},
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED},
{sfCondition, soeOPTIONAL},
@@ -365,6 +368,7 @@ LEDGER_ENTRY(ltESCROW, 0x0075, Escrow, escrow, ({
LEDGER_ENTRY(ltPAYCHAN, 0x0078, PayChannel, payment_channel, ({
{sfAccount, soeREQUIRED},
{sfDestination, soeREQUIRED},
{sfSequence, soeOPTIONAL},
{sfAmount, soeREQUIRED},
{sfBalance, soeREQUIRED},
{sfPublicKey, soeREQUIRED},
@@ -433,6 +437,7 @@ LEDGER_ENTRY(ltMPTOKEN, 0x007f, MPToken, mptoken, ({
*/
LEDGER_ENTRY(ltORACLE, 0x0080, Oracle, oracle, ({
{sfOwner, soeREQUIRED},
{sfOracleDocumentID, soeOPTIONAL},
{sfProvider, soeREQUIRED},
{sfPriceDataSeries, soeREQUIRED},
{sfAssetClass, soeREQUIRED},
@@ -505,5 +510,69 @@ 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},
//#if LOANDRAW
// TODO: Remove this when you remove the rest of the LOANDRAW blocks.
// Directives don't work with macro expansion.
{sfAssetsAvailable, soeDEFAULT},
//#endif
{sfPrincipalOutstanding, soeREQUIRED},
// Save the original request amount for rounding / scaling of
// other computations, particularly for IOUs
{sfPrincipalRequested, soeREQUIRED},
}))
#undef EXPAND
#undef LEDGER_ENTRY_DUPLICATE

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)
@@ -115,6 +118,21 @@ TYPED_SFIELD(sfFirstNFTokenSequence, UINT32, 50)
TYPED_SFIELD(sfOracleDocumentID, UINT32, 51)
TYPED_SFIELD(sfPermissionValue, UINT32, 52)
TYPED_SFIELD(sfMutableFlags, UINT32, 53)
TYPED_SFIELD(sfStartDate, UINT32, 54)
TYPED_SFIELD(sfPaymentInterval, UINT32, 55)
TYPED_SFIELD(sfGracePeriod, UINT32, 56)
TYPED_SFIELD(sfPreviousPaymentDate, UINT32, 57)
TYPED_SFIELD(sfNextPaymentDueDate, UINT32, 58)
TYPED_SFIELD(sfPaymentRemaining, UINT32, 59)
TYPED_SFIELD(sfPaymentTotal, UINT32, 60)
TYPED_SFIELD(sfLoanSequence, UINT32, 61)
TYPED_SFIELD(sfCoverRateMinimum, UINT32, 62) // 1/10 basis points (bips)
TYPED_SFIELD(sfCoverRateLiquidation, UINT32, 63) // 1/10 basis points (bips)
TYPED_SFIELD(sfOverpaymentFee, UINT32, 64) // 1/10 basis points (bips)
TYPED_SFIELD(sfInterestRate, UINT32, 65) // 1/10 basis points (bips)
TYPED_SFIELD(sfLateInterestRate, UINT32, 66) // 1/10 basis points (bips)
TYPED_SFIELD(sfCloseInterestRate, UINT32, 67) // 1/10 basis points (bips)
TYPED_SFIELD(sfOverpaymentInterestRate, UINT32, 68) // 1/10 basis points (bips)
// 64-bit integers (common)
TYPED_SFIELD(sfIndexNext, UINT64, 1)
@@ -146,6 +164,8 @@ TYPED_SFIELD(sfMPTAmount, UINT64, 26, SField::sMD_BaseTen|SFie
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, 30)
TYPED_SFIELD(sfLoanBrokerNode, UINT64, 31)
// 128-bit
TYPED_SFIELD(sfEmailHash, UINT128, 1)
@@ -174,7 +194,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)
@@ -196,8 +217,12 @@ 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(sfVaultID, UINT256, 35,
SField::sMD_PseudoAccount | SField::sMD_Default)
TYPED_SFIELD(sfParentBatchID, UINT256, 36)
TYPED_SFIELD(sfLoanBrokerID, UINT256, 37,
SField::sMD_PseudoAccount | SField::sMD_Default)
TYPED_SFIELD(sfLoanID, UINT256, 38)
// number (common)
TYPED_SFIELD(sfNumber, NUMBER, 1)
@@ -205,6 +230,21 @@ 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)
// int32
// NOTE: Do not use `sfDummyInt32`. It's so far the only use of INT32
// in this file and has been defined here for test only.
// TODO: Replace `sfDummyInt32` with actually useful field.
TYPED_SFIELD(sfDummyInt32, INT32, 1) // for tests only
// currency amount (common)
TYPED_SFIELD(sfAmount, AMOUNT, 1)
@@ -300,6 +340,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)
@@ -363,6 +405,7 @@ UNTYPED_SFIELD(sfCredential, OBJECT, 33)
UNTYPED_SFIELD(sfRawTransaction, OBJECT, 34)
UNTYPED_SFIELD(sfBatchSigner, OBJECT, 35)
UNTYPED_SFIELD(sfBook, OBJECT, 36)
UNTYPED_SFIELD(sfCounterpartySignature, OBJECT, 37, SField::sMD_Default, SField::notSigning)
// array of objects (common)
// ARRAY/1 is reserved for end of array
@@ -397,3 +440,5 @@ 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

@@ -22,16 +22,31 @@
#endif
/**
* TRANSACTION(tag, value, name, delegatable, amendments, fields)
* TRANSACTION(tag, value, name, delegatable, amendments, privileges, fields)
*
* To ease maintenance, you may replace any unneeded values with "..."
* e.g. #define TRANSACTION(tag, value, name, ...)
*
* 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 defined and used in InvariantCheck.cpp
*/
/** This transaction type executes a payment. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Payment.h>
#endif
TRANSACTION(ttPAYMENT, 0, Payment,
Delegation::delegatable,
uint256{},
createAcct,
({
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
@@ -45,9 +60,13 @@ TRANSACTION(ttPAYMENT, 0, Payment,
}))
/** This transaction type creates an escrow object. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Escrow.h>
#endif
TRANSACTION(ttESCROW_CREATE, 1, EscrowCreate,
Delegation::delegatable,
uint256{},
noPriv,
({
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
@@ -61,6 +80,7 @@ TRANSACTION(ttESCROW_CREATE, 1, EscrowCreate,
TRANSACTION(ttESCROW_FINISH, 2, EscrowFinish,
Delegation::delegatable,
uint256{},
noPriv,
({
{sfOwner, soeREQUIRED},
{sfOfferSequence, soeREQUIRED},
@@ -71,9 +91,13 @@ TRANSACTION(ttESCROW_FINISH, 2, EscrowFinish,
/** This transaction type adjusts various account settings. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/SetAccount.h>
#endif
TRANSACTION(ttACCOUNT_SET, 3, AccountSet,
Delegation::notDelegatable,
uint256{},
noPriv,
({
{sfEmailHash, soeOPTIONAL},
{sfWalletLocator, soeOPTIONAL},
@@ -88,18 +112,26 @@ TRANSACTION(ttACCOUNT_SET, 3, AccountSet,
}))
/** This transaction type cancels an existing escrow. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Escrow.h>
#endif
TRANSACTION(ttESCROW_CANCEL, 4, EscrowCancel,
Delegation::delegatable,
uint256{},
noPriv,
({
{sfOwner, soeREQUIRED},
{sfOfferSequence, soeREQUIRED},
}))
/** This transaction type sets or clears an account's "regular key". */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/SetRegularKey.h>
#endif
TRANSACTION(ttREGULAR_KEY_SET, 5, SetRegularKey,
Delegation::notDelegatable,
uint256{},
noPriv,
({
{sfRegularKey, soeOPTIONAL},
}))
@@ -107,9 +139,13 @@ TRANSACTION(ttREGULAR_KEY_SET, 5, SetRegularKey,
// 6 deprecated
/** This transaction type creates an offer to trade one asset for another. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CreateOffer.h>
#endif
TRANSACTION(ttOFFER_CREATE, 7, OfferCreate,
Delegation::delegatable,
uint256{},
noPriv,
({
{sfTakerPays, soeREQUIRED},
{sfTakerGets, soeREQUIRED},
@@ -119,9 +155,13 @@ TRANSACTION(ttOFFER_CREATE, 7, OfferCreate,
}))
/** This transaction type cancels existing offers to trade one asset for another. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CancelOffer.h>
#endif
TRANSACTION(ttOFFER_CANCEL, 8, OfferCancel,
Delegation::delegatable,
uint256{},
noPriv,
({
{sfOfferSequence, soeREQUIRED},
}))
@@ -129,9 +169,13 @@ TRANSACTION(ttOFFER_CANCEL, 8, OfferCancel,
// 9 deprecated
/** This transaction type creates a new set of tickets. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CreateTicket.h>
#endif
TRANSACTION(ttTICKET_CREATE, 10, TicketCreate,
Delegation::delegatable,
featureTicketBatch,
noPriv,
({
{sfTicketCount, soeREQUIRED},
}))
@@ -141,18 +185,26 @@ TRANSACTION(ttTICKET_CREATE, 10, TicketCreate,
/** 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.
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/SetSignerList.h>
#endif
TRANSACTION(ttSIGNER_LIST_SET, 12, SignerListSet,
Delegation::notDelegatable,
uint256{},
noPriv,
({
{sfSignerQuorum, soeREQUIRED},
{sfSignerEntries, soeOPTIONAL},
}))
/** This transaction type creates a new unidirectional XRP payment channel. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/PayChan.h>
#endif
TRANSACTION(ttPAYCHAN_CREATE, 13, PaymentChannelCreate,
Delegation::delegatable,
uint256{},
noPriv,
({
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED},
@@ -166,6 +218,7 @@ TRANSACTION(ttPAYCHAN_CREATE, 13, PaymentChannelCreate,
TRANSACTION(ttPAYCHAN_FUND, 14, PaymentChannelFund,
Delegation::delegatable,
uint256{},
noPriv,
({
{sfChannel, soeREQUIRED},
{sfAmount, soeREQUIRED},
@@ -176,6 +229,7 @@ TRANSACTION(ttPAYCHAN_FUND, 14, PaymentChannelFund,
TRANSACTION(ttPAYCHAN_CLAIM, 15, PaymentChannelClaim,
Delegation::delegatable,
uint256{},
noPriv,
({
{sfChannel, soeREQUIRED},
{sfAmount, soeOPTIONAL},
@@ -186,9 +240,13 @@ TRANSACTION(ttPAYCHAN_CLAIM, 15, PaymentChannelClaim,
}))
/** This transaction type creates a new check. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CreateCheck.h>
#endif
TRANSACTION(ttCHECK_CREATE, 16, CheckCreate,
Delegation::delegatable,
featureChecks,
noPriv,
({
{sfDestination, soeREQUIRED},
{sfSendMax, soeREQUIRED},
@@ -198,9 +256,13 @@ TRANSACTION(ttCHECK_CREATE, 16, CheckCreate,
}))
/** This transaction type cashes an existing check. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CashCheck.h>
#endif
TRANSACTION(ttCHECK_CASH, 17, CheckCash,
Delegation::delegatable,
featureChecks,
noPriv,
({
{sfCheckID, soeREQUIRED},
{sfAmount, soeOPTIONAL},
@@ -208,17 +270,25 @@ TRANSACTION(ttCHECK_CASH, 17, CheckCash,
}))
/** This transaction type cancels an existing check. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/CancelCheck.h>
#endif
TRANSACTION(ttCHECK_CANCEL, 18, CheckCancel,
Delegation::delegatable,
featureChecks,
noPriv,
({
{sfCheckID, soeREQUIRED},
}))
/** This transaction type grants or revokes authorization to transfer funds. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/DepositPreauth.h>
#endif
TRANSACTION(ttDEPOSIT_PREAUTH, 19, DepositPreauth,
Delegation::delegatable,
featureDepositPreauth,
noPriv,
({
{sfAuthorize, soeOPTIONAL},
{sfUnauthorize, soeOPTIONAL},
@@ -227,9 +297,13 @@ TRANSACTION(ttDEPOSIT_PREAUTH, 19, DepositPreauth,
}))
/** This transaction type modifies a trustline between two accounts. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/SetTrust.h>
#endif
TRANSACTION(ttTRUST_SET, 20, TrustSet,
Delegation::delegatable,
uint256{},
noPriv,
({
{sfLimitAmount, soeOPTIONAL},
{sfQualityIn, soeOPTIONAL},
@@ -237,9 +311,13 @@ TRANSACTION(ttTRUST_SET, 20, TrustSet,
}))
/** This transaction type deletes an existing account. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/DeleteAccount.h>
#endif
TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete,
Delegation::notDelegatable,
uint256{},
mustDeleteAcct,
({
{sfDestination, soeREQUIRED},
{sfDestinationTag, soeOPTIONAL},
@@ -249,9 +327,13 @@ TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete,
// 22 reserved
/** This transaction mints a new NFT. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenMint.h>
#endif
TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint,
Delegation::delegatable,
featureNonFungibleTokensV1,
changeNFTCounts,
({
{sfNFTokenTaxon, soeREQUIRED},
{sfTransferFee, soeOPTIONAL},
@@ -263,18 +345,26 @@ TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint,
}))
/** This transaction burns (i.e. destroys) an existing NFT. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenBurn.h>
#endif
TRANSACTION(ttNFTOKEN_BURN, 26, NFTokenBurn,
Delegation::delegatable,
featureNonFungibleTokensV1,
changeNFTCounts,
({
{sfNFTokenID, soeREQUIRED},
{sfOwner, soeOPTIONAL},
}))
/** This transaction creates a new offer to buy or sell an NFT. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenCreateOffer.h>
#endif
TRANSACTION(ttNFTOKEN_CREATE_OFFER, 27, NFTokenCreateOffer,
Delegation::delegatable,
featureNonFungibleTokensV1,
noPriv,
({
{sfNFTokenID, soeREQUIRED},
{sfAmount, soeREQUIRED},
@@ -284,17 +374,25 @@ TRANSACTION(ttNFTOKEN_CREATE_OFFER, 27, NFTokenCreateOffer,
}))
/** This transaction cancels an existing offer to buy or sell an existing NFT. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenCancelOffer.h>
#endif
TRANSACTION(ttNFTOKEN_CANCEL_OFFER, 28, NFTokenCancelOffer,
Delegation::delegatable,
featureNonFungibleTokensV1,
noPriv,
({
{sfNFTokenOffers, soeREQUIRED},
}))
/** This transaction accepts an existing offer to buy or sell an existing NFT. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenAcceptOffer.h>
#endif
TRANSACTION(ttNFTOKEN_ACCEPT_OFFER, 29, NFTokenAcceptOffer,
Delegation::delegatable,
featureNonFungibleTokensV1,
noPriv,
({
{sfNFTokenBuyOffer, soeOPTIONAL},
{sfNFTokenSellOffer, soeOPTIONAL},
@@ -302,18 +400,26 @@ TRANSACTION(ttNFTOKEN_ACCEPT_OFFER, 29, NFTokenAcceptOffer,
}))
/** This transaction claws back issued tokens. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Clawback.h>
#endif
TRANSACTION(ttCLAWBACK, 30, Clawback,
Delegation::delegatable,
featureClawback,
noPriv,
({
{sfAmount, soeREQUIRED, soeMPTSupported},
{sfHolder, soeOPTIONAL},
}))
/** This transaction claws back tokens from an AMM pool. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMClawback.h>
#endif
TRANSACTION(ttAMM_CLAWBACK, 31, AMMClawback,
Delegation::delegatable,
featureAMMClawback,
mayDeleteAcct | overrideFreeze,
({
{sfHolder, soeREQUIRED},
{sfAsset, soeREQUIRED},
@@ -322,9 +428,13 @@ TRANSACTION(ttAMM_CLAWBACK, 31, AMMClawback,
}))
/** This transaction type creates an AMM instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMCreate.h>
#endif
TRANSACTION(ttAMM_CREATE, 35, AMMCreate,
Delegation::delegatable,
featureAMM,
createPseudoAcct,
({
{sfAmount, soeREQUIRED},
{sfAmount2, soeREQUIRED},
@@ -332,9 +442,13 @@ TRANSACTION(ttAMM_CREATE, 35, AMMCreate,
}))
/** This transaction type deposits into an AMM instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMDeposit.h>
#endif
TRANSACTION(ttAMM_DEPOSIT, 36, AMMDeposit,
Delegation::delegatable,
featureAMM,
noPriv,
({
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
@@ -346,9 +460,13 @@ TRANSACTION(ttAMM_DEPOSIT, 36, AMMDeposit,
}))
/** This transaction type withdraws from an AMM instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMWithdraw.h>
#endif
TRANSACTION(ttAMM_WITHDRAW, 37, AMMWithdraw,
Delegation::delegatable,
featureAMM,
mayDeleteAcct,
({
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
@@ -359,9 +477,13 @@ TRANSACTION(ttAMM_WITHDRAW, 37, AMMWithdraw,
}))
/** This transaction type votes for the trading fee */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMVote.h>
#endif
TRANSACTION(ttAMM_VOTE, 38, AMMVote,
Delegation::delegatable,
featureAMM,
noPriv,
({
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
@@ -369,9 +491,13 @@ TRANSACTION(ttAMM_VOTE, 38, AMMVote,
}))
/** This transaction type bids for the auction slot */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMBid.h>
#endif
TRANSACTION(ttAMM_BID, 39, AMMBid,
Delegation::delegatable,
featureAMM,
noPriv,
({
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
@@ -381,18 +507,26 @@ TRANSACTION(ttAMM_BID, 39, AMMBid,
}))
/** This transaction type deletes AMM in the empty state */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/AMMDelete.h>
#endif
TRANSACTION(ttAMM_DELETE, 40, AMMDelete,
Delegation::delegatable,
featureAMM,
mustDeleteAcct,
({
{sfAsset, soeREQUIRED},
{sfAsset2, soeREQUIRED},
}))
/** This transactions creates a crosschain sequence number */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/XChainBridge.h>
#endif
TRANSACTION(ttXCHAIN_CREATE_CLAIM_ID, 41, XChainCreateClaimID,
Delegation::delegatable,
featureXChainBridge,
noPriv,
({
{sfXChainBridge, soeREQUIRED},
{sfSignatureReward, soeREQUIRED},
@@ -403,6 +537,7 @@ TRANSACTION(ttXCHAIN_CREATE_CLAIM_ID, 41, XChainCreateClaimID,
TRANSACTION(ttXCHAIN_COMMIT, 42, XChainCommit,
Delegation::delegatable,
featureXChainBridge,
noPriv,
({
{sfXChainBridge, soeREQUIRED},
{sfXChainClaimID, soeREQUIRED},
@@ -414,6 +549,7 @@ TRANSACTION(ttXCHAIN_COMMIT, 42, XChainCommit,
TRANSACTION(ttXCHAIN_CLAIM, 43, XChainClaim,
Delegation::delegatable,
featureXChainBridge,
noPriv,
({
{sfXChainBridge, soeREQUIRED},
{sfXChainClaimID, soeREQUIRED},
@@ -426,6 +562,7 @@ TRANSACTION(ttXCHAIN_CLAIM, 43, XChainClaim,
TRANSACTION(ttXCHAIN_ACCOUNT_CREATE_COMMIT, 44, XChainAccountCreateCommit,
Delegation::delegatable,
featureXChainBridge,
noPriv,
({
{sfXChainBridge, soeREQUIRED},
{sfDestination, soeREQUIRED},
@@ -437,6 +574,7 @@ TRANSACTION(ttXCHAIN_ACCOUNT_CREATE_COMMIT, 44, XChainAccountCreateCommit,
TRANSACTION(ttXCHAIN_ADD_CLAIM_ATTESTATION, 45, XChainAddClaimAttestation,
Delegation::delegatable,
featureXChainBridge,
createAcct,
({
{sfXChainBridge, soeREQUIRED},
@@ -453,9 +591,11 @@ TRANSACTION(ttXCHAIN_ADD_CLAIM_ATTESTATION, 45, XChainAddClaimAttestation,
}))
/** This transaction adds an attestation to an account */
TRANSACTION(ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION, 46, XChainAddAccountCreateAttestation,
TRANSACTION(ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION, 46,
XChainAddAccountCreateAttestation,
Delegation::delegatable,
featureXChainBridge,
createAcct,
({
{sfXChainBridge, soeREQUIRED},
@@ -476,6 +616,7 @@ TRANSACTION(ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION, 46, XChainAddAccountCreateA
TRANSACTION(ttXCHAIN_MODIFY_BRIDGE, 47, XChainModifyBridge,
Delegation::delegatable,
featureXChainBridge,
noPriv,
({
{sfXChainBridge, soeREQUIRED},
{sfSignatureReward, soeOPTIONAL},
@@ -486,6 +627,7 @@ TRANSACTION(ttXCHAIN_MODIFY_BRIDGE, 47, XChainModifyBridge,
TRANSACTION(ttXCHAIN_CREATE_BRIDGE, 48, XChainCreateBridge,
Delegation::delegatable,
featureXChainBridge,
noPriv,
({
{sfXChainBridge, soeREQUIRED},
{sfSignatureReward, soeREQUIRED},
@@ -493,9 +635,13 @@ TRANSACTION(ttXCHAIN_CREATE_BRIDGE, 48, XChainCreateBridge,
}))
/** This transaction type creates or updates a DID */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/DID.h>
#endif
TRANSACTION(ttDID_SET, 49, DIDSet,
Delegation::delegatable,
featureDID,
noPriv,
({
{sfDIDDocument, soeOPTIONAL},
{sfURI, soeOPTIONAL},
@@ -506,12 +652,17 @@ TRANSACTION(ttDID_SET, 49, DIDSet,
TRANSACTION(ttDID_DELETE, 50, DIDDelete,
Delegation::delegatable,
featureDID,
noPriv,
({}))
/** This transaction type creates an Oracle instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/SetOracle.h>
#endif
TRANSACTION(ttORACLE_SET, 51, OracleSet,
Delegation::delegatable,
featurePriceOracle,
noPriv,
({
{sfOracleDocumentID, soeREQUIRED},
{sfProvider, soeOPTIONAL},
@@ -522,26 +673,38 @@ TRANSACTION(ttORACLE_SET, 51, OracleSet,
}))
/** This transaction type deletes an Oracle instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/DeleteOracle.h>
#endif
TRANSACTION(ttORACLE_DELETE, 52, OracleDelete,
Delegation::delegatable,
featurePriceOracle,
noPriv,
({
{sfOracleDocumentID, soeREQUIRED},
}))
/** This transaction type fixes a problem in the ledger state */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LedgerStateFix.h>
#endif
TRANSACTION(ttLEDGER_STATE_FIX, 53, LedgerStateFix,
Delegation::delegatable,
fixNFTokenPageLinks,
noPriv,
({
{sfLedgerFixType, soeREQUIRED},
{sfOwner, soeOPTIONAL},
}))
/** This transaction type creates a MPTokensIssuance instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/MPTokenIssuanceCreate.h>
#endif
TRANSACTION(ttMPTOKEN_ISSUANCE_CREATE, 54, MPTokenIssuanceCreate,
Delegation::delegatable,
featureMPTokensV1,
createMPTIssuance,
({
{sfAssetScale, soeOPTIONAL},
{sfTransferFee, soeOPTIONAL},
@@ -552,17 +715,25 @@ TRANSACTION(ttMPTOKEN_ISSUANCE_CREATE, 54, MPTokenIssuanceCreate,
}))
/** This transaction type destroys a MPTokensIssuance instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/MPTokenIssuanceDestroy.h>
#endif
TRANSACTION(ttMPTOKEN_ISSUANCE_DESTROY, 55, MPTokenIssuanceDestroy,
Delegation::delegatable,
featureMPTokensV1,
destroyMPTIssuance,
({
{sfMPTokenIssuanceID, soeREQUIRED},
}))
/** This transaction type sets flags on a MPTokensIssuance or MPToken instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/MPTokenIssuanceSet.h>
#endif
TRANSACTION(ttMPTOKEN_ISSUANCE_SET, 56, MPTokenIssuanceSet,
Delegation::delegatable,
featureMPTokensV1,
noPriv,
({
{sfMPTokenIssuanceID, soeREQUIRED},
{sfHolder, soeOPTIONAL},
@@ -573,18 +744,26 @@ TRANSACTION(ttMPTOKEN_ISSUANCE_SET, 56, MPTokenIssuanceSet,
}))
/** This transaction type authorizes a MPToken instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/MPTokenAuthorize.h>
#endif
TRANSACTION(ttMPTOKEN_AUTHORIZE, 57, MPTokenAuthorize,
Delegation::delegatable,
featureMPTokensV1,
mustAuthorizeMPT,
({
{sfMPTokenIssuanceID, soeREQUIRED},
{sfHolder, soeOPTIONAL},
}))
/** This transaction type create an Credential instance */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Credentials.h>
#endif
TRANSACTION(ttCREDENTIAL_CREATE, 58, CredentialCreate,
Delegation::delegatable,
featureCredentials,
noPriv,
({
{sfSubject, soeREQUIRED},
{sfCredentialType, soeREQUIRED},
@@ -596,6 +775,7 @@ TRANSACTION(ttCREDENTIAL_CREATE, 58, CredentialCreate,
TRANSACTION(ttCREDENTIAL_ACCEPT, 59, CredentialAccept,
Delegation::delegatable,
featureCredentials,
noPriv,
({
{sfIssuer, soeREQUIRED},
{sfCredentialType, soeREQUIRED},
@@ -605,6 +785,7 @@ TRANSACTION(ttCREDENTIAL_ACCEPT, 59, CredentialAccept,
TRANSACTION(ttCREDENTIAL_DELETE, 60, CredentialDelete,
Delegation::delegatable,
featureCredentials,
noPriv,
({
{sfSubject, soeOPTIONAL},
{sfIssuer, soeOPTIONAL},
@@ -612,9 +793,13 @@ TRANSACTION(ttCREDENTIAL_DELETE, 60, CredentialDelete,
}))
/** This transaction type modify a NFToken */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/NFTokenModify.h>
#endif
TRANSACTION(ttNFTOKEN_MODIFY, 61, NFTokenModify,
Delegation::delegatable,
featureDynamicNFT,
noPriv,
({
{sfNFTokenID, soeREQUIRED},
{sfOwner, soeOPTIONAL},
@@ -622,35 +807,51 @@ TRANSACTION(ttNFTOKEN_MODIFY, 61, NFTokenModify,
}))
/** This transaction type creates or modifies a Permissioned Domain */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/PermissionedDomainSet.h>
#endif
TRANSACTION(ttPERMISSIONED_DOMAIN_SET, 62, PermissionedDomainSet,
Delegation::delegatable,
featurePermissionedDomains,
noPriv,
({
{sfDomainID, soeOPTIONAL},
{sfAcceptedCredentials, soeREQUIRED},
}))
/** This transaction type deletes a Permissioned Domain */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/PermissionedDomainDelete.h>
#endif
TRANSACTION(ttPERMISSIONED_DOMAIN_DELETE, 63, PermissionedDomainDelete,
Delegation::delegatable,
featurePermissionedDomains,
noPriv,
({
{sfDomainID, soeREQUIRED},
}))
/** This transaction type delegates authorized account specified permissions */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/DelegateSet.h>
#endif
TRANSACTION(ttDELEGATE_SET, 64, DelegateSet,
Delegation::notDelegatable,
featurePermissionDelegation,
noPriv,
({
{sfAuthorize, soeREQUIRED},
{sfPermissions, soeREQUIRED},
}))
/** This transaction creates a single asset vault. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultCreate.h>
#endif
TRANSACTION(ttVAULT_CREATE, 65, VaultCreate,
Delegation::delegatable,
featureSingleAssetVault,
createPseudoAcct | createMPTIssuance | mustModifyVault,
({
{sfAsset, soeREQUIRED, soeMPTSupported},
{sfAssetsMaximum, soeOPTIONAL},
@@ -662,9 +863,13 @@ TRANSACTION(ttVAULT_CREATE, 65, VaultCreate,
}))
/** This transaction updates a single asset vault. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultSet.h>
#endif
TRANSACTION(ttVAULT_SET, 66, VaultSet,
Delegation::delegatable,
featureSingleAssetVault,
mustModifyVault,
({
{sfVaultID, soeREQUIRED},
{sfAssetsMaximum, soeOPTIONAL},
@@ -673,26 +878,38 @@ TRANSACTION(ttVAULT_SET, 66, VaultSet,
}))
/** This transaction deletes a single asset vault. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultDelete.h>
#endif
TRANSACTION(ttVAULT_DELETE, 67, VaultDelete,
Delegation::delegatable,
featureSingleAssetVault,
mustDeleteAcct | destroyMPTIssuance | mustModifyVault,
({
{sfVaultID, soeREQUIRED},
}))
/** This transaction trades assets for shares with a vault. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultDeposit.h>
#endif
TRANSACTION(ttVAULT_DEPOSIT, 68, VaultDeposit,
Delegation::delegatable,
featureSingleAssetVault,
mayAuthorizeMPT | mustModifyVault,
({
{sfVaultID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
}))
/** This transaction trades shares for assets with a vault. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultWithdraw.h>
#endif
TRANSACTION(ttVAULT_WITHDRAW, 69, VaultWithdraw,
Delegation::delegatable,
featureSingleAssetVault,
mayDeleteMPT | mustModifyVault,
({
{sfVaultID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
@@ -701,9 +918,13 @@ TRANSACTION(ttVAULT_WITHDRAW, 69, VaultWithdraw,
}))
/** This transaction claws back tokens from a vault. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/VaultClawback.h>
#endif
TRANSACTION(ttVAULT_CLAWBACK, 70, VaultClawback,
Delegation::delegatable,
featureSingleAssetVault,
mayDeleteMPT | mustModifyVault,
({
{sfVaultID, soeREQUIRED},
{sfHolder, soeREQUIRED},
@@ -711,21 +932,176 @@ TRANSACTION(ttVAULT_CLAWBACK, 70, VaultClawback,
}))
/** This transaction type batches together transactions. */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Batch.h>
#endif
TRANSACTION(ttBATCH, 71, Batch,
Delegation::notDelegatable,
featureBatch,
noPriv,
({
{sfRawTransactions, soeREQUIRED},
{sfBatchSigners, soeOPTIONAL},
}))
/** Reserve 72-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,
Delegation::delegatable,
featureLendingProtocol,
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,
Delegation::delegatable,
featureLendingProtocol,
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,
Delegation::delegatable,
featureLendingProtocol,
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,
Delegation::delegatable,
featureLendingProtocol,
mayAuthorizeMPT, ({
{sfLoanBrokerID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
{sfDestination, soeOPTIONAL},
{sfDestinationTag, soeOPTIONAL},
}))
/** This transaction claws back First Loss Capital from a Loan Broker to
the issuer of the capital */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanBrokerCoverClawback.h>
#endif
TRANSACTION(ttLOAN_BROKER_COVER_CLAWBACK, 78, LoanBrokerCoverClawback,
Delegation::delegatable,
featureLendingProtocol,
noPriv, ({
{sfLoanBrokerID, soeOPTIONAL},
{sfAmount, soeOPTIONAL, soeMPTSupported},
}))
/** This transaction creates a Loan */
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/LoanSet.h>
#endif
TRANSACTION(ttLOAN_SET, 80, LoanSet,
Delegation::delegatable,
featureLendingProtocol,
mayAuthorizeMPT | mustModifyVault, ({
{sfLoanBrokerID, soeREQUIRED},
{sfData, soeOPTIONAL},
{sfCounterparty, soeOPTIONAL},
{sfCounterpartySignature, soeOPTIONAL},
{sfLoanOriginationFee, soeOPTIONAL},
{sfLoanServiceFee, soeOPTIONAL},
{sfLatePaymentFee, soeOPTIONAL},
{sfClosePaymentFee, soeOPTIONAL},
{sfOverpaymentFee, soeOPTIONAL},
{sfInterestRate, soeOPTIONAL},
{sfLateInterestRate, soeOPTIONAL},
{sfCloseInterestRate, soeOPTIONAL},
{sfOverpaymentInterestRate, soeOPTIONAL},
{sfPrincipalRequested, 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, 81, LoanDelete,
Delegation::delegatable,
featureLendingProtocol,
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, 82, LoanManage,
Delegation::delegatable,
featureLendingProtocol,
// All of the LoanManage options will modify the vault, but the
// transaction can succeed without options, essentially making it
// a noop.
mayModifyVault, ({
{sfLoanID, soeREQUIRED},
}))
#if LOANDRAW
/** 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, 83, LoanDraw,
Delegation::delegatable,
featureLendingProtocol,
noPriv, ({
{sfLoanID, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported},
}))
#endif
/** 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, 84, LoanPay,
Delegation::delegatable,
featureLendingProtocol,
mayAuthorizeMPT | mustModifyVault, ({
{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
*/
#if TRANSACTION_INCLUDE
# include <xrpld/app/tx/detail/Change.h>
#endif
TRANSACTION(ttAMENDMENT, 100, EnableAmendment,
Delegation::notDelegatable,
uint256{},
noPriv,
({
{sfLedgerSequence, soeREQUIRED},
{sfAmendment, soeREQUIRED},
@@ -737,6 +1113,7 @@ TRANSACTION(ttAMENDMENT, 100, EnableAmendment,
TRANSACTION(ttFEE, 101, SetFee,
Delegation::notDelegatable,
uint256{},
noPriv,
({
{sfLedgerSequence, soeOPTIONAL},
// Old version uses raw numbers
@@ -757,6 +1134,7 @@ TRANSACTION(ttFEE, 101, SetFee,
TRANSACTION(ttUNL_MODIFY, 102, UNLModify,
Delegation::notDelegatable,
uint256{},
noPriv,
({
{sfUNLModifyDisabling, soeREQUIRED},
{sfLedgerSequence, soeREQUIRED},

View File

@@ -59,6 +59,8 @@ JSS(BaseAsset); // in: Oracle
JSS(BidMax); // in: AMM Bid
JSS(BidMin); // in: AMM Bid
JSS(ClearFlag); // field.
JSS(Counterparty); // field.
JSS(CounterpartySignature);// field.
JSS(DeliverMax); // out: alias to Amount
JSS(DeliverMin); // in: TransactionSign
JSS(Destination); // in: TransactionSign; field.
@@ -392,6 +394,8 @@ JSS(load_factor_local); // out: NetworkOPs
JSS(load_factor_net); // out: NetworkOPs
JSS(load_factor_server); // out: NetworkOPs
JSS(load_fee); // out: LoadFeeTrackImp, NetworkOPs
JSS(loan_broker_id); // in: LedgerEntry
JSS(loan_seq); // in: LedgerEntry
JSS(local); // out: resource/Logic.h
JSS(local_txs); // out: GetCounts
JSS(local_static_keys); // out: ValidatorList
@@ -504,6 +508,7 @@ JSS(propose_seq); // out: LedgerPropose
JSS(proposers); // out: NetworkOPs, LedgerConsensus
JSS(protocol); // out: NetworkOPs, PeerImp
JSS(proxied); // out: RPC ping
JSS(pseudo_account); // out: AccountInfo
JSS(pubkey_node); // out: NetworkOPs
JSS(pubkey_publisher); // out: ValidatorList
JSS(pubkey_validator); // out: NetworkOPs, ValidatorList
@@ -569,6 +574,7 @@ JSS(settle_delay); // out: AccountChannels
JSS(severity); // in: LogLevel
JSS(shares); // out: VaultInfo
JSS(signature); // out: NetworkOPs, ChannelAuthorize
JSS(signature_target); // in: TransactionSign
JSS(signature_verified); // out: ChannelVerify
JSS(signing_key); // out: NetworkOPs
JSS(signing_keys); // out: ValidatorList
@@ -722,11 +728,11 @@ JSS(write_load); // out: GetCounts
#pragma push_macro("LEDGER_ENTRY_DUPLICATE")
#undef LEDGER_ENTRY_DUPLICATE
#define LEDGER_ENTRY(tag, value, name, rpcName, fields) \
JSS(name); \
#define LEDGER_ENTRY(tag, value, name, rpcName, ...) \
JSS(name); \
JSS(rpcName);
#define LEDGER_ENTRY_DUPLICATE(tag, value, name, rpcName, fields) JSS(rpcName);
#define LEDGER_ENTRY_DUPLICATE(tag, value, name, rpcName, ...) JSS(rpcName);
#include <xrpl/protocol/detail/ledger_entries.macro>

View File

@@ -436,10 +436,12 @@ public:
admin_.erase(admin_.iterator_to(entry));
break;
default:
// LCOV_EXCL_START
UNREACHABLE(
"ripple::Resource::Logic::release : invalid entry "
"kind");
break;
// LCOV_EXCL_STOP
}
inactive_.push_back(entry);
entry.whenExpires = m_clock.now() + secondsUntilExpiration;

View File

@@ -30,15 +30,29 @@
#include <boost/asio/buffer.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/beast/core/detect_ssl.hpp>
#include <boost/beast/core/multi_buffer.hpp>
#include <boost/beast/core/tcp_stream.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/predef.h>
#if !BOOST_OS_WINDOWS
#include <sys/resource.h>
#include <dirent.h>
#include <unistd.h>
#endif
#include <algorithm>
#include <chrono>
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <sstream>
namespace ripple {
@@ -98,10 +112,27 @@ private:
boost::asio::strand<boost::asio::io_context::executor_type> strand_;
bool ssl_;
bool plain_;
static constexpr std::chrono::milliseconds INITIAL_ACCEPT_DELAY{50};
static constexpr std::chrono::milliseconds MAX_ACCEPT_DELAY{2000};
std::chrono::milliseconds accept_delay_{INITIAL_ACCEPT_DELAY};
boost::asio::steady_timer backoff_timer_;
static constexpr double FREE_FD_THRESHOLD = 0.70;
struct FDStats
{
std::uint64_t used{0};
std::uint64_t limit{0};
};
void
reOpen();
std::optional<FDStats>
query_fd_stats() const;
bool
should_throttle_for_fds();
public:
Door(
Handler& handler,
@@ -299,6 +330,7 @@ Door<Handler>::Door(
, plain_(
port_.protocol.count("http") > 0 || port_.protocol.count("ws") > 0 ||
port_.protocol.count("ws2"))
, backoff_timer_(io_context)
{
reOpen();
}
@@ -323,6 +355,7 @@ Door<Handler>::close()
return boost::asio::post(
strand_,
std::bind(&Door<Handler>::close, this->shared_from_this()));
backoff_timer_.cancel();
error_code ec;
acceptor_.close(ec);
}
@@ -368,6 +401,17 @@ Door<Handler>::do_accept(boost::asio::yield_context do_yield)
{
while (acceptor_.is_open())
{
if (should_throttle_for_fds())
{
backoff_timer_.expires_after(accept_delay_);
boost::system::error_code tec;
backoff_timer_.async_wait(do_yield[tec]);
accept_delay_ = std::min(accept_delay_ * 2, MAX_ACCEPT_DELAY);
JLOG(j_.warn()) << "Throttling do_accept for "
<< accept_delay_.count() << "ms.";
continue;
}
error_code ec;
endpoint_type remote_address;
stream_type stream(ioc_);
@@ -377,15 +421,28 @@ Door<Handler>::do_accept(boost::asio::yield_context do_yield)
{
if (ec == boost::asio::error::operation_aborted)
break;
JLOG(j_.error()) << "accept: " << ec.message();
if (ec == boost::asio::error::no_descriptors)
if (ec == boost::asio::error::no_descriptors ||
ec == boost::asio::error::no_buffer_space)
{
JLOG(j_.info()) << "re-opening acceptor";
reOpen();
JLOG(j_.warn()) << "accept: Too many open files. Pausing for "
<< accept_delay_.count() << "ms.";
backoff_timer_.expires_after(accept_delay_);
boost::system::error_code tec;
backoff_timer_.async_wait(do_yield[tec]);
accept_delay_ = std::min(accept_delay_ * 2, MAX_ACCEPT_DELAY);
}
else
{
JLOG(j_.error()) << "accept error: " << ec.message();
}
continue;
}
accept_delay_ = INITIAL_ACCEPT_DELAY;
if (ssl_ && plain_)
{
if (auto sp = ios().template emplace<Detector>(
@@ -408,6 +465,60 @@ Door<Handler>::do_accept(boost::asio::yield_context do_yield)
}
}
template <class Handler>
std::optional<typename Door<Handler>::FDStats>
Door<Handler>::query_fd_stats() const
{
#if BOOST_OS_WINDOWS
return std::nullopt;
#else
FDStats s;
struct rlimit rl;
if (getrlimit(RLIMIT_NOFILE, &rl) != 0 || rl.rlim_cur == RLIM_INFINITY)
return std::nullopt;
s.limit = static_cast<std::uint64_t>(rl.rlim_cur);
#if BOOST_OS_LINUX
constexpr char const* kFdDir = "/proc/self/fd";
#else
constexpr char const* kFdDir = "/dev/fd";
#endif
if (DIR* d = ::opendir(kFdDir))
{
std::uint64_t cnt = 0;
while (::readdir(d) != nullptr)
++cnt;
::closedir(d);
// readdir counts '.', '..', and the DIR* itself shows in the list
s.used = (cnt >= 3) ? (cnt - 3) : 0;
return s;
}
return std::nullopt;
#endif
}
template <class Handler>
bool
Door<Handler>::should_throttle_for_fds()
{
#if BOOST_OS_WINDOWS
return false;
#else
auto const stats = query_fd_stats();
if (!stats || stats->limit == 0)
return false;
auto const& s = *stats;
auto const free = (s.limit > s.used) ? (s.limit - s.used) : 0ull;
double const free_ratio =
static_cast<double>(free) / static_cast<double>(s.limit);
if (free_ratio < FREE_FD_THRESHOLD)
{
return true;
}
return false;
#endif
}
} // namespace ripple
#endif

View File

@@ -239,9 +239,11 @@ Logs::fromSeverity(beast::severities::Severity level)
case kError:
return lsERROR;
// LCOV_EXCL_START
default:
UNREACHABLE("ripple::Logs::fromSeverity : invalid severity");
[[fallthrough]];
// LCOV_EXCL_STOP
case kFatal:
break;
}
@@ -265,9 +267,11 @@ Logs::toSeverity(LogSeverity level)
return kWarning;
case lsERROR:
return kError;
// LCOV_EXCL_START
default:
UNREACHABLE("ripple::Logs::toSeverity : invalid severity");
[[fallthrough]];
// LCOV_EXCL_STOP
case lsFATAL:
break;
}
@@ -292,9 +296,11 @@ Logs::toString(LogSeverity s)
return "Error";
case lsFATAL:
return "Fatal";
// LCOV_EXCL_START
default:
UNREACHABLE("ripple::Logs::toString : invalid severity");
return "Unknown";
// LCOV_EXCL_STOP
}
}
@@ -356,9 +362,11 @@ Logs::format(
case kError:
output += "ERR ";
break;
// LCOV_EXCL_START
default:
UNREACHABLE("ripple::Logs::format : invalid severity");
[[fallthrough]];
// LCOV_EXCL_STOP
case kFatal:
output += "FTL ";
break;

View File

@@ -36,6 +36,7 @@ LogThrow(std::string const& title)
[[noreturn]] void
LogicError(std::string const& s) noexcept
{
// LCOV_EXCL_START
JLOG(debugLog().fatal()) << s;
std::cerr << "Logic error: " << s << std::endl;
// Use a non-standard contract naming here (without namespace) because
@@ -45,6 +46,7 @@ LogicError(std::string const& s) noexcept
// For the above reasons, we want this contract to stand out.
UNREACHABLE("LogicError", {{"message", s}});
std::abort();
// LCOV_EXCL_STOP
}
} // namespace ripple

View File

@@ -174,7 +174,7 @@ Array::append(Json::Value const& v)
return;
}
}
UNREACHABLE("Json::Array::append : invalid type");
UNREACHABLE("Json::Array::append : invalid type"); // LCOV_EXCL_LINE
}
void
@@ -209,7 +209,7 @@ Object::set(std::string const& k, Json::Value const& v)
return;
}
}
UNREACHABLE("Json::Object::set : invalid type");
UNREACHABLE("Json::Object::set : invalid type"); // LCOV_EXCL_LINE
}
//------------------------------------------------------------------------------

View File

@@ -213,8 +213,10 @@ Value::Value(ValueType type) : type_(type), allocated_(0)
value_.bool_ = false;
break;
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::Value(ValueType) : invalid type");
// LCOV_EXCL_STOP
}
}
@@ -290,8 +292,10 @@ Value::Value(Value const& other) : type_(other.type_)
value_.map_ = new ObjectValues(*other.value_.map_);
break;
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::Value(Value const&) : invalid type");
// LCOV_EXCL_STOP
}
}
@@ -318,8 +322,10 @@ Value::~Value()
delete value_.map_;
break;
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::~Value : invalid type");
// LCOV_EXCL_STOP
}
}
@@ -419,8 +425,10 @@ operator<(Value const& x, Value const& y)
return *x.value_.map_ < *y.value_.map_;
}
// LCOV_EXCL_START
default:
UNREACHABLE("Json::operator<(Value, Value) : invalid type");
// LCOV_EXCL_STOP
}
return 0; // unreachable
@@ -465,8 +473,10 @@ operator==(Value const& x, Value const& y)
return x.value_.map_->size() == y.value_.map_->size() &&
*x.value_.map_ == *y.value_.map_;
// LCOV_EXCL_START
default:
UNREACHABLE("Json::operator==(Value, Value) : invalid type");
// LCOV_EXCL_STOP
}
return 0; // unreachable
@@ -506,8 +516,10 @@ Value::asString() const
case objectValue:
JSON_ASSERT_MESSAGE(false, "Type is not convertible to string");
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::asString : invalid type");
// LCOV_EXCL_STOP
}
return ""; // unreachable
@@ -548,8 +560,10 @@ Value::asInt() const
case objectValue:
JSON_ASSERT_MESSAGE(false, "Type is not convertible to int");
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::asInt : invalid type");
// LCOV_EXCL_STOP
}
return 0; // unreachable;
@@ -590,8 +604,10 @@ Value::asUInt() const
case objectValue:
JSON_ASSERT_MESSAGE(false, "Type is not convertible to uint");
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::asUInt : invalid type");
// LCOV_EXCL_STOP
}
return 0; // unreachable;
@@ -622,8 +638,10 @@ Value::asDouble() const
case objectValue:
JSON_ASSERT_MESSAGE(false, "Type is not convertible to double");
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::asDouble : invalid type");
// LCOV_EXCL_STOP
}
return 0; // unreachable;
@@ -654,8 +672,10 @@ Value::asBool() const
case objectValue:
return value_.map_->size() != 0;
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::asBool : invalid type");
// LCOV_EXCL_STOP
}
return false; // unreachable;
@@ -710,8 +730,10 @@ Value::isConvertibleTo(ValueType other) const
return other == objectValue ||
(other == nullValue && value_.map_->size() == 0);
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::isConvertible : invalid type");
// LCOV_EXCL_STOP
}
return false; // unreachable;
@@ -744,8 +766,10 @@ Value::size() const
case objectValue:
return Int(value_.map_->size());
// LCOV_EXCL_START
default:
UNREACHABLE("Json::Value::size : invalid type");
// LCOV_EXCL_STOP
}
return 0; // unreachable;

View File

@@ -17,11 +17,10 @@
*/
//==============================================================================
#include <xrpld/ledger/detail/ApplyStateTable.h>
#include <xrpl/basics/Log.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/json/to_string.h>
#include <xrpl/ledger/detail/ApplyStateTable.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/st.h>
@@ -260,9 +259,11 @@ ApplyStateTable::apply(
}
else
{
// LCOV_EXCL_START
UNREACHABLE(
"ripple::detail::ApplyStateTable::apply : unsupported "
"operation type");
// LCOV_EXCL_STOP
}
}

View File

@@ -17,14 +17,135 @@
*/
//==============================================================================
#include <xrpld/ledger/ApplyView.h>
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/protocol/Protocol.h>
namespace ripple {
namespace directory {
std::uint64_t
createRoot(
ApplyView& view,
Keylet const& directory,
uint256 const& key,
std::function<void(std::shared_ptr<SLE> const&)> const& describe)
{
auto newRoot = std::make_shared<SLE>(directory);
newRoot->setFieldH256(sfRootIndex, directory.key);
describe(newRoot);
STVector256 v;
v.push_back(key);
newRoot->setFieldV256(sfIndexes, v);
view.insert(newRoot);
return std::uint64_t{0};
}
auto
findPreviousPage(ApplyView& view, Keylet const& directory, SLE::ref start)
{
std::uint64_t page = start->getFieldU64(sfIndexPrevious);
auto node = start;
if (page)
{
node = view.peek(keylet::page(directory, page));
if (!node)
LogicError("Directory chain: root back-pointer broken.");
}
auto indexes = node->getFieldV256(sfIndexes);
return std::make_tuple(page, node, indexes);
}
std::uint64_t
insertKey(
ApplyView& view,
SLE::ref node,
std::uint64_t page,
bool preserveOrder,
STVector256& indexes,
uint256 const& key)
{
if (preserveOrder)
{
if (std::find(indexes.begin(), indexes.end(), key) != indexes.end())
LogicError("dirInsert: double insertion");
indexes.push_back(key);
}
else
{
// We can't be sure if this page is already sorted because
// it may be a legacy page we haven't yet touched. Take
// the time to sort it.
std::sort(indexes.begin(), indexes.end());
auto pos = std::lower_bound(indexes.begin(), indexes.end(), key);
if (pos != indexes.end() && key == *pos)
LogicError("dirInsert: double insertion");
indexes.insert(pos, key);
}
node->setFieldV256(sfIndexes, indexes);
view.update(node);
return page;
}
std::optional<std::uint64_t>
insertPage(
ApplyView& view,
std::uint64_t page,
SLE::pointer node,
std::uint64_t nextPage,
SLE::ref next,
uint256 const& key,
Keylet const& directory,
std::function<void(std::shared_ptr<SLE> const&)> const& describe)
{
// Check whether we're out of pages.
if (++page >= dirNodeMaxPages)
{
return std::nullopt;
}
// We are about to create a new node; we'll link it to
// the chain first:
node->setFieldU64(sfIndexNext, page);
view.update(node);
next->setFieldU64(sfIndexPrevious, page);
view.update(next);
// Insert the new key:
STVector256 indexes;
indexes.push_back(key);
node = std::make_shared<SLE>(keylet::page(directory, page));
node->setFieldH256(sfRootIndex, directory.key);
node->setFieldV256(sfIndexes, indexes);
// Save some space by not specifying the value 0 since
// it's the default.
if (page != 1)
node->setFieldU64(sfIndexPrevious, page - 1);
if (nextPage)
node->setFieldU64(sfIndexNext, nextPage);
describe(node);
view.insert(node);
return page;
}
} // namespace directory
std::optional<std::uint64_t>
ApplyView::dirAdd(
bool preserveOrder,
@@ -37,89 +158,21 @@ ApplyView::dirAdd(
if (!root)
{
// No root, make it.
root = std::make_shared<SLE>(directory);
root->setFieldH256(sfRootIndex, directory.key);
describe(root);
STVector256 v;
v.push_back(key);
root->setFieldV256(sfIndexes, v);
insert(root);
return std::uint64_t{0};
return directory::createRoot(*this, directory, key, describe);
}
std::uint64_t page = root->getFieldU64(sfIndexPrevious);
auto node = root;
if (page)
{
node = peek(keylet::page(directory, page));
if (!node)
LogicError("Directory chain: root back-pointer broken.");
}
auto indexes = node->getFieldV256(sfIndexes);
auto [page, node, indexes] =
directory::findPreviousPage(*this, directory, root);
// If there's space, we use it:
if (indexes.size() < dirNodeMaxEntries)
{
if (preserveOrder)
{
if (std::find(indexes.begin(), indexes.end(), key) != indexes.end())
LogicError("dirInsert: double insertion");
indexes.push_back(key);
}
else
{
// We can't be sure if this page is already sorted because
// it may be a legacy page we haven't yet touched. Take
// the time to sort it.
std::sort(indexes.begin(), indexes.end());
auto pos = std::lower_bound(indexes.begin(), indexes.end(), key);
if (pos != indexes.end() && key == *pos)
LogicError("dirInsert: double insertion");
indexes.insert(pos, key);
}
node->setFieldV256(sfIndexes, indexes);
update(node);
return page;
return directory::insertKey(
*this, node, page, preserveOrder, indexes, key);
}
// Check whether we're out of pages.
if (++page >= dirNodeMaxPages)
return std::nullopt;
// We are about to create a new node; we'll link it to
// the chain first:
node->setFieldU64(sfIndexNext, page);
update(node);
root->setFieldU64(sfIndexPrevious, page);
update(root);
// Insert the new key:
indexes.clear();
indexes.push_back(key);
node = std::make_shared<SLE>(keylet::page(directory, page));
node->setFieldH256(sfRootIndex, directory.key);
node->setFieldV256(sfIndexes, indexes);
// Save some space by not specifying the value 0 since
// it's the default.
if (page != 1)
node->setFieldU64(sfIndexPrevious, page - 1);
describe(node);
insert(node);
return page;
return directory::insertPage(
*this, page, node, 0, root, key, directory, describe);
}
bool
@@ -134,8 +187,10 @@ ApplyView::emptyDirDelete(Keylet const& directory)
if (directory.type != ltDIR_NODE ||
node->getFieldH256(sfRootIndex) != directory.key)
{
// LCOV_EXCL_START
UNREACHABLE("ripple::ApplyView::emptyDirDelete : invalid node type");
return false;
// LCOV_EXCL_STOP
}
// The directory still contains entries and so it cannot be removed

View File

@@ -17,7 +17,7 @@
*/
//==============================================================================
#include <xrpld/ledger/detail/ApplyViewBase.h>
#include <xrpl/ledger/detail/ApplyViewBase.h>
namespace ripple {
namespace detail {

View File

@@ -17,7 +17,7 @@
*/
//==============================================================================
#include <xrpld/ledger/ApplyViewImpl.h>
#include <xrpl/ledger/ApplyViewImpl.h>
namespace ripple {

View File

@@ -18,9 +18,8 @@
*/
//==============================================================================
#include <xrpld/ledger/BookDirs.h>
#include <xrpld/ledger/View.h>
#include <xrpl/ledger/BookDirs.h>
#include <xrpl/ledger/View.h>
#include <xrpl/protocol/Indexes.h>
namespace ripple {
@@ -37,7 +36,9 @@ BookDirs::BookDirs(ReadView const& view, Book const& book)
{
if (!cdirFirst(*view_, key_, sle_, entry_, index_))
{
// LCOV_EXCL_START
UNREACHABLE("ripple::BookDirs::BookDirs : directory is empty");
// LCOV_EXCL_STOP
}
}
}
@@ -111,9 +112,11 @@ BookDirs::const_iterator::operator++()
}
else if (!cdirFirst(*view_, cur_key_, sle_, entry_, index_))
{
// LCOV_EXCL_START
UNREACHABLE(
"ripple::BookDirs::const_iterator::operator++ : directory is "
"empty");
// LCOV_EXCL_STOP
}
}

View File

@@ -17,9 +17,8 @@
*/
//==============================================================================
#include <xrpld/ledger/CachedView.h>
#include <xrpl/basics/TaggedCache.ipp>
#include <xrpl/ledger/CachedView.h>
namespace ripple {
namespace detail {

View File

@@ -17,9 +17,8 @@
*/
//==============================================================================
#include <xrpld/app/misc/CredentialHelpers.h>
#include <xrpld/ledger/View.h>
#include <xrpl/ledger/CredentialHelpers.h>
#include <xrpl/ledger/View.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/digest.h>

View File

@@ -17,7 +17,7 @@
*/
//==============================================================================
#include <xrpld/ledger/Dir.h>
#include <xrpl/ledger/Dir.h>
namespace ripple {

View File

@@ -17,9 +17,8 @@
*/
//==============================================================================
#include <xrpld/ledger/OpenView.h>
#include <xrpl/basics/contract.h>
#include <xrpl/ledger/OpenView.h>
namespace ripple {

View File

@@ -17,11 +17,9 @@
*/
//==============================================================================
#include <xrpld/app/paths/detail/AmountSpec.h>
#include <xrpld/ledger/PaymentSandbox.h>
#include <xrpld/ledger/View.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/ledger/PaymentSandbox.h>
#include <xrpl/ledger/View.h>
#include <xrpl/protocol/SField.h>
namespace ripple {

View File

@@ -17,9 +17,8 @@
*/
//==============================================================================
#include <xrpld/ledger/detail/RawStateTable.h>
#include <xrpl/basics/contract.h>
#include <xrpl/ledger/detail/RawStateTable.h>
namespace ripple {
namespace detail {

View File

@@ -17,7 +17,7 @@
*/
//==============================================================================
#include <xrpld/ledger/ReadView.h>
#include <xrpl/ledger/ReadView.h>
namespace ripple {

View File

@@ -17,14 +17,13 @@
*/
//==============================================================================
#include <xrpld/app/misc/CredentialHelpers.h>
#include <xrpld/ledger/ReadView.h>
#include <xrpld/ledger/View.h>
#include <xrpl/basics/Expected.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/chrono.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/ledger/CredentialHelpers.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/ledger/View.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/LedgerFormats.h>
@@ -325,10 +324,12 @@ isVaultPseudoAccountFrozen(
auto const issuer = mptIssuance->getAccountID(sfIssuer);
auto const mptIssuer = view.read(keylet::account(issuer));
if (mptIssuer == nullptr)
{ // LCOV_EXCL_START
{
// LCOV_EXCL_START
UNREACHABLE("ripple::isVaultPseudoAccountFrozen : null MPToken issuer");
return false;
} // LCOV_EXCL_STOP
// LCOV_EXCL_STOP
}
if (!mptIssuer->isFieldPresent(sfVaultID))
return false; // not a Vault pseudo-account, common case
@@ -339,7 +340,8 @@ isVaultPseudoAccountFrozen(
{ // LCOV_EXCL_START
UNREACHABLE("ripple::isVaultPseudoAccountFrozen : null vault");
return false;
} // LCOV_EXCL_STOP
// LCOV_EXCL_STOP
}
return isAnyFrozen(view, {issuer, account}, vault->at(sfAsset), depth + 1);
}
@@ -627,8 +629,8 @@ xrpLiquid(
std::uint32_t const ownerCount = confineOwnerCount(
view.ownerCountHook(id, sle->getFieldU32(sfOwnerCount)), ownerCountAdj);
// AMMs have no reserve requirement
auto const reserve = sle->isFieldPresent(sfAMMID)
// Pseudo-accounts have no reserve requirement
auto const reserve = isPseudoAccount(sle)
? XRPAmount{0}
: view.fees().accountReserve(ownerCount);
@@ -1040,7 +1042,7 @@ adjustOwnerCount(
AccountID const id = (*sle)[sfAccount];
std::uint32_t const adjusted = confineOwnerCount(current, amount, id, j);
view.adjustOwnerCountHook(id, current, adjusted);
sle->setFieldU32(sfOwnerCount, adjusted);
sle->at(sfOwnerCount) = adjusted;
view.update(sle);
}
@@ -1053,13 +1055,17 @@ describeOwnerDir(AccountID const& account)
}
TER
dirLink(ApplyView& view, AccountID const& owner, std::shared_ptr<SLE>& object)
dirLink(
ApplyView& view,
AccountID const& owner,
std::shared_ptr<SLE>& object,
SF_UINT64 const& node)
{
auto const page = view.dirInsert(
keylet::ownerDir(owner), object->key(), describeOwnerDir(owner));
if (!page)
return tecDIR_FULL; // LCOV_EXCL_LINE
object->setFieldU64(sfOwnerNode, *page);
object->setFieldU64(node, *page);
return tesSUCCESS;
}
@@ -1080,15 +1086,51 @@ pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey)
return beast::zero;
}
// Note, the list of the pseudo-account designator fields below MUST be
// maintained but it does NOT need to be amendment-gated, since a
// non-active amendment will not set any field, by definition. Specific
// properties of a pseudo-account are NOT checked here, that's what
// Pseudo-account designator fields MUST be maintained by including the
// SField::sMD_PseudoAccount flag in the SField definition. (Don't forget to
// "| SField::sMD_Default"!) The fields do NOT need to be amendment-gated,
// since a non-active amendment will not set any field, by definition.
// Specific properties of a pseudo-account are NOT checked here, that's what
// InvariantCheck is for.
static std::array<SField const*, 2> const pseudoAccountOwnerFields = {
&sfAMMID, //
&sfVaultID, //
};
[[nodiscard]] std::vector<SField const*> const&
getPseudoAccountFields()
{
static std::vector<SField const*> const pseudoFields = []() {
auto const ar = LedgerFormats::getInstance().findByType(ltACCOUNT_ROOT);
if (!ar)
{
// LCOV_EXCL_START
LogicError(
"ripple::isPseudoAccount : unable to find account root ledger "
"format");
// LCOV_EXCL_STOP
}
auto const& soTemplate = ar->getSOTemplate();
std::vector<SField const*> pseudoFields;
for (auto const& field : soTemplate)
{
if (field.sField().shouldMeta(SField::sMD_PseudoAccount))
pseudoFields.emplace_back(&field.sField());
}
return pseudoFields;
}();
return pseudoFields;
}
[[nodiscard]] bool
isPseudoAccount(std::shared_ptr<SLE const> sleAcct)
{
auto const& fields = getPseudoAccountFields();
// Intentionally use defensive coding here because it's cheap and makes the
// semantics of true return value clean.
return sleAcct && sleAcct->getType() == ltACCOUNT_ROOT &&
std::count_if(
fields.begin(), fields.end(), [&sleAcct](SField const* sf) -> bool {
return sleAcct->isFieldPresent(*sf);
}) > 0;
}
Expected<std::shared_ptr<SLE>, TER>
createPseudoAccount(
@@ -1096,10 +1138,12 @@ createPseudoAccount(
uint256 const& pseudoOwnerKey,
SField const& ownerField)
{
[[maybe_unused]]
auto const& fields = getPseudoAccountFields();
XRPL_ASSERT(
std::count_if(
pseudoAccountOwnerFields.begin(),
pseudoAccountOwnerFields.end(),
fields.begin(),
fields.end(),
[&ownerField](SField const* sf) -> bool {
return *sf == ownerField;
}) == 1,
@@ -1117,9 +1161,10 @@ createPseudoAccount(
// Pseudo-accounts can't submit transactions, so set the sequence number
// to 0 to make them easier to spot and verify, and add an extra level
// of protection.
std::uint32_t const seqno = //
view.rules().enabled(featureSingleAssetVault) //
? 0 //
std::uint32_t const seqno = //
view.rules().enabled(featureSingleAssetVault) || //
view.rules().enabled(featureLendingProtocol) //
? 0 //
: view.seq();
account->setFieldU32(sfSequence, seqno);
// Ignore reserves requirement, disable the master key, allow default
@@ -1135,18 +1180,42 @@ createPseudoAccount(
return account;
}
[[nodiscard]] bool
isPseudoAccount(std::shared_ptr<SLE const> sleAcct)
[[nodiscard]] TER
canAddHolding(ReadView const& view, Issue const& issue)
{
// Intentionally use defensive coding here because it's cheap and makes the
// semantics of true return value clean.
return sleAcct && sleAcct->getType() == ltACCOUNT_ROOT &&
std::count_if(
pseudoAccountOwnerFields.begin(),
pseudoAccountOwnerFields.end(),
[&sleAcct](SField const* sf) -> bool {
return sleAcct->isFieldPresent(*sf);
}) > 0;
if (issue.native())
return tesSUCCESS; // No special checks for XRP
auto const issuer = view.read(keylet::account(issue.getIssuer()));
if (!issuer)
return terNO_ACCOUNT;
else if (!issuer->isFlag(lsfDefaultRipple))
return terNO_RIPPLE;
return tesSUCCESS;
}
[[nodiscard]] TER
canAddHolding(ReadView const& view, MPTIssue const& mptIssue)
{
auto mptID = mptIssue.getMptID();
auto issuance = view.read(keylet::mptIssuance(mptID));
if (!issuance)
return tecOBJECT_NOT_FOUND;
if (!issuance->isFlag(lsfMPTCanTransfer))
return tecNO_AUTH;
return tesSUCCESS;
}
[[nodiscard]] TER
canAddHolding(ReadView const& view, Asset const& asset)
{
return std::visit(
[&]<ValidIssueType TIss>(TIss const& issue) -> TER {
return canAddHolding(view, issue);
},
asset.value());
}
[[nodiscard]] TER
@@ -2616,7 +2685,8 @@ enforceMPTokenAuthorization(
UNREACHABLE(
"ripple::enforceMPTokenAuthorization : condition list is incomplete");
return tefINTERNAL;
} // LCOV_EXCL_STOP
// LCOV_EXCL_STOP
}
TER
canTransfer(
@@ -3066,7 +3136,7 @@ rippleUnlockEscrowMPT(
{ // LCOV_EXCL_START
JLOG(j.error())
<< "rippleUnlockEscrowMPT: MPToken not found for " << receiver;
return tecOBJECT_NOT_FOUND; // LCOV_EXCL_LINE
return tecOBJECT_NOT_FOUND;
} // LCOV_EXCL_STOP
auto current = sle->getFieldU64(sfMPTAmount);

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