Compare commits

..

356 Commits

Author SHA1 Message Date
Vito
943c92ca1e perf: Dispatch hasInvalidAmount on type tag instead of dynamic_cast
hasInvalidAmount runs on the per-transaction invariant-checking path
(ValidAmounts::finalize) and at preflight, walking every field of every
modified entry. The previous implementation tried a dynamic_cast chain
(STAmount, STObject, STArray) on each field, so every scalar non-amount
field paid three failed RTTI casts.

Dispatch on the serialized type tag via getSType() and a switch instead.
The object-like tags all denote STObject subclasses (STLedgerEntry, STTx),
so the downcast is sound; safeDowncast keeps a dynamic_cast validity
assert in debug builds while compiling to static_cast in release.
2026-06-04 15:27:22 +02:00
Ayaz Salikhov
6c543426c3 ci: Fix clang asan include dirs in nix images, add curl & gnupg (#7400) 2026-06-03 22:19:15 +00:00
yinyiqian1
e5cf1a0985 fix: Add zero NFT Offer ID check for NFTokenCancelOffer (#7391) 2026-06-03 19:30:20 +00:00
Ayaz Salikhov
023bdaeeed ci: Install gcov, nettools, cacert in nix images (#7398) 2026-06-03 19:14:17 +00:00
Bart
96b2c0964f refactor: Replace intr_ptr::SharedPtr<SHAMapTreeNode> by SHAMapTreeNodePtr (#7396)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-06-03 15:34:19 +00:00
Ayaz Salikhov
1441d4690d chore: Update flake.lock to allow conan with clang-22 support (#7390) 2026-06-03 00:16:02 +00:00
Vito Tumas
225ed204ad test: Suppress invariant-failure logs in Vault and LoanBroker bug-regression tests (#7379) 2026-06-02 17:12:09 +00:00
Ayaz Salikhov
ad111bcc22 ci: Patch binaries in nix-based images and test in every distro (#7376)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-02 13:51:20 +00:00
Ayaz Salikhov
d4cb68d5a1 ci: Check binaries separately from building them (#7355)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-01 16:47:01 +00:00
dependabot[bot]
e209ee5371 ci: [DEPENDABOT] bump eps1lon/actions-label-merge-conflict from 3.0.3 to 3.1.0 (#7375)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-01 15:29:12 +00:00
Vito Tumas
109b649106 refactor: Use STLedgerEntry type aliases instead of std::shared_ptr (#7282) 2026-06-01 15:27:13 +00:00
Michael Legleux
0fffe23abc fix: Adjust xrpld systemd service and update timer (#7374) 2026-06-01 03:33:19 +00:00
Bart
7e15621e7b release: Bump version to 3.2.0-rc3 (#7371)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-05-31 22:55:18 +00:00
Vito Tumas
99431d7833 fix: Pin overpayment principal reduction to exact on-grid value (#7360) 2026-05-31 22:54:23 +00:00
Ed Hennis
47365f4220 fix: Improve upward rounding edge cases for Number::operator/= (#7328)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
2026-05-31 00:23:29 +00:00
Bart
1599c1a672 refactor: Revert "perf: Remove unnecessary caches (#5439)" (#7359)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-05-30 18:48:59 +00:00
yinyiqian1
763dd503be fix: Add zero domainID check for permissionedDomain (#7362) 2026-05-30 00:16:25 +00:00
Bart
2f3558c610 ci: Run PR title and description checks on staging and release branches (#7331)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-05-28 14:57:29 +00:00
Ayaz Salikhov
f9551ac5ca style: Run shfmt on workflows, actions and markdown bash code (#7333) 2026-05-27 19:24:18 +00:00
Bart
1acc42313c release: Bump version to 3.2.0-rc2 (#7348) 2026-05-27 15:11:38 -04:00
Bart
396d772a15 refactor: Enable support for fixCleanup3_2_0 amendment (#7347) 2026-05-27 19:10:33 +00:00
Ayaz Salikhov
1438bf1c67 release: Bump version to 3.2.0-rc1 (#7335) 2026-05-27 13:20:57 -04:00
Ed Hennis
7da643d864 fix: Fix a rounding error at the Number::maxRep cusp (#7051)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
2026-05-27 15:19:20 +00:00
Ayaz Salikhov
1162371def ci: Only push docker images in XRPLF/rippled (#7330) 2026-05-26 20:03:04 +00:00
dependabot[bot]
2a0feca46b ci: [DEPENDABOT] bump docker/setup-buildx-action from 4.0.0 to 4.1.0 (#7322)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-26 19:36:32 +00:00
dependabot[bot]
108a4c8217 ci: [DEPENDABOT] bump codecov/codecov-action from 6.0.0 to 6.0.1 (#7321)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-26 19:36:21 +00:00
dependabot[bot]
4584b01bde ci: [DEPENDABOT] bump docker/build-push-action from 7.1.0 to 7.2.0 (#7320)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-26 19:36:13 +00:00
dependabot[bot]
7c59786565 ci: [DEPENDABOT] bump docker/metadata-action from 6.0.0 to 6.1.0 (#7319)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-26 19:36:00 +00:00
dependabot[bot]
9623e67b76 ci: [DEPENDABOT] bump docker/login-action from 4.1.0 to 4.2.0 (#7318)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-26 19:35:52 +00:00
Andrzej Budzanowski
85af406a0f fix: Update clang-tidy to include src/tests directory header check (#7307) 2026-05-26 19:35:32 +00:00
Ayaz Salikhov
ac33fb32a7 chore: Pin Python packages for codegen using uv (#7329) 2026-05-26 18:35:38 +00:00
Ayaz Salikhov
23d0812827 style: Use shfmt instead of bashate (#7326) 2026-05-26 18:28:23 +00:00
Vito Tumas
49567e7283 fix: Fix edge-case where vault-depositor may get stuck (#7139) 2026-05-26 18:18:40 +00:00
Vito Tumas
633ef4706f fix: Fix VaultInvariant and VaultDeposit precision bugs at IOU scale boundaries (#7272)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-05-26 16:32:44 +00:00
Ayaz Salikhov
49cb3f45a4 ci: Add clang to nix images (#7308)
Co-authored-by: semgrep-companion-app[bot] <218312740+semgrep-companion-app[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-26 15:45:33 +00:00
Vito Tumas
22a21b175e fix: Include management-fee delta in doOverpayment assertion (#7039) 2026-05-26 14:01:52 +00:00
Pratik Mankawde
e9d885bd9b fix: Fix clang-tidy pre-commit hook to locate compile_commands.json from repo root (#7325)
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-05-26 13:50:18 +00:00
Jingchen
a911f9089e fix: Use consistent scale for debtTotal (#7093)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-24 20:44:29 +00:00
Peter Chen
e34c2667d7 fix: Skip deleted book directories and non-root modifications in ValidBookDirectory invariant (#7312) 2026-05-24 20:37:16 +00:00
Valentin Balaschenko
30de556224 fix: Address review feedback on FD/handle guarding (#5823 follow-up) (#7310) 2026-05-23 14:48:48 +00:00
Gregory Tsipenyuk
dcd2ff0b5f fix: Fix non-canonical MPT amount (#7117)
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-23 06:40:26 +00:00
Bart
dfb9b8ed9a release: Bump version to 3.2.0-b7 (#7316)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-05-22 19:32:12 +00:00
Jingchen
179e73594a fix: Check if the MPT first loss cover can be sent to the broker before deleting the broker (#7125)
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-05-22 11:58:48 +00:00
Michael Legleux
15dd653e4b fix: Fix RPM prerelease ordering and start xrpld on DEB install (#7313) 2026-05-22 11:30:45 +00:00
Michael Legleux
a37afe13ff ci: Re-enable full nproc for Linux (#7315) 2026-05-22 11:30:37 +00:00
Gregory Tsipenyuk
3547a9335f fix: Add assorted MPT/DEX fixes (#7040)
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
Co-authored-by: Shawn Xie <35279399+shawnxie999@users.noreply.github.com>
2026-05-21 18:29:53 +00:00
Bart
1a98182e23 refactor: Remove dead fetchBatch code (#7309)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-05-21 17:52:41 +00:00
Bart
79308705c5 release: Bump version to 3.2.0-b6 (#7311)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-05-21 17:50:59 +00:00
Vito Tumas
e24de65f42 chore: Revert graceful peer disconnection and follow-up fix (#7296) 2026-05-21 16:13:41 +00:00
Vito Tumas
7fdaa0a5ef fix: Fix IOU precision issues in LoanBrokerCover transactions (#7274) 2026-05-21 14:51:58 +00:00
Vito Tumas
795dc5e364 fix: Avoid principal-zeroing in non-final loan payments at coarse scale (#7050)
Co-authored-by: Ed Hennis <ed@ripple.com>
2026-05-21 14:46:26 +00:00
Pratik Mankawde
f6fd5ddb0a fix: Add null check (#7305)
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-21 13:24:04 +00:00
Rithvik Reddygari
afcf6fbcdc docs: Add --parallel flag to cmake build commands in BUILD.md (#7302) 2026-05-21 06:33:19 +00:00
Shawn Xie
28cc20c816 fix: Fix wrong hybrid offer orderbook placement and update LedgerStateFix to amend ExchangeRate meta (#7087)
Co-authored-by: Peter Chen <ychen@ripple.com>
2026-05-21 06:19:04 +00:00
Alex Kremer
a830ab10ef style: More clang-tidy identifier renaming (#7290) 2026-05-20 21:31:15 +00:00
Shawn Xie
8c0080020f fix: Update pDEX invariant firing under a valid offer deletion (#7118)
Co-authored-by: Peter Chen <ychen@ripple.com>
2026-05-20 21:10:04 +00:00
yinyiqian1
9cb0740673 fix: Fix multisign and signfor to check for delegate (#7064) 2026-05-20 20:24:09 +00:00
Mayukha Vadari
242ce3e9e4 refactor: Fix sfGeneric and sfInvalid field names (#7300) 2026-05-20 19:47:59 +00:00
box4wangjing
a5d238e7d4 docs: Fix some comments to improve readability (#7122)
Signed-off-by: box4wangjing <box4wangjing@outlook.com>
Co-authored-by: Mayukha Vadari <mvadari@ripple.com>
2026-05-20 19:46:45 +00:00
Vito Tumas
9cb049276d feat: Propagate underlying MPT flags to vault shares (#7077)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Denis Angell <dangell@transia.co>
Co-authored-by: Fomo <508629+shortthefomo@users.noreply.github.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-20 19:44:09 +00:00
Vito Tumas
93ac1aa7aa fix: Disable unnecessary sanity-check in VaultDeposit (#7288) 2026-05-19 16:38:50 +00:00
dependabot[bot]
d9a3af8207 ci: [DEPENDABOT] bump actions/upload-artifact from 7.0.0 to 7.0.1 (#7286)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-19 16:35:38 +00:00
Ayaz Salikhov
8d1083e5ea ci: Only run reusable package in public repos (#7293) 2026-05-19 13:15:11 +00:00
Fomo
1e45d363c5 fix: Set default peering port to 2459 (#6848)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-05-19 06:05:47 +00:00
Denis Angell
ad3d172a1f fix: Use account ledger entry when canceling token escrows (#6171) 2026-05-18 20:08:48 +00:00
Mayukha Vadari
ad7232cbc5 refactor: Rename account_ to accountID_ (#7284) 2026-05-18 10:56:54 +00:00
Michael Legleux
93836f22db ci: Add Linux package builds (DEB + RPM) to CI (#6639) 2026-05-16 05:08:37 +00:00
Mayukha Vadari
c7ecfc6a97 refactor: Clean up comments post-clang-tidy changes (#7283) 2026-05-15 23:02:04 +00:00
Ed Hennis
6809690fad release: Set version to 3.3.0-b0 (#7280)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-05-15 18:04:49 +00:00
Alex Kremer
5b6e8b6f93 refactor: Rename static constants (#7120)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-05-15 15:32:19 +00:00
Mayukha Vadari
028f0cb5da refactor: Use isFlag where possible instead of bitwise math (#7278) 2026-05-15 14:00:13 +00:00
Ayaz Salikhov
15b3ed1ae7 ci: Update XRPLF/actions (#7281) 2026-05-15 11:21:29 +00:00
Jingchen
cce4cfef10 feat: Add verify_endpoints to help local peer network development (#7268)
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-05-14 17:07:08 +00:00
Bart
afbccf971a chore: Consolidate fix amendments (#7134)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-05-13 20:46:30 +00:00
Michael Legleux
2f65cb5610 ci: Add Conan retry (#7147) 2026-05-13 19:34:46 +00:00
Olek
d4ebd6a168 fix: Backport Permissioned Domains fixes (#7016) 2026-05-13 19:22:29 +00:00
Sergey Kuznetsov
551f3c3b96 refactor: Move unhex lookup table out of function (#7104) 2026-05-13 17:48:43 +00:00
Luc des Trois Maisons
aa5e4ff89f refactor: Improve Forwarded header field parsing (#7126) 2026-05-13 16:48:38 +00:00
Sergey Kuznetsov
977e5a7dba fix: Check network ID in transactionSignFor (#7102) 2026-05-13 16:03:57 +00:00
Ayaz Salikhov
648ec747f2 feat: Implement nix-based Dockerfile for CI (#7083) 2026-05-13 15:10:53 +00:00
Sergey Kuznetsov
c8b42a7f48 refactor: Improve RPC variable naming and handling (#7103) 2026-05-13 14:33:49 +00:00
Valentin Balaschenko
4ad94ae2ff refactor: Use named constant for leaf item size (#39) (#7130)
Co-authored-by: Ed Hennis <ed@ripple.com>
2026-05-13 13:53:01 +00:00
Valentin Balaschenko
411286c519 refactor: Prevent dry-run transactions from being queued (#92) (#7131) 2026-05-13 13:22:00 +00:00
Alex Kremer
e8bdbaa1e8 refactor: Limit JSON array size (#7112) 2026-05-13 12:42:05 +00:00
Vito Tumas
6340c986c9 feat: Enable and rename fixSecurity3_1_3 to fixCleanup3_1_3 (#7128)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-13 09:42:34 +00:00
Michael Legleux
170eb5e588 ci: Limit nproc on Linux builds temporarily (#7132) 2026-05-12 20:46:33 +00:00
Olek
590906dadf fix: Use transaction sequence numbers in permissioned domains (#7129) 2026-05-12 20:15:17 +00:00
Sergey Kuznetsov
448ae8b9df fix: Improve json parsing of currency issuers (#7110) 2026-05-12 20:13:36 +00:00
rrmanukyan
45b1f4dbeb refactor: Fill txJson based on apiVersion (#7109)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-05-12 19:27:07 +00:00
Ed Hennis
8012b5d34f fix: Fix touchy "funds are conserved" assertion in LoanPay (#6231) (#6967)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-05-12 19:25:11 +00:00
Ayaz Salikhov
6c2266c5c7 refactor: Remove erroneous base_uint ctor from container (#7123) 2026-05-12 19:24:05 +00:00
Ayaz Salikhov
aa55392453 ci: Make Show test failure summary work with no build dir (#7124) 2026-05-12 15:54:04 +00:00
Mayukha Vadari
c4c95dbe76 refactor: Replace featureInvariantsV1_1 with fixCleanup3_2_0 (#7116) 2026-05-12 12:26:02 +00:00
Jingchen
a761b0d43c chore: Upgrade mako version (#7108) 2026-05-11 16:32:08 +00:00
Alex Kremer
cdee9a675c refactor: Use more scoped enums (#7086) 2026-05-11 15:39:48 +00:00
Zhiyuan Wang
779b49cd93 fix: Prevent stale AuthAccounts from persisting after tfTwoAssetIfEmpty re-initialization (#6996)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-05-09 14:43:56 +00:00
Vito Tumas
4f8142fd10 fix: Numerically-stable (1+r)^n-1 in computePaymentFactor (#7033) 2026-05-07 19:02:09 +00:00
Ayaz Salikhov
4a9f72c73e style: Make .clang-tidy style a bit more consistent with Clio (#7096) 2026-05-07 17:14:01 +00:00
Alex Kremer
7afdd71a54 chore: More fixes for bad renames (#7092) 2026-05-07 17:04:30 +00:00
Olek
af89854a43 fix: Stop tx processing if failed to delete expired credentials (#6715) (#6962)
Co-authored-by: Ed Hennis <ed@ripple.com>
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-07 12:57:50 +00:00
Ed Hennis
d6c4e6cb93 fix: Cap the base fee for LoanPay (#6969) (#6970)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-05-07 12:48:55 +00:00
Bronek Kozicki
d67e06102a chore: Upgrade Clang sanitizer to clang-22 and switch gcc-15 sanitizer to Release (#7079) 2026-05-07 10:36:36 +00:00
Bart
8c71ec803d fix: Restore clang-tidy change to section name in config (#7091)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-05-07 10:34:47 +00:00
Ayaz Salikhov
8e2aa33f64 chore: Add IWYU pragma for boost::optional to fix clang-tidy (#7088) 2026-05-06 23:31:10 +00:00
Ayaz Salikhov
13b72a4120 chore: Update zlib to 1.3.2, sqlite to 3.53.0, libarchive to 3.8.7, jemalloc to 5.3.1, boost to 1.91.0 (#7084) 2026-05-06 17:05:11 +00:00
Ayaz Salikhov
fcae50a487 chore: Update conan.lock (#7081)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-05-06 14:36:42 +00:00
Vito Tumas
a4720d0449 chore: Mark empty transactor invariants as future work (#7080) 2026-05-06 12:55:24 +00:00
Vet
50244a8637 chore: Update default values of base and owner reserve to 1/0.2 (#6382)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-05-06 11:19:57 +00:00
Mayukha Vadari
5e1c35f7f7 fix: Fix regressions in server_definitions (#7008) 2026-05-05 17:18:26 +00:00
Ayaz Salikhov
27f7fdb3a6 chore: Do not duplicate sanitizer flags (#7058)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-05 16:32:43 +00:00
Ayaz Salikhov
6e6fb9cdf3 ci: Run pre-commit on diff in clang-tidy workflow (#7078)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-05 16:31:46 +00:00
Ayaz Salikhov
e092c52409 ci: Use XRPLF/create-issue (#7076) 2026-05-05 13:49:13 +00:00
Ayaz Salikhov
d050073842 ci: Rewrite clang-tidy workflow(s) in a reusable manner (#7062) 2026-05-04 12:51:07 +00:00
Alex Kremer
8490206228 chore: Ignore identifier-naming update in git blame (#7066)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-03 21:42:44 +00:00
Alex Kremer
8995564ed6 refactor: Enable clang-tidy readability-identifier-naming check (#6571) 2026-05-03 10:31:53 +00:00
Bart
182d844996 refactor: Revert certain Throws by LogicErrors (#7036)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-05-01 09:50:00 +00:00
Ayaz Salikhov
37b895b678 ci: Rename print-env -> print-build-env (#7061) 2026-05-01 09:44:52 +00:00
Pratik Mankawde
c6053f5d64 fix: Gate -mcmodel flags to x86_64 in sanitizer builds (#7049)
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-04-30 13:33:33 +00:00
Vito Tumas
31180f94c2 fix: Prevents overwriting a bool value in an invariant (#6609)
Co-authored-by: Ed Hennis <ed@ripple.com>
2026-04-30 13:05:09 +00:00
Pratik Mankawde
6407f0fa52 fix: Address code review comments regarding boost::coroutine2 (#6977)
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-04-30 10:36:12 +00:00
Bart
4d0ea8ae36 refactor: Apply various minor improvements and corrections (#7045)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-04-30 10:22:11 +00:00
Zhiyuan Wang
dbd646bd53 fix: Store Delegate object in delegating and authorized account directories for proper deletion (#6681) 2026-04-29 18:17:01 +00:00
Ayaz Salikhov
6ae090ba45 ci: Use print-env from XRPLF/actions (#7052) 2026-04-29 18:14:16 +00:00
Mayukha Vadari
7be98d95de fix: Make assorted RPC fixes (#6529)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-29 18:05:34 +00:00
Alex Kremer
f7275b7ad9 chore: Enable clang-tidy v21 new checks (#7031) 2026-04-29 15:17:35 +00:00
Jingchen
46b997b774 feat: Create new transaction testing framework TxTest (#6537)
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
Co-authored-by: Copilot <copilot@github.com>
2026-04-28 14:16:10 +00:00
Vito Tumas
147da57348 feat: Add cleanup amendment for 3.2.0 (#7037) 2026-04-28 10:22:32 +00:00
Pratik Mankawde
3547112540 fix: Fix ubsan flagged issues (#6151)
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-04-27 20:34:16 +00:00
Alex Kremer
4dc923dcc5 chore: Enable clang-tidy modernize-use-nodiscard check (#7015) 2026-04-24 17:19:30 +00:00
Pratik Mankawde
158df5394c fix: Resolve MSVC Debug build failure in JobQueue.h; re-enable _CRTDBG_MAP_ALLOC in CI (#6993)
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Co-authored-by: Ed Hennis <ed@ripple.com>
2026-04-24 16:47:16 +00:00
Zhiyuan Wang
a6bd9251d2 docs: Update hybrid offer invariant comment (#7007) 2026-04-24 16:35:10 +00:00
Mayukha Vadari
9ae29612ea fix: Fix flaky CI tests (#7005)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-24 13:23:43 +00:00
Mayukha Vadari
82abf2a849 docs: Update bug bounty information (#7006) 2026-04-24 13:15:12 +00:00
Mayukha Vadari
7cfa5d4610 fix: Make assorted Payments fixes (#6585) 2026-04-24 12:56:50 +00:00
Mayukha Vadari
248cb29681 refactor: Move LendingHelpers into libxrpl/ledger/helpers (#6638)
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-04-24 12:06:26 +00:00
Jingchen
7a449edebb refactor: Clean up NetworkOPs (#6575)
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2026-04-23 17:59:49 +00:00
Alex Kremer
19da25812b fix: Remaining clang-tidy unchecked optionals (#6979) 2026-04-23 16:21:01 +00:00
Jingchen
7cd503859e refactor: Remove seq from TMGetObjectByHash (#6976) 2026-04-23 13:59:23 +00:00
Alex Kremer
b41cbb08c6 chore: Add pre-commit hook to fix include style (#6995)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-04-22 22:20:14 +00:00
pdp2121
bd1b126230 feat: Add --definitions flag and artifact (#6858)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-04-22 20:10:52 +00:00
Mayukha Vadari
1c6cdc653c fix: More clang-tidy issues (#6992) 2026-04-22 17:42:15 +00:00
Alex Kremer
4ab20770f7 chore: Optionally run clang-tidy via pre-commit (#6680)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-04-22 15:06:36 +00:00
Vito Tumas
2e307329f0 refactor: Add transaction-specific invariant checking (#6551) 2026-04-22 14:41:19 +00:00
Ayaz Salikhov
3429845c40 style: Add bashate pre-commit hook to unify bash style (#6994) 2026-04-22 14:26:02 +00:00
Alex Kremer
7c7c1894b9 chore: Add -fix to clang-tidy invocation (#6990) 2026-04-21 19:00:00 +00:00
Jingchen
45d4aacb53 chore: Remove empty Taker.h (#6984) 2026-04-21 18:15:58 +00:00
Alex Kremer
ce3951bbb3 chore: Enable clang-tidy modernize checks (#6975)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-04-21 15:32:51 +00:00
Ayaz Salikhov
ab887f5049 ci: Upload clang-tidy git diff (#6983) 2026-04-21 14:22:33 +00:00
Alex Kremer
ea023121f5 fix: Add rounding to Vault invariants (#6217) (#6955)
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
Co-authored-by: Ed Hennis <ed@ripple.com>
2026-04-21 12:14:07 +00:00
yinyiqian1
4b198cd5bb fix: Disallow MPTClearRequireAuth if is set (#6712)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-04-20 21:25:52 +00:00
Alex Kremer
726f20c8f6 feat: Add GRPC TLS support (#6374)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-20 17:12:14 +00:00
Zhiyuan Wang
96643bb0fa fix: Check for empty sfAdditionalBooks array in hybrid offer invariant (#6716) 2026-04-20 17:10:28 +00:00
chuanshanjida
e83818241a chore: Remove repetitive word in multiple files (#6978)
Signed-off-by: chuanshanjida <chuanshanjida@outlook.com>
2026-04-20 16:56:03 +00:00
Ayaz Salikhov
852fbe955d ci: Add workflow to check PR description has been filled (#6965) 2026-04-20 12:12:58 +00:00
dependabot[bot]
b33d0a0479 ci: [DEPENDABOT] Bump tj-actions/changed-files from 47.0.5 to 47.0.6 (#6973)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 11:20:42 +00:00
Alex Kremer
653a383ff5 chore: Enable clang-tidy include cleaner (#6947) 2026-04-17 16:43:49 +00:00
Gregory Tsipenyuk
affe5835fe fix: Change AMMClawback return code to tecNO_PERMISSION (#6946) 2026-04-17 14:19:58 +00:00
dependabot[bot]
ef2642f873 ci: [DEPENDABOT] bump actions/upload-pages-artifact from 4.0.0 to 5.0.0 (#6927)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-17 14:02:02 +00:00
dependabot[bot]
b2038163bc ci: [DEPENDABOT] bump actions/upload-artifact from 7.0.0 to 7.0.1 (#6928)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-17 14:01:56 +00:00
Alex Kremer
f1a5ba43ad chore: Enable clang-tidy readability checks (#6930)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-04-17 13:30:52 +00:00
Jingchen
4a73be499d fix: Fix unity build for book step (#6942)
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-04-16 17:12:00 +00:00
Sergey Kuznetsov
d52d735543 chore: Move codegen venv setup into build stage (#6617)
Co-authored-by: JCW <a1q123456@users.noreply.github.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-04-15 18:50:49 +00:00
Alex Kremer
6a0ce46755 chore: Enable most clang-tidy bugprone checks (#6929)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-04-14 20:24:21 +00:00
Bart
2f029a2120 refactor: Improve exception handling (#6540) (#6735)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-04-14 17:14:24 +00:00
Zhiyuan Wang
61fbde3a71 refactor: Remove unused notTooManyOffers function from NFTokenUtils (#6737) 2026-04-13 23:18:10 +00:00
Bart
e2e537b3bb fix: Change Tuning::bookOffers minimum limit to 1 (#6812)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-04-10 14:38:46 +00:00
Ed Hennis
a873250019 chore: Make pre-commit line ending conversions work on Windows (#6832) (#6833) 2026-04-10 10:12:52 +00:00
Gregory Tsipenyuk
56c9d1d497 fix: Add description for terLOCKED error (#6811) 2026-04-08 20:56:19 +00:00
yinyiqian1
d52dd29d20 fix: Address AI reviewer comments for Permission Delegation (#6675) 2026-04-08 20:22:19 +00:00
Mayukha Vadari
7793b5f10b refactor: Combine AMMHelpers and AMMUtils (#6733) 2026-04-08 17:38:33 +00:00
Gregory Tsipenyuk
dfcad69155 feat: Add MPT support to DEX (#5285) 2026-04-08 16:17:37 +00:00
Pratik Mankawde
6d1a5be8d2 fix: Handle WSClient write failure when server closes WebSocket (#6671)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 19:15:40 +00:00
Ayaz Salikhov
b0fe2ec58a ci: Change conditions for uploading artifacts in public/private/org repos (#6734) 2026-04-07 14:32:13 +00:00
Bart
c00ed673a8 refactor: Rename non-functional uses of ripple(d) to xrpl(d) (#6676)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-04-07 13:00:17 +00:00
Mayukha Vadari
f239256d87 refactor: Move more helper files into libxrpl/ledger/helpers (#6731)
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-04-06 22:36:32 +00:00
Mayukha Vadari
00761dbb67 fix: Minor RPC fixes (#6730) 2026-04-06 22:15:16 +00:00
Zhiyuan Wang
077e03ff33 fix: Prevent deletion of MPTokens with active escrow (#6635)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-04-06 17:51:46 +00:00
Vito Tumas
7d524a03b8 fix: Clamp VaultClawback to assetsAvailable for zero-amount clawback (#6646) 2026-04-06 15:13:03 +00:00
Vito Tumas
c0ee813666 fix: Add assorted Lending Protocol fixes (#6678)
Co-authored-by: Shawn Xie <35279399+shawnxie999@users.noreply.github.com>
2026-04-03 17:41:45 +00:00
Mayukha Vadari
8e05416211 fix: Change variable signedness and correctly handle std::optional (#6657) 2026-04-03 15:16:50 +00:00
Mayukha Vadari
81555d5456 refactor: Reorganize RPC handler files (#6628) 2026-04-02 23:46:17 +00:00
Ayaz Salikhov
6b55c4cdc8 chore: Update XRPLF/actions (#6713) 2026-04-02 21:34:20 +00:00
yinyiqian1
3414a1776b docs: Add explanatory comment to checkFee (#6631) 2026-04-02 20:48:35 +00:00
yinyiqian1
6d9ed125f3 fix: Decouple reserve from fee in delegate payment (#6568) 2026-04-02 20:48:00 +00:00
Vito Tumas
02fa55df8d fix: Check trustline limits for share-denominated vault withdrawals (#6645) 2026-04-01 19:31:45 +00:00
Valentin Balaschenko
6e2452207d fix: Remove fatal assertion on Linux thread name truncation (#6690) 2026-04-01 16:56:45 +00:00
Alex Kremer
29e49abd3c chore: Enable clang-tidy coreguidelines checks (#6698)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-04-01 15:46:14 +00:00
Ayaz Salikhov
ae21f53e4d ci: Allow uploading artifacts for XRPLF org (#6702) 2026-04-01 13:37:35 +00:00
Vito Tumas
bee1056faa fix: Enforce aggregate MaximumAmount in multi-send MPT (#6644)
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-04-01 13:35:13 +00:00
Ayaz Salikhov
b6aa4a8fde chore: Use nudb recipe from the upstream (#6701) 2026-04-01 10:33:02 +00:00
Mayukha Vadari
a9afd2c116 fix: Fix previous ledger size typo in RCLConsensus (#6696) 2026-03-31 19:56:30 +00:00
Alex Kremer
2502befb42 chore: Enable clang-tidy misc checks (#6655) 2026-03-31 17:29:45 +00:00
Ayaz Salikhov
c3fae847f3 ci: Use pull_request_target to check for signed commits (#6697) 2026-03-31 17:14:41 +00:00
Bart
7f53351920 chore: Remove unnecessary clang-format off/on directives (#6682)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-03-31 15:38:04 +00:00
Pratik Mankawde
bb95a7d6cd fix: Fix Workers::stop() race between m_allPaused and m_runningTaskCount (#6574)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 15:06:04 +00:00
Ayaz Salikhov
5c8dfe5456 ci: Only publish docs in public repos (#6687) 2026-03-30 17:15:40 +00:00
Alex Kremer
ab8c168e3b chore: Enable remaining clang-tidy performance checks (#6648)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-30 17:08:47 +00:00
Jingchen
3a477e4d01 refactor: Address PR comments after the modularisation PRs (#6389)
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-03-30 15:22:38 +00:00
Alex Kremer
96bfc32fe2 chore: Fix clang-tidy header filter (#6686) 2026-03-30 14:59:53 +00:00
dependabot[bot]
de671863e2 ci: [DEPENDABOT] bump actions/deploy-pages from 4.0.5 to 5.0.0 (#6684)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 14:09:57 +00:00
dependabot[bot]
e0cabb9f8c ci: [DEPENDABOT] bump codecov/codecov-action from 5.5.3 to 6.0.0 (#6685)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 13:57:32 +00:00
Pratik Mankawde
3d9c545f59 fix: Guard Coro::resume() against completed coroutines (#6608)
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-27 18:52:18 +00:00
Vito Tumas
9b944ee8c2 refactor: Split LoanInvariant into LoanBrokerInvariant and LoanInvariant (#6674) 2026-03-27 18:35:42 +00:00
Ayaz Salikhov
509677abfd ci: Don't publish docs on release branches (#6673) 2026-03-26 14:11:37 +00:00
Jingchen
addc1e8e25 refactor: Make function naming in ServiceRegistry consistent (#6390)
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
Co-authored-by: Ed Hennis <ed@ripple.com>
2026-03-26 14:11:16 +00:00
Valentin Balaschenko
faf69da4b0 chore: Shorten job names to stay within Linux 15-char thread limit (#6669) 2026-03-26 14:10:51 +00:00
Vito Tumas
76e3b4fb0f fix: Improve loan invariant message (#6668) 2026-03-26 12:40:26 +00:00
Ayaz Salikhov
e8bdbf975a ci: Upload artifacts only in public repositories (#6670) 2026-03-26 12:37:37 +00:00
Ayaz Salikhov
2c765f6eb0 ci: Add conflicting-pr workflow (#6656)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-03-26 00:18:17 +00:00
Mayukha Vadari
a9269fa846 chore: Add more AI tools to .gitignore (#6658)
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-03-25 23:55:50 +00:00
Jingchen
15fd9feae5 chore: Show warning message if user may need to connect to VPN (#6619)
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2026-03-25 23:54:49 +00:00
Vito Tumas
b9d07730f3 feat: Add placeholder amendment for assorted bug fixes (#6652) 2026-03-25 23:54:33 +00:00
Ayaz Salikhov
85b65c8e9a chore: Update sqlite3->3.51.0, protobuf->6.33.5, openssl->3.6.1, grpc->1.78.1 (#6653) 2026-03-25 18:22:50 +00:00
Jingchen
8f182e825a refactor: Modularise ledger (#6536)
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
Co-authored-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-03-25 16:32:45 +00:00
Ayaz Salikhov
cd78569d94 chore: Use unpatched version of soci (#6649) 2026-03-25 16:06:31 +00:00
Mayukha Vadari
2c7af360c2 fix: Remove unused/unreachable transactor code (#6612) 2026-03-25 16:02:14 +00:00
Alex Kremer
403fd7c649 fix: More clang-tidy issues found after merging to develop (#6640)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-03-25 14:28:28 +00:00
Ayaz Salikhov
dfed0481f7 docs: Rewrite conan docs for custom recipes (#6647) 2026-03-25 14:25:33 +00:00
Bart
0dc0c8e912 docs: Update LICENSE.md year to present (#6636)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-03-25 14:24:10 +00:00
Ayaz Salikhov
0510ee47d7 chore: Update some external dependencies (#6642) 2026-03-25 10:44:14 +00:00
Ayaz Salikhov
589c9c694c chore: Update external dependencies due to upstream merge (#6630) 2026-03-24 23:18:41 +00:00
Jingchen
4096623ae1 chore: Remove the forward declarations that cause build errors when unity build is enabled (#6633)
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2026-03-24 23:00:41 +00:00
Alex Kremer
dda162087f docs: Add note about clang-tidy installation (#6634) 2026-03-24 21:18:03 +00:00
Mayukha Vadari
85a4015a64 fix: Assorted Permissioned Domain fixes (#6587) 2026-03-24 18:53:57 +00:00
Mayukha Vadari
f7bb4018fa fix: Assorted Vault fixes (#6607) 2026-03-24 18:53:49 +00:00
Alex Kremer
0eedefbf45 refactor: Enable more clang-tidy readability checks (#6595)
Co-authored-by: Sergey Kuznetsov <kuzzz99@gmail.com>
2026-03-24 15:42:12 +00:00
Mayukha Vadari
8b986e4ab0 refactor: Improve imports to only call the needed helpers (#6624) 2026-03-24 10:20:32 +00:00
Olek
dcfcdab14e fix: Remove superfluous view update from credentials (#6545) 2026-03-23 18:29:34 +00:00
Mayukha Vadari
e0dbe90370 refactor: Move ledger entry helper functions from View.h/View.cpp to dedicated helper files (#6453)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-23 15:39:58 +00:00
dependabot[bot]
c463d0ff06 ci: [DEPENDABOT] bump codecov/codecov-action from 5.5.2 to 5.5.3 (#6615)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-23 14:04:22 +00:00
Mayukha Vadari
be1cc48d84 fix: Assorted Oracle fixes (#6570) 2026-03-22 18:08:18 +00:00
Ayaz Salikhov
cf2eb149ee fix: Update .git-blame-ignore-revs (#6577) 2026-03-19 22:48:20 +00:00
Ayaz Salikhov
762922a07f chore: Don't allow files more than 400kb to be added to the repo (#6597) 2026-03-19 21:20:56 +00:00
Bart
fd28656ded ci: Check for signed commits in PR (#6559)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-03-19 17:38:09 +00:00
Ayaz Salikhov
9316da784a ci: Update XRPLF/actions (#6594) 2026-03-19 17:29:22 +00:00
Michael Legleux
6efd31229a fix: Use correct format and event for workflows for release tags (#6554) 2026-03-19 10:23:51 +00:00
Alex Kremer
12954d5392 fix: Address remaining issue after clang-tidy merge (#6582) 2026-03-18 22:41:09 +00:00
Jingchen
b1e5ba0518 feat: Add code generator for transactions and ledger entries (#6443)
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-03-18 21:11:51 +00:00
Mayukha Vadari
d360e7c5b6 refactor: Rename transactor files/classes to match the tx name (#6580) 2026-03-18 19:52:07 +00:00
Ayaz Salikhov
804a351773 ci: Use external action implementation of check-pr-title (#6578) 2026-03-18 18:31:42 +00:00
Ayaz Salikhov
697fb64e8c ci: Don't check PR title for drafts (#6573) 2026-03-18 17:46:27 +00:00
Alex Kremer
57e4cbbcd9 refactor: Add simple clang-tidy readability checks (#6556)
This change enables the following clang-tidy checks:
-  readability-avoid-nested-conditional-operator,
-  readability-avoid-return-with-void-value,
-  readability-braces-around-statements,
-  readability-const-return-type,
-  readability-container-contains,
-  readability-container-size-empty,
-  readability-else-after-return,
-  readability-make-member-function-const,
-  readability-redundant-casting,
-  readability-redundant-inline-specifier,
-  readability-redundant-member-init,
-  readability-redundant-string-init,
-  readability-reference-to-constructed-temporary,
-  readability-static-definition
2026-03-18 16:41:49 +00:00
Mayukha Vadari
b92a9a3053 fix: Make assorted NFT fixes (#6566)
This change:
* Removes a set of unnecessary brackets in the initialization of an `std::uint32_t`.
* Fixes a couple of incorrect flags (same value, just wrong variables - so no amendment needed).
2026-03-18 14:47:59 +00:00
Mayukha Vadari
dcaef828b4 refactor: Replace !=/== tesSuccess with using isTesSuccess (#6409)
This change replaces all instances of `<variable> != tesSUCCESS` with `!isTesSuccess(<variable>)` and `<variable> == tesSUCCESS` with `isTesSuccess(<variable>)`.
2026-03-18 14:15:10 +00:00
yinyiqian1
6fbeb04d9e fix: Disallow empty permission list when Delegate object is absent (#6542)
This change fixes delegation:
* If the Delegate object is not present, we should disallow empty permission list in DelegateSet preclaim.
* Empty permission list is only allowed to delete the existing Delegate object.
* In `doApply`, permission list being empty returns `tecINTERNAL`, which should not happen.
2026-03-18 13:39:31 +00:00
Alex Kremer
2a325e7e2c chore: Enable clang-tidy bugprone-use-after-move check (#6476) 2026-03-18 00:12:06 +00:00
Bart
808e814489 ci: Update check-pr-title action hash (#6572) 2026-03-17 23:26:01 +00:00
Copilot
9e14707e77 fix: Peer crawler port field type inconsistency (#6318)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
Co-authored-by: Mayukha Vadari <mvadari@gmail.com>
Co-authored-by: Mayukha Vadari <mvadari@ripple.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-03-17 22:03:56 +00:00
Mayukha Vadari
95a45d7442 chore: Add comment explaining why ammLPHolds is called twice (#6546) 2026-03-17 20:11:36 +00:00
Bart
5fc4ab3e37 ci: Let required runs be triggered by merge group events (#6563)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-03-17 20:03:48 +00:00
tequ
b129b71c33 refactor: Use ReadView instead of ApplyView in authorizedDepositPreauth() (#6560) 2026-03-17 15:56:51 -04:00
tequ
013c2d6a56 refactor: Add const qualifier to SLE in verifyDepositPreauth parameter (#6555) 2026-03-17 19:33:18 +00:00
Alex Kremer
72f4cb097f refactor: Enable remaining clang-tidy cppcoreguidelines checks (#6538) 2026-03-17 19:09:05 +00:00
Michael Legleux
b523770486 fix: Remove nonexistent boost::coroutine2 library (#6561) 2026-03-17 18:46:46 +00:00
Mayukha Vadari
a5185890ff refactor: Remove dead code in escrow helper logic (#6553) 2026-03-17 18:13:08 +00:00
Jingchen
0a9513e7f3 ci: Fix build errors on Windows (#6562) 2026-03-17 13:50:44 -04:00
Mayukha Vadari
78b2d70a11 refactor: Assorted small DID fixes (#6552)
This change:
* Makes `addSLE` in `DIDSet` a static function, instead of a free function.
* Renames `Attestation` to `Data` everywhere (an artifact of a previous name for the field).
* Actually runs a set of tests that were not included in the `run` function of `DID_test`.
2026-03-17 14:44:07 +00:00
Mayukha Vadari
252c6768df refactor: Clean up getFeePayer, mSourceBalance, and mPriorBalance (#6478)
This change:
* Introduces a new helper function on `STTx`, `getFeePayer`.
* Removes the usage of `mSourceBalance` and replaces it with SLE balance lookups.
* Renames `mPriorBalance` to `preFeeBalance_`

This simplifies some of the code in the transactors and makes it a lot more readable.
2026-03-17 14:12:16 +00:00
Pratik Mankawde
5ae97fa8ae refactor: Add no-ASAN macro for Throw statements (#6373)
Throwing exceptions from code sometime confuses ASAN, as it cannot keep track of stack frames. This change therefore adds a macro to skip instrumentation around the `Throw` function.
2026-03-17 13:10:32 +00:00
Pratik Mankawde
eff344faf9 chore: Move sanitizer runtime options out to files (#6371)
This change moves the sanitizer runtime options out to dedicated files, such that they can be used in multiple places (CI, local runs) without any need to rewrite them.
2026-03-17 11:22:49 +00:00
Alex Kremer
7e7b71d84c chore: Fix tests for clang-tidy bugprone-unchecked-optional-access check (#6502) 2026-03-16 19:47:40 -04:00
Bart
ffea3977f0 refactor: Rename system name from 'ripple' to 'xrpld' (#6347)
Per [XLS-0095](https://xls.xrpl.org/xls/XLS-0095-rename-rippled-to-xrpld.html), we are taking steps to rename ripple(d) to xrpl(d). This change modifies the system name from `rippled` to `xrpld`.

The system name is used in limited places:
* When no explicit config file is passed via the `--config` flag, then the system name is used to construct the path where the config file and database may be stored, via the `$XDG_CONFIG_HOME` and `$XDG_DATA_HOME` directories, respectively.
* It is used in the metadata and user-agent as part of RPC calls.
* It is newly used in the full version string.
2026-03-16 21:51:31 +00:00
Alex Kremer
47a235b7be chore: Enable clang-tidy switch-missing-default-case check (#6461) 2026-03-16 17:19:37 -04:00
Alex Kremer
f5e2415c98 chore: Enable clang-tidy check for CRTP constructor accessibility (#6452)
This change enables the `bugprone-crtp-constructor-accessibility` check and fixes the few compilation issues resulting from enabling it.
2026-03-16 20:18:15 +00:00
Mayukha Vadari
1a4c359351 refactor: use hasExpired in CancelCheck (#6533) 2026-03-16 18:14:59 +00:00
Mayukha Vadari
e4dbaf5efc test: Remove testline JTX helper class (#6539)
This change removes the JTX helper class `testline`, which adds the line that made the `env` call, as it is no longer necessary.
2026-03-16 16:28:49 +00:00
Pratik Mankawde
983816248a fix: Switch to boost::coroutine2 (#6372)
ASAN wasn't able to keep track of `boost::coroutine` context switches, and would lead to many false positives being detected. By switching to `boost::coroutine2` and `ucontext`, ASAN is able to know about the context switches advertised by the `boost::fiber` class, which in turn leads to more cleaner ASAN analysis.
2026-03-16 15:34:15 +00:00
Pratik Mankawde
b585dc78bb fix: Fix memory leaks in HTTPClient (#6370)
The `HTTPClient` class initializes a global SSL context via `initializeSSLContext()`. However, it had no way to release it, which caused memory leaks flagged by the LeakSanitizer. Multiple LSAN suppressions in the sanitizers' suppressions file were masking these leaks. Our test code also manually called `initializeSSLContext()` in each test without guaranteed cleanup on failure paths.

This change fixes these memory leaks by adding a `cleanupSSLContext()` method to properly release the global SSL context, and removes the corresponding LSAN suppressions. The change further refactors the `HTTPClient` tests to use a Google Test fixture (`HTTPClientTest`) that manages the SSL context lifecycle via RAII (SetUp/TearDown), making it impossible for tests to leak the context.
2026-03-16 14:12:48 +00:00
Alex Kremer
918185e18f chore: Enable clang-tidy bugprone-unused-return-value check (#6475) 2026-03-16 13:55:22 +00:00
Pratik Mankawde
1738a69619 refactor: Delete SecretKey compare op from library and move it to tests module (#6503)
This change deletes the `SecretKey` equality/inequality operators from the public library header and moves the comparison logic into test-only code.

Specifically, the `operator==` and `operator!=` free functions on `SecretKey` have been removed from `include/xrpl/protocol/SecretKey.h` and have been replaced with explicitly deleted member functions to prevent accidental use in production code. A named `test::equal()` helper has also been added in `src/test/unit_test/utils.h` for test assertions that need to compare secret keys.
2026-03-16 10:55:12 +00:00
Mayukha Vadari
1bf9e6e7da fix: Remove a newline from logging statement in changeSpotPrice calculation (#6547)
This change removes an unnecessary newline in a logging statement. Namely, `std::endl` is unneeded in `JLOG`, since it automatically places a newline at the end of the string.
2026-03-13 18:12:25 +00:00
Bronek Kozicki
0446bef7e5 feat: Enforce feature name lengths and character set (#5555)
This change enforces a maximum length of 63 characters on feature names, as well as not permitting an exactly 32 character long feature name to avoid confusion with those that use a `uint256` hex representation, as that is an alternative way to specify a feature. This change further prevents the use of Unicode characters in feature names, because some can be confused with regular ASCII characters despite being valid in identifiers.
2026-03-13 13:41:50 -04:00
Mayukha Vadari
7a3bf1692d refactor: Simplify set/get field call to use existing variable (#6534)
The `setFieldU32` call is currently used to set the credential's expiry using a `getFieldU32` call to obtain the expiration time. However, that value was already obtained previously and can thus be reused.
2026-03-13 13:53:44 +00:00
Vito Tumas
c1d108e565 docs: Improve documentation for InvariantCheck (#6518) 2026-03-12 21:50:35 +00:00
Mayukha Vadari
1ba1bf9ade chore: Fix typo in freezeHandling parameter name (#6543) 2026-03-12 21:24:38 +00:00
Mayukha Vadari
7dd3e0b3cc refactor: remove dead code in CreateOffer (#6541)
Removed redundant check for account creating trustline to itself.
2026-03-12 17:03:35 -04:00
Vito Tumas
2b14ee3018 refactor: Split combined transactor files into individual classes (#6495)
DID, Escrows, PaymentChannels, and Credentials previously contained multiple unrelated transactor classes in a single header/implementation pair. This change splits each into one class per file, following the same pattern established by the rest of the codebase.
2026-03-12 17:19:29 +00:00
Jingchen
ce31a7ed16 chore: Replace levelization shell script by python script (#6325)
The new python version is significantly faster.
2026-03-12 15:38:00 +00:00
tsinglua
91a23cf80b chore: Fix minor issues in the comments (#6535) 2026-03-12 11:15:30 -04:00
Ayaz Salikhov
e460ea0840 ci: Move Type of Change from PR template to CONTRIBUTING (#6522)
Now that prefixes in PR titles are being validated as part of CI, the "Type of Change" section in the PR template is no longer needed. The prefixes and descriptions in the `CONTRIBUTING.md` file have been updated to reflect the currently supported list.
2026-03-12 06:39:40 +01:00
yinyiqian1
46d5c67a8d fix: Mark SAV and Lending transactions as NotDelegable (#6489)
New transactions should be marked as `NotDelegable`, until the interactions with other transactions have been fully tested and validated.
2026-03-11 21:27:35 +00:00
Mayukha Vadari
ce9ccf844a fix: Remove unneeded import, fix log (#6532)
This change:
* Removes an unneeded import in `DeleteAccount.cpp`.
* Fixes a typo in a log statement in `SetAccount.cpp`.
2026-03-11 19:36:03 +00:00
Sergey Kuznetsov
c791cae1ec test: Fix flaky subscribe tests (#6510)
Subscribe tests have a problem that there is no way to synchronize application running in background threads and test threads. Threads are communicating via websocket messages. When the code is compiled in debug mode with code coverage enabled it executes quite slow, so receiving websocket messages by the client in subscribe tests may time out.

This change does 2 things to fix the problem:
* Increases timeout for receiving a websocket message.
* Decreases the number of tests running in parallel.

While testing the fix for subscribe test another flaky test in ledger replay was found, which has also been addressed.
2026-03-11 18:06:12 +00:00
Alex Kremer
7b3724b7a3 fix: Add missed clang-tidy bugprone-inc-dec-conditions check (#6526) 2026-03-11 14:04:26 +00:00
Ayaz Salikhov
bee2d112c6 ci: Fix how clang-tidy is run when .clang-tidy is changed (#6521) 2026-03-11 14:18:18 +01:00
Bart
01c977bbfe ci: Fix rules used to determine when to upload Conan recipes (#6524)
The refs as previously used pointed to the source branch, not the target branch. However, determining the target branch is different depending on the GitHub event. The pull request logic was incorrect and needed to be fixed, and the logic inside the workflow could be simplified. Both modifications have been made in this commit.
2026-03-11 13:43:58 +01:00
Bart
3baf5454f2 ci: Only upload artifacts in the XRPLF/rippled repository (#6523)
This change will only attempt to upload artifacts for CI runs performed in the XRPLF/rippled repository.
2026-03-11 11:48:40 +01:00
Michael Legleux
24a5cbaa93 chore: Build voidstar on amd64 only (#6481)
* chore: Build voidstar on amd64 only

* fatal error if configuring voidstar on  non x86
2026-03-10 23:59:43 +00:00
Michael Legleux
eb7c8c6c7a chore: Use CMake components for install (#6485)
* chore: Use components for install

* rm CMake export targets

* reformat
2026-03-10 23:38:43 +00:00
Alex Kremer
f27d8f3890 chore: Enable clang-tidy bugprone-inc-dec-in-conditions check (#6455) 2026-03-10 20:12:15 +00:00
Alex Kremer
8345cd77df chore: Enable clang-tidy bugprone-unused-raii check (#6505) 2026-03-10 19:48:56 +00:00
Alex Kremer
c38aabdaee chore: Enable clang-tidy bugprone-unhandled-self-assignment check (#6504) 2026-03-10 17:42:49 +00:00
Alex Kremer
a896ed3987 chore: Enable clang-tidy bugprone-optional-value-conversion check (#6470) 2026-03-10 15:56:24 +01:00
Alex Kremer
1a7d67c4db chore: Enable clang-tidy bugprone-reserved-identifier check (#6456) 2026-03-10 10:29:08 +01:00
Alex Kremer
92983d8040 chore: Enable clang-tidy bugprone-too-small-loop-variable check (#6473) 2026-03-10 08:56:44 +00:00
Alex Kremer
320a65f77c chore: Enable clang-tidy bugprone-suspicious-stringview-data-usage check (#6467) 2026-03-10 08:34:27 +00:00
Ayaz Salikhov
45b8c4d732 chore: Update XRPLF/actions (#6508)
This change mainly includes XRPLF/actions#51.
2026-03-09 21:47:22 +00:00
Alex Kremer
e284969ae4 chore: Enable clang-tidy bugprone-pointer-arithmetic-on-polymorphic-object check (#6469) 2026-03-09 19:36:56 +01:00
Alex Kremer
0335076359 chore: Fix additional clang-tidy issues for unused-local-non-trivial-variable check (#6509) 2026-03-09 17:16:04 +00:00
Ayaz Salikhov
7e2b137131 chore: Use check-pr-title from XRPLF/actions (#6506) 2026-03-09 17:53:52 +01:00
Sergey Kuznetsov
e2290b1a0a feat: Add mutex wrapper from clio (#6447)
This change adds a mutex wrapper copied from clio. The wrapper attaches a mutex to the data it protects, which improves safety and readability.
2026-03-09 16:33:20 +00:00
Alex Kremer
1ee0567b14 chore: Enable clang-tidy bugprone-suspicious-missing-comma check (#6468) 2026-03-09 15:48:38 +00:00
Alex Kremer
6b301efc8c chore: Enable clang-tidy bugprone-unused-local-non-trivial-variable check (#6458) 2026-03-09 15:25:52 +00:00
dependabot[bot]
9e0d350fca ci: [DEPENDABOT] bump tj-actions/changed-files from 47.0.4 to 47.0.5 (#6501) 2026-03-09 15:27:03 +01:00
Ayaz Salikhov
7b12c00e6b chore: Add custom cmake definitions for gersemi (#6491)
This change adds definitions for our custom functions/macros, so gersemi will nicely format them too.
2026-03-06 13:50:00 +01:00
Vito Tumas
5865bd017f refactor: Update transaction folder structure (#6483)
This change reorganizes the `tx/transactors` directory for consistency and discoverability. There are no behavioral changes, this is a pure refactor. Underscores were chosen as the way to separate multi-words as this is the more popular option in C++ projects.
 
Specific changes:
- Rename all subdirectories to lowercase/snake_case (`AMM` → `amm`, `Check` → `check`, `NFT` → `nft`, `PermissionedDomain` → `permissioned_domain`, etc.)
- Merge `AMM/` and `Offer/` into `dex/`, including `PermissionedDEXHelpers`
- Rename `MPT/` → `token/`, absorbing `SetTrust` and `Clawback`
- Move top-level transactors into named groups: `account/`, `bridge/`, `credentials/`, `did/`, `escrow/`, `oracle/`, `payment/`, `payment_channel/`, `system/`
- Update all include paths across the codebase and `transactions.macro`
2026-03-06 08:25:31 +00:00
Ayaz Salikhov
af0ec7defd chore: Apply gersemi changes (#6486) 2026-03-05 19:54:44 +00:00
Ayaz Salikhov
0c74270b05 chore: Use gersemi instead of ancient cmake-format (#6486) 2026-03-05 19:54:37 +00:00
Alex Kremer
dde450784d Add Formats and Flags to server_definitions (#6321)
This change implements https://github.com/XRPLF/XRPL-Standards/discussions/418: "System XLS: Add Formats and Flags to server_definitions".
2026-03-05 16:11:27 +00:00
Michael Legleux
08e734457f fix: Fix docs deployment for pull requests (#6482) 2026-03-05 00:12:41 -08:00
Michael Legleux
77518394e8 fix: Stop committing generated docs to prevent repo bloat (#6474) 2026-03-04 19:19:57 -08:00
Ayaz Salikhov
c69091bded chore: Add Git information compile-time info to only one file (#6464)
The existing code added the git commit info (`GIT_COMMIT_HASH` and `GIT_BRANCH`) to every file, which was a problem for leveraging `ccache` to cache build objects. This change adds a separate C++ file from where these compile-time variables are propagated to wherever they are needed. A new CMake file is added to set the commit info if the `git` binary is available.
2026-03-04 19:45:28 +00:00
Alex Kremer
595f0dd461 chore: Enable clang-tidy bugprone-sizeof-expression check (#6466) 2026-03-04 19:15:22 +00:00
Alex Kremer
b451d5e412 chore: Enable clang-tidy bugprone-return-const-ref-from-parameter check (#6459) 2026-03-04 18:10:10 +00:00
Alex Kremer
af97df5a63 chore: Enable clang-tidy bugprone-move-forwarding-reference check (#6457) 2026-03-04 17:03:27 +00:00
Peter Chen
e39954d128 fix: Gateway balance with MPT (#6143)
When `gateway_balances` gets called on an account that is involved in the `EscrowCreate` transaction (with MPT being escrowed), the method returns internal error. This change fixes this case by excluding the MPT type when totaling escrow amount.
2026-03-04 15:50:51 +00:00
tequ
3cd1e3d94e refactor: Update PermissionedDomainDelete to use keylet for sle access (#6063) 2026-03-04 04:11:58 +01:00
Ayaz Salikhov
fcec31ed20 chore: Update pre-commit hooks (#6460) 2026-03-03 20:23:22 +00:00
dependabot[bot]
0abd762781 ci: [DEPENDABOT] bump actions/upload-artifact from 6.0.0 to 7.0.0 (#6450) 2026-03-03 17:17:08 +00:00
Sergey Kuznetsov
5300e65686 tests: Improve stability of Subscribe tests (#6420)
The `Subscribe` tests were flaky, because each test performs some operations (e.g. sends transactions) and waits for messages to appear in subscription with a 100ms timeout. If tests are slow (e.g. compiled in debug mode or a slow machine) then some of them could fail. This change adds an attempt to synchronize the background Env's thread and the test's thread by ensuring that all the scheduled operations are started before the test's thread starts to wait for a websocket message. This is done by limiting I/O threads of the app inside Env to 1 and adding a synchronization barrier after closing the ledger.
2026-03-03 08:46:55 -05:00
Alex Kremer
afc660a1b5 refactor: Fix clang-tidy bugprone-empty-catch check (#6419)
This change fixes or suppresses instances detected by the `bugprone-empty-catch` clang-tidy check.
2026-03-02 17:08:56 +00:00
Vito Tumas
1a7f824b89 refactor: Splits invariant checks into multiple classes (#6440)
The invariant check system had grown into a single monolithic file pair containing 24 invariant checker classes. The large `InvariantCheck.cpp` file was a frequent source of merge conflicts and difficult to navigate. This refactoring improves maintainability and readability with zero behavioral changes.

In particular, this change:
- Splits `InvariantCheck.h` and `InvariantCheck.cpp` into 10 focused header/source pairs organized by domain under a new `invariants/` subdirectory.
- Extracts the shared `Privilege` enum and `hasPrivilege()` function into a dedicated `InvariantCheckPrivilege.h` header, so domain-specific files can reference them independently.
2026-02-27 21:02:39 +00:00
Sergey Kuznetsov
b58c681189 chore: Make nix hook optional (#6431)
This change makes the `nix` pre-commit hook optional in development environments, and enforced only inside Github Actions.
2026-02-27 13:36:10 -05:00
Mayukha Vadari
404f35d556 test: Grep for failures in CI (#6339)
This change adjusts the CI tests to make it easier to spot errors, without needing to sift through the thousands of lines of output.
2026-02-27 03:01:38 +00:00
Alex Kremer
2e595b6031 chore: Enable clang-tidy checks without issues (#6414)
This change enables all clang-tidy checks that are already passing. It also modifies the clang-tidy CI job, so it runs against all files if .clang-tidy changed.
2026-02-26 18:26:58 +00:00
Bart
3a8a18c2ca refactor: Use uint256 directly as key instead of void pointer (#6313)
This change replaces `void const*` by `uint256 const&` for database fetches.

Object hashes are expressed using the `uint256` data type, and are converted to `void *` when calling the `fetch` or `fetchBatch` functions. However, in these fetch functions they are converted back to `uint256`, making the conversion process unnecessary. In a few cases the underlying pointer is needed, but that can then be easy obtained via `[hash variable].data()`.
2026-02-25 18:23:34 -05:00
Ayaz Salikhov
65e63ebef3 chore: Update cleanup-workspace to delete old .conan2 dir on macOS (#6412) 2026-02-25 01:12:16 +00:00
Valentin Balaschenko
bdd106d992 Explicitly trim the heap after cache sweeps (#6022)
Limited to Linux/glibc builds.
2026-02-24 21:33:13 +00:00
Valentin Balaschenko
24cbaf76a5 ci: Update prepare-runner action to fix macOS build environment (empty)
Updates XRPLF/actions prepare-runner to version 2cbf48101 which fixes
pip upgrade failures on macOS runners with Homebrew-managed Python.

* This commit was cherry-picked from "release-3.1", but ended up empty
  because the changes are already present. It is included only for
  accounting - to indicate that all changes/commits from the previous
  release will be in the next one.
2026-02-24 12:52:32 -05:00
Valentin Balaschenko
3a805cc646 Disable featureBatch and fixBatchInnerSigs amendments (#6402) 2026-02-24 12:49:59 -05:00
Sergey Kuznetsov
0fd237d707 chore: Add nix development environment (#6314)
---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-23 20:10:07 -05:00
dependabot[bot]
3542daa4cc ci: [DEPENDABOT] bump actions/upload-artifact from 4.6.2 to 6.0.0 (#6396)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.2 to 6.0.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](ea165f8d65...b7c566a772)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-20 22:48:01 +00:00
dependabot[bot]
fd9f57ec97 ci: [DEPENDABOT] bump actions/checkout from 4.3.0 to 6.0.2 (#6397)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.3.0 to 6.0.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4.3.0...de0fac2e4500dabe0009e67214ff5f5447ce83dd)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.2
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-20 22:09:48 +00:00
dependabot[bot]
625becff18 ci: [DEPENDABOT] bump actions/setup-python from 5.6.0 to 6.2.0 (#6395)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.6.0 to 6.2.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](a26af69be9...a309ff8b42)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: 6.2.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-20 21:29:05 +00:00
dependabot[bot]
4bcbc6e50f ci: [DEPENDABOT] bump tj-actions/changed-files from 46.0.5 to 47.0.4 (#6394)
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 46.0.5 to 47.0.4.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](ed68ef82c0...7dee1b0c15)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-version: 47.0.4
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-20 19:59:37 +00:00
dependabot[bot]
0bc4a0cfe8 ci: [DEPENDABOT] bump codecov/codecov-action from 5.4.3 to 5.5.2 (#6398)
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.4.3 to 5.5.2.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](18283e04ce...671740ac38)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-version: 5.5.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-20 19:11:26 +00:00
Ayaz Salikhov
cb54adefed ci: Build docs in PRs and in private repos (#6400) 2026-02-20 13:41:43 -05:00
Ayaz Salikhov
d03d72bfd5 ci: Add dependabot config (#6379) 2026-02-20 09:19:00 +00:00
Ed Hennis
6f35d94b2f Fix tautological assertion (#6393) 2026-02-20 01:58:47 +00:00
Ayaz Salikhov
2c1fad1023 chore: Apply clang-format width 100 (#6387) 2026-02-19 23:30:00 +00:00
Ayaz Salikhov
25cca46553 chore: Set clang-format width to 100 in config file (#6387) 2026-02-19 23:29:46 +00:00
Ayaz Salikhov
469ce9f291 chore: Set cmake-format width to 100 (#6386) 2026-02-19 19:42:51 +00:00
Sergey Kuznetsov
31302877ab ci: Add clang tidy workflow to ci (#6369) 2026-02-19 14:06:44 -05:00
Jingchen
0976b2b68b refactor: Modularize app/tx (#6228) 2026-02-17 18:10:07 +00:00
Jingchen
36240116a5 refactor: Decouple app/tx from Application and Config (#6227)
This change decouples app/tx from `Application` and `Config` to clear the way to moving transactors to `libxrpl`.
2026-02-17 11:29:53 -05:00
Sergey Kuznetsov
958d8f3754 chore: Update clang-format to 21.1.8 (#6352) 2026-02-16 14:31:18 -05:00
Jingchen
ac0ad3627f refactor: Modularize HashRouter, Conditions, and OrderBookDB (#6226)
This change modularizes additional components by moving code to `libxrpl`.
2026-02-13 10:34:37 -05:00
nuxtreact
cd218346ff chore: Fix minor issues in comments (#6346) 2026-02-12 14:55:27 -05:00
Jingchen
5edd3566f7 refactor: Modularize the NetworkOPs interface (#6225)
This change moves the NetworkOPs interface into `libxrpl` and it leaves its implementation in `xrpld`.
2026-02-12 13:15:03 -05:00
Pratik Mankawde
11e8d1f8a2 chore: Fix gcov lib coverage build failure on macOS (#6350)
For coverage builds, we try to link against the `gcov` library (specific to the environment). But as macOS doesn't have this library and thus doesn't have the coverage tools to generate reports, the coverage builds on that platform were failing on linking.

We actually don't need to explicitly force this linking, as the `CodeCoverage` file already has correct detection logic (currently on lines 177-193), which is invoked when the `--coverage` flag is provided:
* AppleClang: Uses `xcrun -f llvm-cov` to set `GCOV_TOOL="llvm-cov gcov"`.
* Clang: Finds `llvm-cov` to set `GCOV_TOOL="llvm-cov gcov"`.
* GCC: Finds `gcov` to set `GCOV_TOOL="gcov"`.
The `GCOV_TOOL` is then passed to `gcovr` on line 416, so the correct tool is used for processing coverage data.

This change therefore removes the `gcov` suffix from lines 473 and 475 in the `CodeCoverage.cmake` file.
2026-02-12 06:11:26 -05:00
Jingchen
9f17d10348 refactor: Modularize RelationalDB (#6224)
The rdb module was not properly designed, which is fixed in this change. The module had three classes:
1) The abstract class `RelationalDB`.
2) The abstract class `SQLiteDatabase`, which inherited from `RelationalDB` and added some pure virtual methods.
3) The concrete class `SQLiteDatabaseImp`, which inherited from `SQLiteDatabase` and implemented all methods.

The updated code simplifies this as follows:
* The `SQLiteDatabaseImp` has become `SQLiteDatabase`, and
* The former `SQLiteDatabase `has merged with `RelationalDatabase`.
2026-02-11 16:22:01 +00:00
Jingchen
ef284692db refactor: Modularize WalletDB and Manifest (#6223)
This change modularizes the `WalletDB` and `Manifest`. Note that the wallet db has nothing to do with account wallets and it stores node configuration, which is why it depends on the manifest code.
2026-02-11 13:42:31 +00:00
Olek
e11f6190b7 fix: Update invariant checks for Permissioned Domains (#6134) 2026-02-10 14:02:53 -05:00
Valentin Balaschenko
db2734cbc9 refactor: Change main thread name to xrpld-main (#6336)
This change builds on the thread-renaming PR (#6212), by renaming the main thread name to reduce ambiguity in performance monitoring tools.
2026-02-06 16:33:42 -05:00
Mayukha Vadari
bf4674f42b refactor: Fix spelling issues in tests (#6199)
This change removes the `src/tests` exception from the `cspell` config and fixes all the issues that arise as a result. No functionality/test change.
2026-02-06 20:30:22 +00:00
Mayukha Vadari
f5208fc850 test: Add file and line location to Env (#6276)
This change uses `std::source_location` to output the file and line location of the call that triggered a failed transaction.
2026-02-06 18:37:01 +00:00
2011 changed files with 238542 additions and 100917 deletions

View File

@@ -37,7 +37,7 @@ BinPackParameters: false
BreakBeforeBinaryOperators: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true
ColumnLimit: 120
ColumnLimit: 100
CommentPragmas: "^ IWYU pragma:"
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
@@ -50,20 +50,21 @@ ForEachMacros: [Q_FOREACH, BOOST_FOREACH]
IncludeBlocks: Regroup
IncludeCategories:
- Regex: "^<(test)/"
Priority: 0
- Regex: "^<(xrpld)/"
Priority: 1
- Regex: "^<(xrpl)/"
- Regex: "^<(xrpld)/"
Priority: 2
- Regex: "^<(boost)/"
- Regex: "^<(xrpl)/"
Priority: 3
- Regex: "^.*/"
- Regex: "^<(boost)/"
Priority: 4
- Regex: '^.*\.h'
- Regex: "^.*/"
Priority: 5
- Regex: ".*"
- Regex: '^.*\.h'
Priority: 6
- Regex: ".*"
Priority: 7
IncludeIsMainRegex: "$"
MainIncludeChar: AngleBracket
IndentCaseLabels: true
IndentFunctionDeclarationAfterType: false
IndentRequiresClause: true

204
.clang-tidy Normal file
View File

@@ -0,0 +1,204 @@
---
Checks: "-*,
bugprone-argument-comment,
bugprone-assert-side-effect,
bugprone-bad-signal-to-kill-thread,
bugprone-bool-pointer-implicit-conversion,
bugprone-capturing-this-in-member-variable,
bugprone-casting-through-void,
bugprone-chained-comparison,
bugprone-compare-pointer-to-member-virtual-function,
bugprone-copy-constructor-init,
bugprone-crtp-constructor-accessibility,
bugprone-dangling-handle,
bugprone-dynamic-static-initializers,
bugprone-empty-catch,
bugprone-fold-init-type,
bugprone-forward-declaration-namespace,
bugprone-inaccurate-erase,
bugprone-inc-dec-in-conditions,
bugprone-incorrect-enable-if,
bugprone-incorrect-roundings,
bugprone-infinite-loop,
bugprone-integer-division,
bugprone-lambda-function-name,
bugprone-macro-parentheses,
bugprone-macro-repeated-side-effects,
bugprone-misleading-setter-of-reference,
bugprone-misplaced-operator-in-strlen-in-alloc,
bugprone-misplaced-pointer-arithmetic-in-alloc,
bugprone-misplaced-widening-cast,
bugprone-move-forwarding-reference,
bugprone-multi-level-implicit-pointer-conversion,
bugprone-multiple-new-in-one-expression,
bugprone-multiple-statement-macro,
bugprone-no-escape,
bugprone-non-zero-enum-to-bool-conversion,
bugprone-optional-value-conversion,
bugprone-parent-virtual-call,
bugprone-pointer-arithmetic-on-polymorphic-object,
bugprone-posix-return,
bugprone-redundant-branch-condition,
bugprone-reserved-identifier,
bugprone-return-const-ref-from-parameter,
bugprone-shared-ptr-array-mismatch,
bugprone-signal-handler,
bugprone-signed-char-misuse,
bugprone-sizeof-container,
bugprone-sizeof-expression,
bugprone-spuriously-wake-up-functions,
bugprone-standalone-empty,
bugprone-string-constructor,
bugprone-string-integer-assignment,
bugprone-string-literal-with-embedded-nul,
bugprone-stringview-nullptr,
bugprone-suspicious-enum-usage,
bugprone-suspicious-include,
bugprone-suspicious-memory-comparison,
bugprone-suspicious-memset-usage,
bugprone-suspicious-missing-comma,
bugprone-suspicious-realloc-usage,
bugprone-suspicious-semicolon,
bugprone-suspicious-string-compare,
bugprone-suspicious-stringview-data-usage,
bugprone-swapped-arguments,
bugprone-switch-missing-default-case,
bugprone-terminating-continue,
bugprone-throw-keyword-missing,
bugprone-too-small-loop-variable,
bugprone-unchecked-optional-access,
bugprone-undefined-memory-manipulation,
bugprone-undelegated-constructor,
bugprone-unhandled-exception-at-new,
bugprone-unhandled-self-assignment,
bugprone-unique-ptr-array-mismatch,
bugprone-unsafe-functions,
bugprone-unused-local-non-trivial-variable,
bugprone-unused-raii,
bugprone-unused-return-value,
bugprone-use-after-move,
bugprone-virtual-near-miss,
cppcoreguidelines-init-variables,
cppcoreguidelines-misleading-capture-default-by-value,
cppcoreguidelines-no-suspend-with-lock,
cppcoreguidelines-pro-type-member-init,
cppcoreguidelines-pro-type-static-cast-downcast,
cppcoreguidelines-rvalue-reference-param-not-moved,
cppcoreguidelines-use-default-member-init,
cppcoreguidelines-use-enum-class,
cppcoreguidelines-virtual-class-destructor,
hicpp-ignored-remove-result,
llvm-namespace-comment,
misc-const-correctness,
misc-definitions-in-headers,
misc-header-include-cycle,
misc-include-cleaner,
misc-misplaced-const,
misc-redundant-expression,
misc-static-assert,
misc-throw-by-value-catch-by-reference,
misc-unused-alias-decls,
misc-unused-using-decls,
modernize-concat-nested-namespaces,
modernize-deprecated-headers,
modernize-make-shared,
modernize-make-unique,
modernize-pass-by-value,
modernize-type-traits,
modernize-use-designated-initializers,
modernize-use-emplace,
modernize-use-equals-default,
modernize-use-equals-delete,
modernize-use-nodiscard,
modernize-use-override,
modernize-use-ranges,
modernize-use-scoped-lock,
modernize-use-starts-ends-with,
modernize-use-std-numbers,
modernize-use-using,
performance-faster-string-find,
performance-for-range-copy,
performance-implicit-conversion-in-loop,
performance-inefficient-vector-operation,
performance-move-const-arg,
performance-move-constructor-init,
performance-no-automatic-move,
performance-trivially-destructible,
readability-ambiguous-smartptr-reset-call,
readability-avoid-nested-conditional-operator,
readability-avoid-return-with-void-value,
readability-braces-around-statements,
readability-const-return-type,
readability-container-contains,
readability-container-size-empty,
readability-convert-member-functions-to-static,
readability-duplicate-include,
readability-else-after-return,
readability-enum-initial-value,
readability-identifier-naming,
readability-implicit-bool-conversion,
readability-make-member-function-const,
readability-math-missing-parentheses,
readability-misleading-indentation,
readability-non-const-parameter,
readability-redundant-casting,
readability-redundant-declaration,
readability-redundant-inline-specifier,
readability-redundant-member-init,
readability-redundant-string-init,
readability-reference-to-constructed-temporary,
readability-simplify-boolean-expr,
readability-static-definition-in-anonymous-namespace,
readability-suspicious-call-argument,
readability-use-std-min-max
"
# ---
# readability-inconsistent-declaration-parameter-name, # in this codebase this check will break a lot of arg names
# readability-static-accessed-through-instance, # this check is probably unnecessary. it makes the code less readable
# ---
CheckOptions:
bugprone-unsafe-functions.ReportMoreUnsafeFunctions: true
bugprone-unused-return-value.CheckedReturnTypes: ::std::error_code;::std::error_condition;::std::errc
misc-include-cleaner.IgnoreHeaders: ".*/(detail|impl)/.*;.*fwd\\.h(pp)?;time.h;stdlib.h;sqlite3.h;netinet/in\\.h;sys/resource\\.h;sys/sysinfo\\.h;linux/sysinfo\\.h;__chrono/.*;bits/.*;_abort\\.h;boost/uuid/uuid_hash.hpp;boost/beast/core/flat_buffer\\.hpp;boost/beast/http/field\\.hpp;boost/beast/http/dynamic_body\\.hpp;boost/beast/http/message\\.hpp;boost/beast/http/read\\.hpp;boost/beast/http/write\\.hpp;openssl/obj_mac\\.h"
readability-braces-around-statements.ShortStatementLines: 2
readability-identifier-naming.MacroDefinitionCase: UPPER_CASE
readability-identifier-naming.ClassCase: CamelCase
readability-identifier-naming.StructCase: CamelCase
readability-identifier-naming.UnionCase: CamelCase
readability-identifier-naming.EnumCase: CamelCase
readability-identifier-naming.EnumConstantCase: CamelCase
readability-identifier-naming.ScopedEnumConstantCase: CamelCase
readability-identifier-naming.GlobalConstantCase: CamelCase
readability-identifier-naming.GlobalConstantPrefix: "k"
readability-identifier-naming.GlobalVariableCase: CamelCase
readability-identifier-naming.GlobalVariablePrefix: "g"
readability-identifier-naming.ConstexprFunctionCase: camelBack
readability-identifier-naming.ConstexprMethodCase: camelBack
readability-identifier-naming.ClassMethodCase: camelBack
readability-identifier-naming.ClassMemberCase: camelBack
readability-identifier-naming.ClassConstantCase: CamelCase
readability-identifier-naming.ClassConstantPrefix: "k"
readability-identifier-naming.StaticConstantCase: CamelCase
readability-identifier-naming.StaticConstantPrefix: "k"
readability-identifier-naming.StaticVariableCase: camelBack
readability-identifier-naming.ConstexprVariableCase: camelBack
readability-identifier-naming.LocalConstantCase: camelBack
readability-identifier-naming.LocalVariableCase: camelBack
readability-identifier-naming.TemplateParameterCase: CamelCase
readability-identifier-naming.ParameterCase: camelBack
readability-identifier-naming.FunctionCase: camelBack
readability-identifier-naming.MemberCase: camelBack
readability-identifier-naming.PrivateMemberCase: camelBack
readability-identifier-naming.PrivateMemberSuffix: _
readability-identifier-naming.ProtectedMemberCase: camelBack
readability-identifier-naming.ProtectedMemberSuffix: _
readability-identifier-naming.PublicMemberCase: camelBack
readability-identifier-naming.PublicMemberSuffix: ""
readability-identifier-naming.GlobalFunctionIgnoredRegexp: "^(to_string|hash_append|tuple_hash)$"
HeaderFilterRegex: '^.*/(tests?|xrpl|xrpld)/.*\.(h|hpp|ipp)$'
ExcludeHeaderFilterRegex: '^.*/protocol_autogen/.*\.(h|hpp)$'
WarningsAsErrors: "*"

View File

@@ -1,54 +0,0 @@
# Workflow Orchestration
## 1. Plan Mode Default
- Enter plan mode for ANY non-trivial task (3+ steps or architectural decisions)
- If something goes sideways, STOP and re-plan immediately - don't keep pushing
- Use plan mode for verification steps, not just building
- Write detailed specs upfront to reduce ambiguity
## 2. Subagent Strategy
- Use subagents liberally to keep main context window clean
- Offload research, exploration, and parallel analysis to subagents
- For complex problems, throw compute at it via parallelizing
- One task per subagent for focused execution
## 3. Self-Improvement Loop
- After ANY correction from the user: update `tasks/lessons.md` with the pattern
- Write rules for yourself that prevent the same mistake
- Ruthlessly iterate on these rules until mistake drops
- Review lessons at session start for relevant project
## 4. Verification Before Done
- Never mark a task complete without proving it works
- Diff behavior between main and your changes when relevant
- Ask yourself: "Would a staff engineer approve this?"
- Run tests, check logs, demonstrate correctness
## 5. Demand Elegance (Balanced)
- For non-trivial changes: pause and ask "is there a more elegant way?"
- If a fix feels hacky: "Know now, do later, implement the elegant solution"
- Skip this for simple, obvious fixes - don't over-engineer
- Challenge your own first solution
## 6. Autonomous Bug Fixing
- When given a bug report: just fix it. Don't ask for hand-holding
- Point at logs, errors, failing tests - then resolve them
- Zero context switching required from the user
- Go fix failing CI tests without being told how
# Task Management
1. **Plan First**: Write plan to `tasks/todo.md` with checkable items
2. **Verify Plans**: Check in before starting implementation
3. **Track Progress**: Mark items complete as you go
4. **Explain Changes**: High-level summary at each step
5. **Document Results**: Add review section to `tasks/todo.md`
6. **Capture Lessons**: Update `tasks/lessons.md` after corrections
# Core Principles
**Simplicity First**: Make every change as simple as possible. Impact minimal code.
**No Boilerplate**: Skip documentation. No README/docs bloat. Test only if requested.
**Minimal Impact**: Changes should only touch what's necessary. Avoid introducing bugs.

View File

@@ -1,530 +0,0 @@
# XRPL Amendment Creation Skill
This skill guides you through creating XRPL amendments, whether for brand new features or fixes/extensions to existing functionality.
## Amendment Types
There are two main types of amendments:
1. **New Feature Amendment** (`feature{Name}`) - Entirely new functionality
2. **Fix/Extension Amendment** (`fix{Name}`) - Modifications to existing functionality
## Step 1: Determine Amendment Type
Ask the user:
- Is this a **brand new feature** (new transaction type, ledger entry, or capability)?
- Or is this a **fix or extension** to existing functionality?
---
## For NEW FEATURE Amendments
### Checklist:
#### 1. Feature Definition in features.macro
**ONLY FILE TO EDIT:** `include/xrpl/protocol/detail/features.macro`
- [ ] Add to TOP of features.macro (reverse chronological order):
```
XRPL_FEATURE(YourFeatureName, Supported::no, VoteBehavior::DefaultNo)
```
- [ ] This creates the variable `featureYourFeatureName` automatically
- [ ] Follow naming convention: Use the feature name WITHOUT the "feature" prefix
- [ ] Examples: `Batch``featureBatch`, `LendingProtocol``featureLendingProtocol`
#### 2. Support Status
- [ ] Start with `Supported::no` during development
- [ ] Change to `Supported::yes` when ready for network voting
- [ ] Use `VoteBehavior::DefaultNo` (validators must explicitly vote for it)
#### 3. Code Implementation
- [ ] Implement new functionality (transaction type, ledger entry, etc.)
- [ ] Add feature gate check in preflight:
```cpp
if (!env.current()->rules().enabled(feature{Name}))
{
return temDISABLED;
}
```
#### 4. Disable Route Handling
- [ ] Ensure transaction returns `temDISABLED` when amendment is disabled
- [ ] Implement early rejection in preflight/preclaim phase
- [ ] Add appropriate error messages
#### 5. Test Implementation
Create comprehensive test suite with this structure:
```cpp
class {FeatureName}_test : public beast::unit_test::suite
{
public:
void testEnable(FeatureBitset features)
{
testcase("enabled");
// Test with feature DISABLED
{
auto const amendNoFeature = features - feature{Name};
Env env{*this, amendNoFeature};
env(transaction, ter(temDISABLED));
}
// Test with feature ENABLED
{
Env env{*this, features};
env(transaction, ter(tesSUCCESS));
// Validate new functionality works
}
}
void testPreflight(FeatureBitset features)
{
testcase("preflight");
// Test malformed transaction validation
}
void testPreclaim(FeatureBitset features)
{
testcase("preclaim");
// Test signature and claim phase validation
}
void testWithFeats(FeatureBitset features)
{
testEnable(features);
testPreflight(features);
testPreclaim(features);
// Add feature-specific tests
}
void run() override
{
using namespace test::jtx;
auto const all = supported_amendments();
testWithFeats(all);
}
};
```
#### 6. Test Coverage Requirements
- [ ] Test amendment DISABLED state (returns `temDISABLED`)
- [ ] Test amendment ENABLED state (returns `tesSUCCESS`)
- [ ] Test malformed transactions
- [ ] Test signature validation
- [ ] Test edge cases specific to feature
- [ ] Test amendment transition behavior
#### 7. Documentation
- [ ] Create specification document (XLS_{NAME}.md)
- [ ] Document new transaction types, ledger entries, or capabilities
- [ ] Create test plan document
- [ ] Document expected behavior when enabled/disabled
---
## For FIX/EXTENSION Amendments
### Checklist:
#### 1. Fix Definition in features.macro
**ONLY FILE TO EDIT:** `include/xrpl/protocol/detail/features.macro`
- [ ] Add to TOP of features.macro (reverse chronological order):
```
XRPL_FIX(YourFixName, Supported::no, VoteBehavior::DefaultNo)
```
- [ ] This creates the variable `fixYourFixName` automatically
- [ ] Follow naming convention: Use the fix name WITHOUT the "fix" prefix (it's added automatically)
- [ ] Examples: `TokenEscrowV1``fixTokenEscrowV1`, `DirectoryLimit``fixDirectoryLimit`
- [ ] Start with `Supported::no` during development, change to `Supported::yes` when ready
#### 2. Backward Compatibility Implementation
**Critical**: Use enable() with if/else to preserve existing functionality
```cpp
// Check if fix is enabled
bool const fix{Name} = env.current()->rules().enabled(fix{Name});
// Conditional logic based on amendment state
if (fix{Name})
{
// NEW behavior with fix applied
// This is the corrected/improved logic
}
else
{
// OLD behavior (legacy path)
// Preserve original functionality for backward compatibility
}
```
**Alternative pattern with ternary operator:**
```cpp
auto& viewToUse = sb.rules().enabled(fix{Name}) ? sb : legacyView;
```
#### 3. Multiple Fix Versions Pattern
For iterative fixes, use version checking:
```cpp
bool const fixV1 = rv.rules().enabled(fixXahauV1);
bool const fixV2 = rv.rules().enabled(fixXahauV2);
switch (transactionType)
{
case TYPE_1:
if (fixV1) {
// Behavior with V1 fix
} else {
// Legacy behavior
}
break;
case TYPE_2:
if (fixV2) {
// Behavior with V2 fix
} else if (fixV1) {
// Behavior with only V1
} else {
// Legacy behavior
}
break;
}
```
#### 4. Test Both Paths
Always test BOTH enabled and disabled states:
```cpp
void testFix(FeatureBitset features)
{
testcase("fix behavior");
for (bool withFix : {false, true})
{
auto const amend = withFix ? features : features - fix{Name};
Env env{*this, amend};
// Setup test scenario
env.fund(XRP(1000), alice);
env.close();
if (!withFix)
{
// Test OLD behavior (before fix)
env(operation, ter(expectedErrorWithoutFix));
// Verify old behavior is preserved
}
else
{
// Test NEW behavior (after fix)
env(operation, ter(expectedErrorWithFix));
// Verify fix works correctly
}
}
}
```
#### 5. Security Fix Pattern
For security-critical fixes (like fixBatchInnerSigs):
```cpp
// Test vulnerability exists WITHOUT fix
{
auto const amendNoFix = features - fix{Name};
Env env{*this, amendNoFix};
// Demonstrate vulnerability
// Expected: Validity::Valid (WRONG - vulnerable!)
BEAST_EXPECT(result == Validity::Valid);
}
// Test vulnerability is FIXED WITH amendment
{
Env env{*this, features};
// Demonstrate fix
// Expected: Validity::SigBad (CORRECT - protected!)
BEAST_EXPECT(result == Validity::SigBad);
}
```
#### 6. Test Coverage Requirements
- [ ] Test fix DISABLED (legacy behavior preserved)
- [ ] Test fix ENABLED (new behavior applied)
- [ ] Test amendment transition
- [ ] For security fixes: demonstrate vulnerability without fix
- [ ] For security fixes: demonstrate protection with fix
- [ ] Test edge cases that triggered the fix
- [ ] Test combinations with other amendments
#### 7. Documentation
- [ ] Document what was broken/suboptimal
- [ ] Document the fix applied
- [ ] Document backward compatibility behavior
- [ ] Create test summary showing both paths
---
## Best Practices for All Amendments
### 1. Naming Conventions
- New features: `feature{DescriptiveName}` (e.g., `featureBatch`, `featureHooks`)
- Fixes: `fix{IssueDescription}` (e.g., `fixBatchInnerSigs`, `fixNSDelete`)
- Use CamelCase without underscores
### 2. Feature Flag Checking
```cpp
// At the point where behavior diverges:
bool const amendmentEnabled = env.current()->rules().enabled(feature{Name});
// Or in view/rules context:
if (!rv.rules().enabled(feature{Name}))
return {}; // or legacy behavior
```
### 3. Error Codes
- New features when disabled: `temDISABLED`
- Fixes may return different validation errors based on state
- Document all error code changes
### 4. Test Structure Template
```cpp
class Amendment_test : public beast::unit_test::suite
{
public:
// Core tests
void testEnable(FeatureBitset features); // Enable/disable states
void testPreflight(FeatureBitset features); // Validation
void testPreclaim(FeatureBitset features); // Claim phase
// Feature-specific tests
void test{SpecificScenario1}(FeatureBitset features);
void test{SpecificScenario2}(FeatureBitset features);
// Master orchestrator
void testWithFeats(FeatureBitset features)
{
testEnable(features);
testPreflight(features);
testPreclaim(features);
test{SpecificScenario1}(features);
test{SpecificScenario2}(features);
}
void run() override
{
using namespace test::jtx;
auto const all = supported_amendments();
testWithFeats(all);
}
};
BEAST_DEFINE_TESTSUITE(Amendment, app, ripple);
```
### 5. Documentation Files
Create these files:
- **Specification**: `XLS_{FEATURE_NAME}.md` - Technical specification
- **Test Plan**: `{FEATURE}_COMPREHENSIVE_TEST_PLAN.md` - Test strategy
- **Test Summary**: `{FEATURE}_TEST_IMPLEMENTATION_SUMMARY.md` - Test results
- **Review Findings**: `{FEATURE}_REVIEW_FINDINGS.md` (if applicable)
### 6. Amendment Transition Testing
Test the moment an amendment activates:
```cpp
void testAmendmentTransition(FeatureBitset features)
{
testcase("amendment transition");
// Start with amendment disabled
auto const amendNoFeature = features - feature{Name};
Env env{*this, amendNoFeature};
// Perform operations in disabled state
env(operation1, ter(temDISABLED));
// Enable amendment mid-test (if testing mechanism supports it)
// Verify state transitions correctly
// Perform operations in enabled state
env(operation2, ter(tesSUCCESS));
}
```
### 7. Cache Behavior
If amendment affects caching (like fixBatchInnerSigs):
- [ ] Test cache behavior without fix
- [ ] Test cache behavior with fix
- [ ] Document cache invalidation requirements
### 8. Multi-Amendment Combinations
Test interactions with other amendments:
```cpp
void testMultipleAmendments(FeatureBitset features)
{
// Test all combinations
for (bool withFeature1 : {false, true})
for (bool withFeature2 : {false, true})
{
auto amend = features;
if (!withFeature1) amend -= feature1;
if (!withFeature2) amend -= feature2;
Env env{*this, amend};
// Test interaction behavior
}
}
```
### 9. Performance Considerations
- [ ] Minimize runtime checks (cache `rules().enabled()` result if used multiple times)
- [ ] Avoid nested feature checks where possible
- [ ] Document performance impact
### 10. Code Review Checklist
- [ ] Both enabled/disabled paths are tested
- [ ] Backward compatibility is preserved (for fixes)
- [ ] Error codes are appropriate
- [ ] Documentation is complete
- [ ] Security implications are considered
- [ ] Cache behavior is correct
- [ ] Edge cases are covered
---
## Common Patterns Reference
### Pattern: New Transaction Type
```cpp
// In transactor code:
TER doApply() override
{
if (!ctx_.view().rules().enabled(feature{Name}))
return temDISABLED;
// New transaction logic here
return tesSUCCESS;
}
```
### Pattern: New Ledger Entry Type
```cpp
// In ledger entry creation:
if (!view.rules().enabled(feature{Name}))
return temDISABLED;
auto const sle = std::make_shared<SLE>(ltNEW_TYPE, keylet);
view.insert(sle);
```
### Pattern: Behavioral Fix
```cpp
// At decision point:
bool const useFix = view.rules().enabled(fix{Name});
if (useFix)
{
// Corrected behavior
return performCorrectValidation();
}
else
{
// Legacy behavior (preserved for compatibility)
return performLegacyValidation();
}
```
### Pattern: View Selection
```cpp
// Select which view to use based on amendment:
auto& applyView = sb.rules().enabled(feature{Name}) ? newView : legacyView;
```
---
## Example Workflows
### Workflow 1: Creating a New Feature Amendment
1. User requests: "Add a new ClaimReward transaction type"
2. Skill asks: "What should the amendment be called? (e.g., BalanceRewards - without 'feature' prefix)"
3. Add to features.macro:
```
XRPL_FEATURE(BalanceRewards, Supported::no, VoteBehavior::DefaultNo)
```
4. Implement transaction with `temDISABLED` gate using `featureBalanceRewards`
5. Create test suite with testEnable, testPreflight, testPreclaim
6. Run tests with amendment enabled and disabled
7. When ready, update to `Supported::yes` in features.macro
8. Create specification document
9. Review checklist
### Workflow 2: Creating a Fix Amendment
1. User requests: "Fix the signature validation bug in batch transactions"
2. Skill asks: "What should the fix be called? (e.g., BatchInnerSigs - without 'fix' prefix)"
3. Add to features.macro:
```
XRPL_FIX(BatchInnerSigs, Supported::no, VoteBehavior::DefaultNo)
```
4. Implement fix with if/else using `fixBatchInnerSigs` to preserve old behavior
5. Create test demonstrating vulnerability without fix
6. Create test showing fix works when enabled
7. When ready, update to `Supported::yes` in features.macro
8. Document both code paths
9. Review checklist
---
## Quick Reference: File Locations
- **Amendment definitions (ONLY place to add)**: `include/xrpl/protocol/detail/features.macro`
- **Feature.h (auto-generated, DO NOT EDIT)**: `include/xrpl/protocol/Feature.h`
- **Feature.cpp (auto-generated, DO NOT EDIT)**: `src/libxrpl/protocol/Feature.cpp`
- **Test files**: `src/test/app/` or `src/test/protocol/`
- **Specifications**: Project root (e.g., `XLS_SMART_CONTRACTS.md`)
- **Test plans**: Project root (e.g., `BATCH_COMPREHENSIVE_TEST_PLAN.md`)
## How the Macro System Works
The amendment system uses C preprocessor macros:
1. **features.macro** - Single source of truth (ONLY file you edit):
```
XRPL_FEATURE(Batch, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX(TokenEscrowV1, Supported::yes, VoteBehavior::DefaultNo)
```
2. **Feature.h** - Auto-generated declarations from macro:
```cpp
extern uint256 const featureBatch;
extern uint256 const fixTokenEscrowV1;
```
3. **Feature.cpp** - Auto-generated registrations from macro:
```cpp
uint256 const featureBatch = registerFeature("Batch", ...);
uint256 const fixTokenEscrowV1 = registerFeature("fixTokenEscrowV1", ...);
```
**DO NOT** modify Feature.h or Feature.cpp directly - they process features.macro automatically.
---
## When to Use This Skill
Invoke this skill when:
- Creating a new XRPL amendment
- Adding a new transaction type or ledger entry
- Fixing existing XRPL functionality
- Need guidance on amendment best practices
- Setting up amendment tests
- Reviewing amendment implementation
The skill will guide you through the appropriate workflow based on amendment type.

View File

@@ -1,99 +0,0 @@
# xrpld Codebase Skills Index
## Description
This is the top-level guide for all best-practices skills in this repository. Use this to understand the codebase organization and find the right skill for any task.
## When to Use Skills
Reference a skill whenever you are:
- **Writing new code** in a module - check the skill first for established patterns
- **Modifying existing code** - verify your changes follow module conventions
- **Adding a new transaction type** - see `libxrpl/tx/transactors.md` for the full template
- **Debugging** - skills list key files and common pitfalls per module
- **Reviewing code** - skills document what "correct" looks like for each module
## Codebase Architecture
The codebase is split into two main areas:
### `src/libxrpl/` — The Library (skills in `.claude/skills/libxrpl/`)
Reusable library code: data types, serialization, cryptography, ledger state, transaction processing, and storage. This is the **protocol layer**.
| Module | Responsibility |
|--------|---------------|
| `basics` | Foundational types: Buffer, Slice, base_uint, Number, logging, error contracts |
| `beast` | Support layer: Journal logging, test framework, instrumentation, IP types |
| `conditions` | Crypto-conditions (RFC): fulfillment validation, DER encoding |
| `core` | Job queue, load monitoring, hash-based message dedup |
| `crypto` | CSPRNG, secure erasure, RFC1751 encoding |
| `json` | Json::Value, parsing, serialization, StaticString optimization |
| `ledger` | ReadView/ApplyView, state tables, payment sandbox, credit ops |
| `net` | HTTP/HTTPS client, SSL certs, async I/O |
| `nodestore` | Persistent node storage: RocksDB, NuDB, Memory backends |
| `protocol` | STObject hierarchy, SField, Serializer, TER codes, Features, Keylets |
| `proto` | Protocol Buffer generated headers (gRPC API definitions) |
| `rdb` | SOCI database wrapper, checkpointing |
| `resource` | Rate limiting, endpoint tracking, abuse prevention |
| `server` | Port config, SSL/TLS, WebSocket, admin networks |
| `shamap` | SHA-256 Merkle radix tree (16-way branching, COW) |
| `tx` | Transaction pipeline: Transactor base, preflight/preclaim/doApply |
### `src/xrpld/` — The Server Application (skills in `.claude/skills/xrpld/`)
The running rippled server: application lifecycle, consensus, networking, RPC, and peer management. This is the **application layer**.
| Module | Responsibility |
|--------|---------------|
| `app` | Application singleton, ledger management, consensus adapters, services |
| `app/main` | Application initialization and lifecycle |
| `app/ledger` | Ledger storage, retrieval, immutable state management |
| `app/consensus` | RCL consensus adapters (bridges generic algorithm to rippled) |
| `app/misc` | Fee voting, amendments, SHAMapStore, TxQ, validators, NetworkOPs |
| `app/paths` | Payment path finding algorithm, trust line caching |
| `app/rdb` | Application-level database operations |
| `app/tx` | Application-level transaction handling |
| `consensus` | Generic consensus algorithm (CRTP-based, app-independent) |
| `core` | Configuration (Config.h), time keeping, network ID |
| `overlay` | P2P networking: peer connections, protocol buffers, clustering |
| `peerfinder` | Network discovery: bootcache, livecache, slot management |
| `perflog` | Performance logging and instrumentation |
| `rpc` | RPC handler dispatch, coroutine suspension, 40+ command handlers |
| `shamap` | Application-level SHAMap operations (NodeFamily) |
### `include/xrpl/` — Header Files
Headers live in `include/xrpl/` and mirror the `src/libxrpl/` structure. Each skill already references its corresponding headers in the "Key Files" section.
## Cross-Cutting Conventions
### Error Handling
- **Transaction errors**: Return `TER` enum (tesSUCCESS, tecFROZEN, temBAD_AMOUNT, etc.)
- **Logic errors**: `Throw<std::runtime_error>()`, `LogicError()`, `XRPL_ASSERT()`
- **I/O errors**: `Status` enum or `boost::system::error_code`
- **RPC errors**: Inject via `context.params`
### Assertions
```cpp
XRPL_ASSERT(condition, "ClassName::method : description"); // Debug only
XRPL_VERIFY(condition, "ClassName::method : description"); // Always enabled
```
### Logging
```cpp
JLOG(j_.warn()) << "Message"; // Always wrap in JLOG macro
```
### Memory Management
- `IntrusiveRefCounts` + `SharedIntrusive` for shared ownership in libxrpl
- `std::shared_ptr` for shared ownership in xrpld
- `std::unique_ptr` for exclusive ownership
- `CountedObject<T>` mixin for instance tracking
### Feature Gating
```cpp
if (ctx.rules.enabled(featureMyFeature)) { /* new behavior */ }
```
### Code Organization
- Headers in `include/xrpl/`, implementations in `src/libxrpl/` or `src/xrpld/`
- `#pragma once` (never `#ifndef` guards)
- `namespace xrpl { }` for all code
- `detail/` namespace for internal helpers
- Factory functions: `make_*()` returning `unique_ptr` or `shared_ptr`

View File

@@ -1,79 +0,0 @@
# Basics Module Best Practices
## Description
Use when working with foundational utilities in `src/libxrpl/basics/` or `include/xrpl/basics/`. Covers data structures, memory management, logging, numeric operations, error handling, and string utilities.
## Responsibility
Provides fundamental building blocks for the entire codebase: memory types (Buffer, Slice, Blob), intrusive smart pointers, arbitrary-precision integers (base_uint), multi-precision decimal arithmetic (Number), logging infrastructure, exception handling contracts, and platform abstractions.
## Key Patterns
### Memory Types
- **Slice** - Non-owning view into contiguous bytes (like std::span)
- **Buffer** - Owning byte container (like std::vector<uint8_t>)
- **Blob** - Alias for std::vector<unsigned char>
- Prefer `Slice` for read-only parameters, `Buffer` for owned data
### Intrusive Smart Pointers
```cpp
// Prefer intrusive pointers over std::shared_ptr for minimal overhead
// Object embeds its own reference count
class MyObject : public IntrusiveRefCounts {
// ...
};
// Use SharedIntrusive<MyObject> when weak pointers needed
```
### Error Handling
```cpp
// Contract-based exceptions (logs call stack then throws)
Throw<std::runtime_error>("Invalid source file");
LogThrow("exception message");
// Logic errors for invariant violations
LogicError("This should never happen");
// Assertions (fuzzing-aware)
XRPL_ASSERT(condition, "function_name : description");
XRPL_VERIFY(condition, "message"); // Always enabled, not just debug
```
### Logging
```cpp
// Use JLOG macro - short-circuits if level disabled
JLOG(debugLog().warn()) << "Message: " << value;
JLOG(j_.trace()) << "Verbose detail";
// Never: debugLog().warn() << "msg"; // Missing JLOG wastes formatting
```
### Number Precision
```cpp
// Use Number for multi-precision decimal arithmetic
// Always use RAII guard for rounding mode
NumberRoundModeGuard mg(Number::towards_zero);
auto result = amount * rate;
// Guard restores previous mode on scope exit
```
### base_uint Template
```cpp
// Typed big-endian integers: base_uint<Bits, Tag>
// Tag prevents mixing unrelated types of same width
using uint256 = base_uint<256, void>;
using AccountID = base_uint<160, detail::AccountIDTag>;
```
## Common Pitfalls
- Never use `std::shared_ptr` when IntrusiveRefCounts is available - it adds a separate allocation
- Never format log messages without JLOG wrapper - wastes CPU when level is disabled
- Never use raw `assert()` - use `XRPL_ASSERT` for fuzzing instrumentation support
- Never mix `Buffer` and `Slice` ownership semantics - Slice does NOT own its data
## Key Files
- `include/xrpl/basics/IntrusiveRefCounts.h` - Atomic reference counting
- `include/xrpl/basics/IntrusivePointer.h` - Smart pointer using intrusive refs
- `include/xrpl/basics/base_uint.h` - Arbitrary-length big-endian integers
- `include/xrpl/basics/Buffer.h`, `Blob.h`, `Slice.h` - Memory types
- `include/xrpl/basics/Number.h` - Multi-precision decimal arithmetic
- `include/xrpl/basics/Log.h` - Logging infrastructure
- `include/xrpl/basics/contract.h` - Throw, LogicError, XRPL_ASSERT

View File

@@ -1,62 +0,0 @@
# Beast Module Best Practices
## Description
Use when working with the Beast support layer in `src/libxrpl/beast/` or `include/xrpl/beast/`. Covers networking types, unit testing, Journal logging, and instrumentation.
## Responsibility
Library support layer providing network types (IP addresses, endpoints), unit testing framework, Journal/logging abstractions, instrumentation/assertion macros, and type introspection utilities.
## Key Patterns
### Journal Logging
```cpp
// Journal wraps a Sink pointer - copy by value is cheap
beast::Journal const j_;
// Severity levels: kTrace, kDebug, kInfo, kWarning, kError, kFatal
JLOG(j_.warn()) << "User-facing issue";
JLOG(j_.debug()) << "Implementation detail";
JLOG(j_.trace()) << "Very verbose diagnostic";
JLOG(j_.error()) << "Unexpected failure";
```
### Unit Testing
```cpp
class MyTest : public beast::unit_test::suite {
void run() override {
testcase("feature description");
BEAST_EXPECT(value == expected); // Non-fatal assertion
BEAST_REQUIRE(value == expected); // Fatal - aborts test on failure
}
};
BEAST_DEFINE_TESTSUITE(MyTest, module, ripple);
```
### Instrumentation
```cpp
// Use XRPL_ASSERT for debug-only assertions (fuzzing-aware)
XRPL_ASSERT(ptr != nullptr, "MyClass::method : null pointer");
// Format: "ClassName::methodName : description"
// The string format is important for fuzzing instrumentation
```
### IP Endpoint Types
```cpp
// Use beast::IP::Endpoint for network addresses
beast::IP::Endpoint endpoint;
// Supports both IPv4 and IPv6
// Includes port information
```
## Common Pitfalls
- Never use `BEAST_EXPECT` when the test cannot continue on failure - use `BEAST_REQUIRE` instead
- Never create a Journal with a dangling Sink pointer - ensure Sink outlives Journal
- Always include "ClassName::methodName" prefix in XRPL_ASSERT messages for traceability
## Key Files
- `include/xrpl/beast/utility/Journal.h` - Log sink abstraction
- `include/xrpl/beast/unit_test/suite.h` - Test framework
- `include/xrpl/beast/utility/instrumentation.h` - XRPL_ASSERT macros
- `include/xrpl/beast/net/IPEndpoint.h` - Network endpoint types
- `include/xrpl/beast/core/SemanticVersion.h` - Version parsing

View File

@@ -1,33 +0,0 @@
# Beast Clock Module Best Practices
## Description
Use when working with clock abstractions in `src/libxrpl/beast/clock/` or `include/xrpl/beast/clock/`. Covers abstract clock interfaces and manual clock implementations for testing.
## Responsibility
Provides clock abstractions that decouple code from system time, enabling deterministic testing with manual clocks and supporting different time granularities.
## Key Patterns
### Abstract Clock Interface
```cpp
// Use abstract_clock<T> for testable time-dependent code
// Production: uses system clock
// Testing: uses manual_clock for deterministic control
```
### Manual Clock for Testing
```cpp
// Advance time manually in tests
manual_clock<std::chrono::steady_clock> clock;
clock.advance(std::chrono::seconds(30));
// Deterministic - no flaky tests from timing issues
```
## Common Pitfalls
- Never use `std::chrono::system_clock::now()` directly - inject clock dependency
- Always use manual_clock in unit tests for deterministic behavior
- Be aware of Ripple Epoch vs Unix Epoch when working with ledger timestamps
## Key Files
- `include/xrpl/beast/clock/abstract_clock.h` - Abstract clock interface
- `include/xrpl/beast/clock/manual_clock.h` - Testable clock implementation

View File

@@ -1,29 +0,0 @@
# Beast Core Module Best Practices
## Description
Use when working with core beast utilities in `src/libxrpl/beast/core/` or `include/xrpl/beast/core/`. Covers semantic versioning and core type utilities.
## Responsibility
Provides core utilities including semantic version parsing/comparison, system abstractions, and foundational type support.
## Key Patterns
### Semantic Version Parsing
```cpp
// Parse version strings following semver spec
SemanticVersion version;
if (version.parse("1.2.3-beta")) {
auto major = version.majorVersion;
auto minor = version.minorVersion;
auto patch = version.patchVersion;
}
// Supports comparison operators for version ordering
```
## Common Pitfalls
- Always validate version strings before using - parse() returns false on invalid input
- Remember that pre-release versions have lower precedence than release versions
## Key Files
- `include/xrpl/beast/core/SemanticVersion.h` - Version parsing and comparison
- `src/libxrpl/beast/core/SemanticVersion.cpp` - Implementation

View File

@@ -1,41 +0,0 @@
# Beast Insight Module Best Practices
## Description
Use when working with metrics and monitoring in `src/libxrpl/beast/insight/` or `include/xrpl/beast/insight/`. Covers counters, gauges, and metrics collection.
## Responsibility
Provides metrics collection infrastructure for monitoring application performance: counters for cumulative values, gauges for point-in-time measurements, and hooks for metrics export.
## Key Patterns
### Metrics Types
```cpp
// Counter: Monotonically increasing value (e.g., total requests)
insight::Counter requests;
++requests;
// Gauge: Point-in-time value (e.g., current connections)
insight::Gauge connections;
connections = currentCount;
// Event: Timed operation tracking
insight::Event latency;
```
### Null Metrics
```cpp
// Use NullCollector when metrics disabled
// All operations become no-ops with zero overhead
auto collector = insight::NullCollector::New();
```
## Common Pitfalls
- Use Counter for cumulative values, Gauge for current state - don't mix them
- Always use NullCollector for tests - avoids metrics overhead
- Never store raw metric values in long-lived objects - use the insight types
## Key Files
- `include/xrpl/beast/insight/Counter.h` - Cumulative counter
- `include/xrpl/beast/insight/Gauge.h` - Point-in-time gauge
- `include/xrpl/beast/insight/Collector.h` - Metrics collector interface
- `include/xrpl/beast/insight/NullCollector.h` - No-op collector

View File

@@ -1,46 +0,0 @@
# Beast Net Module Best Practices
## Description
Use when working with network types in `src/libxrpl/beast/net/` or `include/xrpl/beast/net/`. Covers IP address and endpoint representations.
## Responsibility
Provides network type abstractions for IP addresses (v4 and v6) and endpoints (address + port), with parsing utilities and comparison operators.
## Key Patterns
### IP Endpoint Usage
```cpp
// beast::IP::Endpoint combines address + port
beast::IP::Endpoint endpoint(
beast::IP::Address::from_string("127.0.0.1"), 51235);
// Supports both IPv4 and IPv6
beast::IP::Endpoint v6endpoint(
beast::IP::Address::from_string("::1"), 51235);
```
### Address Parsing
```cpp
// Parse from string with error handling
boost::system::error_code ec;
auto address = beast::IP::Address::from_string(input, ec);
if (ec) { /* handle invalid address */ }
```
### Comparison and Ordering
```cpp
// Endpoints support full comparison for use in containers
std::set<beast::IP::Endpoint> endpoints;
std::map<beast::IP::Endpoint, Consumer> consumers;
```
## Common Pitfalls
- Always handle both IPv4 and IPv6 when working with endpoints
- Use error_code overload of from_string to handle invalid input gracefully
- Never assume address format - always parse and validate
## Key Files
- `include/xrpl/beast/net/IPEndpoint.h` - Combined address + port
- `include/xrpl/beast/net/IPAddress.h` - IP address types
- `include/xrpl/beast/net/IPAddressV4.h` - IPv4 specific
- `include/xrpl/beast/net/IPAddressV6.h` - IPv6 specific

View File

@@ -1,47 +0,0 @@
# Beast Utility Module Best Practices
## Description
Use when working with beast utility classes in `src/libxrpl/beast/utility/` or `include/xrpl/beast/utility/`. Covers Journal logging, instrumentation, and type introspection.
## Responsibility
Provides utility classes including the Journal logging abstraction (Sink + Stream), XRPL_ASSERT/XRPL_VERIFY instrumentation macros, and type introspection helpers.
## Key Patterns
### Journal and Sink Architecture
```cpp
// Sink: abstract base for log message routing
class Sink {
virtual void write(beast::severities::Severity level, std::string const& text) = 0;
void console(bool output); // Enable console output
};
// Journal: lightweight wrapper around Sink* (copy by value)
beast::Journal j(sinkPtr);
JLOG(j.warn()) << "Message";
// WrappedSink: adds prefix to all messages
beast::WrappedSink wrappedSink(parentSink, "MyModule");
```
### Instrumentation Macros
```cpp
// XRPL_ASSERT: Debug-only assertion (disabled in release, fuzzing-aware)
XRPL_ASSERT(condition, "ClassName::method : description");
// XRPL_VERIFY: Always-enabled assertion
XRPL_VERIFY(condition, "ClassName::method : description");
// Format convention: "ClassName::methodName : human-readable description"
```
## Common Pitfalls
- Always use "ClassName::methodName" prefix in assertion messages
- Journal is cheap to copy (just a pointer) - pass by value is fine
- WrappedSink must outlive any Journal created from it
- XRPL_ASSERT is no-op in release builds - don't put side effects in the condition
## Key Files
- `include/xrpl/beast/utility/Journal.h` - Log sink abstraction and Journal
- `include/xrpl/beast/utility/instrumentation.h` - XRPL_ASSERT, XRPL_VERIFY
- `include/xrpl/beast/utility/WrappedSink.h` - Prefixed log sink

View File

@@ -1,63 +0,0 @@
# Conditions Module Best Practices
## Description
Use when working with crypto-conditions in `src/libxrpl/conditions/` or `include/xrpl/conditions/`. Implements the RFC crypto-conditions specification.
## Responsibility
Implements crypto-conditions for conditional payments: condition fingerprints, fulfillment validation, multiple condition types (preimage, prefix, threshold, RSA, Ed25519), and binary DER serialization/deserialization.
## Key Patterns
### Fulfillment Interface
```cpp
// Abstract base for all fulfillment types
struct Fulfillment {
virtual ~Fulfillment() = default;
virtual Buffer fingerprint() const = 0;
virtual Type type() const = 0;
virtual bool validate(Slice data) const = 0;
virtual std::uint32_t cost() const = 0;
virtual Condition condition() const = 0;
};
```
### Factory Pattern for Deserialization
```cpp
// Returns unique_ptr + sets error_code (non-throwing)
std::unique_ptr<Fulfillment> deserialize(Slice s, std::error_code& ec);
// Usage:
std::error_code ec;
auto fulfillment = Fulfillment::deserialize(data, ec);
if (ec) return {}; // Early return on error
```
### Type-Safe Enums
```cpp
enum class Type : std::uint8_t {
preimageSha256 = 0,
prefixSha256 = 1,
thresholdSha256 = 2,
rsaSha256 = 3,
ed25519Sha256 = 4
};
```
### Size Limits
```cpp
static constexpr std::size_t maxSerializedCondition = 128;
static constexpr std::size_t maxSerializedFulfillment = 256;
// Always respect these limits when creating conditions
```
## Common Pitfalls
- Never throw exceptions from binary parsing - use `std::error_code` parameter pattern
- Always check `ec` after deserialization before using the result
- Respect `maxSerializedFulfillment` size limits
## Key Files
- `include/xrpl/conditions/Condition.h` - Base condition with type/fingerprint/cost
- `include/xrpl/conditions/Fulfillment.h` - Abstract fulfillment interface
- `include/xrpl/conditions/detail/PreimageSha256.h` - Preimage implementation
- `include/xrpl/conditions/detail/utils.h` - DER encoding/decoding
- `include/xrpl/conditions/detail/error.h` - Error codes

View File

@@ -1,61 +0,0 @@
# Core Module Best Practices
## Description
Use when working with job processing and routing infrastructure in `src/libxrpl/core/` or `include/xrpl/core/`. Covers job queues, load monitoring, and message deduplication.
## Responsibility
Distributed job processing with priority levels, load monitoring for execution tracking, and hash-based message suppression/routing for peer deduplication.
## Key Patterns
### Job Queue Priorities
```cpp
// Job types ordered by priority (lower enum = lower priority)
enum JobType {
jtINVALID = -1,
jtPACK, // Lowest priority
jtCLIENT_WEBSOCKET,
// ...
jtVALIDATION_t, // Trusted validation (high)
jtADMIN // Admin operations (highest)
};
// Position in enum determines scheduling priority
```
### HashRouter for Deduplication
```cpp
// Suppress duplicate messages from peers
std::optional<std::set<PeerShortID>> shouldRelay(uint256 const& key);
// Returns {} if already relayed, set of peers if should relay
// Track peer that sent a message
auto result = router.addSuppressionPeer(key, peer);
```
### RAII Locking
```cpp
// Always use lock_guard for mutex protection
std::lock_guard lock(mutex_);
auto result = emplace(key);
result.first.addPeer(peer);
return result.second; // Return while lock is held
```
### Optional Return Types
```cpp
// Use std::optional for "maybe" results
std::optional<std::set<PeerShortID>> shouldRelay(uint256 const& key);
// Caller checks: if (auto peers = shouldRelay(key)) { ... }
```
## Common Pitfalls
- Never hold locks longer than necessary - lock_guard scope = critical section
- Never ignore job priorities when scheduling work - use appropriate JobType
- Always let HashRouter handle message deduplication rather than implementing custom logic
## Key Files
- `include/xrpl/core/Job.h` - Job wrapper with type, index, function
- `include/xrpl/core/JobTypes.h` - Job type enumerations and metadata
- `include/xrpl/core/JobQueue.h` - Priority queue for dispatching jobs
- `include/xrpl/core/HashRouter.h` - Duplicate message suppression
- `include/xrpl/core/LoadMonitor.h` - Job execution time tracking

View File

@@ -1,32 +0,0 @@
# Core Detail Module Best Practices
## Description
Use when working with internal core implementation details in `src/libxrpl/core/detail/`. These are private implementation helpers not intended for direct external use.
## Responsibility
Internal implementation details for the core module, including helper functions and private data structures used by JobQueue, HashRouter, and LoadMonitor.
## Key Patterns
### Detail Namespace Convention
```cpp
namespace xrpl {
namespace detail {
// Internal helpers - not part of public API
// May change without notice between versions
}
}
```
### Encapsulation
- Code in `detail/` should only be included by its parent module
- Never include detail headers from outside the core module
- If you need functionality from detail, use the public core API instead
## Common Pitfalls
- Never depend on detail namespace types or functions from outside the core module
- Detail implementations may change without preserving API compatibility
- Always use the public `core/` headers for stable interfaces
## Key Files
- Files in this directory are implementation details of `include/xrpl/core/` headers

View File

@@ -1,51 +0,0 @@
# Crypto Module Best Practices
## Description
Use when working with cryptographic operations in `src/libxrpl/crypto/` or `include/xrpl/crypto/`. Covers CSPRNG, secure memory erasure, and RFC1751 encoding.
## Responsibility
Low-level cryptographic operations: cryptographically secure random number generation (CSPRNG), RFC1751 word-based encoding for keys, and secure memory erasure to prevent sensitive data leakage.
## Key Patterns
### CSPRNG Usage
```cpp
// Thread-safe PRNG - use the global singleton
auto& prng = crypto_prng();
// Generate random value
auto randomValue = prng();
// Fill buffer with random bytes
prng(buffer.data(), buffer.size());
// NEVER create your own csprng_engine - use crypto_prng()
```
### Secure Memory Erasure
```cpp
// Use volatile memset to prevent compiler optimization
secure_erase(secretKey.data(), secretKey.size());
// MUST be called before destroying any buffer containing secrets
```
### Engine Concept Conformance
```cpp
// csprng_engine meets UniformRandomNumberEngine requirements
using result_type = std::uint64_t;
static constexpr result_type min();
static constexpr result_type max();
// Can be used with standard distributions
```
## Common Pitfalls
- Never create a local `csprng_engine` instance - always use `crypto_prng()` singleton
- Never use `std::rand()` or `std::mt19937` for security-sensitive operations
- Always call `secure_erase()` on secret key material before destruction
- Never copy or move a `csprng_engine` - it's non-copyable and non-movable by design
- Be aware of OpenSSL version differences - locking behavior varies
## Key Files
- `include/xrpl/crypto/csprng.h` - Thread-safe PRNG engine
- `include/xrpl/crypto/RFC1751.h` - Human-readable key encoding
- `include/xrpl/crypto/secure_erase.h` - Volatile memset for secrets

View File

@@ -1,68 +0,0 @@
# JSON Module Best Practices
## Description
Use when working with JSON parsing and serialization in `src/libxrpl/json/` or `include/xrpl/json/`. Covers Json::Value, readers, writers, and custom allocators.
## Responsibility
JSON value representation (discriminated union for all JSON types), parsing text to Value objects, serialization from Value to text, and custom string allocation for memory control.
## Key Patterns
### Json::Value Usage
```cpp
// Discriminated union - supports all JSON types
Json::Value obj(Json::objectValue);
obj["key"] = "string_value";
obj["count"] = 42u;
obj["flag"] = true;
obj["nested"] = Json::objectValue;
// Array creation
Json::Value arr(Json::arrayValue);
arr.append("item");
arr.append(123);
// Type checking
if (obj.isObject()) { ... }
if (obj.isMember("key")) { ... }
```
### StaticString Optimization
```cpp
// Use StaticString for compile-time known keys to avoid allocation
static const Json::StaticString code("code");
static const Json::StaticString message("message");
object[code] = 1234; // No dynamic allocation for key
object[message] = "ok"; // Key stored as pointer, not copied
```
### Value Type Enum
```cpp
enum ValueType {
nullValue = 0,
intValue, uintValue, realValue,
stringValue, booleanValue,
arrayValue, objectValue
};
// Check type before accessing to avoid undefined behavior
```
### Lazy Initialization
```cpp
// Container elements auto-created on access (like JavaScript)
Json::Value obj;
obj["newKey"]["nested"] = 1; // Creates intermediate objects automatically
// Be aware: accessing a non-existent key creates it
```
## Common Pitfalls
- Accessing a non-existent key via `operator[]` creates a null entry - use `isMember()` to check first if you don't want side effects
- Use `const` overload of `operator[]` to avoid auto-creation: `obj["key"]` on const ref returns null reference
- Prefer `StaticString` for frequently-used keys to avoid repeated allocations
- Never assume JSON numeric types - check `isInt()`, `isUInt()`, `isDouble()` explicitly
## Key Files
- `include/xrpl/json/json_value.h` - Main Value class
- `include/xrpl/json/json_reader.h` - Text-to-Value parser
- `include/xrpl/json/json_writer.h` - Value-to-text serializer
- `include/xrpl/json/json_forwards.h` - Forward declarations and aliases

View File

@@ -1,84 +0,0 @@
# Ledger Module Best Practices
## Description
Use when working with ledger state management in `src/libxrpl/ledger/` or `include/xrpl/ledger/`. Covers views, state tables, payments, and credit operations.
## Responsibility
Manages the state of the distributed ledger: abstractions for viewing, reading, and applying transactions to ledger state. Handles account ownership tracking, trust lines, payment processing, directory management, and credential verification.
## Key Patterns
### ReadView vs ApplyView
```cpp
// ReadView: Read-only access to ledger state
bool exists = view.exists(keylet::account(accountID));
auto sle = view.read(keylet::account(accountID)); // Returns shared_ptr<SLE const>
// ApplyView: Mutable access for transaction application
auto sle = view.peek(keylet::account(accountID)); // Returns shared_ptr<SLE>
sle->setFieldAmount(sfBalance, newBalance);
view.update(sle); // Commit change
view.insert(newSle); // Create new entry
view.erase(sle); // Remove entry
```
### Enum-Based Control (No Boolean Blindness)
```cpp
// NEVER: bool ignoreFreeze = true;
// ALWAYS: Use named enums
enum FreezeHandling { fhIGNORE_FREEZE, fhZERO_IF_FROZEN };
enum AuthHandling { ahIGNORE_AUTH, ahZERO_IF_UNAUTHORIZED };
STAmount accountHolds(ReadView const& view, AccountID const& account,
Currency const& currency, AccountID const& issuer,
FreezeHandling zeroIfFrozen, beast::Journal j);
```
### Asset Variant Handling
```cpp
// Use std::visit for Asset (Issue or MPTIssue)
return std::visit(
[&](auto const& issue) {
return isIndividualFrozen(view, account, issue);
},
asset.value());
```
### PaymentSandbox for Isolation
```cpp
// Test payment effects before committing
PaymentSandbox sandbox(&view);
// ... apply changes to sandbox ...
sandbox.apply(view); // Commit all changes atomically
// Or let sandbox destruct to discard
```
### TER Return Codes
```cpp
// Transaction results are returned as TER, not exceptions
TER result = doApply();
if (result != tesSUCCESS) return result;
// TER categories: tes (success), tec (claimed fee), tef (failure), tel (local), tem (malformed)
```
### Depth Limiting
```cpp
// Recursive operations use depth parameter to prevent infinite recursion
TER checkVaultState(ReadView const& view, AccountID const& id, int depth = 0);
if (depth > maxDepth) return tecINTERNAL;
```
## Common Pitfalls
- Never use `read()` when you need to modify - use `peek()` instead
- Never forget to call `view.update(sle)` after modifying a peeked SLE
- Never use bare booleans for control flags - use the enum types
- Always check for frozen/unauthorized states before operating on trust lines
- Never ignore TER return values - propagate them up the call chain
## Key Files
- `include/xrpl/ledger/View.h` - Core read/write operations (largest file)
- `include/xrpl/ledger/ReadView.h` - Read-only interface
- `include/xrpl/ledger/ApplyView.h` - Mutable interface
- `src/libxrpl/ledger/PaymentSandbox.cpp` - Isolated payment testing
- `src/libxrpl/ledger/ApplyStateTable.cpp` - State change management
- `src/libxrpl/ledger/Credit.cpp` - Trust line and IOU operations

View File

@@ -1,58 +0,0 @@
# Net Module Best Practices
## Description
Use when working with network communication in `src/libxrpl/net/` or `include/xrpl/net/`. Covers HTTP/HTTPS client functionality and SSL certificate management.
## Responsibility
Provides HTTP/HTTPS client functionality for network requests, including SSL certificate registration, asynchronous request handling with boost::asio, and callback-based completion.
## Key Patterns
### Async HTTP with Callbacks
```cpp
// Callback returns bool indicating success/continuation
HTTPClient::get(
bSSL, io_context,
std::deque<std::string>{"site1.com", "site2.com"}, // Fallback sites
443, "/path",
maxResponseBytes,
timeout,
[](boost::system::error_code const& ec, int status, std::string const& body) -> bool {
if (ec) return false; // Stop
// Process response
return true; // Success
},
headers, journal);
```
### Lifetime Management with shared_from_this
```cpp
// Async callbacks use intrusive_ptr for safe lifetime
class HTTPClientImp : public HTTPClient,
public std::enable_shared_from_this<HTTPClientImp> {
void startAsync() {
auto self = shared_from_this(); // Prevent premature destruction
// ... schedule async operations ...
}
};
```
### Deadline Timers
```cpp
// Always set timeouts for network operations
boost::asio::basic_waitable_timer<std::chrono::steady_clock> timer_;
timer_.expires_after(std::chrono::seconds(timeout));
// Cancel pending operation on timeout
```
## Common Pitfalls
- Never start async operations without capturing shared_from_this - object may be destroyed before callback
- Always set deadline timers on network operations to prevent hanging connections
- Always set maximum response size limits to prevent resource exhaustion
- Never assume DNS resolution will succeed - handle resolver errors
## Key Files
- `include/xrpl/net/HTTPClient.h` - Main HTTP client interface
- `src/libxrpl/net/HTTPClient.cpp` - Implementation with async I/O
- `src/libxrpl/net/RegisterSSLCerts.cpp` - SSL certificate registration
- `include/xrpl/net/HTTPClientSSLContext.h` - SSL context management

View File

@@ -1,24 +0,0 @@
# Net Images Module Best Practices
## Description
Use when working with static image assets in `src/libxrpl/net/images/`. Contains embedded image data used by the HTTP server.
## Responsibility
Stores static image assets (favicons, logos) as embedded byte arrays for serving via the built-in HTTP server without external file dependencies.
## Key Patterns
### Embedded Assets
```cpp
// Images stored as static const byte arrays
// Compiled directly into the binary - no file I/O needed at runtime
static unsigned char const favicon[] = { /* ... */ };
```
## Common Pitfalls
- Keep embedded images small - they increase binary size
- Use appropriate image formats (ICO for favicons, PNG for logos)
- Update both the source image and the byte array when changing assets
## Key Files
- `src/libxrpl/net/images/` - Static image byte arrays embedded in the binary

View File

@@ -1,68 +0,0 @@
# NodeStore Module Best Practices
## Description
Use when working with persistent node storage in `src/libxrpl/nodestore/` or `include/xrpl/nodestore/`. Covers the storage abstraction layer, backend implementations, and caching.
## Responsibility
Abstraction layer for persistent storage of ledger nodes (SHAMap leaves and inner nodes). Supports multiple backend implementations (RocksDB, NuDB, Memory, Null) with a plugin architecture, caching, and async operations.
## Key Patterns
### Abstract Factory for Backends
```cpp
// Backend is pure virtual - concrete implementations selected at runtime
class Backend {
virtual ~Backend() = default;
virtual Status fetch(void const* key, std::shared_ptr<NodeObject>*) = 0;
virtual void store(std::shared_ptr<NodeObject> const&) = 0;
virtual void storeBatch(Batch const& batch) = 0;
};
// Backends: RocksDB, NuDB, Memory (testing), Null (disabled)
```
### Batch Operations
```cpp
// Always prefer batch operations for multiple reads/writes
virtual std::pair<std::vector<std::shared_ptr<NodeObject>>, Status>
fetchBatch(std::vector<uint256 const*> const& hashes) = 0;
virtual void storeBatch(Batch const& batch) = 0;
// Significantly reduces I/O overhead vs individual operations
```
### Status Enum (Not Exceptions)
```cpp
enum class Status { ok, notFound, keyTooBig, /* ... */ };
// I/O operations return Status, NOT throw exceptions
auto [objects, status] = backend->fetchBatch(hashes);
if (status != Status::ok) { /* handle */ }
```
### Configuration via Section
```cpp
// Backend options come from config file sections
RocksDBBackend(int keyBytes, Section const& keyValues,
Scheduler& scheduler, beast::Journal journal);
// Allows runtime tuning without recompilation
```
### Async Fetch with Scheduler
```cpp
// Non-blocking reads via scheduler integration
virtual void asyncFetch(uint256 const& hash,
std::function<void(std::shared_ptr<NodeObject>)>&& callback);
// Callback invoked on scheduler thread
```
## Common Pitfalls
- Never use individual fetch/store in tight loops - use batch operations
- Never throw exceptions from backend implementations - return Status enum
- Always configure appropriate cache sizes for the workload
- Never assume a fetch will succeed - always check Status
- Use Memory backend for unit tests, never RocksDB
## Key Files
- `include/xrpl/nodestore/Database.h` - Main storage interface
- `include/xrpl/nodestore/Backend.h` - Abstract backend interface
- `include/xrpl/nodestore/Manager.h` - Backend factory
- `include/xrpl/nodestore/NodeObject.h` - Individual node wrapper
- `src/libxrpl/nodestore/BatchWriter.cpp` - Batch write optimization

View File

@@ -1,66 +0,0 @@
# NodeStore Backend Module Best Practices
## Description
Use when working with storage backend implementations in `src/libxrpl/nodestore/backend/`. Covers RocksDB, NuDB, Memory, and Null backend factories.
## Responsibility
Concrete backend implementations for the NodeStore abstraction layer. Each backend provides persistent (or ephemeral) storage with different performance characteristics and use cases.
## Key Patterns
### Backend Factory Registration
```cpp
// Each backend is a factory that creates Backend instances
// Registered by name in the Manager
class RocksDBFactory : public Factory {
std::string getName() const override { return "RocksDB"; }
std::unique_ptr<Backend> createInstance(...) override;
};
```
### RocksDB Configuration
```cpp
// Extensive tuning via config Section
// Key options:
// open_files - Max open file descriptors
// filter_bits - Bloom filter bits per key (default 10)
// cache_mb - Block cache size in MB
// file_size_mb - Target SST file size
// compression - snappy (default), zlib, lz4, none
// block_size - Block size in KB (default 4)
// num_threads - Background compaction threads
```
### NuDB for Deterministic Storage
```cpp
// NuDB supports deterministic initialization
// Useful for reproducible test databases
// Hash-based storage with direct memory-mapped I/O
// Lower CPU overhead than RocksDB for write-heavy workloads
```
### Memory Backend for Testing
```cpp
// In-memory storage - fast but not persistent
// Use for unit tests only
// Thread-safe with internal mutex
```
### Null Backend for Disabled Storage
```cpp
// No-op backend - all operations succeed but store nothing
// Use when storage feature is disabled in config
```
## Common Pitfalls
- Use Memory backend for tests, never RocksDB (test isolation and speed)
- Always tune RocksDB bloom filter bits - default 10 is good for most workloads
- NuDB doesn't support range queries - only point lookups by hash
- Never use Null backend in production - data loss guaranteed
- Always configure appropriate open_files limits for the OS
## Key Files
- `src/libxrpl/nodestore/backend/RocksDBFactory.cpp` - RocksDB backend (~12.5KB)
- `src/libxrpl/nodestore/backend/NuDBFactory.cpp` - NuDB backend (~12KB)
- `src/libxrpl/nodestore/backend/MemoryFactory.cpp` - In-memory backend (~5KB)
- `src/libxrpl/nodestore/backend/NullFactory.cpp` - No-op backend (~2KB)

View File

@@ -1,35 +0,0 @@
# Proto Module Best Practices
## Description
Use when working with Protocol Buffer definitions in `include/xrpl/proto/`. Covers gRPC API definitions and generated protobuf headers.
## Responsibility
Contains Protocol Buffer generated headers defining the gRPC API for rippled. These define the wire format for RPC communication between clients and the server.
## Key Patterns
### Proto Organization
```
include/xrpl/proto/
└── org/xrpl/rpc/v1/
└── *.proto generated headers
```
### Usage
```cpp
#include <xrpl/proto/org/xrpl/rpc/v1/xrp_ledger.grpc.pb.h>
// Use generated types for gRPC request/response
```
### Versioning
- API is versioned under `org/xrpl/rpc/v1/`
- New versions get a new directory (v2/, etc.)
- Never modify generated files directly - modify the .proto source
## Common Pitfalls
- Never hand-edit generated .pb.h files - regenerate from .proto sources
- Always use the versioned path (v1/) when including proto headers
- Proto types are for serialization only - convert to native types for business logic
## Key Files
- `include/xrpl/proto/org/xrpl/rpc/v1/` - Generated gRPC API headers

View File

@@ -1,123 +0,0 @@
# Protocol Module Best Practices
## Description
Use when working with serialization and data types in `src/libxrpl/protocol/` or `include/xrpl/protocol/`. Covers STObject hierarchy, SField registry, serialization, TER codes, features, and keylets.
## Responsibility
Defines serialization formats, data types, and protocol constants. Handles conversion between C++ objects and wire format, JSON representation, and database storage. The largest module in libxrpl with 60+ files.
## Key Patterns
### STObject Hierarchy
```cpp
// STBase is the abstract root for all serializable types
// Concrete types: STInteger<N>, STBlob, STAmount, STArray, STObject, STPathSet, STVector256
// Access fields type-safely via SField references
auto amount = obj[sfAmount]; // Returns STAmount
auto flags = obj[sfFlags]; // Returns uint32
auto dest = obj[sfDestination]; // Returns AccountID
auto has = obj.isFieldPresent(sfMemos); // Check presence
```
### SField Registry
```cpp
// Fields are statically registered - never create SField at runtime
// SField carries type information and field ID
extern SField const sfAmount; // STAmount type
extern SField const sfFlags; // STInteger<uint32> type
extern SField const sfDestination; // STAccount type
// Field IDs are protocol-defined and must not change
```
### Serializer for Binary Format
```cpp
// Deterministic binary serialization
Serializer s;
obj.add(s); // Append binary representation
auto blob = s.peekData(); // Get bytes
// Deserialization
SerialIter sit(blob.data(), blob.size());
auto obj = std::make_shared<STObject>(sit, sfTransaction);
```
### Bidirectional JSON/Binary Conversion
```cpp
// Object to JSON
Json::Value json = obj.getJson(JsonOptions::none);
// JSON to Object
STParsedJSONObject parsed("tx_json", json);
if (parsed.object) { /* use parsed.object */ }
```
### TER (Transaction Error Result) Codes
```cpp
// Categories:
// tes - success (tesSUCCESS)
// tec - claimed fee, no effect (tecNO_DST, tecFROZEN, tecINSUFFICIENT_RESERVE)
// tef - failure (tefFAILURE)
// tel - local error (telNETWORK_ID_MAKES_TX_NON_CANONICAL)
// tem - malformed (temINVALID, temBAD_AMOUNT, temDISABLED)
// Check categories:
isTesSuccess(ter) // ter == tesSUCCESS
isTecClaim(ter) // tec range
isTemMalformed(ter) // tem range
```
### Feature/Amendment Flags
```cpp
// Gate new behavior on amendments
if (ctx.rules.enabled(featureMyFeature)) {
// New behavior
} else {
// Legacy behavior
}
// Register features in Feature.cpp
```
### Keylet for Ledger Entry Keys
```cpp
// Type-safe ledger key generation
auto key = keylet::account(accountID); // Account root
auto key = keylet::line(a, b, currency); // Trust line
auto key = keylet::offer(account, seq); // Offer
auto key = keylet::nftoken(tokenID); // NFT
// Keylet carries both the key (uint256) and the expected ledger entry type
```
### SOTemplate for Schema Validation
```cpp
// Define expected fields for a ledger entry type
SOTemplate const ltACCOUNT_ROOT = {
{sfAccount, soeREQUIRED},
{sfBalance, soeREQUIRED},
{sfFlags, soeREQUIRED},
{sfSequence, soeREQUIRED},
{sfOwnerCount, soeDEFAULT},
// ...
};
```
## Common Pitfalls
- Never create SField instances at runtime - they are static protocol definitions
- Never modify field IDs - they are part of the binary protocol
- Always use `isFieldPresent()` before accessing optional fields
- Never ignore TER return values - they carry critical error information
- Always gate new fields/behavior on feature amendments for consensus safety
- Respect JSON parsing depth limit of 10 to prevent stack overflow
- Use `[[nodiscard]]` on functions returning TER
## Key Files
- `include/xrpl/protocol/STObject.h` - Generic structured object container
- `include/xrpl/protocol/STAmount.h` - XRP and IOU amounts
- `include/xrpl/protocol/SField.h` - Field definitions
- `include/xrpl/protocol/TER.h` - Transaction result codes
- `include/xrpl/protocol/Feature.h` - Amendment flags
- `include/xrpl/protocol/Indexes.h` - Ledger entry key generation
- `include/xrpl/protocol/Keylet.h` - Type-safe ledger keys
- `include/xrpl/protocol/SOTemplate.h` - Object schema definitions
- `src/libxrpl/protocol/STParsedJSON.cpp` - JSON to object conversion

View File

@@ -1,60 +0,0 @@
# RDB Module Best Practices
## Description
Use when working with relational database access in `src/libxrpl/rdb/` or `include/xrpl/rdb/`. Covers SOCI wrapper, database configuration, and checkpointing.
## Responsibility
Provides a C++ wrapper around SOCI (SQLite/PostgreSQL abstraction) for relational data access, configuration management, blob type conversions, and periodic WAL checkpoint management.
## Key Patterns
### DBConfig Lazy Initialization
```cpp
// Construct config without opening connection
DBConfig config(basicConfig, "my_database");
// Open session later when needed
soci::session session;
config.open(session);
// Allows config parsing separate from database I/O
```
### Blob Conversions
```cpp
// Convert between SOCI blobs and standard types
soci::blob blob(session);
std::vector<std::uint8_t> bytes;
convert(blob, bytes); // blob -> vector
std::string str;
convert(blob, str); // blob -> string
```
### Checkpointer with Weak Pointer Safety
```cpp
// Checkpointer uses weak_ptr to detect session destruction
auto checkpointer = makeCheckpointer(
id,
std::weak_ptr<soci::session>(sessionPtr),
jobQueue,
logs);
checkpointer->schedule(); // Periodic WAL checkpoints
// If session is destroyed, checkpointer safely no-ops
```
### Thread-Safe Sessions
```cpp
// Each thread gets its own soci::session from the pool
// Never share a soci::session across threads
```
## Common Pitfalls
- Never share a soci::session across threads - each thread needs its own
- Always use `std::weak_ptr` for session references in long-lived objects (like Checkpointer)
- Be aware of SOCI include warnings - use pragma diagnostic push/pop
- Always convert blobs to standard types before processing
## Key Files
- `include/xrpl/rdb/SociDB.h` - Main wrapper interface
- `src/libxrpl/rdb/SociDB.cpp` - Implementation
- `src/libxrpl/rdb/DatabaseCon.cpp` - Database connection setup

View File

@@ -1,64 +0,0 @@
# Resource Module Best Practices
## Description
Use when working with rate limiting and resource management in `src/libxrpl/resource/` or `include/xrpl/resource/`. Covers endpoint tracking, charge/fee management, and abuse prevention.
## Responsibility
Tracks resource consumption by network endpoints (inbound/outbound connections) to prevent abuse and ensure fair resource allocation. Manages consumer lifecycle, charge accounting, and gossip-based reputation sharing.
## Key Patterns
### Manager/Impl Pattern
```cpp
// Abstract Manager interface with factory function
class Manager { virtual ~Manager() = 0; };
std::unique_ptr<Manager> make_Manager(beast::Journal journal);
// Implementation hidden in cpp
class ManagerImp : public Manager { /* ... */ };
```
### Consumer Factory
```cpp
// Different consumer types for different connection sources
Consumer newInboundEndpoint(beast::IP::Endpoint const& address);
Consumer newOutboundEndpoint(beast::IP::Endpoint const& address);
Consumer newUnlimitedEndpoint(beast::IP::Endpoint const& address);
```
### Background Thread Shutdown
```cpp
// Clean shutdown pattern with condition variable
~ManagerImp() {
{
std::lock_guard lock(mutex_);
stop_ = true;
cond_.notify_one();
}
thread_.join(); // Wait for thread to finish
}
```
### Proxy-Aware Endpoint Detection
```cpp
// Handle forwarded-for headers safely
boost::system::error_code ec;
auto proxiedIp = boost::asio::ip::make_address(forwardedFor, ec);
if (ec) {
journal_.warn() << "Invalid IP: " << ec.message();
return newInboundEndpoint(address); // Fallback to socket IP
}
```
## Common Pitfalls
- Never trust forwarded-for headers without proxy flag validation
- Always use the factory methods - never construct Consumer directly
- Always join background threads in destructor
- Use separate consumer types for different connection trust levels
## Key Files
- `include/xrpl/resource/ResourceManager.h` - Manager interface
- `src/libxrpl/resource/ResourceManager.cpp` - Implementation
- `include/xrpl/resource/Consumer.h` - Per-endpoint tracking
- `src/libxrpl/resource/Charge.cpp` - Cost definitions
- `src/libxrpl/resource/Fees.cpp` - Fee calculations

View File

@@ -1,68 +0,0 @@
# Server Module Best Practices
## Description
Use when working with server configuration in `src/libxrpl/server/` or `include/xrpl/server/`. Covers port configuration, SSL/TLS, WebSocket options, and authentication.
## Responsibility
Manages server listening ports, WebSocket configuration, SSL/TLS setup, authentication credentials, and admin network restrictions. Handles parsing configuration into validated port structures.
## Key Patterns
### Dual ParsedPort/Port Pattern
```cpp
// ParsedPort: intermediate parsing result (may be incomplete)
struct ParsedPort { /* partially validated fields */ };
// Port: final validated configuration (ready to use)
struct Port {
std::string name;
boost::asio::ip::address ip;
std::uint16_t port = 0;
std::set<std::string, iless> protocol;
// ...
};
```
### Configuration Section Parsing
```cpp
// Parse from config file section, log errors to stream
void parse_Port(ParsedPort& port, Section const& section, std::ostream& log);
// Does NOT throw - logs issues and sets defaults
```
### CIDR Admin Networks
```cpp
// IP-based admin access control with CIDR support
std::vector<boost::asio::ip::network_v4> admin_nets_v4;
std::vector<boost::asio::ip::network_v6> admin_nets_v6;
// Supports both IPv4 and IPv6 ranges
```
### WebSocket Options
```cpp
// Fine-grained compression control
boost::beast::websocket::permessage_deflate pmd_options;
// Queue limits prevent memory exhaustion
std::optional<std::uint16_t> ws_queue_limit;
// limit=0 means unlimited (not -1)
```
### SSL Context Lazy Creation
```cpp
// SSL context created only when needed
std::shared_ptr<boost::asio::ssl::context> context;
// Initialized when first SSL connection established
```
## Common Pitfalls
- Never use port-only access control - always use CIDR network restrictions for admin
- Use `iless` comparator for protocol names (case-insensitive)
- Remember that `limit=0` means unlimited, not disabled
- Always log parsing errors rather than throwing
- Separate user/admin credentials - don't reuse
## Key Files
- `include/xrpl/server/Port.h` - Port configuration structure
- `src/libxrpl/server/Port.cpp` - Parsing and validation
- `src/libxrpl/server/JSONRPCUtil.cpp` - RPC utility functions
- `src/libxrpl/server/LoadFeeTrack.cpp` - Load and fee tracking

View File

@@ -1,83 +0,0 @@
# SHAMap Module Best Practices
## Description
Use when working with the Merkle tree implementation in `src/libxrpl/shamap/` or `include/xrpl/shamap/`. Covers the SHA-256 based radix tree used for ledger state representation.
## Responsibility
Implements a SHA-256 based Merkle radix tree with 16-way branching (hexadecimal). Provides efficient ledger state representation with O(log N) proof-of-inclusion, copy-on-write snapshots, synchronization, and delta calculation.
## Key Patterns
### State Machine Lifecycle
```cpp
enum class SHAMapState { Modifying, Immutable, Synching, Invalid };
// Modifying: Can add/remove/modify entries
// Immutable: Snapshot - no modifications allowed
// Synching: Being synchronized from peers
// Invalid: Corrupted or destroyed
// Transitions are one-way: Modifying -> Immutable (via snapshot)
```
### Copy-on-Write via COWID
```cpp
std::uint32_t cowid_ = 1;
// Each snapshot gets a new COWID
// Children are only copied when modified (lazy copy)
// Immutable snapshots share nodes with the active map
auto snapshot = map.snapShot(true); // Creates immutable copy
```
### 16-Way Radix Branching
```cpp
static inline constexpr unsigned int branchFactor = 16;
static inline constexpr unsigned int leafDepth = 64;
// 256-bit key / 4 bits per nibble = 64 levels max
// Each inner node has up to 16 children
```
### Node Type Hierarchy
```cpp
// SHAMapTreeNode (base) -> SHAMapInnerNode (16 children)
// -> SHAMapLeafNode (data + key)
// Use dynamic_pointer_cast for safe downcasting
auto inner = intr_ptr::dynamic_pointer_cast<SHAMapInnerNode>(node);
if (inner) { /* process inner node */ }
```
### Walk-Up for Modifications (dirtyUp)
```cpp
// After modifying a leaf, propagate hash changes to root
void dirtyUp(SharedPtrNodeStack& stack, uint256 const& target, ...);
// Updates hashes from leaf -> root through the stack
```
### Lazy Traversal
```cpp
// Navigate to a leaf by key
SHAMapLeafNode* walkTowardsKey(uint256 const& id,
SharedPtrNodeStack* stack = nullptr);
// Returns leaf or nullptr; optionally records path for dirtyUp
```
### Intrusive Pointers for Nodes
```cpp
// Nodes use intrusive reference counting (not std::shared_ptr)
intr_ptr::SharedPtr<SHAMapTreeNode> root_;
// Minimal overhead - reference count embedded in node
```
## Common Pitfalls
- Never modify an Immutable map - check state before mutations
- Always call dirtyUp after modifying a leaf to maintain hash integrity
- Never assume node type without dynamic_pointer_cast check
- Remember that snapshots share nodes - COW means nodes are only copied on write
- Always use the provided iterators for safe traversal, not manual tree walking
## Key Files
- `include/xrpl/shamap/SHAMap.h` - Main map implementation
- `include/xrpl/shamap/SHAMapTreeNode.h` - Base node class
- `include/xrpl/shamap/SHAMapInnerNode.h` - Interior nodes (16-way)
- `include/xrpl/shamap/SHAMapLeafNode.h` - Leaf nodes with data
- `include/xrpl/shamap/SHAMapNodeID.h` - Tree position identifier
- `src/libxrpl/shamap/SHAMapDelta.cpp` - Difference between maps
- `src/libxrpl/shamap/SHAMapSync.cpp` - Synchronization algorithm

View File

@@ -1,137 +0,0 @@
# Transaction (tx) Module Best Practices
## Description
Use when working with transaction processing in `src/libxrpl/tx/` or `include/xrpl/tx/`. Covers the Transactor base class, transaction pipeline, invariant checks, and apply context.
## Responsibility
Implements the transaction processing pipeline: static validation (preflight), fee-claim checks (preclaim), transaction execution (doApply), and post-apply invariant verification. All transaction types derive from the Transactor base class.
## Key Patterns
### Transaction Pipeline (3 Phases)
```cpp
// Phase 1: Preflight - Static validation, NO ledger access
static NotTEC preflight(PreflightContext const& ctx) {
if (ctx.tx[sfAmount] <= beast::zero)
return temBAD_AMOUNT;
return tesSUCCESS;
}
// Phase 2: Preclaim - Ledger read-only checks
static TER preclaim(PreclaimContext const& ctx) {
auto sle = ctx.view.read(keylet::account(ctx.tx[sfAccount]));
if (!sle) return tecNO_DST;
return tesSUCCESS;
}
// Phase 3: doApply - Actual ledger mutations
TER doApply() override {
auto sle = view().peek(keylet::account(account_));
sle->setFieldAmount(sfBalance, newBalance);
view().update(sle);
return tesSUCCESS;
}
```
### Transactor Base Class
```cpp
class MyTransaction : public Transactor {
public:
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
explicit MyTransaction(ApplyContext& ctx) : Transactor(ctx) {}
// Optional: Gate on amendment
static bool checkExtraFeatures(PreflightContext const& ctx);
// Optional: Custom flag mask
static std::uint32_t getFlagsMask(PreflightContext const& ctx);
// Required
static NotTEC preflight(PreflightContext const& ctx);
static TER preclaim(PreclaimContext const& ctx);
TER doApply() override;
// Optional: Custom fee calculation
static XRPAmount calculateBaseFee(ReadView const& view, STTx const& tx);
};
```
### Feature Gating
```cpp
static bool checkExtraFeatures(PreflightContext const& ctx) {
// Return false to disable when amendment not enabled
return ctx.rules.enabled(featureMyFeature);
}
```
### Flag Validation
```cpp
static std::uint32_t getFlagsMask(PreflightContext const& ctx) {
return tfMyTransactionMask; // Allowed flags
}
// Base class validates: (tx.getFlags() & ~getFlagsMask()) == 0
```
### ConsequencesFactory Types
```cpp
// Normal: Standard transaction
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
// Blocker: Affects subsequent transactions' ability to claim fees
static constexpr ConsequencesFactoryType ConsequencesFactory{Blocker};
// Custom: Override makeTxConsequences() static method
static constexpr ConsequencesFactoryType ConsequencesFactory{Custom};
```
### TER Error Code Progression
```
tem* (malformed): temINVALID, temBAD_AMOUNT, temDISABLED - preflight errors
tef* (failure): tefFAILURE, tefNESTED_FAILURE - infrastructure errors
tel* (local): telNETWORK_ID_MAKES_TX_NON_CANONICAL - local-only errors
tec* (claimed): tecNO_DST, tecFROZEN, tecINSUFFICIENT_RESERVE - fee claimed, no effect
tes (success): tesSUCCESS - transaction applied
```
### Logging Convention
```cpp
JLOG(ctx.j.warn()) << "User error message"; // User-facing issues
JLOG(ctx.j.debug()) << "Detailed diagnostic"; // Implementation details
JLOG(ctx.j.trace()) << "Very verbose info"; // Deep debugging
JLOG(ctx.j.error()) << "Unexpected failure"; // Should not happen
```
### View Operations in doApply
```cpp
// Read-only (returns const SLE)
auto sle = view().read(keylet::account(accountID));
// Mutable (returns non-const SLE)
auto sle = view().peek(keylet::account(accountID));
sle->setFieldAmount(sfBalance, newBalance);
view().update(sle); // MUST call after modification
// Create new entry
auto sle = std::make_shared<SLE>(keylet::myEntry(id));
sle->setFieldText(sfData, data);
view().insert(sle);
// Remove entry
view().erase(sle);
```
## Common Pitfalls
- Never access ledger state in preflight - it only has PreflightContext (no view)
- Never mutate ledger state in preclaim - it has ReadView only
- Always call `view().update(sle)` after modifying a peeked SLE
- Never return `tesSUCCESS` from preclaim/preflight if validation failed
- Always gate new transaction types on feature amendments
- Use `NotTEC` return type for preflight (not TER) - prevents returning tec codes from static checks
- Never forget to register new transaction types in `transactions.macro` and `applySteps.cpp`
## Key Files
- `include/xrpl/tx/Transactor.h` - Base class with static method signatures
- `src/libxrpl/tx/Transactor.cpp` - Base implementation (41KB)
- `src/libxrpl/tx/apply.cpp` - Transaction application entry point
- `src/libxrpl/tx/ApplyContext.cpp` - Context management
- `src/libxrpl/tx/InvariantCheck.cpp` - Post-apply invariant validation (117KB)
- `src/libxrpl/tx/applySteps.cpp` - Step-by-step dispatch

View File

@@ -1,72 +0,0 @@
# Transaction Paths Module Best Practices
## Description
Use when working with payment path finding and execution in `src/libxrpl/tx/paths/` or `include/xrpl/tx/paths/`. Covers the flow engine, ripple calculation, and offer stream processing.
## Responsibility
Implements payment path finding and execution for cross-currency payments. Handles the flow engine for executing payments across multiple paths (strands), offer book management, and amount calculation.
## Key Patterns
### Flow Engine Entry Point
```cpp
path::RippleCalc::Output flow(
PaymentSandbox& view,
STAmount const& deliver,
AccountID const& src,
AccountID const& dst,
STPathSet const& paths,
bool defaultPaths,
bool partialPayment,
bool ownerPaysTransferFee,
OfferCrossing offerCrossing,
std::optional<Quality> const& limitQuality,
std::optional<STAmount> const& sendMax,
std::optional<uint256> const& domainID,
beast::Journal j,
path::detail::FlowDebugInfo* flowDebugInfo = nullptr);
```
### Strand-Based Execution
```cpp
// A "strand" is a single payment path through the DEX
// Multiple strands can be tried to find the best rate
// StrandFlow executes a single strand
// Flow tries all strands and picks the best result
```
### OfferStream for Order Book Processing
```cpp
// Iterates through offers in an order book
// Handles expired offers, unfunded offers, and self-crossing
// Automatically cleans up stale offers during traversal
```
### Quality-Based Routing
```cpp
// Quality = exchange rate between input and output
// Lower quality number = better rate
// limitQuality prevents accepting rates worse than threshold
```
### PaymentSandbox Isolation
```cpp
// All path calculations happen in a PaymentSandbox
// Changes are only committed if the payment succeeds
// Allows trying multiple paths without side effects
```
## Common Pitfalls
- Never modify the ledger directly during path calculation - use PaymentSandbox
- Always respect limitQuality to prevent unfavorable exchange rates
- Be aware that offer traversal may clean up stale offers as a side effect
- FlowDebugInfo is optional and only for debugging - never rely on it in production logic
- Path finding is computationally expensive - respect depth and complexity limits
## Key Files
- `include/xrpl/tx/paths/Flow.h` - Main flow engine entry point
- `include/xrpl/tx/paths/RippleCalc.h` - Payment amount calculation
- `src/libxrpl/tx/paths/OfferStream.cpp` - Order book traversal (~12KB)
- `src/libxrpl/tx/paths/BookTip.cpp` - Order book tip management
- `src/libxrpl/tx/paths/detail/Steps.h` - Step-by-step calculation
- `src/libxrpl/tx/paths/detail/StrandFlow.h` - Single path execution

View File

@@ -1,164 +0,0 @@
# Transactors Module Best Practices
## Description
Use when adding or modifying transaction types in `src/libxrpl/tx/transactors/`. This is the guide for implementing new transactors following the established patterns.
## Responsibility
Contains all concrete transaction type implementations. Each transactor follows the Transactor base class pattern with preflight/preclaim/doApply phases. Transaction types are organized by feature area in subdirectories.
## Template for New Transactors
### Header File (`include/xrpl/tx/transactors/MyTx.h`)
```cpp
#pragma once
#include <xrpl/tx/Transactor.h>
namespace xrpl {
class MyTransaction : public Transactor {
public:
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
explicit MyTransaction(ApplyContext& ctx) : Transactor(ctx) {}
static bool checkExtraFeatures(PreflightContext const& ctx);
static std::uint32_t getFlagsMask(PreflightContext const& ctx);
static NotTEC preflight(PreflightContext const& ctx);
static TER preclaim(PreclaimContext const& ctx);
TER doApply() override;
};
}
```
### Implementation File (`src/libxrpl/tx/transactors/MyFeature/MyTx.cpp`)
```cpp
#include <xrpl/tx/transactors/MyTx.h>
#include <xrpl/ledger/View.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/TxFlags.h>
namespace xrpl {
bool
MyTransaction::checkExtraFeatures(PreflightContext const& ctx)
{
return ctx.rules.enabled(featureMyFeature);
}
std::uint32_t
MyTransaction::getFlagsMask(PreflightContext const& ctx)
{
return tfUniversalMask; // Or custom mask
}
NotTEC
MyTransaction::preflight(PreflightContext const& ctx)
{
// Static validation - NO ledger access
auto const& tx = ctx.tx;
if (tx[sfAmount] <= beast::zero)
{
JLOG(ctx.j.warn()) << "Bad amount.";
return temBAD_AMOUNT;
}
return tesSUCCESS;
}
TER
MyTransaction::preclaim(PreclaimContext const& ctx)
{
// Ledger read-only checks
auto const sle = ctx.view.read(
keylet::account(ctx.tx[sfAccount]));
if (!sle)
return terNO_ACCOUNT;
return tesSUCCESS;
}
TER
MyTransaction::doApply()
{
// Mutate ledger state
auto sle = view().peek(keylet::account(account_));
if (!sle)
return tefINTERNAL;
sle->setFieldAmount(sfBalance, newBalance);
view().update(sle);
return tesSUCCESS;
}
}
```
### Registration Checklist
1. Add transaction type to `include/xrpl/protocol/detail/transactions.macro`
2. Add dispatch case to `src/libxrpl/tx/applySteps.cpp`
3. Add feature flag to `include/xrpl/protocol/Feature.h` and `src/libxrpl/protocol/Feature.cpp`
4. Add invariant checks if needed in `src/libxrpl/tx/InvariantCheck.cpp`
5. Add to `disabledTxTypes` in Batch.cpp if not batch-compatible
## Key Patterns Across All Transactors
### Feature Gating
```cpp
static bool checkExtraFeatures(PreflightContext const& ctx) {
return ctx.rules.enabled(featureMyFeature);
}
```
### Variant-Aware Validation
```cpp
// When handling Asset (Issue or MPTIssue):
if (auto const ret = std::visit(
[&]<typename T>(T const&) { return preflightHelper<T>(ctx); },
ctx.tx[sfAmount].asset().value()); !isTesSuccess(ret))
return ret;
```
### Ledger Entry CRUD in doApply
```cpp
// Create
auto sle = std::make_shared<SLE>(keylet::myEntry(id));
view().insert(sle);
// Read (mutable)
auto sle = view().peek(keylet::myEntry(id));
// Update
sle->setFieldU32(sfFlags, newFlags);
view().update(sle);
// Delete
view().erase(sle);
```
### Helper/Utils Files
```cpp
// Complex features use a separate Helpers/Utils file:
// AMM -> AMMHelpers.h, AMMUtils.h
// NFT -> NFTokenUtils.h
// Lending -> LendingHelpers.h
// Keep reusable logic in helpers, transaction-specific logic in transactors
```
## Common Pitfalls
- Never forget to register in `transactions.macro` and `applySteps.cpp`
- Never access ledger state in preflight (no view available)
- Never mutate state in preclaim (read-only view)
- Always call `view().update(sle)` after modifying a peeked entry
- Always gate on feature amendment for consensus safety
- Use `NotTEC` return type from preflight, `TER` from preclaim/doApply
- Put shared logic in a *Helpers.h file, not duplicated across transactors
## Key Files
- `include/xrpl/tx/Transactor.h` - Base class definition
- `src/libxrpl/tx/applySteps.cpp` - Transaction type dispatch
- `include/xrpl/protocol/detail/transactions.macro` - Transaction type registry
- `src/libxrpl/tx/InvariantCheck.cpp` - Post-apply validation

View File

@@ -1,68 +0,0 @@
# AMM (Automated Market Maker) Transactors Best Practices
## Description
Use when working with AMM transaction types in `src/libxrpl/tx/transactors/AMM/`. Covers pool creation, deposits, withdrawals, voting, bidding, deletion, and clawback.
## Responsibility
Implements decentralized trading pools with liquidity provider (LP) tokens. Allows users to create AMM pools, deposit/withdraw liquidity, vote on trading fees, bid on auction slots, and manage pool lifecycle.
## Key Patterns
### AMM Transaction Types
- **AMMCreate** - Create a new AMM pool with two assets
- **AMMDeposit** - Add liquidity to a pool, receive LP tokens
- **AMMWithdraw** - Remove liquidity, burn LP tokens
- **AMMVote** - Vote on trading fee percentage
- **AMMBid** - Bid on the auction slot for discounted trading
- **AMMDelete** - Remove an empty AMM pool
- **AMMClawback** - Issuer clawback of assets from AMM
### Precision Arithmetic
```cpp
// AMM calculations require controlled rounding
// ALWAYS use NumberRoundModeGuard for rounding control
NumberRoundModeGuard mg(Number::towards_zero);
auto lpTokens = ammLPTokens(amount1, amount2, lptIssue);
// Or explicit mode changes with RAII save
{
saveNumberRoundMode _{Number::getround()};
Number::setround(Number::upward);
auto value = calculation;
}
```
### Helper Functions (AMMHelpers.h)
```cpp
ammLPTokens() // Calculate LP tokens from pool reserves
lpTokensOut() // LP tokens from deposit
ammAssetIn() / ammAssetOut() // Calculate swap amounts
withinRelativeDistance() // Quality tolerance checks
changeSpotPriceQuality() // Quote generation algorithm
// Quadratic equation solving for pricing
```
### Feature Gates
```cpp
// Multiple amendment versions
ammEnabled(ctx.rules) // Base AMM feature
fixAMMv1_1 // First fix amendment
fixAMMv1_3 // Third fix amendment
// Always check which amendments are active
```
## Common Pitfalls
- Never perform AMM math without setting the rounding mode first
- Always use `NumberRoundModeGuard` (RAII) - never manually set/restore rounding
- Be aware that AMM calculations involve quadratic equations - precision matters
- AMMClawback has different authorization requirements than regular clawback
- Check `withinRelativeDistance` for quality tolerance rather than exact equality
## Key Files
- `src/libxrpl/tx/transactors/AMM/AMMCreate.cpp` - Pool creation
- `src/libxrpl/tx/transactors/AMM/AMMDeposit.cpp` - Liquidity deposit (~887 lines)
- `src/libxrpl/tx/transactors/AMM/AMMWithdraw.cpp` - Liquidity withdrawal (~911 lines)
- `src/libxrpl/tx/transactors/AMM/AMMVote.cpp` - Fee voting
- `src/libxrpl/tx/transactors/AMM/AMMBid.cpp` - Auction slot bidding
- `include/xrpl/tx/transactors/AMM/AMMHelpers.h` - Shared math utilities
- `include/xrpl/tx/transactors/AMM/AMMUtils.h` - AMM state utilities

View File

@@ -1,44 +0,0 @@
# Check Transactors Best Practices
## Description
Use when working with Check transaction types in `src/libxrpl/tx/transactors/Check/`. Covers check creation, cashing, and cancellation.
## Responsibility
Implements a check-like payment mechanism (delayed payment authorization). A sender creates a check, the recipient cashes it, and either party can cancel it (with expiration support).
## Key Patterns
### Check Lifecycle
```cpp
// 1. CreateCheck - Sender authorizes payment
// Validates: destination exists, amount valid, expiration future
// Creates: Check ledger entry with sender, destination, amount
// 2. CashCheck - Recipient claims payment
// Validates: caller is destination, check not expired
// Executes: transfers funds from sender to destination
// 3. CancelCheck - Either party cancels
// Validates: caller is sender or destination, or check expired
// Removes: Check ledger entry
```
### Error Codes
```cpp
tecNO_DST // Destination account doesn't exist
temREDUNDANT // Check to self
temBAD_AMOUNT // Invalid amount
temBAD_EXPIRATION // Expiration in the past
tecEXPIRED // Check has expired (for CashCheck)
```
## Common Pitfalls
- Checks can be cancelled by either sender or destination
- Expired checks can be cancelled by anyone
- CashCheck must handle both exact amount and "deliver minimum" modes
- Always validate expiration against the parent ledger close time
## Key Files
- `src/libxrpl/tx/transactors/Check/CreateCheck.cpp` - Check creation
- `src/libxrpl/tx/transactors/Check/CashCheck.cpp` - Check fulfillment (~440 lines)
- `src/libxrpl/tx/transactors/Check/CancelCheck.cpp` - Check cancellation

View File

@@ -1,43 +0,0 @@
# Delegate Transactors Best Practices
## Description
Use when working with delegation transaction types in `src/libxrpl/tx/transactors/Delegate/`. Covers delegate set and utilities.
## Responsibility
Manages transaction signing delegation, allowing accounts to authorize other accounts to sign transactions on their behalf without exposing the master key.
## Key Patterns
### Delegate Operations
```cpp
// DelegateSet - Create or modify a delegation
// Validates: delegate account exists, permissions valid
// Creates/Updates: Delegate ledger entry
// DelegateUtils - Shared utilities
// deleteDelegate() - Public cleanup interface, used by DeleteAccount
```
### Feature Gates
```cpp
// fixDelegateV1_1 - Added data existence checks
if (ctx.rules.enabled(fixDelegateV1_1)) {
// Perform additional validation
}
```
### Integration with DeleteAccount
```cpp
// DelegateUtils::deleteDelegate() is called by DeleteAccount
// for cleanup when an account is being deleted
// Must handle all delegation-related ledger entries
```
## Common Pitfalls
- Always check feature gate `fixDelegateV1_1` for data existence validation
- Delegate cleanup must be thorough - used by DeleteAccount
- Never allow self-delegation
## Key Files
- `src/libxrpl/tx/transactors/Delegate/DelegateSet.cpp` - Delegation management
- `include/xrpl/tx/transactors/Delegate/DelegateUtils.h` - Shared utilities

View File

@@ -1,69 +0,0 @@
# Lending Transactors Best Practices
## Description
Use when working with lending protocol transaction types in `src/libxrpl/tx/transactors/Lending/`. Covers loan management, broker operations, and payment calculation.
## Responsibility
Implements a complex loan protocol with amortization schedules, interest calculation, broker management, and collateral handling. The largest transactor feature area by code volume.
## Key Patterns
### Loan Lifecycle
```cpp
// LoanSet - Create or configure a loan
// LoanPay - Make loan payments (principal + interest)
// LoanManage - Manage loan state transitions
// LoanDelete - Remove a completed/cancelled loan
```
### Broker Operations
```cpp
// LoanBrokerSet - Create/configure a broker
// LoanBrokerDelete - Remove a broker
// LoanBrokerCoverDeposit - Deposit collateral
// LoanBrokerCoverWithdraw - Withdraw collateral
// LoanBrokerCoverClawback - Clawback broker assets
```
### Payment Calculation (LendingHelpers.h)
```cpp
struct LoanPaymentParts {
Number principalPaid; // Reduces loan balance
Number interestPaid; // Goes to Vault
Number valueChange; // Loan value adjustment
Number feePaid; // Goes to Broker
};
// Key helper functions:
checkLendingProtocolDependencies() // Validate feature gates
loanPeriodicRate() // Interest with secondsInYear
roundPeriodicPayment() // Consistent rounding
```
### Feature Gate
```cpp
// All lending operations gated on single feature
ctx.rules.enabled(featureLendingProtocol)
```
### Batch Transaction Restriction
```cpp
// Lending transactions are DISABLED in batch transactions
// Listed in Batch::disabledTxTypes
// Cannot be included in atomic batch operations
```
## Common Pitfalls
- Lending is disabled in Batch transactions - do not try to batch lending ops
- Payment calculations require precise rounding - use LendingHelpers functions
- Always validate lending protocol dependencies before operations
- Interest calculation uses `secondsInYear` constant - be aware of leap year handling
- LendingHelpers.h is ~1800 lines - the most complex helper file in the codebase
## Key Files
- `src/libxrpl/tx/transactors/Lending/LoanSet.cpp` - Loan configuration (~585 lines)
- `src/libxrpl/tx/transactors/Lending/LoanPay.cpp` - Payment processing (~548 lines)
- `src/libxrpl/tx/transactors/Lending/LoanManage.cpp` - State management
- `src/libxrpl/tx/transactors/Lending/LoanDelete.cpp` - Loan removal
- `src/libxrpl/tx/transactors/Lending/LoanBrokerSet.cpp` - Broker setup
- `include/xrpl/tx/transactors/Lending/LendingHelpers.h` - Shared calculations (~1799 lines)

View File

@@ -1,53 +0,0 @@
# MPT (Multi-Purpose Token) Transactors Best Practices
## Description
Use when working with MPT transaction types in `src/libxrpl/tx/transactors/MPT/`. Covers token issuance creation, configuration, destruction, and authorization.
## Responsibility
Implements Multi-Purpose Token (MPT) operations - a fungible token system simpler than full IOU trust lines. Handles token issuance lifecycle and holder authorization.
## Key Patterns
### MPT Transaction Types
```cpp
// MPTokenIssuanceCreate - Create a new token issuance
// MPTokenIssuanceSet - Modify issuance settings
// MPTokenIssuanceDestroy - Destroy an issuance (if no holders)
// MPTokenAuthorize - Authorize/deauthorize a holder
```
### MPT vs IOU Trust Lines
```cpp
// MPT is simpler than IOU trust lines:
// - No rippling mechanics
// - No transfer fees between holders (only issuer)
// - Simpler authorization model
// - Uses MPTIssue instead of Issue
// - Uses MPTAmount instead of IOUAmount
```
### Feature Gate
```cpp
ctx.rules.enabled(featureMPTokensV1)
```
### Asset Variant Handling
```cpp
// MPTIssue is part of the Asset variant (Issue | MPTIssue)
// Use std::visit when handling Asset generically:
std::visit([&](auto const& issue) {
// Works for both Issue and MPTIssue
}, asset.value());
```
## Common Pitfalls
- MPT issuances cannot be destroyed if any holders exist
- Authorization is per-holder, not per-token
- Don't confuse MPTIssue with Issue - they have different keylet types
- Always check `featureMPTokensV1` before MPT operations
## Key Files
- `src/libxrpl/tx/transactors/MPT/MPTokenIssuanceCreate.cpp` - Create issuance
- `src/libxrpl/tx/transactors/MPT/MPTokenIssuanceSet.cpp` - Modify settings
- `src/libxrpl/tx/transactors/MPT/MPTokenIssuanceDestroy.cpp` - Destroy issuance
- `src/libxrpl/tx/transactors/MPT/MPTokenAuthorize.cpp` - Holder authorization

View File

@@ -1,76 +0,0 @@
# NFT (Non-Fungible Token) Transactors Best Practices
## Description
Use when working with NFT transaction types in `src/libxrpl/tx/transactors/NFT/`. Covers minting, burning, offer management, and token modification.
## Responsibility
Implements NFT creation, trading, and lifecycle management. Handles token minting, burning, buy/sell offer creation and acceptance, offer cancellation, and dynamic NFT modification.
## Key Patterns
### NFT Transaction Types
```cpp
// NFTokenMint - Create a new NFT
// NFTokenBurn - Destroy an NFT
// NFTokenCreateOffer - Create a buy or sell offer
// NFTokenCancelOffer - Cancel an existing offer
// NFTokenAcceptOffer - Accept a buy or sell offer (execute trade)
// NFTokenModify - Modify NFT metadata (dynamic NFTs)
```
### NFTokenUtils - Shared Utilities (~1025 lines)
```cpp
// Key utility functions:
findToken() // Find an NFT in owner's token pages
insertToken() // Add NFT to owner's directory
removeToken() // Remove NFT from owner's directory
deleteTokenOffer() // Clean up a single offer
removeTokenOffersWithLimit() // Batch cleanup with limit
notTooManyOffers() // Check offer count limits
changeTokenURI() // Update NFT URI (dynamic NFTs)
struct TokenAndPage {
STObject token;
std::shared_ptr<SLE> page;
};
```
### Token Storage in Pages
```cpp
// NFTs are stored in paginated directories
// Each page holds multiple tokens
// Pages are linked as a doubly-linked list
// insertToken/removeToken manage page splits and merges
```
### Feature Gates
```cpp
featureNFTokenMintOffer // Combined mint + offer
fixRemoveNFTokenAutoTrustLine // Fix for auto trust line removal
featureDynamicNFT // NFTokenModify support
```
### Offer Directory Structure
```cpp
// Buy offers and sell offers stored in separate directories
// Indexed by token ID
// Offers can have expiration times
// Offers can specify a destination (private offers)
```
## Common Pitfalls
- Token page management is complex - always use NFTokenUtils functions
- Offer cleanup has limits (`removeTokenOffersWithLimit`) - don't assume all offers removed
- `notTooManyOffers()` must be checked before creating new offers
- Dynamic NFT modification requires `featureDynamicNFT` amendment
- Transfer fees only apply when the NFT issuer is not a party to the trade
- Burning an NFT with outstanding offers requires offer cleanup
## Key Files
- `src/libxrpl/tx/transactors/NFT/NFTokenMint.cpp` - Token minting
- `src/libxrpl/tx/transactors/NFT/NFTokenBurn.cpp` - Token destruction
- `src/libxrpl/tx/transactors/NFT/NFTokenCreateOffer.cpp` - Offer creation
- `src/libxrpl/tx/transactors/NFT/NFTokenAcceptOffer.cpp` - Offer acceptance (trade)
- `src/libxrpl/tx/transactors/NFT/NFTokenCancelOffer.cpp` - Offer cancellation
- `src/libxrpl/tx/transactors/NFT/NFTokenModify.cpp` - Dynamic NFT changes
- `include/xrpl/tx/transactors/NFT/NFTokenUtils.h` - Shared utilities (~1025 lines)

View File

@@ -1,56 +0,0 @@
# Offer Transactors Best Practices
## Description
Use when working with DEX offer transaction types in `src/libxrpl/tx/transactors/Offer/`. Covers order creation and cancellation on the native decentralized exchange.
## Responsibility
Implements decentralized exchange order management for the native XRPL order book. Handles offer creation (with matching/crossing), cancellation, and order book management.
## Key Patterns
### Offer Transaction Types
```cpp
// CreateOffer (~854 lines) - Create a new DEX order
// - Validates amounts, currency pairs, account state
// - Attempts to cross with existing offers (matching engine)
// - Remaining amount becomes a standing order if not fully filled
// - Handles self-crossing, expired offers, unfunded offers
// CancelOffer - Remove an existing order
// - Validates caller owns the offer
// - Removes offer from order book directory
```
### Offer Crossing (Matching Engine)
```cpp
// CreateOffer performs offer crossing inline:
// 1. Look up existing offers on the opposite side
// 2. Match at the offer's quality (exchange rate)
// 3. Consume matched offers (partial or full)
// 4. Place remaining amount as standing order
// This is the core DEX matching engine
```
### Quality and Order Books
```cpp
// Quality = exchange rate between TakerPays and TakerGets
// Order books indexed by currency pair and sorted by quality
// Lower quality number = better rate for taker
```
### Ticket Support
```cpp
// Offers can use tickets for sequence management
// Feature gate: featureTickets
```
## Common Pitfalls
- CreateOffer is one of the most complex transactors (~854 lines) - be thorough with changes
- Offer crossing modifies multiple ledger entries atomically
- Self-crossing (same account on both sides) has special handling
- Expired and unfunded offers are cleaned up during crossing
- Always validate that TakerPays and TakerGets are different assets
## Key Files
- `src/libxrpl/tx/transactors/Offer/CreateOffer.cpp` - Order creation and matching (~854 lines)
- `src/libxrpl/tx/transactors/Offer/CancelOffer.cpp` - Order cancellation

View File

@@ -1,36 +0,0 @@
# PermissionedDomain Transactors Best Practices
## Description
Use when working with permissioned domain transaction types in `src/libxrpl/tx/transactors/PermissionedDomain/`. Covers domain-based access control for the DEX.
## Responsibility
Implements domain-based access control for permissioned DEX operations. Allows creating and deleting permissioned domains that gate who can participate in certain trading activities.
## Key Patterns
### PermissionedDomain Transaction Types
```cpp
// PermissionedDomainSet - Create or update a permissioned domain
// PermissionedDomainDelete - Remove a permissioned domain
```
### Integration with Payments
```cpp
// Payments can reference a domain via sfDomainID field
// The domain gates which accounts can participate
// Used for regulated/permissioned trading environments
```
### Feature Gate
```cpp
ctx.rules.enabled(featurePermissionedDEX)
```
## Common Pitfalls
- Domains are referenced by other transactions (Payments) - deletion must check for references
- Always validate the feature gate before domain operations
- Domain ID matching is exact - no partial matches
## Key Files
- `src/libxrpl/tx/transactors/PermissionedDomain/PermissionedDomainSet.cpp` - Create/update domain
- `src/libxrpl/tx/transactors/PermissionedDomain/PermissionedDomainDelete.cpp` - Remove domain

View File

@@ -1,61 +0,0 @@
# Vault Transactors Best Practices
## Description
Use when working with vault transaction types in `src/libxrpl/tx/transactors/Vault/`. Covers vault creation, configuration, deposits, withdrawals, deletion, and clawback.
## Responsibility
Implements the vault mechanism for asset holding and loan collateral management. Allows creating vaults, depositing/withdrawing assets, configuring vault parameters, and managing vault lifecycle.
## Key Patterns
### Vault Transaction Types
```cpp
// VaultCreate - Create a new vault
// VaultSet - Configure vault parameters
// VaultDelete - Remove an empty vault
// VaultDeposit - Deposit assets into a vault
// VaultWithdraw - Withdraw assets from a vault
// VaultClawback - Issuer clawback from vault
```
### Feature Gate
```cpp
ctx.rules.enabled(featureSingleAssetVault)
```
### Batch Transaction Restriction
```cpp
// Vault transactions are DISABLED in batch transactions
// Listed in Batch::disabledTxTypes alongside Lending
// Cannot be included in atomic batch operations
```
### Depth Limiting for Recursive Operations
```cpp
// Vault operations may involve recursive state checks
// Use depth parameter to prevent infinite recursion
TER checkVaultState(ReadView const& view, AccountID const& id, int depth = 0);
if (depth > maxDepth) return tecINTERNAL;
```
### Integration with Lending
```cpp
// Vaults serve as collateral for the lending protocol
// VaultDeposit/Withdraw affect loan collateralization
// Vault state changes may trigger loan state recalculation
```
## Common Pitfalls
- Vault operations are disabled in batch transactions
- Vaults can only be deleted when empty
- Clawback has different authorization requirements than regular withdrawal
- Always respect depth limits in recursive vault state checks
- Vault operations may interact with lending protocol state
## Key Files
- `src/libxrpl/tx/transactors/Vault/VaultCreate.cpp` - Vault creation
- `src/libxrpl/tx/transactors/Vault/VaultSet.cpp` - Configuration
- `src/libxrpl/tx/transactors/Vault/VaultDelete.cpp` - Deletion
- `src/libxrpl/tx/transactors/Vault/VaultDeposit.cpp` - Asset deposit
- `src/libxrpl/tx/transactors/Vault/VaultWithdraw.cpp` - Asset withdrawal
- `src/libxrpl/tx/transactors/Vault/VaultClawback.cpp` - Issuer clawback

View File

@@ -1,228 +0,0 @@
# Merge Conflict Resolution Guide
## Description
Use when resolving merge conflicts after merging `develop` into a feature branch. Covers the key files that commonly conflict, field number allocation, namespace conventions, and the correct resolution strategy for each file type.
## General Principles
### Namespace
- All code uses `namespace xrpl { }` (not `ripple`). If a conflict shows `namespace ripple`, take the `xrpl` version.
- Qualified references: `xrpl::sign(...)`, `xrpl::sha256_hasher`, etc. Never `ripple::`.
### Header Guards
- Always `#pragma once`. Never `#ifndef` include guards. If a conflict shows old-style guards, take the `#pragma once` version.
### Copyright Headers
- The `develop` branch has removed copyright/license comment blocks from source files. If a conflict is just about the copyright header, take `develop`'s version (no header).
### File Moves
- Many files have been moved from `src/xrpld/` to `src/libxrpl/` or from `src/xrpld/` headers to `include/xrpl/`. If git shows a file as "deleted in develop" but it exists at a new path, delete the old-path file (`git rm`) and keep the new-path version.
- Common moves:
- `src/xrpld/app/tx/detail/*.h``include/xrpl/tx/transactors/*.h`
- `src/xrpld/app/tx/detail/*.cpp``src/libxrpl/tx/*.cpp` or `src/libxrpl/tx/transactors/*.cpp`
- `src/xrpld/app/tx/detail/InvariantCheck.cpp``src/libxrpl/tx/invariants/InvariantCheck.cpp`
### Transactor Migration
When merging transactors from `src/xrpld/app/tx/detail/` into `develop`, they must be fully migrated to the new libxrpl structure:
**File locations:**
- Header: `src/xrpld/app/tx/detail/Foo.h``include/xrpl/tx/transactors/Foo.h`
- Source: `src/xrpld/app/tx/detail/Foo.cpp``src/libxrpl/tx/transactors/Foo.cpp`
- Delete the old `.cpp` (both `src/xrpld/` and `src/libxrpl/` are GLOB_RECURSE discovered — duplicates cause linker errors)
- Optionally leave a forwarding header at the old `.h` location: `#include <xrpl/tx/transactors/Foo.h>`
**Header changes:**
- `#pragma once` (not `#ifndef` guards)
- `namespace xrpl` (not `ripple`)
- `#include <xrpl/tx/Transactor.h>` (not `<xrpld/app/tx/detail/Transactor.h>`)
**Source changes:**
- `namespace xrpl` (not `ripple`)
- `#include <xrpl/tx/transactors/Foo.h>` (not `<xrpld/app/tx/detail/Foo.h>`)
- `#include <xrpl/ledger/ApplyView.h>` (not `<xrpld/ledger/ApplyView.h>`)
- `#include <xrpl/ledger/View.h>` for `describeOwnerDir`
**API changes in the new Transactor:**
- `preflight1()` and `preflight2()` are **private** — transactor `preflight()` must NOT call them. The framework calls them automatically.
- Flag checking (`tfUniversalMask`) is handled by the framework via `getFlagsMask()`. Override `getFlagsMask()` only if custom flag handling is needed; otherwise the default handles `tfUniversalMask`.
- A simple `preflight()` that only did flag checks + preflight1/preflight2 should just `return tesSUCCESS;`
- `ctx_.app.journal(...)``ctx_.registry.journal(...)`
- `ctx_.app` does not exist in the new `ApplyContext`; use `ctx_.registry` for service access
**transactions.macro entry:**
Every transactor must have a `#if TRANSACTION_INCLUDE` block:
```cpp
#if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Foo.h>
#endif
TRANSACTION(ttFOO, <number>, Foo, ...)
```
### Include Paths
- `develop` uses the new macro-based transactor include system via `transactions.macro` with `TRANSACTION_INCLUDE`. Old-style explicit `#include <xrpld/app/tx/detail/*.h>` lists should be replaced with the macro approach.
## File-Specific Resolution Rules
### `include/xrpl/protocol/detail/features.macro`
New feature amendments go **at the top** of the active list (below the macro guard checks and `// clang-format off`), in reverse chronological order.
```
// Add new amendments to the top of this list.
// Keep it sorted in reverse chronological order.
XRPL_FEATURE(MyNewFeature, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (ExistingFix, Supported::yes, VoteBehavior::DefaultNo)
...
```
Resolution: Keep both sides' new amendments. Place your feature branch's new amendments at the very top.
### `include/xrpl/protocol/detail/sfields.macro`
Fields are grouped by type (UINT32, UINT64, UINT128, etc.) with common and uncommon sections. Each field has a unique **type + field number** pair.
**Resolution strategy:**
1. Keep both sides' new fields.
2. Check for field number collisions within each type. Use the next available number for your feature's fields.
3. Common fields come first, uncommon fields after (there's a comment separator).
To find the next available field number for a type:
```bash
grep "TYPED_SFIELD.*UINT32" include/xrpl/protocol/detail/sfields.macro | sed 's/.*UINT32, *//;s/).*//' | sort -n
```
Similarly for OBJECT and ARRAY types (using `UNTYPED_SFIELD`):
```bash
grep "UNTYPED_SFIELD.*OBJECT" include/xrpl/protocol/detail/sfields.macro | sed 's/.*OBJECT, *//;s/).*//' | sort -n
grep "UNTYPED_SFIELD.*ARRAY" include/xrpl/protocol/detail/sfields.macro | sed 's/.*ARRAY, *//;s/).*//' | sort -n
```
### `include/xrpl/protocol/detail/transactions.macro`
Transaction types have a unique **transaction type number**. New feature transactions go **at the bottom** of the active transaction list (before the system transactions starting at 100+).
**Resolution strategy:**
1. Keep all of `develop`'s transactions.
2. Add your feature's transactions at the bottom with the next available number.
3. Use the new 7-argument `TRANSACTION` macro format:
```cpp
/** Description of the transaction */
#if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/MyTransactor.h>
#endif
TRANSACTION(ttMY_TX, <next_number>, MyTx,
Delegation::delegable,
featureMyFeature,
noPriv, ({
{sfSomeField, soeREQUIRED},
}))
```
To find the next available transaction number:
```bash
grep "^TRANSACTION(" include/xrpl/protocol/detail/transactions.macro | sed 's/.*,\s*\([0-9]*\),.*/\1/' | sort -n
```
Note: Transaction numbers 100+ are reserved for system transactions (amendments, fees, UNL).
### `include/xrpl/protocol/detail/ledger_entries.macro`
Ledger entry types have a unique **ledger type number** (hex). New entries go **at the bottom** of the active list.
**Resolution strategy:**
1. Keep all of `develop`'s entries.
2. Add your feature's entries at the bottom with the next available hex number.
3. Check for collisions:
```bash
grep "^LEDGER_ENTRY(" include/xrpl/protocol/detail/ledger_entries.macro | grep -o '0x[0-9a-fA-F]*' | sort
```
### `src/libxrpl/protocol/Indexes.cpp`
The `LedgerNameSpace` enum assigns a unique single character to each ledger entry type for index hashing.
**Resolution strategy:**
1. Keep both sides' entries.
2. Check for character collisions. Each entry needs a unique char.
3. Find used characters:
```bash
grep -E "^\s+[A-Z_]+ = " src/libxrpl/protocol/Indexes.cpp | sed "s/.*= '//;s/'.*//" | sort | tr -d '\n'
```
Also check the deprecated chars (reserved, cannot reuse):
```bash
grep "deprecated" src/libxrpl/protocol/Indexes.cpp | sed "s/.*= '//;s/'.*//"
```
### `src/libxrpl/protocol/InnerObjectFormats.cpp`
Inner object formats define the fields allowed inside array elements (e.g., `sfSigners`, `sfPasskeys`).
**Resolution:** Keep both sides' `add(...)` calls. No numbering conflicts here — just ensure no duplicate registrations.
### `src/libxrpl/protocol/STTx.cpp`
The `singleSignHelper` function was refactored in `develop`:
- Parameter name: `sigObject` (not `signer`)
- Signature retrieval: `sigObject.getFieldVL(sfTxnSignature)` (not `getSignature(signer)`)
- No `fullyCanonical` parameter — canonical sig checking was simplified
**Resolution:** Take `develop`'s function signatures and patterns. Adapt any feature-specific logic to match.
### `src/libxrpl/protocol/SecretKey.cpp`
**Resolution:** Use `namespace xrpl`. Keep any additional `#include` directives your feature needs (e.g., OpenSSL headers for new key types).
### `src/libxrpl/tx/Transactor.cpp`
The `checkSign` / `checkSingleSign` / `checkMultiSign` functions were refactored in `develop`:
- `checkSingleSign` no longer takes a `Rules` parameter
- `checkSign` has a new overload taking `PreclaimContext`
- `checkBatchSign` uses the simplified `checkSingleSign` call
**Resolution:** Take `develop`'s function signatures. Add any new authentication checks (e.g., passkey verification) into `checkSingleSign` before the final `return tefBAD_AUTH`, using `view.read(...)` to check ledger state.
### `src/libxrpl/tx/applySteps.cpp`
**Resolution:** Always take `develop`'s macro-based include approach:
```cpp
#include <xrpl/tx/applySteps.h>
#pragma push_macro("TRANSACTION")
#undef TRANSACTION
#define TRANSACTION(...)
#define TRANSACTION_INCLUDE 1
#include <xrpl/protocol/detail/transactions.macro>
#undef TRANSACTION
#pragma pop_macro("TRANSACTION")
```
Never use the old explicit `#include <xrpld/app/tx/detail/*.h>` list.
### `src/test/jtx/impl/utility.cpp`
The `sign` function was refactored in `develop`:
- Takes `sigObject` parameter: `sign(Json::Value& jv, Account const& account, Json::Value& sigObject)`
- Has an overload: `sign(Json::Value& jv, Account const& account)` that calls `sign(jv, account, jv)`
- Uses `xrpl::sign(...)` not `ripple::sign(...)`
**Resolution:** Take `develop`'s function signatures. Adapt feature-specific signing logic to the new pattern.
## Conflict Resolution Checklist
1. List all conflicted files: `git diff --name-only --diff-filter=U`
2. Check which have actual conflict markers vs just unmerged: `grep -l "<<<<<<< HEAD" <file>`
3. For files without markers: stage them or `git rm` if they were moved
4. For each file with markers:
- Take `develop`'s structural changes (namespace, function signatures, macro formats)
- Preserve your feature's additions (new fields, entries, transactions, logic)
- Resolve any numbering collisions by incrementing to the next available number
5. Stage resolved files: `git add <file>`
6. Verify no remaining markers: `grep -r "<<<<<<< " --include="*.cpp" --include="*.h" --include="*.macro"`
7. Verify no remaining unmerged: `git diff --name-only --diff-filter=U`

View File

@@ -1,57 +0,0 @@
# App Module Best Practices
## Description
Use when working with the main application layer in `src/xrpld/app/`. Covers the Application singleton, ledger management, consensus adapters, services, and runtime coordination.
## Responsibility
Contains the main application logic and runtime coordination for the rippled server. The Application singleton provides access to all services. Sub-modules handle ledger management, consensus, fee voting, amendments, path finding, and transaction queuing.
## Key Patterns
### Application Singleton
```cpp
// Application is the master interface - access all services through it
class Application {
virtual Config& config() = 0;
virtual Logs& logs() = 0;
virtual JobQueue& getJobQueue() = 0;
virtual LedgerMaster& getLedgerMaster() = 0;
virtual NetworkOPs& getOPs() = 0;
virtual NodeStore::Database& getNodeStore() = 0;
// ... many more service accessors
};
// Implemented by ApplicationImp (hidden in .cpp)
```
### ServiceRegistry Pattern
```cpp
// Services are injected via ServiceRegistry from libxrpl
// Application provides centralized access to all registered services
```
### Master Mutex
```cpp
// Recursive mutex protects shared state:
using MutexType = std::recursive_mutex;
// Protects: open ledger, server state, consensus engine
// Use std::lock_guard<Application::MutexType> for access
```
### Module Interface Pattern
```cpp
// Public interface: Module.h (abstract)
// Implementation: ModuleImp.h/cpp (hidden)
// Factory: make_Module() returns unique_ptr
```
## Common Pitfalls
- Never access Application services before setup() completes
- Always acquire master mutex when modifying open ledger or consensus state
- Use `std::recursive_mutex` (not plain mutex) - multiple services may lock re-entrantly
- Never create a second Application instance
## Key Files
- `src/xrpld/app/main/Application.h` - Core application interface
- `src/xrpld/app/main/Application.cpp` - Implementation (150+ includes)
- `src/xrpld/app/main/BasicApp.h` - Base application services
- `src/xrpld/app/main/GRPCServer.h` - gRPC server integration

View File

@@ -1,47 +0,0 @@
# App Consensus Module Best Practices
## Description
Use when working with RCL consensus adapters in `src/xrpld/app/consensus/`. Bridges the generic consensus algorithm to rippled-specific types.
## Responsibility
Adapts the generic consensus algorithm (in `xrpld/consensus/`) to work with rippled application types. Provides concrete type adapters for transactions, transaction sets, and ledgers.
## Key Patterns
### RCL Adapters
```cpp
// RCLCxTx - Adapts SHAMapItem as a consensus transaction
// RCLCxTxSet - Adapts SHAMap as a consensus transaction set
// RCLCxLedger - Adapts Ledger as a consensus ledger
// RCLConsensus - Glues generic consensus to rippled Application
```
### Adapter Pattern
```cpp
// Generic consensus works with abstract types via CRTP
// RCL adapters provide concrete implementations
class RCLConsensus : public Consensus<RCLConsensus> {
// Implements required methods using rippled types
// e.g., acquireLedger(), proposeTx(), relay()
};
```
### Validation Handling
```cpp
// RCLValidations tracks validation messages from the network
// Maps to the generic Validations<> template
// Handles trusted vs untrusted validators
```
## Common Pitfalls
- Adapter methods must match the CRTP interface exactly - compiler errors are cryptic
- Never import generic consensus types into adapter code - always go through the adapter
- RCLConsensus holds references to Application services - ensure Application outlives it
## Key Files
- `src/xrpld/app/consensus/RCLConsensus.h` - Main consensus orchestrator
- `src/xrpld/app/consensus/RCLConsensus.cpp` - Implementation
- `src/xrpld/app/consensus/RCLValidations.h` - Validation handling
- `src/xrpld/app/consensus/RCLCxTx.h` - Transaction adapter
- `src/xrpld/app/consensus/RCLCxTxSet.h` - Transaction set adapter
- `src/xrpld/app/consensus/RCLCxLedger.h` - Ledger adapter

View File

@@ -1,67 +0,0 @@
# App Ledger Module Best Practices
## Description
Use when working with ledger management in `src/xrpld/app/ledger/`. Covers ledger storage, retrieval, history, and the Ledger class itself.
## Responsibility
Manages the lifecycle of ledger objects: creation, storage, retrieval, history tracking, inbound acquisition from network, and order book caching. The Ledger class is the central data structure.
## Key Patterns
### Ledger Class
```cpp
// Ledger is composed of two SHAMaps:
// 1. State Map - Account roots, order books, ledger entries (STLedgerEntry)
// 2. Transaction Map - Transactions and metadata for that ledger
class Ledger final : public std::enable_shared_from_this<Ledger>,
public CountedObject<Ledger> {
// Can be mutable (sole ownership) or immutable (shared, read-only)
// Genesis ledger has special constructor
};
```
### Mutable vs Immutable
```cpp
// Mutable: Only one owner, can be modified
// Immutable: Shared via shared_ptr, read-only
// Transition: mutable -> immutable when accepted
// Never modify an immutable ledger
```
### LedgerMaster
```cpp
// Manages the chain of validated ledgers
// Tracks: current, validated, closed ledgers
// Handles ledger transitions during consensus
```
### Inbound Ledger Acquisition
```cpp
// InboundLedgers manages acquiring missing ledgers from peers
// InboundTransactions handles transaction set acquisition
// Both use async fetch with timeout and retry
```
### Iterator Adapters
```cpp
// sles_iter_impl - Iterate over SLE (state entries)
// txs_iter_impl - Iterate over transactions
// Efficient iteration without copying
```
## Common Pitfalls
- Never modify an immutable ledger - check mutability first
- Ledger must be shared via shared_ptr (enable_shared_from_this)
- Genesis ledger construction is special - don't use for normal ledgers
- LedgerMaster state transitions must be atomic with consensus
- CountedObject tracking helps detect leaks - don't disable it
## Key Files
- `src/xrpld/app/ledger/Ledger.h` - Core ledger class
- `src/xrpld/app/ledger/LedgerMaster.h` - Ledger chain management
- `src/xrpld/app/ledger/LedgerHistory.h` - Historical tracking
- `src/xrpld/app/ledger/LedgerCleaner.h` - Online deletion
- `src/xrpld/app/ledger/InboundLedgers.h` - Network acquisition
- `src/xrpld/app/ledger/OrderBookDB.h` - Order book cache
- `src/xrpld/app/ledger/TransactionMaster.h` - Transaction lookup

View File

@@ -1,18 +0,0 @@
# App Ledger Detail Module Best Practices
## Description
Use when working with ledger implementation details in `src/xrpld/app/ledger/detail/`. Internal helpers for the ledger module.
## Responsibility
Internal implementation details for the app/ledger module. Contains private helpers for ledger state management, iteration, and storage operations.
## Key Patterns
### Detail Namespace Convention
- Code in `detail/` is internal to the `app/ledger` module
- Never include detail headers from outside `app/ledger`
- If you need functionality, use the public `app/ledger/` headers instead
## Common Pitfalls
- Detail implementations may change without API compatibility
- Never expose detail types in public interfaces

View File

@@ -1,54 +0,0 @@
# App Main Module Best Practices
## Description
Use when working with application initialization and lifecycle in `src/xrpld/app/main/`. Covers Application startup, shutdown, and core services.
## Responsibility
Application initialization, lifecycle management, and core service wiring. Contains the Application interface and its implementation, gRPC server, load management, node identity, and the node store scheduler.
## Key Patterns
### Application Lifecycle
```cpp
// 1. Construct Application (parse config, create services)
// 2. setup() - Initialize all services, open databases
// 3. run() - Main event loop
// 4. signalStop() - Graceful shutdown
// 5. Destructor - Clean up resources
```
### Node Identity
```cpp
// NodeIdentity manages the node's public/private key pair
// Used for peer handshake, session signatures, and cluster membership
// Keys persisted in wallet_db
```
### Load Manager
```cpp
// Tracks server load across all subsystems
// Triggers load-based fee escalation
// Monitors job queue depth and execution time
```
### gRPC Server
```cpp
// Optional gRPC server alongside JSON-RPC
// Uses proto definitions from include/xrpl/proto/
// Separate handler set from JSON-RPC
```
## Common Pitfalls
- setup() must complete before any service is used
- signalStop() should be called for graceful shutdown - avoid hard kills
- Node identity keys must never be logged or exposed
- Load manager affects fee escalation - test under load
## Key Files
- `src/xrpld/app/main/Application.h` - Core interface
- `src/xrpld/app/main/Application.cpp` - Implementation
- `src/xrpld/app/main/BasicApp.h` - Base services
- `src/xrpld/app/main/GRPCServer.h` - gRPC integration
- `src/xrpld/app/main/LoadManager.h` - Load tracking
- `src/xrpld/app/main/NodeIdentity.h` - Node key management
- `src/xrpld/app/main/NodeStoreScheduler.h` - Async DB scheduler

View File

@@ -1,75 +0,0 @@
# App Misc Module Best Practices
## Description
Use when working with application services in `src/xrpld/app/misc/`. Covers fee voting, amendments, SHAMapStore, transaction queue, validator management, and NetworkOPs.
## Responsibility
Collection of application-level services: fee voting system, amendment mechanism, online deletion (SHAMapStore), transaction queue (TxQ), validator key/list management, and NetworkOPs (the central operations coordinator).
## Key Patterns
### Fee Voting
```cpp
// Validators vote on fee schedules every 256 ledgers ("voting ledgers")
// Pseudo-transactions injected to set fees
// Majority vote determines new fee schedule
// FeeVote.h - voting logic
// FeeEscalation.md - escalation documentation
```
### Amendment Mechanism
```cpp
// Network-wide ledger rule changes
// Requires 80% validator approval sustained for 2 weeks
// Tracked as pseudo-transactions in each ledger
// AmendmentTableImpl.h manages tracking and state
```
### SHAMapStore (Online Delete)
```cpp
// Prunes old ledger history automatically
// Uses rotation between two databases
// Configurable deletion intervals
// Must not delete data needed for active operations
```
### Transaction Queue (TxQ)
```cpp
// Queues transactions when ledger is full
// Priority based on fee level
// Handles fee escalation under load
// TxQ.h - queue implementation
```
### Validator Management
```cpp
// ValidatorKeys.h - Node's own validator keys
// ValidatorList.h - Trusted validator list (UNL)
// ValidatorSite.h - Sites serving validator lists
// Keys loaded from config, lists fetched from URLs
```
### NetworkOPs
```cpp
// Central operations coordinator - the "god object"
// Coordinates: consensus, ledger acceptance, transaction submission
// NetworkOPs.cpp is one of the largest files in the codebase
// Access via app.getOPs()
```
## Common Pitfalls
- Fee voting only happens on voting ledgers (every 256) - don't trigger manually
- Amendments require 2-week sustained 80% approval - no fast path
- SHAMapStore deletion must respect the advisory_delete safety window
- TxQ priority depends on current fee escalation level
- NetworkOPs is massive - changes here affect many systems
## Key Files
- `src/xrpld/app/misc/FeeVote.h` - Fee voting system
- `src/xrpld/app/misc/AmendmentTableImpl.h` - Amendment tracking
- `src/xrpld/app/misc/SHAMapStore.h` - Online deletion
- `src/xrpld/app/misc/TxQ.h` - Transaction queue
- `src/xrpld/app/misc/ValidatorKeys.h` - Validator key management
- `src/xrpld/app/misc/ValidatorList.h` - Trusted validator list
- `src/xrpld/app/misc/NetworkOPs.cpp` - Central operations
- `src/xrpld/app/misc/README.md` - Architecture documentation

View File

@@ -1,18 +0,0 @@
# App Misc Detail Module Best Practices
## Description
Use when working with internal service implementation details in `src/xrpld/app/misc/detail/`. Internal helpers for the misc services module.
## Responsibility
Internal implementation details for app/misc services (fee voting internals, amendment table implementation, SHAMapStore internals, etc.).
## Key Patterns
### Detail Namespace Convention
- Code in `detail/` is internal to the `app/misc` module
- Implementation classes (e.g., AmendmentTableImpl) live here
- Never include detail headers from outside `app/misc`
## Common Pitfalls
- Detail implementations may change without API compatibility
- Always use the public `app/misc/` interfaces

View File

@@ -1,53 +0,0 @@
# App Paths Module Best Practices
## Description
Use when working with payment path finding in `src/xrpld/app/paths/`. Covers the path finding algorithm, trust line caching, and AMM liquidity integration.
## Responsibility
Implements the XRP Ledger payment path finding algorithm at the application level. Manages path requests, trust line caching, and integration with Automated Market Maker liquidity.
## Key Patterns
### Path Finding
```cpp
// Pathfinder: Algorithm that finds payment paths between accounts
// Considers: trust lines, order books, AMM pools
// Returns: Set of paths ranked by cost/quality
```
### Path Request Management
```cpp
// PathRequest - Individual path find request
// PathRequests - Manages collection of active requests
// Requests can be one-shot or subscribed (streaming updates)
```
### Trust Line Caching
```cpp
// RippleLineCache caches trust line data
// Avoids repeated ledger lookups during path finding
// Cache is invalidated on ledger close
// TrustLine.h provides the trust line representation
```
### AMM Integration
```cpp
// AMMLiquidity.h - Integrates AMM pools into path finding
// AMMOffer.h - Represents AMM as a synthetic offer
// AMM pools are treated as a special offer type in the path finder
```
## Common Pitfalls
- Path finding is computationally expensive - respect search depth limits
- Trust line cache must be invalidated on ledger close
- AMM liquidity changes with pool state - don't cache AMM offers across ledgers
- Path subscriptions can be memory-intensive with many clients
## Key Files
- `src/xrpld/app/paths/Pathfinder.h` - Path finding algorithm
- `src/xrpld/app/paths/PathRequest.h` - Individual request handling
- `src/xrpld/app/paths/PathRequests.h` - Request collection management
- `src/xrpld/app/paths/RippleLineCache.h` - Trust line caching
- `src/xrpld/app/paths/TrustLine.h` - Trust line representation
- `src/xrpld/app/paths/AMMLiquidity.h` - AMM pool integration
- `src/xrpld/app/paths/AMMOffer.h` - Synthetic AMM offers

View File

@@ -1,18 +0,0 @@
# App Paths Detail Module Best Practices
## Description
Use when working with path finding implementation details in `src/xrpld/app/paths/detail/`. Internal helpers for the path finding module.
## Responsibility
Internal implementation details for the path finding algorithm, including search heuristics, cost calculation helpers, and internal data structures.
## Key Patterns
### Detail Namespace Convention
- Code in `detail/` is internal to the `app/paths` module
- Contains algorithm-specific helpers not needed by callers
- Never include detail headers from outside `app/paths`
## Common Pitfalls
- Path finding internals are performance-sensitive - profile before modifying
- Detail implementations may change without API compatibility

View File

@@ -1,39 +0,0 @@
# App RDB Module Best Practices
## Description
Use when working with application-level database operations in `src/xrpld/app/rdb/`. Covers database abstractions and backend implementations.
## Responsibility
Application-level relational database operations. Provides interfaces for peer finding data storage, SQLite backend implementation, and database operation details.
## Key Patterns
### Interface-Based Design
```cpp
// PeerFinder.h - Abstract interface for peer data storage
// Backend implementations in backend/ subdirectory
// Allows swapping database backends without changing callers
```
### SQLite Backend
```cpp
// SQLiteDatabase.h - Primary backend implementation
// Uses SOCI wrapper from libxrpl/rdb
// Handles: peer data, transaction history, ledger metadata
```
### Backend Abstraction
```cpp
// backend/ directory contains concrete implementations
// backend/detail/ has implementation-specific helpers
// detail/ has shared implementation details
```
## Common Pitfalls
- Always use the abstract interface, not the SQLite backend directly
- Database operations should be off the main thread (use job queue)
- Respect the SOCI wrapper patterns from libxrpl/rdb
## Key Files
- `src/xrpld/app/rdb/PeerFinder.h` - Peer data interface
- `src/xrpld/app/rdb/backend/SQLiteDatabase.h` - SQLite implementation

View File

@@ -1,31 +0,0 @@
# App RDB Backend Module Best Practices
## Description
Use when working with database backend implementations in `src/xrpld/app/rdb/backend/`. Covers concrete database implementations.
## Responsibility
Concrete database backend implementations for the app/rdb module. Primary implementation is SQLiteDatabase.
## Key Patterns
### SQLiteDatabase
```cpp
// Primary backend implementation using SQLite via SOCI
// Handles: peer storage, transaction history, ledger metadata
// Thread-safe via session-per-thread pattern from libxrpl/rdb
```
### Backend Detail
```cpp
// backend/detail/ contains SQLite-specific helpers
// Schema creation, migration, and optimization queries
```
## Common Pitfalls
- Always use parameterized queries via SOCI - never raw string SQL
- Database files can grow large - implement periodic VACUUM
- WAL checkpoint scheduling prevents unbounded WAL growth
## Key Files
- `src/xrpld/app/rdb/backend/SQLiteDatabase.h` - SQLite implementation
- `src/xrpld/app/rdb/backend/detail/` - SQLite-specific helpers

View File

@@ -1,11 +0,0 @@
# App RDB Backend Detail Module Best Practices
## Description
Use when working with database backend implementation details in `src/xrpld/app/rdb/backend/detail/`. SQLite-specific internal helpers.
## Responsibility
SQLite-specific implementation details: schema definitions, migration scripts, query optimization, and SOCI binding helpers.
## Common Pitfalls
- Schema migrations must be backwards-compatible
- Never include these headers from outside the rdb/backend module

View File

@@ -1,18 +0,0 @@
# App RDB Detail Module Best Practices
## Description
Use when working with database implementation details in `src/xrpld/app/rdb/detail/`. Internal helpers for the relational database module.
## Responsibility
Internal implementation details for app-level database operations, including SQL query helpers and schema management.
## Key Patterns
### Detail Namespace Convention
- Code in `detail/` is internal to the `app/rdb` module
- Contains SQL query construction and result parsing helpers
- Never include detail headers from outside `app/rdb`
## Common Pitfalls
- SQL queries must use parameterized bindings (SOCI style) - never string concatenation
- Detail implementations may change without API compatibility

View File

@@ -1,34 +0,0 @@
# App Tx Module Best Practices
## Description
Use when working with application-level transaction handling in `src/xrpld/app/tx/`. Covers transaction submission, validation, and application-layer processing.
## Responsibility
Application-level transaction handling that bridges the protocol-layer transaction processing (libxrpl/tx) with the running server. Handles transaction submission, validation, and integration with the consensus process.
## Key Patterns
### Relationship to libxrpl/tx
```cpp
// libxrpl/tx: Protocol-level transaction processing (Transactor, preflight, preclaim, doApply)
// xrpld/app/tx: Application-level orchestration (submission, queuing, consensus integration)
// This module calls into libxrpl/tx for actual transaction execution
```
### Transaction Submission Flow
```cpp
// 1. Client submits transaction via RPC
// 2. app/tx validates and queues transaction
// 3. Transaction enters TxQ (app/misc/TxQ)
// 4. Consensus selects transactions for next ledger
// 5. libxrpl/tx executes selected transactions
```
## Common Pitfalls
- Don't duplicate transaction validation logic - defer to libxrpl/tx
- Application-level checks (queue depth, fee escalation) happen here, not in libxrpl
- Transaction metadata is generated at this level after execution
## Key Files
- `src/xrpld/app/tx/` - Application transaction handling
- `src/xrpld/app/tx/detail/` - Implementation details

View File

@@ -1,11 +0,0 @@
# App Tx Detail Module Best Practices
## Description
Use when working with application transaction handling details in `src/xrpld/app/tx/detail/`. Internal helpers for transaction submission and processing.
## Responsibility
Internal implementation details for application-level transaction handling, including submission validation, queue integration, and metadata generation.
## Common Pitfalls
- Don't duplicate libxrpl/tx validation logic here
- Detail implementations may change without API compatibility

View File

@@ -1,59 +0,0 @@
# Consensus Module Best Practices
## Description
Use when working with the generic consensus algorithm in `src/xrpld/consensus/`. This is the application-independent consensus implementation.
## Responsibility
Implements the generic consensus algorithm separate from application-specific types. Uses CRTP (Curiously Recurring Template Pattern) to allow the application layer to plug in concrete types without virtual dispatch overhead.
## Key Patterns
### CRTP Design
```cpp
// Generic consensus uses CRTP - derived class provides concrete types
template <class Derived>
class Consensus {
// Calls static_cast<Derived*>(this)->method() for app-specific behavior
// No virtual dispatch overhead
};
// Application adapter:
class RCLConsensus : public Consensus<RCLConsensus> {
// Provides concrete types: RCLCxTx, RCLCxTxSet, RCLCxLedger
};
```
### Consensus Phases
```cpp
// Open -> Establish -> Accept
// Open: Collecting transactions
// Establish: Proposing and voting on transaction set
// Accept: Applying agreed-upon transaction set to ledger
```
### Consensus Parameters (ConsensusParms.h)
```cpp
// Timing parameters for consensus rounds
// These are tuned for network behavior - don't change without careful analysis
```
### Disputed Transactions
```cpp
// DisputedTx tracks transactions where validators disagree
// Votes are collected and transaction is included/excluded based on threshold
```
## Common Pitfalls
- Never modify consensus parameters without understanding network-wide impact
- CRTP means compilation errors from type mismatches appear in template instantiation - read errors carefully
- The generic consensus module should NEVER depend on application-specific types (Ledger, STTx, etc.)
- Always test consensus changes with multi-node simulation
## Key Files
- `src/xrpld/consensus/Consensus.h` - Main consensus class (extensively documented)
- `src/xrpld/consensus/ConsensusParms.h` - Timing parameters
- `src/xrpld/consensus/ConsensusProposal.h` - Proposal structures
- `src/xrpld/consensus/DisputedTx.h` - Transaction dispute tracking
- `src/xrpld/consensus/LedgerTiming.h` - Ledger timing calculations
- `src/xrpld/consensus/LedgerTrie.h` - Transaction set representation
- `src/xrpld/consensus/Validations.h` - Generic validation tracking

View File

@@ -1,55 +0,0 @@
# Core Module Best Practices
## Description
Use when working with core configuration and system services in `src/xrpld/core/`. Covers Config, time keeping, and network identity.
## Responsibility
System-level configuration and core services. The Config class extends BasicConfig from libxrpl with rippled-specific settings. Provides time keeping and network ID management.
## Key Patterns
### Config Class
```cpp
// Config extends BasicConfig from libxrpl
class Config : public BasicConfig {
// SizedItem enum for memory-dependent configuration
enum SizedItem { siSweepInterval, siNodeCacheSize, ... };
// FeeSetup for fee parameters
struct FeeSetup {
XRPAmount reference_fee;
XRPAmount account_reserve;
XRPAmount owner_reserve;
};
// Access sections by name
auto const& section = config["server"];
};
```
### Configuration Sections
```cpp
// Section names defined in ConfigSections.h
static constexpr char const* SECTION_NODE_DB = "node_db";
static constexpr char const* SECTION_VALIDATORS = "validators";
// Always use constants, never string literals
```
### Gradual Refactoring
```cpp
// Legacy config uses mixed patterns - refactoring is ongoing
// New code should follow the Section-based approach
// Deprecated patterns are documented with TODO comments
```
## Common Pitfalls
- Always use `ConfigSections.h` constants for section names
- Config extends BasicConfig - check both for available methods
- SizedItem values scale with node size configuration - don't hardcode sizes
- Never modify Config after Application startup
## Key Files
- `src/xrpld/core/Config.h` - Configuration object
- `src/xrpld/core/ConfigSections.h` - Section name constants
- `src/xrpld/core/TimeKeeper.h` - System time tracking
- `src/xrpld/core/NetworkIDServiceImpl.h` - Network ID implementation

View File

@@ -1,11 +0,0 @@
# Core Detail Module Best Practices
## Description
Use when working with core configuration implementation details in `src/xrpld/core/detail/`. Internal helpers for the Config system.
## Responsibility
Internal implementation details for the core configuration module, including config parsing helpers and platform-specific abstractions.
## Common Pitfalls
- Never include detail headers from outside the core module
- Config parsing must handle all edge cases gracefully (missing sections, invalid values)

View File

@@ -1,74 +0,0 @@
# Overlay Module Best Practices
## Description
Use when working with P2P networking in `src/xrpld/overlay/`. Covers peer connections, protocol negotiation, message relay, and clustering.
## Responsibility
Manages peer-to-peer connections and the overlay network protocol. Handles HTTP/1.1 upgrade handshake, session signatures (MITM prevention), Protocol Buffer message serialization, message compression, and cluster node management.
## Key Patterns
### HTTP/1.1 Upgrade Handshake
```cpp
// Connection starts as HTTP, upgrades to ripple protocol
// Custom headers:
// Connect-As, Public-Key, Session-Signature
// Network-ID, Network-Time
// Closed-Ledger, Previous-Ledger
// Remote-IP, Local-IP, Crawl
```
### Session Signature (MITM Prevention)
```cpp
// Binds SSL/TLS session to node identities
// Each peer signs the shared SSL session data
// Prevents man-in-the-middle attacks at the protocol level
```
### Message Serialization
```cpp
// Google Protocol Buffers for all p2p messages
// Messages are compressed before transmission
// Compression.h handles LZ4/no-compression selection
```
### Peer Management
```cpp
// Overlay manages the set of connected peers
class Overlay {
virtual Peer::ptr findPeerByShortID(Peer::id_t) = 0;
virtual void send(std::shared_ptr<Message> const&) = 0; // Broadcast
virtual void relay(Message const&, uint256 const& suppression) = 0;
};
```
### Clustering
```cpp
// Multiple rippled nodes can form a cluster
// Cluster nodes: share load, distribute crypto operations
// Cluster membership verified via node public keys
```
### Reduce Relay
```cpp
// ReduceRelayCommon.h - Minimize redundant message relay
// Uses HashRouter for message deduplication
// Peers track which messages they've already seen
```
## Common Pitfalls
- Always validate session signatures during handshake - never skip
- Never send uncompressed messages to peers that advertise compression support
- Cluster keys must be pre-configured - no dynamic cluster joining
- Message suppression via HashRouter is critical for network health - never bypass
- Protocol Buffer messages must match the expected schema version
## Key Files
- `src/xrpld/overlay/Overlay.h` - Main overlay manager interface
- `src/xrpld/overlay/Peer.h` - Peer connection representation
- `src/xrpld/overlay/PeerSet.h` - Collection of peers
- `src/xrpld/overlay/Cluster.h` - Cluster management
- `src/xrpld/overlay/Message.h` - Message structure
- `src/xrpld/overlay/Compression.h` - Message compression
- `src/xrpld/overlay/ReduceRelayCommon.h` - Relay optimization
- `src/xrpld/overlay/README.md` - Comprehensive protocol documentation

View File

@@ -1,27 +0,0 @@
# Overlay Detail Module Best Practices
## Description
Use when working with P2P networking implementation details in `src/xrpld/overlay/detail/`. Internal helpers for the overlay module.
## Responsibility
Internal implementation details for the overlay networking layer, including protocol message handling, peer connection state machines, and handshake implementation.
## Key Patterns
### PeerImp
```cpp
// PeerImp is the concrete implementation of the Peer interface
// Manages: SSL connection, protocol state, message queuing
// Uses enable_shared_from_this for async callback safety
```
### OverlayImpl
```cpp
// OverlayImpl is the concrete implementation of Overlay
// Manages: listening sockets, peer lifecycle, broadcast
```
## Common Pitfalls
- Peer connection state machine transitions must be atomic
- Never access PeerImp internals from outside overlay/detail/
- Message queuing must respect back-pressure limits

View File

@@ -1,58 +0,0 @@
# PeerFinder Module Best Practices
## Description
Use when working with network discovery in `src/xrpld/peerfinder/`. Covers peer bootstrap, cache management, and connection slot strategy.
## Responsibility
Bootstraps into the XRP Ledger network and discovers peers. Manages bootcache (persistent addresses ranked by success), livecache (ephemeral recently-seen peers), and connection slot allocation.
## Key Patterns
### Three-Stage Connection Strategy
```cpp
// Stage 1: Connect to fixed peers (configured addresses)
// Stage 2: Try Livecache addresses (recently seen, with open slots)
// Stage 3: Fall back to Bootcache (persistent, ranked by valence)
```
### Bootcache (Persistent)
```cpp
// Persistent store of peer addresses ranked by "valence" (connection success)
// Higher valence = more reliable peer
// Persisted across restarts
// Used as fallback when livecache is empty
```
### Livecache (Ephemeral)
```cpp
// Recently seen peers with available connection slots
// Uses hop counts for distance estimation
// Random distribution for load balancing
// Not persisted - rebuilt on restart via gossip
```
### Slot Management
```cpp
// Slot states: accept, connect, connected, active, closing
// Slot properties: Inbound/Outbound, Fixed, Cluster
// Slots track connection lifecycle from handshake to disconnect
```
### Callback Pattern
```cpp
// Abstract interface for socket operations
// PeerFinder doesn't directly manage sockets
// Delegates I/O to the overlay layer via callbacks
```
## Common Pitfalls
- Fixed peers should always be tried first (Stage 1) - they are trusted
- Bootcache valence can decay over time - implement proper aging
- Livecache entries expire quickly - don't rely on stale data
- Slot limits prevent connection exhaustion - never bypass them
- Always check README.md for algorithm details before modifying
## Key Files
- `src/xrpld/peerfinder/PeerfinderManager.h` - Main manager interface
- `src/xrpld/peerfinder/Slot.h` - Connection slot representation
- `src/xrpld/peerfinder/README.md` - Extensive design documentation

View File

@@ -1,21 +0,0 @@
# PeerFinder Detail Module Best Practices
## Description
Use when working with peer discovery implementation details in `src/xrpld/peerfinder/detail/`. Internal helpers for the peerfinder module.
## Responsibility
Internal implementation details for peer discovery: bootcache persistence, livecache management, slot state machine, and connection strategy implementation.
## Key Patterns
### Logic Class
```cpp
// The main implementation class for peer finding
// Implements the three-stage connection strategy
// Manages bootcache and livecache state
```
## Common Pitfalls
- Bootcache persistence must be atomic to prevent corruption
- Livecache expiration must be checked on every access
- Never include detail headers from outside peerfinder/

View File

@@ -1,31 +0,0 @@
# PerfLog Module Best Practices
## Description
Use when working with performance logging in `src/xrpld/perflog/`. Covers performance instrumentation and metric collection.
## Responsibility
Performance logging and instrumentation for the rippled server. Tracks timing data, throughput metrics, and operational statistics for monitoring and debugging.
## Key Patterns
### Performance Logging Interface
```cpp
// Abstract interface for performance data collection
// Implementations can log to file, export to monitoring systems, etc.
// Enabled/disabled via configuration
```
### Detail Namespace
```cpp
// Implementation details in detail/ subdirectory
// Not part of public API
```
## Common Pitfalls
- Performance logging should have minimal overhead when disabled
- Never log sensitive data (keys, balances) in performance logs
- Ensure timestamps use consistent clock sources
## Key Files
- `src/xrpld/perflog/` - Performance logging implementation
- `src/xrpld/perflog/detail/` - Implementation details

View File

@@ -1,11 +0,0 @@
# PerfLog Detail Module Best Practices
## Description
Use when working with performance logging implementation details in `src/xrpld/perflog/detail/`. Internal helpers for the perflog module.
## Responsibility
Internal implementation details for performance logging, including metric collection, formatting, and output management.
## Common Pitfalls
- Performance logging overhead must be minimal when disabled
- Never include detail headers from outside perflog/

View File

@@ -1,91 +0,0 @@
# RPC Module Best Practices
## Description
Use when working with RPC request handling in `src/xrpld/rpc/`. Covers command dispatch, handler implementation, coroutine suspension, and the gRPC interface.
## Responsibility
HTTP/JSON and gRPC RPC interface to rippled. Dispatches requests to 40+ command handlers, manages request context, supports coroutine-based suspension for async operations, and handles user roles/permissions.
## Key Patterns
### RPC Handler Pattern
```cpp
// Each handler is a function taking context, returning Json::Value
Json::Value doMyCommand(RPC::JsonContext& context) {
// Validate parameters
if (!context.params.isMember("field"))
return RPC::missing_field_error("field");
// Access application services
auto& app = context.app;
// Build response
Json::Value result(Json::objectValue);
result["status"] = "success";
return result;
}
```
### Coroutine Suspension
```cpp
// RPC handlers can suspend for async operations
// Key types:
// Callback - 0-argument function
// Continuation - Takes callback, promises to call it later
// Suspend - Function from coroutine that takes continuation
// Coroutine - Function given suspend to enable suspension
// This allows handlers to yield without blocking threads
```
### Request Context
```cpp
struct JsonContext {
Application& app;
Resource::Charge& loadType;
Json::Value params;
beast::Journal j;
Role role; // User, Admin, Identified, etc.
};
```
### Role-Based Access
```cpp
enum class Role { GUEST, USER, ADMIN, IDENTIFIED, PROXY, FORBID };
// Handlers specify minimum required role
// Admin handlers only accessible from admin IP ranges
```
### Error Handling
```cpp
// Standard error helpers:
RPC::missing_field_error("field_name");
RPC::invalid_field_error("field_name");
RPC::make_error(rpcINVALID_PARAMS, "description");
// Errors injected into JSON response
```
### gRPC Handlers
```cpp
// Separate handler set for gRPC interface
// Defined in GRPCHandlers.h
// Use Protocol Buffer request/response types
// Convert to/from native types at boundary
```
## Common Pitfalls
- Always validate parameters before accessing them
- Check user Role before executing privileged operations
- Use coroutine suspension for any operation that might block
- Never return internal data structures directly - always convert to JSON
- Handler functions are in `handlers/` directory - one file per command or group
- gRPC handlers must convert proto types to native types at the boundary
## Key Files
- `src/xrpld/rpc/RPCHandler.h` - Command dispatcher
- `src/xrpld/rpc/Context.h` - RPC context/state
- `src/xrpld/rpc/Status.h` - RPC status codes
- `src/xrpld/rpc/Role.h` - User role/permissions
- `src/xrpld/rpc/GRPCHandlers.h` - gRPC integration
- `src/xrpld/rpc/handlers/` - Individual command handlers (40+)
- `src/xrpld/rpc/README.md` - Coroutine documentation

View File

@@ -1,11 +0,0 @@
# RPC Detail Module Best Practices
## Description
Use when working with RPC implementation details in `src/xrpld/rpc/detail/`. Internal helpers for the RPC module.
## Responsibility
Internal implementation details for RPC handling, including request parsing, response formatting, coroutine machinery, and middleware.
## Common Pitfalls
- Coroutine state must be carefully managed to prevent leaks
- Never include detail headers from outside rpc/

View File

@@ -1,74 +0,0 @@
# RPC Handlers Module Best Practices
## Description
Use when adding or modifying RPC command handlers in `src/xrpld/rpc/handlers/`. Contains 40+ individual RPC command implementations.
## Responsibility
Individual RPC command handler implementations. Each file implements one or more related RPC commands following the standard handler pattern.
## Key Patterns
### Handler Function Signature
```cpp
// Standard handler pattern
Json::Value doMyCommand(RPC::JsonContext& context) {
// 1. Validate parameters
if (!context.params.isMember("required_field"))
return RPC::missing_field_error("required_field");
// 2. Check permissions
// (Role already verified by dispatcher based on handler metadata)
// 3. Access application services
auto& app = context.app;
auto& ledger = context.ledgerMaster.getValidatedLedger();
// 4. Execute logic
// ...
// 5. Build and return response
Json::Value result(Json::objectValue);
result["status"] = "success";
return result;
}
```
### Parameter Validation
```cpp
// Use standard error helpers
RPC::missing_field_error("field_name"); // Required field missing
RPC::invalid_field_error("field_name"); // Field has wrong type/value
RPC::make_error(rpcINVALID_PARAMS, "description"); // Generic error
```
### Adding a New Handler
1. Create a new .cpp file in `handlers/`
2. Implement the handler function following the pattern above
3. Register the command in the handler dispatch table
4. Document the command parameters and response format
### Common Handler Files
```
AccountInfo.cpp - account_info command
AccountLines.cpp - account_lines (trust lines)
AccountOffers.cpp - account_offers
Submit.cpp - submit (transaction submission)
Subscribe.cpp - subscribe (event streaming)
LedgerData.cpp - ledger_data
ServerInfo.cpp - server_info
Fee1.cpp - fee command
Tx.cpp - tx (transaction lookup)
BookOffers.cpp - book_offers (order book)
```
## Common Pitfalls
- Always validate ALL parameters before using them
- Never return internal data structures - convert to JSON at the boundary
- Respect Role-based access control - admin handlers must check role
- Handlers should be stateless - all state comes from context
- Use coroutine suspension for any blocking operation (DB queries, network)
- Error responses must follow the standard error format
## Key Files
- `src/xrpld/rpc/handlers/` - All handler implementations
- `src/xrpld/rpc/RPCHandler.h` - Dispatch table and registration

View File

@@ -1,32 +0,0 @@
# SHAMap (xrpld) Module Best Practices
## Description
Use when working with application-level SHAMap operations in `src/xrpld/shamap/`. Covers NodeFamily and application integration with the Merkle tree.
## Responsibility
Application-level integration of the SHAMap (Merkle radix tree) with the rippled server. Provides NodeFamily for managing tree node relationships and connecting the generic SHAMap to the node store.
## Key Patterns
### NodeFamily
```cpp
// NodeFamily connects SHAMap to the persistent NodeStore
// Provides: database access, tree node creation, hash verification
// Each SHAMap references a Family for storage operations
```
### Relationship to libxrpl/shamap
```cpp
// libxrpl/shamap: Generic Merkle tree implementation
// xrpld/shamap: Application-specific integration (NodeFamily, storage)
// The generic tree doesn't know about databases - NodeFamily bridges the gap
```
## Common Pitfalls
- Always use NodeFamily to create SHAMap instances connected to storage
- The libxrpl SHAMap is the implementation - this module is the glue layer
- Don't duplicate SHAMap logic here - extend via NodeFamily only
## Key Files
- `src/xrpld/shamap/NodeFamily.h` - Family relationship management
- `src/xrpld/shamap/NodeFamily.cpp` - Implementation

View File

@@ -1,247 +0,0 @@
_help_parse: Options affecting listfile parsing
parse:
_help_additional_commands:
- Specify structure for custom cmake functions
additional_commands:
target_protobuf_sources:
pargs:
- target
- prefix
kwargs:
PROTOS: "*"
LANGUAGE: cpp
IMPORT_DIRS: "*"
GENERATE_EXTENSIONS: "*"
PLUGIN: "*"
_help_override_spec:
- Override configurations per-command where available
override_spec: {}
_help_vartags:
- Specify variable tags.
vartags: []
_help_proptags:
- Specify property tags.
proptags: []
_help_format: Options affecting formatting.
format:
_help_disable:
- Disable formatting entirely, making cmake-format a no-op
disable: false
_help_line_width:
- How wide to allow formatted cmake files
line_width: 120
_help_tab_size:
- How many spaces to tab for indent
tab_size: 4
_help_use_tabchars:
- If true, lines are indented using tab characters (utf-8
- 0x09) instead of <tab_size> space characters (utf-8 0x20).
- In cases where the layout would require a fractional tab
- character, the behavior of the fractional indentation is
- governed by <fractional_tab_policy>
use_tabchars: false
_help_fractional_tab_policy:
- If <use_tabchars> is True, then the value of this variable
- indicates how fractional indentions are handled during
- whitespace replacement. If set to 'use-space', fractional
- indentation is left as spaces (utf-8 0x20). If set to
- "`round-up` fractional indentation is replaced with a single"
- tab character (utf-8 0x09) effectively shifting the column
- to the next tabstop
fractional_tab_policy: use-space
_help_max_subgroups_hwrap:
- If an argument group contains more than this many sub-groups
- (parg or kwarg groups) then force it to a vertical layout.
max_subgroups_hwrap: 4
_help_max_pargs_hwrap:
- If a positional argument group contains more than this many
- arguments, then force it to a vertical layout.
max_pargs_hwrap: 5
_help_max_rows_cmdline:
- If a cmdline positional group consumes more than this many
- lines without nesting, then invalidate the layout (and nest)
max_rows_cmdline: 2
_help_separate_ctrl_name_with_space:
- If true, separate flow control names from their parentheses
- with a space
separate_ctrl_name_with_space: true
_help_separate_fn_name_with_space:
- If true, separate function names from parentheses with a
- space
separate_fn_name_with_space: false
_help_dangle_parens:
- If a statement is wrapped to more than one line, than dangle
- the closing parenthesis on its own line.
dangle_parens: false
_help_dangle_align:
- If the trailing parenthesis must be 'dangled' on its on
- "line, then align it to this reference: `prefix`: the start"
- "of the statement, `prefix-indent`: the start of the"
- "statement, plus one indentation level, `child`: align to"
- the column of the arguments
dangle_align: prefix
_help_min_prefix_chars:
- If the statement spelling length (including space and
- parenthesis) is smaller than this amount, then force reject
- nested layouts.
min_prefix_chars: 18
_help_max_prefix_chars:
- If the statement spelling length (including space and
- parenthesis) is larger than the tab width by more than this
- amount, then force reject un-nested layouts.
max_prefix_chars: 10
_help_max_lines_hwrap:
- If a candidate layout is wrapped horizontally but it exceeds
- this many lines, then reject the layout.
max_lines_hwrap: 2
_help_line_ending:
- What style line endings to use in the output.
line_ending: unix
_help_command_case:
- Format command names consistently as 'lower' or 'upper' case
command_case: canonical
_help_keyword_case:
- Format keywords consistently as 'lower' or 'upper' case
keyword_case: unchanged
_help_always_wrap:
- A list of command names which should always be wrapped
always_wrap: []
_help_enable_sort:
- If true, the argument lists which are known to be sortable
- will be sorted lexicographicall
enable_sort: true
_help_autosort:
- If true, the parsers may infer whether or not an argument
- list is sortable (without annotation).
autosort: true
_help_require_valid_layout:
- By default, if cmake-format cannot successfully fit
- everything into the desired linewidth it will apply the
- last, most aggressive attempt that it made. If this flag is
- True, however, cmake-format will print error, exit with non-
- zero status code, and write-out nothing
require_valid_layout: false
_help_layout_passes:
- A dictionary mapping layout nodes to a list of wrap
- decisions. See the documentation for more information.
layout_passes: {}
_help_markup: Options affecting comment reflow and formatting.
markup:
_help_bullet_char:
- What character to use for bulleted lists
bullet_char: "-"
_help_enum_char:
- What character to use as punctuation after numerals in an
- enumerated list
enum_char: .
_help_first_comment_is_literal:
- If comment markup is enabled, don't reflow the first comment
- block in each listfile. Use this to preserve formatting of
- your copyright/license statements.
first_comment_is_literal: false
_help_literal_comment_pattern:
- If comment markup is enabled, don't reflow any comment block
- which matches this (regex) pattern. Default is `None`
- (disabled).
literal_comment_pattern: null
_help_fence_pattern:
- Regular expression to match preformat fences in comments
- default= ``r'^\s*([`~]{3}[`~]*)(.*)$'``
fence_pattern: ^\s*([`~]{3}[`~]*)(.*)$
_help_ruler_pattern:
- Regular expression to match rulers in comments default=
- '``r''^\s*[^\w\s]{3}.*[^\w\s]{3}$''``'
ruler_pattern: ^\s*[^\w\s]{3}.*[^\w\s]{3}$
_help_explicit_trailing_pattern:
- If a comment line matches starts with this pattern then it
- is explicitly a trailing comment for the preceding
- argument. Default is '#<'
explicit_trailing_pattern: "#<"
_help_hashruler_min_length:
- If a comment line starts with at least this many consecutive
- hash characters, then don't lstrip() them off. This allows
- for lazy hash rulers where the first hash char is not
- separated by space
hashruler_min_length: 10
_help_canonicalize_hashrulers:
- If true, then insert a space between the first hash char and
- remaining hash chars in a hash ruler, and normalize its
- length to fill the column
canonicalize_hashrulers: true
_help_enable_markup:
- enable comment markup parsing and reflow
enable_markup: false
_help_lint: Options affecting the linter
lint:
_help_disabled_codes:
- a list of lint codes to disable
disabled_codes: []
_help_function_pattern:
- regular expression pattern describing valid function names
function_pattern: "[0-9a-z_]+"
_help_macro_pattern:
- regular expression pattern describing valid macro names
macro_pattern: "[0-9A-Z_]+"
_help_global_var_pattern:
- regular expression pattern describing valid names for
- variables with global (cache) scope
global_var_pattern: "[A-Z][0-9A-Z_]+"
_help_internal_var_pattern:
- regular expression pattern describing valid names for
- variables with global scope (but internal semantic)
internal_var_pattern: _[A-Z][0-9A-Z_]+
_help_local_var_pattern:
- regular expression pattern describing valid names for
- variables with local scope
local_var_pattern: "[a-z][a-z0-9_]+"
_help_private_var_pattern:
- regular expression pattern describing valid names for
- privatedirectory variables
private_var_pattern: _[0-9a-z_]+
_help_public_var_pattern:
- regular expression pattern describing valid names for public
- directory variables
public_var_pattern: "[A-Z][0-9A-Z_]+"
_help_argument_var_pattern:
- regular expression pattern describing valid names for
- function/macro arguments and loop variables.
argument_var_pattern: "[a-z][a-z0-9_]+"
_help_keyword_pattern:
- regular expression pattern describing valid names for
- keywords used in functions or macros
keyword_pattern: "[A-Z][0-9A-Z_]+"
_help_max_conditionals_custom_parser:
- In the heuristic for C0201, how many conditionals to match
- within a loop in before considering the loop a parser.
max_conditionals_custom_parser: 2
_help_min_statement_spacing:
- Require at least this many newlines between statements
min_statement_spacing: 1
_help_max_statement_spacing:
- Require no more than this many newlines between statements
max_statement_spacing: 2
max_returns: 6
max_branches: 12
max_arguments: 5
max_localvars: 15
max_statements: 50
_help_encode: Options affecting file encoding
encode:
_help_emit_byteorder_mark:
- If true, emit the unicode byte-order mark (BOM) at the start
- of the file
emit_byteorder_mark: false
_help_input_encoding:
- Specify the encoding of the input file. Defaults to utf-8
input_encoding: utf-8
_help_output_encoding:
- Specify the encoding of the output file. Defaults to utf-8.
- Note that cmake only claims to support utf-8 so be careful
- when using anything else
output_encoding: utf-8
_help_misc: Miscellaneous configurations options.
misc:
_help_per_command:
- A dictionary containing any per-command configuration
- overrides. Currently only `command_case` is supported.
per_command: {}

101
.gersemi/definitions.cmake Normal file
View File

@@ -0,0 +1,101 @@
# Custom CMake command definitions for gersemi formatting.
# These stubs teach gersemi the signatures of project-specific commands
# so it can format their invocations correctly.
function(git_branch branch_val)
endfunction()
function(isolate_headers target A B scope)
endfunction()
function(create_symbolic_link target link)
endfunction()
function(xrpl_add_test name)
endfunction()
macro(exclude_from_default target_)
endmacro()
macro(exclude_if_included target_)
endmacro()
function(target_protobuf_sources target prefix)
set(options APPEND_PATH DESCRIPTORS)
set(oneValueArgs
LANGUAGE
OUT_VAR
EXPORT_MACRO
TARGET
PROTOC_OUT_DIR
PLUGIN
PLUGIN_OPTIONS
PROTOC_EXE
)
set(multiValueArgs
PROTOS
IMPORT_DIRS
GENERATE_EXTENSIONS
PROTOC_OPTIONS
DEPENDENCIES
)
cmake_parse_arguments(
THIS_FUNCTION_PREFIX
"${options}"
"${oneValueArgs}"
"${multiValueArgs}"
${ARGN}
)
endfunction()
function(add_module parent name)
endfunction()
function(setup_protocol_autogen)
endfunction()
function(target_link_modules parent scope)
endfunction()
function(setup_target_for_coverage_gcovr)
set(options NONE)
set(oneValueArgs BASE_DIRECTORY NAME FORMAT)
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
cmake_parse_arguments(
THIS_FUNCTION_PREFIX
"${options}"
"${oneValueArgs}"
"${multiValueArgs}"
${ARGN}
)
endfunction()
function(add_code_coverage_to_target name scope)
endfunction()
function(verbose_find_path variable name)
set(options
NO_CACHE
REQUIRED
OPTIONAL
NO_DEFAULT_PATH
NO_PACKAGE_ROOT_PATH
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH
NO_CMAKE_INSTALL_PREFIX
CMAKE_FIND_ROOT_PATH_BOTH
ONLY_CMAKE_FIND_ROOT_PATH
NO_CMAKE_FIND_ROOT_PATH
)
set(oneValueArgs REGISTRY_VIEW VALIDATOR DOC)
set(multiValueArgs NAMES HINTS PATHS PATH_SUFFIXES)
cmake_parse_arguments(
THIS_FUNCTION_PREFIX
"${options}"
"${oneValueArgs}"
"${multiValueArgs}"
${ARGN}
)
endfunction()

1
.gersemirc Normal file
View File

@@ -0,0 +1 @@
definitions: [.gersemi]

View File

@@ -1,16 +1,81 @@
# This feature requires Git >= 2.24
# To use it by default in git blame:
# git config blame.ignoreRevsFile .git-blame-ignore-revs
50760c693510894ca368e90369b0cc2dabfd07f3
e2384885f5f630c8f0ffe4bf21a169b433a16858
241b9ddde9e11beb7480600fd5ed90e1ef109b21
760f16f56835663d9286bd29294d074de26a7ba6
0eebe6a5f4246fced516d52b83ec4e7f47373edd
2189cc950c0cebb89e4e2fa3b2d8817205bf7cef
b9d007813378ad0ff45660dc07285b823c7e9855
fe9a5365b8a52d4acc42eb27369247e6f238a4f9
9a93577314e6a8d4b4a8368cc9d2b15a5d8303e8
552377c76f55b403a1c876df873a23d780fcc81c
97f0747e103f13e26e45b731731059b32f7679ac
b13370ac0d207217354f1fc1c29aef87769fb8a1
# This file is sorted in reverse chronological order, with the most recent commits at the top.
# The commits listed here are ignored by git blame, which is useful for formatting-only commits that would otherwise obscure the history of changes to a file.
# refactor: Enable clang-tidy `readability-identifier-naming` check (#6571)
8995564ed6b9e453e144bb663303072a3c1ba305
# refactor: Enable remaining clang-tidy `cppcoreguidelines` checks (#6538)
72f4cb097f626b08b02fc3efcb4aa11cb2e7adb8
# refactor: Rename system name from 'ripple' to 'xrpld' (#6347)
ffea3977f0b771fe8e43a8f74e4d393d63a7afd8
# refactor: Update transaction folder structure (#6483)
5865bd017f777491b4a956f9210be0c4161f5442
# chore: Use gersemi instead of ancient cmake-format (#6486)
0c74270b055133a57a497b5c9fc5a75f7647b1f4
# chore: Apply clang-format width 100 (#6387)
2c1fad102353e11293e3edde1c043224e7d3e983
# chore: Set clang-format width to 100 in config file (#6387)
25cca465538a56cce501477f9e5e2c1c7ea2d84c
# chore: Set cmake-format width to 100 (#6386)
469ce9f291a4480c38d4ee3baca5136b2f053cd0
# refactor: Modularize app/tx (#6228)
0976b2b68b64972af8e6e7c497900b5bce9fe22f
# chore: Update clang-format to 21.1.8 (#6352)
958d8f375453d80bb1aa4c293b5102c045a3e4b4
# refactor: Replace include guards by '#pragma once' (#6322)
34ef577604782ca8d6e1c17df8bd7470990a52ff
# chore: Format all cmake files without comments (#6294)
fe9c8d568fcf6ac21483024e01f58962dd5c8260
# chore: Add cmake-format pre-commit hook (#6279)
a0e09187b9370805d027c611a7e9ff5a0125282a
# chore: Set ColumnLimit to 120 in clang-format (#6288)
5f638f55536def0d88b970d1018a465a238e55f4
# refactor: Fix typos in comments, configure cspell (#6164)
3c9f5b62525cb1d6ca1153eeb10433db7d7379fd
# refactor: Rename `rippled.cfg` to `xrpld.cfg` (#6098)
3d1b3a49b3601a0a7037fa0b19d5df7b5e0e2fc1
# refactor: Rename `ripple` namespace to `xrpl` (#5982)
1eb0fdac6543706b4b9ddca57fd4102928a1f871
# refactor: Rename `rippled` binary to `xrpld` (#5983)
9eb84a561ef8bb066d89f098bd9b4ac71baed67c
# refactor: Replaces secp256k1 source by Conan package (#6089)
813bc4d9491b078bb950f8255f93b02f71320478
# refactor: Remove unnecessary copyright notices already covered by LICENSE.md (#5929)
1d42c4f6de6bf01d1286fc7459b17a37a5189e88
# refactor: Rename `RIPPLE_` and `RIPPLED_` definitions to `XRPL_` (#5821)
ada83564d894829424b0f4d922b0e737e07abbf7
# refactor: Modularize shamap and nodestore (#5668)
8eb233c2ea8ad5a159be73b77f0f5e1496d547ac
# refactor: Modularise ledger (#5493)
dc8b37a52448b005153c13a7f046ad494128cf94
# chore: Update clang-format and prettier with pre-commit (#5709)
c14ce956adeabe476ad73c18d73103f347c9c613
# chore: Fix file formatting (#5718)
896b8c3b54a22b0497cb0d1ce95e1095f9a227ce
# chore: Reverts formatting changes to external files, adds formatting changes to proto files (#5711)
b13370ac0d207217354f1fc1c29aef87769fb8a1
# chore: Run prettier on all files (#5657)
97f0747e103f13e26e45b731731059b32f7679ac
# Reformat code with clang-format-18
552377c76f55b403a1c876df873a23d780fcc81c
# Recompute loops (#4997)
d028005aa6319338b0adae1aebf8abe113162960
# Rewrite includes (#4997)
1d23148e6dd53957fcb6205c07a5c6cd7b64d50c
# Rearrange sources (#4997)
e416ee72ca26fa0c09d2aee1b68bdfb2b7046eed
# Move CMake directory (#4997)
2e902dee53aab2a8f27f32971047bb81e022f94f
# Rewrite includes
0eebe6a5f4246fced516d52b83ec4e7f47373edd
# Format formerly .hpp files
760f16f56835663d9286bd29294d074de26a7ba6
# Rename .hpp to .h
241b9ddde9e11beb7480600fd5ed90e1ef109b21
# Consolidate external libraries
e2384885f5f630c8f0ffe4bf21a169b433a16858
# Format first-party source according to .clang-format
50760c693510894ca368e90369b0cc2dabfd07f3

View File

@@ -1,7 +1,7 @@
---
name: Feature Request
about: Suggest a new feature for the rippled project
title: "[Title with short description] (Version: [rippled version])"
about: Suggest a new feature for the xrpld project
title: "[Title with short description] (Version: [xrpld version])"
labels: Feature Request
assignees: ""
---

View File

@@ -37,12 +37,12 @@ runs:
run: |
echo 'Installing dependencies.'
conan install \
--profile ci \
--build="${BUILD_OPTION}" \
--options:host='&:tests=True' \
--options:host='&:xrpld=True' \
--settings:all build_type="${BUILD_TYPE}" \
--conf:all tools.build:jobs=${BUILD_NPROC} \
--conf:all tools.build:verbosity="${LOG_VERBOSITY}" \
--conf:all tools.compilation:verbosity="${LOG_VERBOSITY}" \
.
--profile ci \
--build="${BUILD_OPTION}" \
--options:host='&:tests=True' \
--options:host='&:xrpld=True' \
--settings:all build_type="${BUILD_TYPE}" \
--conf:all tools.build:jobs=${BUILD_NPROC} \
--conf:all tools.build:verbosity="${LOG_VERBOSITY}" \
--conf:all tools.compilation:verbosity="${LOG_VERBOSITY}" \
.

View File

@@ -11,34 +11,34 @@ runs:
steps:
# When a tag is pushed, the version is used as-is.
- name: Generate version for tag event
if: ${{ github.event_name == 'tag' }}
if: ${{ startsWith(github.ref, 'refs/tags/') }}
shell: bash
env:
VERSION: ${{ github.ref_name }}
run: echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"
run: echo "VERSION=${VERSION}" >>"${GITHUB_ENV}"
# When a tag is not pushed, then the version (e.g. 1.2.3-b0) is extracted
# from the BuildInfo.cpp file and the shortened commit hash appended to it.
# We use a plus sign instead of a hyphen because Conan recipe versions do
# not support two hyphens.
- name: Generate version for non-tag event
if: ${{ github.event_name != 'tag' }}
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
shell: bash
run: |
echo 'Extracting version from BuildInfo.cpp.'
VERSION="$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')"
if [[ -z "${VERSION}" ]]; then
echo 'Unable to extract version from BuildInfo.cpp.'
exit 1
echo 'Unable to extract version from BuildInfo.cpp.'
exit 1
fi
echo 'Appending shortened commit hash to version.'
SHA='${{ github.sha }}'
VERSION="${VERSION}+${SHA:0:7}"
echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"
echo "VERSION=${VERSION}" >>"${GITHUB_ENV}"
- name: Output version
id: version
shell: bash
run: echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"
run: echo "version=${VERSION}" >>"${GITHUB_OUTPUT}"

View File

@@ -1,43 +0,0 @@
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
- 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 compiler version.'
${{ runner.os == 'Linux' && '${CC}' || 'clang' }} --version
echo 'Checking Ninja version.'
ninja --version
echo 'Checking nproc version.'
nproc --version
- name: Check configuration (all)
shell: bash
run: |
echo 'Checking Ccache version.'
ccache --version
echo 'Checking CMake version.'
cmake --version
echo 'Checking Conan version.'
conan --version

45
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,45 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
commit-message:
prefix: "ci: [DEPENDABOT] "
target-branch: develop
- package-ecosystem: github-actions
directory: .github/actions/build-deps/
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
commit-message:
prefix: "ci: [DEPENDABOT] "
target-branch: develop
- package-ecosystem: github-actions
directory: .github/actions/generate-version/
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
commit-message:
prefix: "ci: [DEPENDABOT] "
target-branch: develop
- package-ecosystem: github-actions
directory: .github/actions/setup-conan/
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
commit-message:
prefix: "ci: [DEPENDABOT] "
target-branch: develop

View File

@@ -29,22 +29,6 @@ If a refactor, how is this better than the previous implementation?
If there is a spec or design document for this feature, please link it here.
-->
### Type of Change
<!--
Please check [x] relevant options, delete irrelevant ones.
-->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Refactor (non-breaking change that only restructures code)
- [ ] Performance (increase or change in throughput and/or latency)
- [ ] Tests (you added tests for code that already exists, or your new feature included in this PR)
- [ ] Documentation update
- [ ] Chore (no impact to binary, e.g. `.gitignore`, formatting, dropping support for older tooling)
- [ ] Release
### API Impact
<!--

85
.github/scripts/check-pr-description.py vendored Normal file
View File

@@ -0,0 +1,85 @@
#!/usr/bin/env python3
"""
Checks that a pull request description has been customized from the
pull_request_template.md. Exits with code 1 if the description is empty
or identical to the template (ignoring HTML comments and whitespace).
Usage:
python check-pr-description.py --template-file TEMPLATE --pr-body-file BODY
"""
import argparse
import re
import sys
from pathlib import Path
def normalize(text: str) -> str:
"""Strip HTML comments, trim lines, and remove blank lines."""
# Remove HTML comments (possibly multi-line)
text = re.sub(r"<!--.*?-->", "", text, flags=re.DOTALL)
# Strip each line and drop empties
lines = [line.strip() for line in text.splitlines()]
lines = [line for line in lines if line]
return "\n".join(lines)
def main() -> int:
parser = argparse.ArgumentParser(
description="Check that a PR description differs from the template."
)
parser.add_argument(
"--template-file",
type=Path,
required=True,
help="Path to the pull request template file.",
)
parser.add_argument(
"--pr-body-file",
type=Path,
required=True,
help="Path to a file containing the PR body text.",
)
args = parser.parse_args()
template_path: Path = args.template_file
pr_body_path: Path = args.pr_body_file
if not template_path.is_file():
print(f"::error::Template file {template_path} not found")
return 1
if not pr_body_path.is_file():
print(f"::error::PR body file {pr_body_path} not found")
return 1
template = template_path.read_text(encoding="utf-8")
pr_body = pr_body_path.read_text(encoding="utf-8")
# Check if the PR body is empty or whitespace-only
if not pr_body.strip():
print(
"::error::PR description is empty. "
"Please fill in the pull request template."
)
return 1
norm_template = normalize(template)
norm_pr_body = normalize(pr_body)
if norm_pr_body == norm_template:
print(
"::error::PR description (ignoring HTML comments) is identical"
" to the template. Please fill in the details of your change."
f"\n\nVisible template content:\n---\n{norm_template}\n---"
f"\n\nVisible PR description content:\n---\n{norm_pr_body}\n---"
)
return 1
print("PR description has been customized from the template.")
return 0
if __name__ == "__main__":
sys.exit(main())

403
.github/scripts/format-inline-bash.py vendored Executable file
View File

@@ -0,0 +1,403 @@
#!/usr/bin/env python3
"""
Format embedded shell snippets using the shfmt hook configured in
.pre-commit-config.yaml.
Two shapes are recognised:
* YAML workflow/action files: literal block-scalar runs (`run: |`) and
single-line runs (`run: some command`). A single-line run is upgraded to
a `run: |` block scalar if shfmt's output spans multiple lines.
* Markdown files: ``` ```bash ``` fenced code blocks.
Any block that shfmt cannot parse is skipped with a warning on stderr, so
the file is left untouched and surrounding blocks still get formatted.
For each occurrence the body is dedented, written to a temp .sh file,
formatted via `pre-commit run shfmt --files <temp>` (falling back to
`prek`), then re-indented and written back in place.
When invoked without arguments, every .yml/.yaml under .github/ plus every
.md file in the repo is scanned. When invoked with file arguments (the
pre-commit case), only those files are processed.
"""
from __future__ import annotations
import re
import shutil
import subprocess
import sys
import tempfile
from dataclasses import dataclass
from pathlib import Path
from typing import Union
REPO = Path(__file__).resolve().parents[2]
_HOOK_RUNNER = next((cmd for cmd in ("pre-commit", "prek") if shutil.which(cmd)), None)
if _HOOK_RUNNER is None:
sys.exit("error: neither `pre-commit` nor `prek` found on PATH")
RUN_BLOCK_RE = re.compile(r"^(?P<prefix>[ \t]*(?:- )?)run:[ \t]*\|[+-]?[ \t]*$")
RUN_INLINE_RE = re.compile(
r"^(?P<prefix>[ \t]*(?:- )?)run:[ \t]+" r"(?P<value>(?!\|[+-]?[ \t]*$)\S.*?)[ \t]*$"
)
MD_BASH_OPEN_RE = re.compile(r"^(?P<indent>[ ]{0,3})`{3}bash[ \t]*$")
MD_FENCE_CLOSE_RE = re.compile(r"^[ ]{0,3}`{3,}[ \t]*$")
@dataclass(frozen=True)
class BlockRun:
"""A `run: |` block scalar; `body_start:body_end` slices into `lines`."""
body_start: int
body_end: int
body_indent: int
@dataclass(frozen=True)
class InlineRun:
"""A single-line `run: value` at `line_idx`."""
line_idx: int
prefix: str
value: str
@dataclass(frozen=True)
class MdBashBlock:
"""A markdown ``` ```bash ``` fenced code block.
`body_start:body_end` slices into the file's lines; `open_line_idx`
points at the opening fence line.
"""
open_line_idx: int
body_start: int
body_end: int
body_indent: int
RunItem = Union[BlockRun, InlineRun]
def _scan_block_body(
lines: list[str], body_start: int, run_col: int
) -> tuple[int | None, int]:
"""Locate the body of a `run: |` block scalar starting at `body_start`.
Returns `(body_indent, scan_end)`. `scan_end` is the line index where the
outer scanner should resume. `body_indent` is `None` when no body is
present (the scalar is empty, or the next non-blank line has indent
`<= run_col`).
"""
body_indent: int | None = None
scan_end = len(lines)
for idx in range(body_start, len(lines)):
line = lines[idx]
if line.strip() == "":
continue
indent = len(line) - len(line.lstrip(" "))
if body_indent is None:
if indent > run_col:
body_indent = indent
else:
scan_end = idx
break
elif indent < body_indent:
scan_end = idx
break
if body_indent is not None:
while scan_end > body_start and lines[scan_end - 1].strip() == "":
scan_end -= 1
if scan_end <= body_start:
body_indent = None
return body_indent, scan_end
def find_run_blocks(lines: list[str]) -> list[RunItem]:
"""Return run items in document order."""
items: list[RunItem] = []
line_idx = 0
while line_idx < len(lines):
line = lines[line_idx]
if block_match := RUN_BLOCK_RE.match(line):
run_col = len(block_match.group("prefix"))
body_start = line_idx + 1
body_indent, scan_end = _scan_block_body(lines, body_start, run_col)
if body_indent is not None:
items.append(
BlockRun(
body_start=body_start,
body_end=scan_end,
body_indent=body_indent,
)
)
line_idx = scan_end
continue
if inline_match := RUN_INLINE_RE.match(line):
items.append(
InlineRun(
line_idx=line_idx,
prefix=inline_match.group("prefix"),
value=inline_match.group("value"),
)
)
line_idx += 1
return items
def find_md_bash_blocks(lines: list[str]) -> list[MdBashBlock]:
"""Return ``` ```bash ``` fenced code blocks in document order."""
blocks: list[MdBashBlock] = []
line_idx = 0
while line_idx < len(lines):
open_match = MD_BASH_OPEN_RE.match(lines[line_idx])
if not open_match:
line_idx += 1
continue
body_start = line_idx + 1
close_idx = next(
(
j
for j in range(body_start, len(lines))
if MD_FENCE_CLOSE_RE.match(lines[j])
),
None,
)
if close_idx is None:
line_idx = body_start
continue
body = lines[body_start:close_idx]
non_blank = [b for b in body if b.strip()]
body_indent = (
min(len(b) - len(b.lstrip(" ")) for b in non_blank)
if non_blank
else len(open_match.group("indent"))
)
blocks.append(
MdBashBlock(
open_line_idx=line_idx,
body_start=body_start,
body_end=close_idx,
body_indent=body_indent,
)
)
line_idx = close_idx + 1
return blocks
def dedent(lines: list[str], n: int) -> list[str]:
pad = " " * n
return [
(
""
if line.strip() == ""
else (line[n:] if line.startswith(pad) else line.lstrip(" "))
)
for line in lines
]
def reindent(lines: list[str], n: int) -> list[str]:
pad = " " * n
return [pad + line if line else "" for line in lines]
_SHFMT_ERR_RE = re.compile(r"\.sh:\d+:\d+:\s")
_GHA_EXPR_RE = re.compile(r"\$\{\{.*?\}\}", re.DOTALL)
_GHA_PLACEHOLDER_RE = re.compile(r"__GHA_EXPR_(\d+)__")
def _encode_gha_exprs(text: str) -> tuple[str, list[str]]:
"""Replace `${{ ... }}` expressions with bash-safe placeholder identifiers."""
exprs: list[str] = []
def repl(match: re.Match[str]) -> str:
exprs.append(match.group(0))
return f"__GHA_EXPR_{len(exprs) - 1}__"
return _GHA_EXPR_RE.sub(repl, text), exprs
def _decode_gha_exprs(text: str, exprs: list[str]) -> str:
"""Restore `${{ ... }}` expressions from placeholder identifiers."""
return _GHA_PLACEHOLDER_RE.sub(lambda m: exprs[int(m.group(1))], text)
def shfmt_via_hook(tmp_path: Path) -> tuple[bool, str]:
# `${{ ... }}` is not valid shell, so swap it for a placeholder identifier
# that shfmt can parse, then restore it after formatting.
encoded, exprs = _encode_gha_exprs(tmp_path.read_text())
if exprs:
tmp_path.write_text(encoded)
res = subprocess.run(
[_HOOK_RUNNER, "run", "shfmt", "--files", str(tmp_path)],
cwd=REPO,
capture_output=True,
text=True,
)
output = res.stdout + res.stderr
# shfmt emits parse errors as "<path>:<line>:<col>: <message>".
parse_err = bool(_SHFMT_ERR_RE.search(output))
# A non-zero exit that is neither a parse error nor pre-commit's "I had
# to modify files" signal means the hook itself failed to run (missing
# binary, install failure, bad config, ...). Surface that loudly rather
# than silently treating it as a no-op.
if (
res.returncode != 0
and not parse_err
and "files were modified by this hook" not in output
):
sys.exit(
f"error: `{_HOOK_RUNNER} run shfmt` failed with exit {res.returncode}:\n{output}"
)
if exprs and not parse_err:
tmp_path.write_text(_decode_gha_exprs(tmp_path.read_text(), exprs))
return not parse_err, output
def _skip(path: Path, where: int, kind: str, output: str) -> None:
print(
f" shfmt could not parse {kind} at {path}:{where + 1} — skipped",
file=sys.stderr,
)
print(f" {output.strip()}", file=sys.stderr)
def process_yaml_file(path: Path, tmp_path: Path) -> int:
text = path.read_text()
had_nl = text.endswith("\n")
lines = text.split("\n")
if had_nl:
lines = lines[:-1]
items = find_run_blocks(lines)
if not items:
return 0
changed = 0
# Process in reverse so earlier indices remain valid as we splice.
for item in reversed(items):
if isinstance(item, BlockRun):
body = lines[item.body_start : item.body_end]
tmp_path.write_text("\n".join(dedent(body, item.body_indent)) + "\n")
ok, output = shfmt_via_hook(tmp_path)
if not ok:
_skip(path, item.body_start, "block", output)
continue
formatted = tmp_path.read_text().rstrip("\n")
new_body = reindent(formatted.split("\n"), item.body_indent)
if new_body != body:
lines[item.body_start : item.body_end] = new_body
changed += 1
else:
tmp_path.write_text(item.value + "\n")
ok, output = shfmt_via_hook(tmp_path)
if not ok:
_skip(path, item.line_idx, "inline run", output)
continue
formatted = tmp_path.read_text().rstrip("\n")
if formatted == item.value:
continue
formatted_lines = formatted.split("\n")
if len(formatted_lines) == 1:
lines[item.line_idx] = f"{item.prefix}run: {formatted}"
else:
body_indent = len(item.prefix) + 2
lines[item.line_idx : item.line_idx + 1] = [
f"{item.prefix}run: |",
*reindent(formatted_lines, body_indent),
]
changed += 1
new_text = "\n".join(lines) + ("\n" if had_nl else "")
if new_text != text:
path.write_text(new_text)
return changed
def process_md_file(path: Path, tmp_path: Path) -> int:
text = path.read_text()
had_nl = text.endswith("\n")
lines = text.split("\n")
if had_nl:
lines = lines[:-1]
blocks = find_md_bash_blocks(lines)
if not blocks:
return 0
changed = 0
for block in reversed(blocks):
body = lines[block.body_start : block.body_end]
tmp_path.write_text("\n".join(dedent(body, block.body_indent)) + "\n")
ok, output = shfmt_via_hook(tmp_path)
if not ok:
_skip(path, block.open_line_idx, "```bash block", output)
continue
formatted = tmp_path.read_text().rstrip("\n")
formatted_lines = formatted.split("\n") if formatted else []
new_body = reindent(formatted_lines, block.body_indent)
if new_body != body:
lines[block.body_start : block.body_end] = new_body
changed += 1
new_text = "\n".join(lines) + ("\n" if had_nl else "")
if new_text != text:
path.write_text(new_text)
return changed
def process_file(path: Path, tmp_path: Path) -> int:
if path.suffix in (".yml", ".yaml"):
return process_yaml_file(path, tmp_path)
if path.suffix == ".md":
return process_md_file(path, tmp_path)
return 0
def gather_files(argv: list[str]) -> list[Path]:
"""Return YAML workflow/action files and markdown files that we should
process — either the paths in `argv` or, when `argv` is empty, every
such file in the repo (skipping `external/`)."""
if argv:
candidates: list[Path] = [
(REPO / a).resolve() if not Path(a).is_absolute() else Path(a) for a in argv
]
else:
gh = REPO / ".github"
candidates = [
*gh.rglob("*.yml"),
*gh.rglob("*.yaml"),
*(
p
for p in REPO.rglob("*.md")
if "external" not in p.relative_to(REPO).parts
),
]
return sorted(
p
for p in candidates
if p.exists()
and (
(p.suffix in (".yml", ".yaml") and ".github" in p.parts)
or p.suffix == ".md"
)
)
def main(argv: list[str]) -> int:
files = gather_files(argv)
if not files:
return 0
with tempfile.TemporaryDirectory(prefix="format-inline-bash-") as tmpdir:
tmp_path = Path(tmpdir) / "shfmt.sh"
total = 0
for f in files:
n = process_file(f, tmp_path)
if n:
print(f"{f.relative_to(REPO)}: reformatted {n} block(s)")
total += n
return 1 if total else 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))

View File

@@ -1,14 +1,14 @@
# Levelization
Levelization is the term used to describe efforts to prevent rippled from
Levelization is the term used to describe efforts to prevent xrpld from
having or creating cyclic dependencies.
rippled code is organized into directories under `src/xrpld`, `src/libxrpl` (and
xrpld code is organized into directories under `src/xrpld`, `src/libxrpl` (and
`src/test`) representing modules. The modules are intended to be
organized into "tiers" or "levels" such that a module from one level can
only include code from lower levels. Additionally, a module
in one level should never include code in an `impl` or `detail` folder of any level
other than it's own.
other than its own.
The codebase is split into two main areas:
@@ -22,7 +22,7 @@ levelization violations they find (by moving files or individual
classes). At the very least, don't make things worse.
The table below summarizes the _desired_ division of modules, based on the current
state of the rippled code. The levels are numbered from
state of the xrpld code. The levels are numbered from
the bottom up with the lower level, lower numbered, more independent
modules listed first, and the higher level, higher numbered modules with
more dependencies listed later.
@@ -70,12 +70,12 @@ that `test` code should _never_ be included in `xrpl` or `xrpld` code.)
## Validation
The [levelization](generate.sh) script takes no parameters,
The [levelization](generate.py) script takes no parameters,
reads no environment variables, and can be run from any directory,
as long as it is in the expected location in the rippled repo.
as long as it is in the expected location in the xrpld repo.
It can be run at any time from within a checked out repo, and will
do an analysis of all the `#include`s in
the rippled source. The only caveat is that it runs much slower
the xrpld source. The only caveat is that it runs much slower
under Windows than in Linux. It hasn't yet been tested under MacOS.
It generates many files of [results](results):
@@ -104,7 +104,7 @@ It generates many files of [results](results):
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
done anything else to improve levelization, run `levelization.sh`,
done anything else to improve levelization, run `generate.py`,
and commit the updated results.
The `loops.txt` and `ordering.txt` files relate the modules
@@ -128,7 +128,7 @@ The committed files hide the detailed values intentionally, to
prevent false alarms and merging issues, and because it's easy to
get those details locally.
1. Run `levelization.sh`
1. Run `generate.py`
2. Grep the modules in `paths.txt`.
- For example, if a cycle is found `A ~= B`, simply `grep -w
A .github/scripts/levelization/results/paths.txt | grep -w B`

335
.github/scripts/levelization/generate.py vendored Executable file
View File

@@ -0,0 +1,335 @@
#!/usr/bin/env python3
"""
Usage: generate.py
This script takes no parameters, and can be called from any directory in the file system.
"""
import os
import re
import subprocess
import sys
from collections import defaultdict
from pathlib import Path
from typing import Dict, List, Tuple, Set, Optional
# Compile regex patterns once at module level
INCLUDE_PATTERN = re.compile(r"^\s*#include.*/.*\.h")
INCLUDE_PATH_PATTERN = re.compile(r'[<"]([^>"]+)[>"]')
def dictionary_sort_key(s: str) -> str:
"""
Create a sort key that mimics 'sort -d' (dictionary order).
Dictionary order only considers blanks and alphanumeric characters.
This means punctuation like '.' is ignored during sorting.
"""
# Keep only alphanumeric characters and spaces
return "".join(c for c in s if c.isalnum() or c.isspace())
def get_level(file_path: str) -> str:
"""
Extract the level from a file path (second and third directory components).
Equivalent to bash: cut -d/ -f 2,3
Examples:
src/xrpld/app/main.cpp -> xrpld.app
src/libxrpl/protocol/STObject.cpp -> libxrpl.protocol
include/xrpl/basics/base_uint.h -> xrpl.basics
"""
parts = file_path.split("/")
# Get fields 2 and 3 (indices 1 and 2 in 0-based indexing)
if len(parts) >= 3:
level = f"{parts[1]}/{parts[2]}"
elif len(parts) >= 2:
level = f"{parts[1]}/toplevel"
else:
level = file_path
# If the "level" indicates a file, cut off the filename
if "." in level.split("/")[-1]: # Avoid Path object creation
# Use the "toplevel" label as a workaround for `sort`
# inconsistencies between different utility versions
level = level.rsplit("/", 1)[0] + "/toplevel"
return level.replace("/", ".")
def extract_include_level(include_line: str) -> Optional[str]:
"""
Extract the include path from an #include directive.
Gets the first two directory components from the include path.
Equivalent to bash: cut -d/ -f 1,2
Examples:
#include <xrpl/basics/base_uint.h> -> xrpl.basics
#include "xrpld/app/main/Application.h" -> xrpld.app
"""
# Remove everything before the quote or angle bracket
match = INCLUDE_PATH_PATTERN.search(include_line)
if not match:
return None
include_path = match.group(1)
parts = include_path.split("/")
# Get first two fields (indices 0 and 1)
if len(parts) >= 2:
include_level = f"{parts[0]}/{parts[1]}"
else:
include_level = include_path
# If the "includelevel" indicates a file, cut off the filename
if "." in include_level.split("/")[-1]: # Avoid Path object creation
include_level = include_level.rsplit("/", 1)[0] + "/toplevel"
return include_level.replace("/", ".")
def find_repository_directories(
start_path: Path, depth_limit: int = 10
) -> Tuple[Path, List[Path]]:
"""
Find the repository root by looking for src or include folders.
Walks up the directory tree from the start path.
"""
current = start_path.resolve()
# Walk up the directory tree
for _ in range(depth_limit): # Limit search depth to prevent infinite loops
src_path = current / "src"
include_path = current / "include"
# Check if this directory has src or include folders
has_src = src_path.exists()
has_include = include_path.exists()
if has_src or has_include:
return current, [src_path, include_path]
# Move up one level
parent = current.parent
if parent == current: # Reached filesystem root
break
current = parent
# If we couldn't find it, raise an error
raise RuntimeError(
"Could not find repository root. "
"Expected to find a directory containing 'src' and/or 'include' folders."
)
def main():
# Change to the script's directory
script_dir = Path(__file__).parent.resolve()
os.chdir(script_dir)
# Clean up and create results directory.
results_dir = script_dir / "results"
if results_dir.exists():
import shutil
shutil.rmtree(results_dir)
results_dir.mkdir()
# Find the repository root by searching for src and include directories.
try:
repo_root, scan_dirs = find_repository_directories(script_dir)
print(f"Found repository root: {repo_root}")
print(f"Scanning directories:")
for scan_dir in scan_dirs:
print(f" - {scan_dir.relative_to(repo_root)}")
except RuntimeError as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
print("\nScanning for raw includes...")
# Find all #include directives
raw_includes: List[Tuple[str, str]] = []
rawincludes_file = results_dir / "rawincludes.txt"
# Write to file as we go to avoid storing everything in memory.
with open(rawincludes_file, "w", buffering=8192) as raw_f:
for dir_path in scan_dirs:
print(f" Scanning {dir_path.relative_to(repo_root)}...")
for file_path in dir_path.rglob("*"):
if not file_path.is_file():
continue
try:
rel_path_str = str(file_path.relative_to(repo_root))
# Read file with a large buffer for performance.
with open(
file_path,
"r",
encoding="utf-8",
errors="ignore",
buffering=8192,
) as f:
for line in f:
# Quick check before regex
if "#include" not in line or "boost" in line:
continue
if INCLUDE_PATTERN.match(line):
line_stripped = line.strip()
entry = f"{rel_path_str}:{line_stripped}\n"
print(entry, end="")
raw_f.write(entry)
raw_includes.append((rel_path_str, line_stripped))
except Exception as e:
print(f"Error reading {file_path}: {e}", file=sys.stderr)
# Build levelization paths and count directly (no need to sort first).
print("Build levelization paths")
path_counts: Dict[Tuple[str, str], int] = defaultdict(int)
for file_path, include_line in raw_includes:
include_level = extract_include_level(include_line)
if not include_level:
continue
level = get_level(file_path)
if level != include_level:
path_counts[(level, include_level)] += 1
# Sort and deduplicate paths (using dictionary order like bash 'sort -d').
print("Sort and deduplicate paths")
paths_file = results_dir / "paths.txt"
with open(paths_file, "w") as f:
# Sort using dictionary order: only alphanumeric and spaces matter
sorted_items = sorted(
path_counts.items(),
key=lambda x: (dictionary_sort_key(x[0][0]), dictionary_sort_key(x[0][1])),
)
for (level, include_level), count in sorted_items:
line = f"{count:7} {level} {include_level}\n"
print(line.rstrip())
f.write(line)
# Split into flat-file database
print("Split into flat-file database")
includes_dir = results_dir / "includes"
included_by_dir = results_dir / "included_by"
includes_dir.mkdir()
included_by_dir.mkdir()
# Batch writes by grouping data first to avoid repeated file opens.
includes_data: Dict[str, List[Tuple[str, int]]] = defaultdict(list)
included_by_data: Dict[str, List[Tuple[str, int]]] = defaultdict(list)
# Process in sorted order to match bash script behaviour (dictionary order).
sorted_items = sorted(
path_counts.items(),
key=lambda x: (dictionary_sort_key(x[0][0]), dictionary_sort_key(x[0][1])),
)
for (level, include_level), count in sorted_items:
includes_data[level].append((include_level, count))
included_by_data[include_level].append((level, count))
# Write all includes files in sorted order (dictionary order).
for level in sorted(includes_data.keys(), key=dictionary_sort_key):
entries = includes_data[level]
with open(includes_dir / level, "w") as f:
for include_level, count in entries:
line = f"{include_level} {count}\n"
print(line.rstrip())
f.write(line)
# Write all included_by files in sorted order (dictionary order).
for include_level in sorted(included_by_data.keys(), key=dictionary_sort_key):
entries = included_by_data[include_level]
with open(included_by_dir / include_level, "w") as f:
for level, count in entries:
line = f"{level} {count}\n"
print(line.rstrip())
f.write(line)
# Search for loops
print("Search for loops")
loops_file = results_dir / "loops.txt"
ordering_file = results_dir / "ordering.txt"
loops_found: Set[Tuple[str, str]] = set()
# Pre-load all include files into memory to avoid repeated I/O.
# This is the biggest optimisation - we were reading files repeatedly in nested loops.
# Use list of tuples to preserve file order.
includes_cache: Dict[str, List[Tuple[str, int]]] = {}
includes_lookup: Dict[str, Dict[str, int]] = {} # For fast lookup
# Note: bash script uses 'for source in *' which uses standard glob sorting,
# NOT dictionary order. So we use standard sorted() here, not dictionary_sort_key.
for include_file in sorted(includes_dir.iterdir(), key=lambda p: p.name):
if not include_file.is_file():
continue
includes_cache[include_file.name] = []
includes_lookup[include_file.name] = {}
with open(include_file, "r") as f:
for line in f:
parts = line.strip().split()
if len(parts) >= 2:
include_name = parts[0]
include_count = int(parts[1])
includes_cache[include_file.name].append(
(include_name, include_count)
)
includes_lookup[include_file.name][include_name] = include_count
with open(loops_file, "w", buffering=8192) as loops_f, open(
ordering_file, "w", buffering=8192
) as ordering_f:
# Use standard sorting to match bash glob expansion 'for source in *'.
for source in sorted(includes_cache.keys()):
source_includes = includes_cache[source]
for include, include_freq in source_includes:
# Check if include file exists and references source
if include not in includes_lookup:
continue
source_freq = includes_lookup[include].get(source)
if source_freq is not None:
# Found a loop
loop_key = tuple(sorted([source, include]))
if loop_key in loops_found:
continue
loops_found.add(loop_key)
loops_f.write(f"Loop: {source} {include}\n")
# If the counts are close, indicate that the two modules are
# on the same level, though they shouldn't be.
diff = include_freq - source_freq
if diff > 3:
loops_f.write(f" {source} > {include}\n\n")
elif diff < -3:
loops_f.write(f" {include} > {source}\n\n")
elif source_freq == include_freq:
loops_f.write(f" {include} == {source}\n\n")
else:
loops_f.write(f" {include} ~= {source}\n\n")
else:
ordering_f.write(f"{source} > {include}\n")
# Print results
print("\nOrdering:")
with open(ordering_file, "r") as f:
print(f.read(), end="")
print("\nLoops:")
with open(loops_file, "r") as f:
print(f.read(), end="")
if __name__ == "__main__":
main()

View File

@@ -1,130 +0,0 @@
#!/bin/bash
# Usage: generate.sh
# This script takes no parameters, reads no environment variables,
# and can be run from any directory, as long as it is in the expected
# location in the repo.
pushd $( dirname $0 )
if [ -v PS1 ]
then
# if the shell is interactive, clean up any flotsam before analyzing
git clean -ix
fi
# Ensure all sorting is ASCII-order consistently across platforms.
export LANG=C
rm -rfv results
mkdir results
includes="$( pwd )/results/rawincludes.txt"
pushd ../../..
echo Raw includes:
grep -r '^[ ]*#include.*/.*\.h' include src | \
grep -v boost | tee ${includes}
popd
pushd results
oldifs=${IFS}
IFS=:
mkdir includes
mkdir included_by
echo Build levelization paths
exec 3< ${includes} # open rawincludes.txt for input
while read -r -u 3 file include
do
level=$( echo ${file} | cut -d/ -f 2,3 )
# If the "level" indicates a file, cut off the filename
if [[ "${level##*.}" != "${level}" ]]
then
# Use the "toplevel" label as a workaround for `sort`
# inconsistencies between different utility versions
level="$( dirname ${level} )/toplevel"
fi
level=$( echo ${level} | tr '/' '.' )
includelevel=$( echo ${include} | sed 's/.*["<]//; s/[">].*//' | \
cut -d/ -f 1,2 )
if [[ "${includelevel##*.}" != "${includelevel}" ]]
then
# Use the "toplevel" label as a workaround for `sort`
# inconsistencies between different utility versions
includelevel="$( dirname ${includelevel} )/toplevel"
fi
includelevel=$( echo ${includelevel} | tr '/' '.' )
if [[ "$level" != "$includelevel" ]]
then
echo $level $includelevel | tee -a paths.txt
fi
done
echo Sort and deduplicate paths
sort -ds paths.txt | uniq -c | tee sortedpaths.txt
mv sortedpaths.txt paths.txt
exec 3>&- #close fd 3
IFS=${oldifs}
unset oldifs
echo Split into flat-file database
exec 4<paths.txt # open paths.txt for input
while read -r -u 4 count level include
do
echo ${include} ${count} | tee -a includes/${level}
echo ${level} ${count} | tee -a included_by/${include}
done
exec 4>&- #close fd 4
loops="$( pwd )/loops.txt"
ordering="$( pwd )/ordering.txt"
pushd includes
echo Search for loops
# Redirect stdout to a file
exec 4>&1
exec 1>"${loops}"
for source in *
do
if [[ -f "$source" ]]
then
exec 5<"${source}" # open for input
while read -r -u 5 include includefreq
do
if [[ -f $include ]]
then
if grep -q -w $source $include
then
if grep -q -w "Loop: $include $source" "${loops}"
then
continue
fi
sourcefreq=$( grep -w $source $include | cut -d\ -f2 )
echo "Loop: $source $include"
# If the counts are close, indicate that the two modules are
# on the same level, though they shouldn't be
if [[ $(( $includefreq - $sourcefreq )) -gt 3 ]]
then
echo -e " $source > $include\n"
elif [[ $(( $sourcefreq - $includefreq )) -gt 3 ]]
then
echo -e " $include > $source\n"
elif [[ $sourcefreq -eq $includefreq ]]
then
echo -e " $include == $source\n"
else
echo -e " $include ~= $source\n"
fi
else
echo "$source > $include" >> "${ordering}"
fi
fi
done
exec 5>&- #close fd 5
fi
done
exec 1>&4 #close fd 1
exec 4>&- #close fd 4
cat "${ordering}"
cat "${loops}"
popd
popd
popd

View File

@@ -2,13 +2,10 @@ Loop: test.jtx test.toplevel
test.toplevel > test.jtx
Loop: test.jtx test.unit_test
test.unit_test == test.jtx
Loop: xrpld.app xrpld.core
xrpld.app > xrpld.core
test.unit_test ~= test.jtx
Loop: xrpld.app xrpld.overlay
xrpld.overlay > xrpld.app
xrpld.app > xrpld.overlay
Loop: xrpld.app xrpld.peerfinder
xrpld.peerfinder ~= xrpld.app
@@ -17,7 +14,7 @@ Loop: xrpld.app xrpld.rpc
xrpld.rpc > xrpld.app
Loop: xrpld.app xrpld.shamap
xrpld.shamap ~= xrpld.app
xrpld.shamap > xrpld.app
Loop: xrpld.overlay xrpld.rpc
xrpld.rpc ~= xrpld.overlay

View File

@@ -1,13 +1,19 @@
libxrpl.basics > xrpl.basics
libxrpl.conditions > xrpl.basics
libxrpl.conditions > xrpl.conditions
libxrpl.core > xrpl.basics
libxrpl.core > xrpl.core
libxrpl.core > xrpl.json
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.nodestore
libxrpl.ledger > xrpl.protocol
libxrpl.ledger > xrpl.server
libxrpl.ledger > xrpl.shamap
libxrpl.net > xrpl.basics
libxrpl.net > xrpl.net
libxrpl.nodestore > xrpl.basics
@@ -17,23 +23,38 @@ libxrpl.nodestore > xrpl.protocol
libxrpl.protocol > xrpl.basics
libxrpl.protocol > xrpl.json
libxrpl.protocol > xrpl.protocol
libxrpl.rdb > xrpl.basics
libxrpl.rdb > xrpl.core
libxrpl.rdb > xrpl.rdb
libxrpl.resource > xrpl.basics
libxrpl.resource > xrpl.json
libxrpl.resource > xrpl.protocol
libxrpl.resource > xrpl.resource
libxrpl.server > xrpl.basics
libxrpl.server > xrpl.core
libxrpl.server > xrpl.json
libxrpl.server > xrpl.protocol
libxrpl.server > xrpl.rdb
libxrpl.server > xrpl.resource
libxrpl.server > xrpl.server
libxrpl.shamap > xrpl.basics
libxrpl.shamap > xrpl.nodestore
libxrpl.shamap > xrpl.protocol
libxrpl.shamap > xrpl.shamap
libxrpl.tx > xrpl.basics
libxrpl.tx > xrpl.conditions
libxrpl.tx > xrpl.core
libxrpl.tx > xrpl.json
libxrpl.tx > xrpl.ledger
libxrpl.tx > xrpl.protocol
libxrpl.tx > xrpl.server
libxrpl.tx > xrpl.tx
test.app > test.jtx
test.app > test.rpc
test.app > test.toplevel
test.app > test.unit_test
test.app > xrpl.basics
test.app > xrpl.core
test.app > xrpld.app
test.app > xrpld.consensus
test.app > xrpld.core
test.app > xrpld.overlay
test.app > xrpld.rpc
@@ -42,6 +63,9 @@ test.app > xrpl.ledger
test.app > xrpl.nodestore
test.app > xrpl.protocol
test.app > xrpl.resource
test.app > xrpl.server
test.app > xrpl.shamap
test.app > xrpl.tx
test.basics > test.jtx
test.basics > test.unit_test
test.basics > xrpl.basics
@@ -51,30 +75,36 @@ test.basics > xrpl.json
test.basics > xrpl.protocol
test.beast > xrpl.basics
test.conditions > xrpl.basics
test.conditions > xrpld.conditions
test.conditions > xrpl.conditions
test.consensus > test.csf
test.consensus > test.jtx
test.consensus > test.toplevel
test.consensus > test.unit_test
test.consensus > xrpl.basics
test.consensus > xrpld.app
test.consensus > xrpld.consensus
test.consensus > xrpl.json
test.consensus > xrpl.ledger
test.consensus > xrpl.protocol
test.consensus > xrpl.shamap
test.consensus > xrpl.tx
test.core > test.jtx
test.core > test.toplevel
test.core > test.unit_test
test.core > xrpl.basics
test.core > xrpl.core
test.core > xrpld.core
test.core > xrpl.json
test.core > xrpl.protocol
test.core > xrpl.rdb
test.core > xrpl.server
test.csf > xrpl.basics
test.csf > xrpld.consensus
test.csf > xrpl.json
test.csf > xrpl.ledger
test.csf > xrpl.protocol
test.json > test.jtx
test.json > xrpl.json
test.jtx > xrpl.basics
test.jtx > xrpl.core
test.jtx > xrpld.app
test.jtx > xrpld.core
test.jtx > xrpld.rpc
@@ -84,28 +114,34 @@ test.jtx > xrpl.net
test.jtx > xrpl.protocol
test.jtx > xrpl.resource
test.jtx > xrpl.server
test.jtx > xrpl.tx
test.ledger > test.jtx
test.ledger > test.toplevel
test.ledger > xrpl.basics
test.ledger > xrpl.core
test.ledger > xrpld.app
test.ledger > xrpld.core
test.ledger > xrpl.json
test.ledger > xrpl.ledger
test.ledger > xrpl.protocol
test.nodestore > test.jtx
test.nodestore > test.toplevel
test.nodestore > test.unit_test
test.nodestore > xrpl.basics
test.nodestore > xrpld.core
test.nodestore > xrpl.nodestore
test.nodestore > xrpl.protocol
test.nodestore > xrpl.rdb
test.overlay > test.jtx
test.overlay > test.toplevel
test.overlay > test.unit_test
test.overlay > xrpl.basics
test.overlay > xrpld.app
test.overlay > xrpld.core
test.overlay > xrpld.overlay
test.overlay > xrpld.peerfinder
test.overlay > xrpl.json
test.overlay > xrpl.nodestore
test.overlay > xrpl.protocol
test.overlay > xrpl.resource
test.overlay > xrpl.server
test.overlay > xrpl.shamap
test.peerfinder > test.beast
test.peerfinder > test.unit_test
@@ -113,7 +149,8 @@ test.peerfinder > xrpl.basics
test.peerfinder > xrpld.core
test.peerfinder > xrpld.peerfinder
test.peerfinder > xrpl.protocol
test.protocol > test.toplevel
test.protocol > test.jtx
test.protocol > test.unit_test
test.protocol > xrpl.basics
test.protocol > xrpl.json
test.protocol > xrpl.protocol
@@ -121,7 +158,6 @@ test.resource > test.unit_test
test.resource > xrpl.basics
test.resource > xrpl.resource
test.rpc > test.jtx
test.rpc > test.toplevel
test.rpc > xrpl.basics
test.rpc > xrpl.core
test.rpc > xrpld.app
@@ -129,16 +165,18 @@ test.rpc > xrpld.core
test.rpc > xrpld.overlay
test.rpc > xrpld.rpc
test.rpc > xrpl.json
test.rpc > xrpl.ledger
test.rpc > xrpl.protocol
test.rpc > xrpl.resource
test.rpc > xrpl.server
test.rpc > xrpl.tx
test.server > test.jtx
test.server > test.toplevel
test.server > test.unit_test
test.server > xrpl.basics
test.server > xrpld.app
test.server > xrpld.core
test.server > xrpld.rpc
test.server > xrpl.json
test.server > xrpl.protocol
test.server > xrpl.server
test.shamap > test.unit_test
test.shamap > xrpl.basics
@@ -148,66 +186,100 @@ test.shamap > xrpl.shamap
test.toplevel > test.csf
test.toplevel > xrpl.json
test.unit_test > xrpl.basics
test.unit_test > xrpl.protocol
tests.libxrpl > xrpl.basics
tests.libxrpl > xrpl.core
tests.libxrpl > xrpl.json
tests.libxrpl > xrpl.ledger
tests.libxrpl > xrpl.net
tests.libxrpl > xrpl.nodestore
tests.libxrpl > xrpl.protocol
tests.libxrpl > xrpl.protocol_autogen
tests.libxrpl > xrpl.server
tests.libxrpl > xrpl.shamap
tests.libxrpl > xrpl.tx
xrpl.conditions > xrpl.basics
xrpl.conditions > xrpl.protocol
xrpl.core > xrpl.basics
xrpl.core > xrpl.json
xrpl.core > xrpl.ledger
xrpl.core > xrpl.protocol
xrpl.json > xrpl.basics
xrpl.ledger > xrpl.basics
xrpl.ledger > xrpl.protocol
xrpl.ledger > xrpl.server
xrpl.ledger > xrpl.shamap
xrpl.net > xrpl.basics
xrpl.nodestore > xrpl.basics
xrpl.nodestore > xrpl.protocol
xrpl.protocol > xrpl.basics
xrpl.protocol > xrpl.json
xrpl.protocol_autogen > xrpl.json
xrpl.protocol_autogen > xrpl.protocol
xrpl.rdb > xrpl.basics
xrpl.rdb > xrpl.core
xrpl.rdb > xrpl.protocol
xrpl.resource > xrpl.basics
xrpl.resource > xrpl.json
xrpl.resource > xrpl.protocol
xrpl.server > xrpl.basics
xrpl.server > xrpl.core
xrpl.server > xrpl.json
xrpl.server > xrpl.protocol
xrpl.server > xrpl.rdb
xrpl.server > xrpl.resource
xrpl.server > xrpl.shamap
xrpl.shamap > xrpl.basics
xrpl.shamap > xrpl.nodestore
xrpl.shamap > xrpl.protocol
xrpl.tx > xrpl.basics
xrpl.tx > xrpl.core
xrpl.tx > xrpl.ledger
xrpl.tx > xrpl.protocol
xrpld.app > test.unit_test
xrpld.app > xrpl.basics
xrpld.app > xrpl.core
xrpld.app > xrpld.conditions
xrpld.app > xrpld.consensus
xrpld.app > xrpld.core
xrpld.app > xrpl.json
xrpld.app > xrpl.ledger
xrpld.app > xrpl.net
xrpld.app > xrpl.nodestore
xrpld.app > xrpl.protocol
xrpld.app > xrpl.rdb
xrpld.app > xrpl.resource
xrpld.app > xrpl.server
xrpld.app > xrpl.shamap
xrpld.conditions > xrpl.basics
xrpld.conditions > xrpl.protocol
xrpld.app > xrpl.tx
xrpld.consensus > xrpl.basics
xrpld.consensus > xrpl.json
xrpld.consensus > xrpl.ledger
xrpld.consensus > xrpl.protocol
xrpld.core > xrpl.basics
xrpld.core > xrpl.core
xrpld.core > xrpl.json
xrpld.core > xrpl.net
xrpld.core > xrpl.protocol
xrpld.core > xrpl.rdb
xrpld.overlay > xrpl.basics
xrpld.overlay > xrpl.core
xrpld.overlay > xrpld.consensus
xrpld.overlay > xrpld.core
xrpld.overlay > xrpld.peerfinder
xrpld.overlay > xrpl.json
xrpld.overlay > xrpl.ledger
xrpld.overlay > xrpl.protocol
xrpld.overlay > xrpl.resource
xrpld.overlay > xrpl.server
xrpld.overlay > xrpl.shamap
xrpld.overlay > xrpl.tx
xrpld.peerfinder > xrpl.basics
xrpld.peerfinder > xrpld.core
xrpld.peerfinder > xrpl.protocol
xrpld.peerfinder > xrpl.rdb
xrpld.perflog > xrpl.basics
xrpld.perflog > xrpl.core
xrpld.perflog > xrpld.rpc
xrpld.perflog > xrpl.json
xrpld.perflog > xrpl.protocol
xrpld.rpc > xrpl.basics
xrpld.rpc > xrpl.core
xrpld.rpc > xrpld.core
@@ -216,6 +288,12 @@ xrpld.rpc > xrpl.ledger
xrpld.rpc > xrpl.net
xrpld.rpc > xrpl.nodestore
xrpld.rpc > xrpl.protocol
xrpld.rpc > xrpl.rdb
xrpld.rpc > xrpl.resource
xrpld.rpc > xrpl.server
xrpld.rpc > xrpl.shamap
xrpld.rpc > xrpl.tx
xrpld.shamap > xrpl.basics
xrpld.shamap > xrpld.core
xrpld.shamap > xrpl.protocol
xrpld.shamap > xrpl.shamap

View File

@@ -34,6 +34,8 @@ run from the repository root.
6. `.github/scripts/rename/config.sh`: This script will rename the config from
`rippled.cfg` to `xrpld.cfg`, and updating the code accordingly. The old
filename will still be accepted.
7. `.github/scripts/rename/docs.sh`: This script will rename any lingering
references of `ripple(d)` to `xrpl(d)` in code, comments, and documentation.
You can run all these scripts from the repository root as follows:
@@ -44,4 +46,5 @@ You can run all these scripts from the repository root as follows:
./.github/scripts/rename/binary.sh .
./.github/scripts/rename/namespace.sh .
./.github/scripts/rename/config.sh .
./.github/scripts/rename/docs.sh .
```

View File

@@ -6,11 +6,11 @@ set -e
# On MacOS, ensure that GNU sed is installed and available as `gsed`.
SED_COMMAND=sed
if [[ "${OSTYPE}" == 'darwin'* ]]; then
if ! command -v gsed &> /dev/null; then
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
exit 1
fi
SED_COMMAND=gsed
if ! command -v gsed &>/dev/null; then
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
exit 1
fi
SED_COMMAND=gsed
fi
# This script changes the binary name from `rippled` to `xrpld`, and reverses
@@ -29,7 +29,7 @@ if [ ! -d "${DIRECTORY}" ]; then
echo "Error: Directory '${DIRECTORY}' does not exist."
exit 1
fi
pushd ${DIRECTORY}
pushd "${DIRECTORY}"
# Remove the binary name override added by the cmake.sh script.
${SED_COMMAND} -z -i -E 's@\s+# For the time being.+"rippled"\)@@' cmake/XrplCore.cmake
@@ -49,6 +49,7 @@ ${SED_COMMAND} -i -E 's@ripple/xrpld@XRPLF/rippled@g' BUILD.md
${SED_COMMAND} -i -E 's@XRPLF/xrpld@XRPLF/rippled@g' BUILD.md
${SED_COMMAND} -i -E 's@xrpld \(`xrpld`\)@xrpld@g' BUILD.md
${SED_COMMAND} -i -E 's@XRPLF/xrpld@XRPLF/rippled@g' CONTRIBUTING.md
${SED_COMMAND} -i -E 's@XRPLF/xrpld@XRPLF/rippled@g' docs/build/install.md
popd
echo "Processing complete."

View File

@@ -8,16 +8,16 @@ set -e
SED_COMMAND=sed
HEAD_COMMAND=head
if [[ "${OSTYPE}" == 'darwin'* ]]; then
if ! command -v gsed &> /dev/null; then
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
exit 1
fi
SED_COMMAND=gsed
if ! command -v ghead &> /dev/null; then
echo "Error: ghead is not installed. Please install it using 'brew install coreutils'."
exit 1
fi
HEAD_COMMAND=ghead
if ! command -v gsed &>/dev/null; then
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
exit 1
fi
SED_COMMAND=gsed
if ! command -v ghead &>/dev/null; then
echo "Error: ghead is not installed. Please install it using 'brew install coreutils'."
exit 1
fi
HEAD_COMMAND=ghead
fi
# This script renames CMake files from `RippleXXX.cmake` or `RippledXXX.cmake`
@@ -38,16 +38,16 @@ if [ ! -d "${DIRECTORY}" ]; then
echo "Error: Directory '${DIRECTORY}' does not exist."
exit 1
fi
pushd ${DIRECTORY}
pushd "${DIRECTORY}"
# Rename the files.
find cmake -type f -name 'Rippled*.cmake' -exec bash -c 'mv "${1}" "${1/Rippled/Xrpl}"' - {} \;
find cmake -type f -name 'Ripple*.cmake' -exec bash -c 'mv "${1}" "${1/Ripple/Xrpl}"' - {} \;
if [ -e cmake/xrpl_add_test.cmake ]; then
mv cmake/xrpl_add_test.cmake cmake/XrplAddTest.cmake
mv cmake/xrpl_add_test.cmake cmake/XrplAddTest.cmake
fi
if [ -e include/xrpl/proto/ripple.proto ]; then
mv include/xrpl/proto/ripple.proto include/xrpl/proto/xrpl.proto
mv include/xrpl/proto/ripple.proto include/xrpl/proto/xrpl.proto
fi
# Rename inside the files.
@@ -71,14 +71,14 @@ ${SED_COMMAND} -i 's@xrpl/validator-keys-tool@ripple/validator-keys-tool@' cmake
# Ensure the name of the binary and config remain 'rippled' for now.
${SED_COMMAND} -i -E 's/xrpld(-example)?\.cfg/rippled\1.cfg/g' cmake/XrplInstall.cmake
if grep -q '"xrpld"' cmake/XrplCore.cmake; then
# The script has been rerun, so just restore the name of the binary.
${SED_COMMAND} -i 's/"xrpld"/"rippled"/' cmake/XrplCore.cmake
# The script has been rerun, so just restore the name of the binary.
${SED_COMMAND} -i 's/"xrpld"/"rippled"/' cmake/XrplCore.cmake
elif ! grep -q '"rippled"' cmake/XrplCore.cmake; then
${HEAD_COMMAND} -n -1 cmake/XrplCore.cmake > cmake.tmp
echo ' # For the time being, we will keep the name of the binary as it was.' >> cmake.tmp
echo ' set_target_properties(xrpld PROPERTIES OUTPUT_NAME "rippled")' >> cmake.tmp
tail -1 cmake/XrplCore.cmake >> cmake.tmp
mv cmake.tmp cmake/XrplCore.cmake
${HEAD_COMMAND} -n -1 cmake/XrplCore.cmake >cmake.tmp
echo ' # For the time being, we will keep the name of the binary as it was.' >>cmake.tmp
echo ' set_target_properties(xrpld PROPERTIES OUTPUT_NAME "rippled")' >>cmake.tmp
tail -1 cmake/XrplCore.cmake >>cmake.tmp
mv cmake.tmp cmake/XrplCore.cmake
fi
# Restore the symlink from 'xrpld' to 'rippled'.

View File

@@ -6,11 +6,11 @@ set -e
# On MacOS, ensure that GNU sed is installed and available as `gsed`.
SED_COMMAND=sed
if [[ "${OSTYPE}" == 'darwin'* ]]; then
if ! command -v gsed &> /dev/null; then
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
exit 1
fi
SED_COMMAND=gsed
if ! command -v gsed &>/dev/null; then
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
exit 1
fi
SED_COMMAND=gsed
fi
# This script renames the config from `rippled.cfg` to `xrpld.cfg`, and updates
@@ -28,42 +28,41 @@ if [ ! -d "${DIRECTORY}" ]; then
echo "Error: Directory '${DIRECTORY}' does not exist."
exit 1
fi
pushd ${DIRECTORY}
pushd "${DIRECTORY}"
# Add the xrpld.cfg to the .gitignore.
if ! grep -q 'xrpld.cfg' .gitignore; then
${SED_COMMAND} -i '/rippled.cfg/a\
${SED_COMMAND} -i '/rippled.cfg/a\
/xrpld.cfg' .gitignore
fi
# Rename the files.
if [ -e rippled.cfg ]; then
mv rippled.cfg xrpld.cfg
mv rippled.cfg xrpld.cfg
fi
if [ -e cfg/rippled-example.cfg ]; then
mv cfg/rippled-example.cfg cfg/xrpld-example.cfg
mv cfg/rippled-example.cfg cfg/xrpld-example.cfg
fi
# Rename inside the files.
DIRECTORIES=("cfg" "cmake" "include" "src")
for DIRECTORY in "${DIRECTORIES[@]}"; do
echo "Processing directory: ${DIRECTORY}"
echo "Processing directory: ${DIRECTORY}"
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" -o -name "*.cmake" -o -name "*.txt" -o -name "*.cfg" -o -name "*.md" \) | while read -r FILE; do
echo "Processing file: ${FILE}"
${SED_COMMAND} -i -E 's/rippled(-example)?[ .]cfg/xrpld\1.cfg/g' "${FILE}"
done
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" -o -name "*.cmake" -o -name "*.txt" -o -name "*.cfg" -o -name "*.md" \) | while read -r FILE; do
echo "Processing file: ${FILE}"
${SED_COMMAND} -i -E 's/rippled(-example)?[ .]cfg/xrpld\1.cfg/g' "${FILE}"
${SED_COMMAND} -i 's/rippleConfig/xrpldConfig/g' "${FILE}"
done
done
${SED_COMMAND} -i 's/rippled/xrpld/g' cfg/xrpld-example.cfg
${SED_COMMAND} -i 's/rippled/xrpld/g' src/test/core/Config_test.cpp
${SED_COMMAND} -i 's/ripplevalidators/xrplvalidators/g' src/test/core/Config_test.cpp # cspell: disable-line
${SED_COMMAND} -i 's/rippleConfig/xrpldConfig/g' src/test/core/Config_test.cpp
${SED_COMMAND} -i 's@ripple/@xrpld/@g' src/test/core/Config_test.cpp
${SED_COMMAND} -i 's/Rippled/File/g' src/test/core/Config_test.cpp
# Restore the old config file name in the code that maintains support for now.
${SED_COMMAND} -i 's/configLegacyName = "xrpld.cfg"/configLegacyName = "rippled.cfg"/g' src/xrpld/core/detail/Config.cpp
${SED_COMMAND} -i 's/kConfigLegacyName = "xrpld.cfg"/kConfigLegacyName = "rippled.cfg"/g' src/xrpld/core/detail/Config.cpp
# Restore an URL.
${SED_COMMAND} -i 's/connect-your-xrpld-to-the-xrp-test-net.html/connect-your-rippled-to-the-xrp-test-net.html/g' cfg/xrpld-example.cfg

View File

@@ -6,11 +6,11 @@ set -e
# On MacOS, ensure that GNU sed is installed and available as `gsed`.
SED_COMMAND=sed
if [[ "${OSTYPE}" == 'darwin'* ]]; then
if ! command -v gsed &> /dev/null; then
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
exit 1
fi
SED_COMMAND=gsed
if ! command -v gsed &>/dev/null; then
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
exit 1
fi
SED_COMMAND=gsed
fi
# This script removes superfluous copyright notices in source and header files
@@ -31,7 +31,7 @@ if [ ! -d "${DIRECTORY}" ]; then
echo "Error: Directory '${DIRECTORY}' does not exist."
exit 1
fi
pushd ${DIRECTORY}
pushd "${DIRECTORY}"
# Prevent sed and echo from removing newlines and tabs in string literals by
# temporarily replacing them with placeholders. This only affects one file.
@@ -43,56 +43,56 @@ ${SED_COMMAND} -i -E "s@\\\t@${PLACEHOLDER_TAB}@g" src/test/rpc/ValidatorInfo_te
# Process the include/ and src/ directories.
DIRECTORIES=("include" "src")
for DIRECTORY in "${DIRECTORIES[@]}"; do
echo "Processing directory: ${DIRECTORY}"
echo "Processing directory: ${DIRECTORY}"
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" -o -name "*.macro" \) | while read -r FILE; do
echo "Processing file: ${FILE}"
# Handle the cases where the copyright notice is enclosed in /* ... */
# and usually surrounded by //---- and //======.
${SED_COMMAND} -z -i -E 's@^//-------+\n+@@' "${FILE}"
${SED_COMMAND} -z -i -E 's@^.*Copyright.+(Ripple|Bougalis|Falco|Hinnant|Null|Ritchford|XRPLF).+PERFORMANCE OF THIS SOFTWARE\.\n\*/\n+@@' "${FILE}" # cspell: ignore Bougalis Falco Hinnant Ritchford
${SED_COMMAND} -z -i -E 's@^//=======+\n+@@' "${FILE}"
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" -o -name "*.macro" \) | while read -r FILE; do
echo "Processing file: ${FILE}"
# Handle the cases where the copyright notice is enclosed in /* ... */
# and usually surrounded by //---- and //======.
${SED_COMMAND} -z -i -E 's@^//-------+\n+@@' "${FILE}"
${SED_COMMAND} -z -i -E 's@^.*Copyright.+(Ripple|Bougalis|Falco|Hinnant|Null|Ritchford|XRPLF).+PERFORMANCE OF THIS SOFTWARE\.\n\*/\n+@@' "${FILE}" # cspell: ignore Bougalis Falco Hinnant Ritchford
${SED_COMMAND} -z -i -E 's@^//=======+\n+@@' "${FILE}"
# Handle the cases where the copyright notice is commented out with //.
${SED_COMMAND} -z -i -E 's@^//\n// Copyright.+Falco \(vinnie dot falco at gmail dot com\)\n//\n+@@' "${FILE}" # cspell: ignore Vinnie Falco
done
# Handle the cases where the copyright notice is commented out with //.
${SED_COMMAND} -z -i -E 's@^//\n// Copyright.+Falco \(vinnie dot falco at gmail dot com\)\n//\n+@@' "${FILE}" # cspell: ignore Vinnie Falco
done
done
# Restore copyright notices that were removed from specific files, without
# restoring the verbiage that is already present in LICENSE.md. Ensure that if
# the script is run multiple times, duplicate notices are not added.
if ! grep -q 'Raw Material Software' include/xrpl/beast/core/CurrentThreadName.h; then
echo -e "// Portions of this file are from JUCE (http://www.juce.com).\n// Copyright (c) 2013 - Raw Material Software Ltd.\n// Please visit http://www.juce.com\n\n$(cat include/xrpl/beast/core/CurrentThreadName.h)" > include/xrpl/beast/core/CurrentThreadName.h
echo -e "// Portions of this file are from JUCE (http://www.juce.com).\n// Copyright (c) 2013 - Raw Material Software Ltd.\n// Please visit http://www.juce.com\n\n$(cat include/xrpl/beast/core/CurrentThreadName.h)" >include/xrpl/beast/core/CurrentThreadName.h
fi
if ! grep -q 'Dev Null' src/test/app/NetworkID_test.cpp; then
echo -e "// Copyright (c) 2020 Dev Null Productions\n\n$(cat src/test/app/NetworkID_test.cpp)" > src/test/app/NetworkID_test.cpp
echo -e "// Copyright (c) 2020 Dev Null Productions\n\n$(cat src/test/app/NetworkID_test.cpp)" >src/test/app/NetworkID_test.cpp
fi
if ! grep -q 'Dev Null' src/test/app/tx/apply_test.cpp; then
echo -e "// Copyright (c) 2020 Dev Null Productions\n\n$(cat src/test/app/tx/apply_test.cpp)" > src/test/app/tx/apply_test.cpp
echo -e "// Copyright (c) 2020 Dev Null Productions\n\n$(cat src/test/app/tx/apply_test.cpp)" >src/test/app/tx/apply_test.cpp
fi
if ! grep -q 'Dev Null' src/test/rpc/ManifestRPC_test.cpp; then
echo -e "// Copyright (c) 2020 Dev Null Productions\n\n$(cat src/test/rpc/ManifestRPC_test.cpp)" > src/test/rpc/ManifestRPC_test.cpp
echo -e "// Copyright (c) 2020 Dev Null Productions\n\n$(cat src/test/rpc/ManifestRPC_test.cpp)" >src/test/rpc/ManifestRPC_test.cpp
fi
if ! grep -q 'Dev Null' src/test/rpc/ValidatorInfo_test.cpp; then
echo -e "// Copyright (c) 2020 Dev Null Productions\n\n$(cat src/test/rpc/ValidatorInfo_test.cpp)" > src/test/rpc/ValidatorInfo_test.cpp
echo -e "// Copyright (c) 2020 Dev Null Productions\n\n$(cat src/test/rpc/ValidatorInfo_test.cpp)" >src/test/rpc/ValidatorInfo_test.cpp
fi
if ! grep -q 'Dev Null' src/xrpld/rpc/handlers/DoManifest.cpp; then
echo -e "// Copyright (c) 2019 Dev Null Productions\n\n$(cat src/xrpld/rpc/handlers/DoManifest.cpp)" > src/xrpld/rpc/handlers/DoManifest.cpp
if ! grep -q 'Dev Null' src/xrpld/rpc/handlers/server_info/Manifest.cpp; then
echo -e "// Copyright (c) 2019 Dev Null Productions\n\n$(cat src/xrpld/rpc/handlers/server_info/Manifest.cpp)" >src/xrpld/rpc/handlers/server_info/Manifest.cpp
fi
if ! grep -q 'Dev Null' src/xrpld/rpc/handlers/ValidatorInfo.cpp; then
echo -e "// Copyright (c) 2019 Dev Null Productions\n\n$(cat src/xrpld/rpc/handlers/ValidatorInfo.cpp)" > src/xrpld/rpc/handlers/ValidatorInfo.cpp
if ! grep -q 'Dev Null' src/xrpld/rpc/handlers/admin/status/ValidatorInfo.cpp; then
echo -e "// Copyright (c) 2019 Dev Null Productions\n\n$(cat src/xrpld/rpc/handlers/admin/status/ValidatorInfo.cpp)" >src/xrpld/rpc/handlers/admin/status/ValidatorInfo.cpp
fi
if ! grep -q 'Bougalis' include/xrpl/basics/SlabAllocator.h; then
echo -e "// Copyright (c) 2022, Nikolaos D. Bougalis <nikb@bougalis.net>\n\n$(cat include/xrpl/basics/SlabAllocator.h)" > include/xrpl/basics/SlabAllocator.h # cspell: ignore Nikolaos Bougalis nikb
echo -e "// Copyright (c) 2022, Nikolaos D. Bougalis <nikb@bougalis.net>\n\n$(cat include/xrpl/basics/SlabAllocator.h)" >include/xrpl/basics/SlabAllocator.h # cspell: ignore Nikolaos Bougalis nikb
fi
if ! grep -q 'Bougalis' include/xrpl/basics/spinlock.h; then
echo -e "// Copyright (c) 2022, Nikolaos D. Bougalis <nikb@bougalis.net>\n\n$(cat include/xrpl/basics/spinlock.h)" > include/xrpl/basics/spinlock.h # cspell: ignore Nikolaos Bougalis nikb
echo -e "// Copyright (c) 2022, Nikolaos D. Bougalis <nikb@bougalis.net>\n\n$(cat include/xrpl/basics/spinlock.h)" >include/xrpl/basics/spinlock.h # cspell: ignore Nikolaos Bougalis nikb
fi
if ! grep -q 'Bougalis' include/xrpl/basics/tagged_integer.h; then
echo -e "// Copyright (c) 2014, Nikolaos D. Bougalis <nikb@bougalis.net>\n\n$(cat include/xrpl/basics/tagged_integer.h)" > include/xrpl/basics/tagged_integer.h # cspell: ignore Nikolaos Bougalis nikb
echo -e "// Copyright (c) 2014, Nikolaos D. Bougalis <nikb@bougalis.net>\n\n$(cat include/xrpl/basics/tagged_integer.h)" >include/xrpl/basics/tagged_integer.h # cspell: ignore Nikolaos Bougalis nikb
fi
if ! grep -q 'Ritchford' include/xrpl/beast/utility/Zero.h; then
echo -e "// Copyright (c) 2014, Tom Ritchford <tom@swirly.com>\n\n$(cat include/xrpl/beast/utility/Zero.h)" > include/xrpl/beast/utility/Zero.h # cspell: ignore Ritchford
echo -e "// Copyright (c) 2014, Tom Ritchford <tom@swirly.com>\n\n$(cat include/xrpl/beast/utility/Zero.h)" >include/xrpl/beast/utility/Zero.h # cspell: ignore Ritchford
fi
# Restore newlines and tabs in string literals in the affected file.

View File

@@ -6,11 +6,11 @@ set -e
# On MacOS, ensure that GNU sed is installed and available as `gsed`.
SED_COMMAND=sed
if [[ "${OSTYPE}" == 'darwin'* ]]; then
if ! command -v gsed &> /dev/null; then
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
exit 1
fi
SED_COMMAND=gsed
if ! command -v gsed &>/dev/null; then
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
exit 1
fi
SED_COMMAND=gsed
fi
# This script renames definitions, such as include guards, in this project.

96
.github/scripts/rename/docs.sh vendored Executable file
View File

@@ -0,0 +1,96 @@
#!/bin/bash
# Exit the script as soon as an error occurs.
set -e
# On MacOS, ensure that GNU sed is installed and available as `gsed`.
SED_COMMAND=sed
if [[ "${OSTYPE}" == 'darwin'* ]]; then
if ! command -v gsed &>/dev/null; then
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
exit 1
fi
SED_COMMAND=gsed
fi
# This script renames all remaining references to `ripple` and `rippled` to
# `xrpl` and `xrpld`, respectively, in code, comments, and documentation.
# Usage: .github/scripts/rename/docs.sh <repository directory>
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <repository directory>"
exit 1
fi
DIRECTORY=$1
echo "Processing directory: ${DIRECTORY}"
if [ ! -d "${DIRECTORY}" ]; then
echo "Error: Directory '${DIRECTORY}' does not exist."
exit 1
fi
pushd "${DIRECTORY}"
find . -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" -o -name "*.txt" -o -name "*.cfg" -o -name "*.md" -o -name "*.proto" \) -not -path "./.github/scripts/*" | while read -r FILE; do
echo "Processing file: ${FILE}"
${SED_COMMAND} -i 's/rippleLockEscrowMPT/lockEscrowMPT/g' "${FILE}"
${SED_COMMAND} -i 's/rippleUnlockEscrowMPT/unlockEscrowMPT/g' "${FILE}"
${SED_COMMAND} -i 's/rippleCredit/directSendNoFee/g' "${FILE}"
${SED_COMMAND} -i 's/rippleSend/directSendNoLimit/g' "${FILE}"
${SED_COMMAND} -i -E 's@([^/+-])rippled@\1xrpld@g' "${FILE}"
${SED_COMMAND} -i -E 's@([^/+-])Rippled@\1Xrpld@g' "${FILE}"
${SED_COMMAND} -i -E 's/^rippled/xrpld/g' "${FILE}"
${SED_COMMAND} -i -E 's/^Rippled/Xrpld/g' "${FILE}"
# cspell: disable
${SED_COMMAND} -i -E 's/(r|R)ipple (a|A)ddress/XRPL address/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (a|A)ccount/XRPL account/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (a|A)lgorithm/XRPL algorithm/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (c|C)lient/XRPL client/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (c|C)luster/XRPL cluster/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (c|C)onsensus/XRPL consensus/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (d|D)efault/XRPL default/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (e|E)poch/XRPL epoch/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (f|F)eature/XRPL feature/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (n|N)etwork/XRPL network/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (p|P)ayment/XRPL payment/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (p|P)rotocol/XRPL protocol/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (r|R)epository/XRPL repository/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple RPC/XRPL RPC/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (s|S)erialization/XRPL serialization/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (s|S)erver/XRPL server/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (s|S)pecific/XRPL specific/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple Source/XRPL Source/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (t|T)imestamp/XRPL timestamp/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple uses the consensus/XRPL uses the consensus/g' "${FILE}"
${SED_COMMAND} -i -E 's/(r|R)ipple (v|V)alidator/XRPL validator/g' "${FILE}"
# cspell: enable
${SED_COMMAND} -i 's/RippleLib/XrplLib/g' "${FILE}"
${SED_COMMAND} -i 's/ripple-lib/XrplLib/g' "${FILE}"
${SED_COMMAND} -i 's@opt/ripple/@opt/xrpld/@g' "${FILE}"
${SED_COMMAND} -i 's@src/ripple/@src/xrpld/@g' "${FILE}"
${SED_COMMAND} -i 's@ripple/app/@xrpld/app/@g' "${FILE}"
${SED_COMMAND} -i 's@github.com/ripple/rippled@github.com/XRPLF/rippled@g' "${FILE}"
${SED_COMMAND} -i 's/\ba xrpl/an xrpl/g' "${FILE}"
${SED_COMMAND} -i 's/\ba XRPL/an XRPL/g' "${FILE}"
done
${SED_COMMAND} -i 's/ripple_libs/xrpl_libs/' BUILD.md
${SED_COMMAND} -i 's/Ripple integrators/XRPL developers/' README.md
${SED_COMMAND} -i 's/sanitizer-configuration-for-rippled/sanitizer-configuration-for-xrpld/' docs/build/sanitizers.md
${SED_COMMAND} -i 's/rippled/xrpld/g' .github/scripts/levelization/README.md
${SED_COMMAND} -i 's/rippled/xrpld/g' .github/scripts/strategy-matrix/generate.py
${SED_COMMAND} -i 's@/rippled@/xrpld@g' docs/build/install.md
${SED_COMMAND} -i 's@github.com/XRPLF/xrpld@github.com/XRPLF/rippled@g' docs/build/install.md
${SED_COMMAND} -i 's/rippled/xrpld/g' docs/Doxyfile
${SED_COMMAND} -i 's/ripple_basics/basics/' include/xrpl/basics/CountedObject.h
${SED_COMMAND} -i 's/<ripple/<xrpl/' include/xrpl/protocol/AccountID.h
${SED_COMMAND} -i 's/Ripple:/the XRPL:/g' include/xrpl/protocol/SecretKey.h
${SED_COMMAND} -i 's/Ripple:/the XRPL:/g' include/xrpl/protocol/Seed.h
${SED_COMMAND} -i 's/ripple/xrpl/g' src/test/README.md
${SED_COMMAND} -i 's/www.ripple.com/www.xrpl.org/g' src/test/protocol/Seed_test.cpp
# Restore specific changes.
${SED_COMMAND} -i 's@b5efcc/src/xrpld@b5efcc/src/ripple@' include/xrpl/protocol/README.md
${SED_COMMAND} -i 's/dbPrefix_ = "xrpldb"/dbPrefix_ = "rippledb"/' src/xrpld/app/misc/SHAMapStoreImp.h # cspell: disable-line
${SED_COMMAND} -i 's/kConfigLegacyName = "xrpld.cfg"/kConfigLegacyName = "rippled.cfg"/' src/xrpld/core/detail/Config.cpp
popd
echo "Renaming complete."

View File

@@ -23,8 +23,8 @@ fi
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" \) | while read -r FILE; do
echo "Processing file: ${FILE}"
if grep -q "#ifndef XRPL_" "${FILE}"; then
echo "Please replace all include guards by #pragma once."
exit 1
echo "Please replace all include guards by #pragma once."
exit 1
fi
done
echo "Checking complete."

View File

@@ -6,11 +6,11 @@ set -e
# On MacOS, ensure that GNU sed is installed and available as `gsed`.
SED_COMMAND=sed
if [[ "${OSTYPE}" == 'darwin'* ]]; then
if ! command -v gsed &> /dev/null; then
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
exit 1
fi
SED_COMMAND=gsed
if ! command -v gsed &>/dev/null; then
echo "Error: gsed is not installed. Please install it using 'brew install gnu-sed'."
exit 1
fi
SED_COMMAND=gsed
fi
# This script renames the `ripple` namespace to `xrpl` in this project.
@@ -31,18 +31,19 @@ if [ ! -d "${DIRECTORY}" ]; then
echo "Error: Directory '${DIRECTORY}' does not exist."
exit 1
fi
pushd ${DIRECTORY}
pushd "${DIRECTORY}"
DIRECTORIES=("include" "src" "tests")
for DIRECTORY in "${DIRECTORIES[@]}"; do
echo "Processing directory: ${DIRECTORY}"
echo "Processing directory: ${DIRECTORY}"
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" \) | while read -r FILE; do
echo "Processing file: ${FILE}"
${SED_COMMAND} -i 's/namespace ripple/namespace xrpl/g' "${FILE}"
${SED_COMMAND} -i 's/ripple::/xrpl::/g' "${FILE}"
${SED_COMMAND} -i -E 's/(BEAST_DEFINE_TESTSUITE.+)ripple(.+)/\1xrpl\2/g' "${FILE}"
done
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" -o -name "*.cpp" -o -name "*.macro" \) | while read -r FILE; do
echo "Processing file: ${FILE}"
${SED_COMMAND} -i 's/namespace ripple/namespace xrpl/g' "${FILE}"
${SED_COMMAND} -i 's/ripple::/xrpl::/g' "${FILE}"
${SED_COMMAND} -i 's/"ripple:/"xrpl::/g' "${FILE}"
${SED_COMMAND} -i -E 's/(BEAST_DEFINE_TESTSUITE.+)ripple(.+)/\1xrpl\2/g' "${FILE}"
done
done
# Special case for NuDBFactory that has ripple twice in the test suite name.

View File

@@ -32,7 +32,32 @@ We will further set additional CMake arguments as follows:
"""
def generate_strategy_matrix(all: bool, config: Config) -> list:
def build_config_name(os_entry: dict[str, str], platform: str, build_type: str) -> str:
parts = [os_entry["distro_name"]]
for key in ("distro_version", "compiler_name", "compiler_version"):
if value := os_entry[key]:
parts.append(value)
parts.append("arm64" if "arm64" in platform else "amd64")
parts.append(build_type.lower())
return "-".join(parts)
def generate_packaging_matrix(config: Config) -> list[dict]:
"""Emit one entry per os entry with `package: true`. Architecture is
hardcoded to linux/amd64 here (and the runner is hardcoded at the
workflow level) until arm64 packaging is ready.
"""
return [
{
"artifact_name": f"xrpld-{build_config_name(os, 'linux/amd64', 'Release')}",
"os": os,
}
for os in config.os
if os.get("package", False)
]
def generate_strategy_matrix(all: bool, config: Config) -> list[dict]:
configurations = []
for architecture, os, build_type, cmake_args in itertools.product(
config.architecture, config.os, config.build_type, config.cmake_args
@@ -51,34 +76,35 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
# Only generate a subset of configurations in PRs.
if not all:
# Debian:
# - Bookworm using GCC 13: Release on linux/amd64, set the reference
# fee to 500.
# - Bookworm using GCC 15: Debug on linux/amd64, enable code
# coverage (which will be done below).
# - Bookworm using Clang 16: Debug on linux/arm64, enable voidstar.
# - Bookworm using GCC 13: Debug on linux/amd64, set the reference
# fee to 500 and enable code coverage (which will be done below).
# - Bookworm using GCC 15: Debug on linux/amd64, enable Address and
# UB sanitizers (which will be done below).
# - Bookworm using Clang 16: Debug on linux/amd64, enable voidstar.
# - Bookworm using Clang 17: Release on linux/amd64, set the
# reference fee to 1000.
# - Bookworm using Clang 20: Debug on linux/amd64.
# - Bookworm using Clang 20: Debug on linux/amd64, enable Address
# and UB sanitizers (which will be done below).
if os["distro_name"] == "debian":
skip = True
if os["distro_version"] == "bookworm":
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-13"
and build_type == "Release"
and build_type == "Debug"
and architecture["platform"] == "linux/amd64"
):
cmake_args = f"-DUNIT_TEST_REFERENCE_FEE=500 {cmake_args}"
skip = False
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
and build_type == "Debug"
and build_type == "Release"
and architecture["platform"] == "linux/amd64"
):
skip = False
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-16"
and build_type == "Debug"
and architecture["platform"] == "linux/arm64"
and architecture["platform"] == "linux/amd64"
):
cmake_args = f"-Dvoidstar=ON {cmake_args}"
skip = False
@@ -89,8 +115,9 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
):
cmake_args = f"-DUNIT_TEST_REFERENCE_FEE=1000 {cmake_args}"
skip = False
elif os["distro_version"] == "trixie":
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-20"
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-22"
and build_type == "Debug"
and architecture["platform"] == "linux/amd64"
):
@@ -99,14 +126,15 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
continue
# RHEL:
# - 9 using GCC 12: Debug on linux/amd64.
# - 9 using GCC 12: Debug and Release on linux/amd64
# (Release is required for RPM packaging).
# - 10 using Clang: Release on linux/amd64.
if os["distro_name"] == "rhel":
skip = True
if os["distro_version"] == "9":
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
and build_type == "Debug"
and build_type in ["Debug", "Release"]
and architecture["platform"] == "linux/amd64"
):
skip = False
@@ -121,7 +149,8 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
continue
# Ubuntu:
# - Jammy using GCC 12: Debug on linux/arm64.
# - Jammy using GCC 12: Debug on linux/arm64, Release on
# linux/amd64 (Release is required for DEB packaging).
# - Noble using GCC 14: Release on linux/amd64.
# - Noble using Clang 18: Debug on linux/amd64.
# - Noble using Clang 19: Release on linux/arm64.
@@ -134,6 +163,12 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
and architecture["platform"] == "linux/arm64"
):
skip = False
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
and build_type == "Release"
and architecture["platform"] == "linux/amd64"
):
skip = False
elif os["distro_version"] == "noble":
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-14"
@@ -187,17 +222,18 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
# We skip all clang 20+ on arm64 due to Boost build error.
if (
f"{os['compiler_name']}-{os['compiler_version']}"
in ["clang-20", "clang-21"]
os["compiler_name"] == "clang"
and os["compiler_version"].isdigit()
and int(os["compiler_version"]) >= 20
and architecture["platform"] == "linux/arm64"
):
continue
# Enable code coverage for Debian Bookworm using GCC 15 in Debug on
# linux/amd64
# Enable code coverage for Debian Bookworm using GCC 13 in Debug on
# linux/amd64.
if (
f"{os['distro_name']}-{os['distro_version']}" == "debian-bookworm"
and f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
and f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-13"
and build_type == "Debug"
and architecture["platform"] == "linux/amd64"
):
@@ -215,17 +251,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
# Generate a unique name for the configuration, e.g. macos-arm64-debug
# or debian-bookworm-gcc-12-amd64-release.
config_name = os["distro_name"]
if (n := os["distro_version"]) != "":
config_name += f"-{n}"
if (n := os["compiler_name"]) != "":
config_name += f"-{n}"
if (n := os["compiler_version"]) != "":
config_name += f"-{n}"
config_name += (
f"-{architecture['platform'][architecture['platform'].find('/')+1:]}"
)
config_name += f"-{build_type.lower()}"
config_name = build_config_name(os, architecture["platform"], build_type)
if "-Dcoverage=ON" in cmake_args:
config_name += "-coverage"
if "-Dunity=ON" in cmake_args:
@@ -234,23 +260,39 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
# Add the configuration to the list, with the most unique fields first,
# so that they are easier to identify in the GitHub Actions UI, as long
# names get truncated.
# Add Address and Thread (both coupled with UB) sanitizers for specific bookworm distros.
# GCC-Asan rippled-embedded tests are failing because of https://github.com/google/sanitizers/issues/856
# Add Address and UB sanitizers as separate configurations for specific
# bookworm distros. Thread sanitizer is currently disabled (see below).
# GCC-Asan xrpld-embedded tests are failing because of https://github.com/google/sanitizers/issues/856
if (
os["distro_version"] == "bookworm"
and f"{os['compiler_name']}-{os['compiler_version']}" == "clang-20"
and f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
) or (
os["distro_version"] == "trixie"
and f"{os['compiler_name']}-{os['compiler_version']}" == "clang-22"
):
# Add ASAN + UBSAN configuration.
# Add ASAN and UBSAN configurations for both gcc-15 and clang-22
configurations.append(
{
"config_name": config_name + "-asan-ubsan",
"config_name": config_name + "-asan",
"cmake_args": cmake_args,
"cmake_target": cmake_target,
"build_only": build_only,
"build_type": build_type,
"os": os,
"architecture": architecture,
"sanitizers": "address,undefinedbehavior",
"sanitizers": "address",
}
)
configurations.append(
{
"config_name": config_name + "-ubsan",
"cmake_args": cmake_args,
"cmake_target": cmake_target,
"build_only": build_only,
"build_type": build_type,
"os": os,
"architecture": architecture,
"sanitizers": "undefinedbehavior",
}
)
# TSAN is deactivated due to seg faults with latest compilers.
@@ -313,10 +355,19 @@ if __name__ == "__main__":
required=False,
type=Path,
)
parser.add_argument(
"-p",
"--packaging",
help="Emit the packaging matrix (derived from the 'package' field on os entries) instead of the build/test matrix.",
action="store_true",
)
args = parser.parse_args()
matrix = []
if args.config is None or args.config == "":
if args.packaging:
config_path = args.config if args.config else THIS_DIR / "linux.json"
matrix += generate_packaging_matrix(read_config(config_path))
elif args.config is None or args.config == "":
matrix += generate_strategy_matrix(
args.all, read_config(THIS_DIR / "linux.json")
)

View File

@@ -15,196 +15,205 @@
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "12",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "13",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "gcc",
"compiler_version": "15",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "16",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "17",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "18",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "19",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "bookworm",
"compiler_name": "clang",
"compiler_version": "20",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "gcc",
"compiler_version": "15",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "clang",
"compiler_version": "20",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "clang",
"compiler_version": "21",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "debian",
"distro_version": "trixie",
"compiler_name": "clang",
"compiler_version": "22",
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "8",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "8",
"compiler_name": "clang",
"compiler_version": "any",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "12",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9",
"package": true
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "13",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "9",
"compiler_name": "clang",
"compiler_version": "any",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "10",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "rhel",
"distro_version": "10",
"compiler_name": "clang",
"compiler_version": "any",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "jammy",
"compiler_name": "gcc",
"compiler_version": "12",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9",
"package": true
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "gcc",
"compiler_version": "13",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "gcc",
"compiler_version": "14",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "16",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "17",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "18",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
},
{
"distro_name": "ubuntu",
"distro_version": "noble",
"compiler_name": "clang",
"compiler_version": "19",
"image_sha": "ab4d1f0"
"image_sha": "4c086b9"
}
],
"build_type": ["Debug", "Release"],

109
.github/workflows/build-nix-image.yml vendored Normal file
View File

@@ -0,0 +1,109 @@
name: Build Nix Docker image
on:
push:
branches:
- develop
paths:
- ".github/workflows/build-nix-image.yml"
- ".github/workflows/reusable-build-docker-image.yml"
- "docker/**"
- "flake.nix"
- "flake.lock"
- "nix/**"
pull_request:
paths:
- ".github/workflows/build-nix-image.yml"
- ".github/workflows/reusable-build-docker-image.yml"
- "docker/**"
- "flake.nix"
- "flake.lock"
- "nix/**"
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
build:
name: Build ${{ matrix.distro.name }} (${{ matrix.target.platform }})
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
# The base images are the oldest supported version of each distro
# that we want to build images for.
distro:
- name: nixos
base_image: nixos/nix:latest
- name: ubuntu
base_image: ubuntu:20.04
- name: rhel
base_image: registry.access.redhat.com/ubi9/ubi:latest
- name: debian
base_image: debian:bookworm
target:
- platform: linux/amd64
runner: ubuntu-latest
- platform: linux/arm64
runner: ubuntu-24.04-arm
uses: ./.github/workflows/reusable-build-docker-image.yml
with:
image_name: ghcr.io/xrplf/xrpld/nix-${{ matrix.distro.name }}
dockerfile: docker/nix.Dockerfile
base_image: ${{ matrix.distro.base_image }}
platform: ${{ matrix.target.platform }}
runner: ${{ matrix.target.runner }}
push: ${{ github.repository == 'XRPLF/rippled' && github.event_name == 'push' }}
merge:
name: Merge ${{ matrix.distro }} manifest
needs: build
if: ${{ github.repository == 'XRPLF/rippled' && github.event_name == 'push' }}
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
distro: [nixos, ubuntu, rhel, debian]
env:
IMAGE_NAME: ghcr.io/xrplf/xrpld/nix-${{ matrix.distro }}
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Docker metadata
id: meta
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
with:
images: ${{ env.IMAGE_NAME }}
tags: |
type=sha,prefix=sha-,format=short
type=raw,value=latest
- name: Login to GitHub Container Registry
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create multi-arch manifests
run: |
for tag in $(jq -cr '.tags[]' <<<"$DOCKER_METADATA_OUTPUT_JSON"); do
docker buildx imagetools create -t "$tag" "${tag}-amd64" "${tag}-arm64"
done
- name: Inspect image
run: |
docker buildx imagetools inspect "${IMAGE_NAME}:${{ steps.meta.outputs.version }}"

13
.github/workflows/check-pr-commits.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
name: Check PR commits
on:
pull_request_target:
# The action needs to have write permissions to post comments on the PR.
permissions:
contents: read
pull-requests: write
jobs:
check_commits:
uses: XRPLF/actions/.github/workflows/check-pr-commits.yml@e2c7f400d1e85ae65dad552fd425169fbacca4a3

View File

@@ -0,0 +1,39 @@
name: Check PR description
on:
merge_group:
types:
- checks_requested
pull_request:
types:
- opened
- edited
- reopened
- synchronize
- ready_for_review
branches:
- develop
- "release-*"
- "release/*"
- "staging/*"
jobs:
check_description:
if: ${{ github.event.pull_request.draft != true }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Write PR body to file
env:
PR_BODY: ${{ github.event.pull_request.body }}
if: ${{ github.event_name == 'pull_request' }}
run: printenv PR_BODY >pr_body.md
- name: Check PR description differs from template
if: ${{ github.event_name == 'pull_request' }}
run: |
python .github/scripts/check-pr-description.py \
--template-file .github/pull_request_template.md \
--pr-body-file pr_body.md

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