Compare commits

...

687 Commits

Author SHA1 Message Date
Denis Angell
f7ec38c843 compose: alphanet from XRPLF/rippled@develop @ 94037361 (19 branches)
Multibranch-Builder-Manifest: {"base":"XRPLF/rippled@develop","base_sha":"94037361992ad75b32a6b2659b655ab96b7cb7c2","branches":[{"repo":"XRPLF/rippled","branch":"dangell7/supported-cicd","sha":"48ca26c2a441e0670b4f6bd11af4b25e70c1f0ee","outcome":"merged","rebase":true},{"repo":"XRPLF/rippled","branch":"dangell7/datagram","sha":"6b24a5c32ec372b08615b413bea6b29058df475c","outcome":"merged","rebase":true},{"repo":"XRPLF/rippled","branch":"dangell/smart-contracts","sha":"bcb8fb7d4f5c011940cdbd8b34f6873e1fb3cfbe","outcome":"ai-resolved","rebase":true},{"repo":"Transia-RnD/rippled","branch":"dangell7/escrow-paychan-refactor","sha":"b72ff981593e01d4aab426c647a4decf171880dc","outcome":"ai-resolved","rebase":true},{"repo":"XRPLF/rippled","branch":"token-paychan","sha":"2ba6f4cc68016054de844305bf98a969b1db0c4d","outcome":"ai-resolved","rebase":true},{"repo":"XRPLF/rippled","branch":"dangell7/token-paychan-clawback","sha":"1e5e8ef018c64b70f710466ad24079f25f512b32","outcome":"ai-resolved","rebase":true},{"repo":"Transia-RnD/rippled","branch":"dilithium-full","sha":"e634c6ddc7f69de12f67a87ada18a50252b03f0f","outcome":"ai-resolved","rebase":true},{"repo":"Transia-RnD/rippled","branch":"feature-p256","sha":"b30e9fc369a431ce766b7ae8158479cf236033d5","outcome":"ai-resolved","rebase":true},{"repo":"Transia-RnD/rippled","branch":"dangell7/mpt-structured-data","sha":"3e7af2ab7e05e0b4258627508659af4c073fe824","outcome":"merged","rebase":true},{"repo":"Transia-RnD/rippled","branch":"dangell7/token-issuance","sha":"b045b862223d3a6735161bf0fffa23cffa12b2ed","outcome":"ai-resolved","rebase":true},{"repo":"Transia-RnD/rippled","branch":"dangell7/vault-accrual","sha":"bb60431ebf6ef5d41ef588d8475dbb52f95744b5","outcome":"ai-resolved","rebase":true},{"repo":"Transia-RnD/rippled","branch":"dangell7/coupon-payments","sha":"5af42fc4756fe9bb93552e7a5a294ad97e1c26ed","outcome":"ai-resolved","rebase":true},{"repo":"Transia-RnD/rippled","branch":"dangell7/confidential-voting","sha":"adaae9496ac89c9c015d047bade5b38833ad87bc","outcome":"ai-resolved","rebase":true},{"repo":"Transia-RnD/rippled","branch":"dangell7/amm-curves","sha":"2a11a0f342f207638e6aef2ff070bd935401f39f","outcome":"ai-resolved","rebase":true},{"repo":"Transia-RnD/rippled","branch":"dangell7/offer-qualifiers","sha":"6ad5aae76100ae9e8274a8a84ddca38933f21233","outcome":"ai-resolved","rebase":true},{"repo":"Transia-RnD/rippled","branch":"dangell7/subscriptions","sha":"f3e2670dfa26263526bdac00386f7c78c36a302a","outcome":"ai-resolved","rebase":true},{"repo":"Transia-RnD/rippled","branch":"dangell7/repo-market","sha":"6badf9b5aa3330bf6c8b8c33b47d161df72f7540","outcome":"ai-resolved","rebase":true},{"repo":"Transia-RnD/rippled","branch":"dangell7/beneficiary","sha":"e34711194ce3486a54d1f17b2071aed319b1de8f","outcome":"ai-resolved","rebase":true},{"repo":"Transia-RnD/rippled","branch":"dangell7/firewall","sha":"008643d01cf50c20b2afd324f28dfd9dc771a55e","outcome":"ai-resolved","rebase":true}],"composed_sha":"39341a5b7aafa551ecea78d13cd30ad7aef8c18f","kind":"xrpld","tree_dir":"rippled","target":"XRPLF/rippled@alphanet","options":{"force_supported":"ON"},"prepared":{}}
2026-09-13 19:43:45 -04:00
Denis Angell
39341a5b7a Merge remote-tracking branch 'Transia-RnD-rippled/dangell7/firewall' into develop
# Conflicts:
#	cmake/scripts/codegen/generate_tx_classes.py
#	include/xrpl/protocol/Indexes.h
#	include/xrpl/protocol/TxSettings.h
#	include/xrpl/protocol/detail/transactions.macro
#	src/libxrpl/protocol/Indexes.cpp
#	src/libxrpl/tx/transactors/account/AccountDelete.cpp
#	src/xrpld/rpc/handlers/ledger/LedgerEntry.cpp
2026-09-13 19:43:45 -04:00
Denis Angell
c842da7ffa Merge remote-tracking branch 'Transia-RnD-rippled/dangell7/beneficiary' into develop
# Conflicts:
#	include/xrpl/protocol/detail/ledger_entries.macro
#	include/xrpl/tx/invariants/InvariantCheck.h
#	src/libxrpl/protocol/Indexes.cpp
#	src/libxrpl/tx/Transactor.cpp
2026-09-13 19:41:00 -04:00
Denis Angell
a9a27fee8f Merge remote-tracking branch 'Transia-RnD-rippled/dangell7/repo-market' into develop
# Conflicts:
#	include/xrpl/protocol/TER.h
#	src/libxrpl/protocol/Indexes.cpp
#	src/libxrpl/protocol/TER.cpp
2026-09-13 19:38:39 -04:00
Denis Angell
6538794e81 Merge remote-tracking branch 'Transia-RnD-rippled/dangell7/subscriptions' into develop
# Conflicts:
#	include/xrpl/protocol/Indexes.h
#	include/xrpl/protocol/LedgerFormats.h
#	include/xrpl/protocol/TxFlags.h
#	include/xrpl/protocol/jss.h
#	include/xrpl/tx/invariants/InvariantCheck.h
#	src/libxrpl/protocol/Indexes.cpp
2026-09-13 19:37:19 -04:00
Denis Angell
aece614450 Merge remote-tracking branch 'Transia-RnD-rippled/dangell7/offer-qualifiers' into develop
# Conflicts:
#	include/xrpl/protocol/TER.h
#	include/xrpl/protocol/jss.h
#	src/libxrpl/protocol/TER.cpp
2026-09-13 19:35:28 -04:00
Denis Angell
8c1af90d8a Merge remote-tracking branch 'Transia-RnD-rippled/dangell7/amm-curves' into develop
# Conflicts:
#	.cspell.config.yaml
#	include/xrpl/protocol/Indexes.h
#	include/xrpl/protocol/TER.h
#	include/xrpl/protocol/jss.h
#	src/libxrpl/protocol/Indexes.cpp
#	src/libxrpl/protocol/TER.cpp
#	src/libxrpl/tx/paths/BookStep.cpp
#	src/test/app/Delegate_test.cpp
#	src/xrpld/rpc/detail/RPCCall.cpp
2026-09-13 19:34:28 -04:00
Denis Angell
2c0fde6943 Merge remote-tracking branch 'Transia-RnD-rippled/dangell7/confidential-voting' into develop
# Conflicts:
#	include/xrpl/protocol/Indexes.h
#	include/xrpl/protocol/LedgerFormats.h
#	include/xrpl/protocol/TER.h
#	include/xrpl/protocol/TxFlags.h
#	include/xrpl/protocol/detail/ledger_entries.macro
#	include/xrpl/protocol/jss.h
#	include/xrpl/protocol_autogen/ledger_entries/MPToken.h
#	include/xrpl/tx/invariants/InvariantCheck.h
#	src/libxrpl/protocol/Indexes.cpp
#	src/libxrpl/protocol/InnerObjectFormats.cpp
#	src/libxrpl/protocol/TER.cpp
#	src/tests/libxrpl/protocol_autogen/ledger_entries/MPTokenTests.cpp
2026-09-13 19:32:32 -04:00
Denis Angell
4c24f5aed6 Merge remote-tracking branch 'Transia-RnD-rippled/dangell7/coupon-payments' into develop
# Conflicts:
#	include/xrpl/protocol/detail/ledger_entries.macro
#	include/xrpl/protocol/jss.h
#	include/xrpl/tx/invariants/InvariantCheck.h
#	src/libxrpl/protocol/Indexes.cpp
#	src/libxrpl/tx/transactors/token/MPTokenIssuanceDestroy.cpp
2026-09-13 19:29:24 -04:00
Denis Angell
642fd96ca7 Merge remote-tracking branch 'Transia-RnD-rippled/dangell7/vault-accrual' into develop
# Conflicts:
#	include/xrpl/tx/invariants/InvariantCheck.h
2026-09-13 19:27:32 -04:00
Denis Angell
c822dcc075 Merge remote-tracking branch 'Transia-RnD-rippled/dangell7/token-issuance' into develop
# Conflicts:
#	include/xrpl/protocol/Protocol.h
#	include/xrpl/protocol/TER.h
#	include/xrpl/protocol/detail/ledger_entries.macro
#	src/libxrpl/protocol/TER.cpp
2026-09-13 19:26:58 -04:00
Denis Angell
af5a877a4d Merge remote-tracking branch 'Transia-RnD-rippled/dangell7/mpt-structured-data' into develop 2026-09-13 19:25:43 -04:00
Denis Angell
dce61d0d8c Merge remote-tracking branch 'Transia-RnD-rippled/feature-p256' into develop
# Conflicts:
#	include/xrpl/protocol/Indexes.h
#	include/xrpl/protocol/KeyType.h
#	include/xrpl/protocol/PublicKey.h
#	src/libxrpl/protocol/Indexes.cpp
#	src/libxrpl/protocol/PublicKey.cpp
#	src/libxrpl/protocol/SecretKey.cpp
2026-09-13 19:25:42 -04:00
Denis Angell
7f1be3103b Merge remote-tracking branch 'Transia-RnD-rippled/dilithium-full' into develop
# Conflicts:
#	cmake/XrplCore.cmake
2026-09-13 19:24:07 -04:00
Denis Angell
0d3750f39d Merge remote-tracking branch 'XRPLF-rippled/dangell7/token-paychan-clawback' into develop
# Conflicts:
#	src/test/app/Delegate_test.cpp
2026-09-13 19:23:39 -04:00
Denis Angell
b20a95ad78 Merge remote-tracking branch 'XRPLF-rippled/token-paychan' into develop
# Conflicts:
#	src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp
#	src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp
#	src/test/app/PayChan_test.cpp
#	src/test/jtx/impl/paychan.cpp
#	src/test/jtx/paychan.h
2026-09-13 19:22:13 -04:00
Denis Angell
ea63e465f0 Merge remote-tracking branch 'Transia-RnD-rippled/dangell7/escrow-paychan-refactor' into develop
# Conflicts:
#	src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp
#	src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp
2026-09-13 19:20:52 -04:00
Denis Angell
5057dba76f Merge remote-tracking branch 'XRPLF-rippled/dangell/smart-contracts' into develop
# Conflicts:
#	include/xrpl/protocol/jss.h
2026-09-13 19:19:43 -04:00
Denis Angell
78fc349f09 Merge remote-tracking branch 'XRPLF-rippled/dangell7/datagram' into develop 2026-09-13 19:18:58 -04:00
Denis Angell
03ff361885 Merge remote-tracking branch 'XRPLF-rippled/dangell7/supported-cicd' into develop 2026-09-13 19:18:57 -04:00
Denis Angell
bcb8fb7d4f fix: compile the smart-contracts merge against develop and embed the contract test fixtures 2026-09-12 16:57:19 -04:00
Denis Angell
0ae6a81246 chore: merge develop into smart-contracts 2026-09-12 16:17:03 -04:00
Denis Angell
6b24a5c32e feat: DatagramMonitor and consensus-testing admin RPCs 2026-09-12 14:40:25 -04:00
Denis Angell
48ca26c2a4 ci: add the all-amendments supported build workflow 2026-09-12 14:20:05 -04:00
Denis Angell
bb60431ebf featureVaultContinuousAccrual 2026-09-12 06:41:06 -04:00
Denis Angell
2a11a0f342 featureAMMCurves 2026-09-12 06:35:48 -04:00
Denis Angell
008643d01c featureFirewall 2026-09-12 06:35:47 -04:00
Denis Angell
6badf9b5aa featureRepo 2026-09-12 06:35:47 -04:00
Denis Angell
f3e2670dfa featureSubscription 2026-09-12 06:35:47 -04:00
Denis Angell
adaae9496a featureConfidentialVoting 2026-09-12 06:35:47 -04:00
Denis Angell
b045b86222 featureTokenIssuance 2026-09-12 06:35:47 -04:00
Denis Angell
e34711194c featureBeneficiary 2026-09-12 06:35:46 -04:00
Denis Angell
e634c6ddc7 featureQuantum 2026-09-12 06:01:04 -04:00
Denis Angell
b30e9fc369 featurePasskey 2026-09-12 05:51:14 -04:00
Denis Angell
6ad5aae761 featureOfferQualifiers 2026-09-12 05:36:26 -04:00
Denis Angell
5af42fc475 featureCouponPayments 2026-09-11 23:27:17 -04:00
Denis Angell
3e7af2ab7e featureMPTStructuredData 2026-09-11 22:58:58 -04:00
Sergey Kuznetsov
9403736199 ci: Exclude Rust unit tests from code coverage (#8203) 2026-09-10 11:38:25 +00:00
Mayukha Vadari
028783661d feat: Apply .macro changes from ripple/smart-escrow (#8157)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-09-09 20:05:58 +00:00
Vito Tumas
21890d9daf feat: Register featureLendingProtocolV1_2 amendment (#8185)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-09-09 10:01:32 +00:00
Sergey Kuznetsov
060957ed39 ci: Add nightly Rust toolchain to the CI image (#8182)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-09-09 01:24:28 +00:00
Ayaz Salikhov
1381483c7a build: Fix test installation on debian:11 due to EOL (#8200) 2026-09-08 22:49:16 +00:00
dependabot[bot]
3e4bdf2782 ci: [DEPENDABOT] bump actions/deploy-pages from 5.0.0 to 5.0.1 in the github-actions group across 1 directory (#8180)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-07 16:07:56 +00:00
Mayukha Vadari
e3c8996e44 feat: Add fixCleanup3_5_0 amendment placeholder (#8174) 2026-09-05 00:06:14 +00:00
yinyiqian1
d5bfe94f15 feat: Support key rotation in MPTokenIssuanceSet (#7915) 2026-09-03 21:13:06 +00:00
Bart
2ad4def35f chore: Bump version to 3.4.0-rc1 (#8171)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-09-03 20:07:24 +00:00
Mayukha Vadari
f7f50caa6e docs: Backfill API-CHANGELOG.md for 3.1.1 through 3.3.0 (#8159) 2026-09-03 19:48:15 +00:00
Ayaz Salikhov
3e54e7d00b fix: Don't use github.workspace as it slow downs gcovr (#8173) 2026-09-03 19:20:38 +00:00
Valentin Balaschenko
827b50f169 fix: Flaky online delete tests, and cover the health checks added in #5531 (#8137) 2026-09-03 18:56:30 +00:00
Mayukha Vadari
58a59c37ed fix: Add signature prefixes for sfCounterpartySignature and sfSponsorSignature (#8162) 2026-09-03 17:19:07 +00:00
Ayaz Salikhov
986065c16f build: Verify glibc version was determined in debian package (#8170) 2026-09-03 16:54:54 +00:00
Denis Angell
37cb4cdbe3 fix: Recycle the escrow reserve in EscrowCancel and EscrowFinish (#8142) 2026-09-03 16:27:45 +00:00
Bart
2ddf6ee148 ci: Update pre-commit SHA (#8169)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-09-03 14:52:42 +00:00
Pratik Mankawde
8ce4f71427 docs: Use consistent heading levels in PR template (#8155) 2026-09-03 14:48:32 +00:00
Bart
6e1eb88e6e ci: Update prepare-runner SHA (#8168)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-09-03 11:52:08 +00:00
Ayaz Salikhov
49cdc105de fix: Correct and simplify Linux packaging (#8165) 2026-09-02 21:18:13 +00:00
Chenna Keshava B S
636d2d4851 fix: Reinforce the priority of AMMClawback in case of insufficient reserves (#7796)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-09-02 20:48:53 +00:00
Kassaking7
7d7275847d fix: PermissionedDEX (CreateOffer/Payment) never deletes expired credentials (#6827) 2026-09-02 19:38:01 +00:00
Bart
f0fd6ad85e fix: Clamp the depth used to index selectBranch's key byte (#7941)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-09-02 18:06:48 +00:00
Timur Yalymov
5d8fd9824e fix: Revert credential cleanup for pseudo-accounts (#8161) 2026-09-02 15:00:50 +00:00
Vito Tumas
346ea40f69 fix: Allow zero-value MPT vault withdraw when the asset holding is missing (#8153) 2026-09-02 13:45:52 +00:00
Vito Tumas
8809bdf3f0 fix: Treat an existing IOU line as a no-op in addEmptyHolding (#8154) 2026-09-02 12:15:29 +00:00
Mayukha Vadari
deaf596494 docs: Add AGENTS.md/CLAUDE.md for AI coding agent guidance (#8067) 2026-09-01 21:57:34 +00:00
Vito Tumas
7863ac8cf6 fix: Add 60s buffer before closed-ended vault redemption (#8151) 2026-09-01 18:27:05 +00:00
Vito Tumas
b3b38e4416 fix: Correct fee-payer XRP delta in ValidVault for sponsored VaultWithdraw (#8141) 2026-09-01 14:43:11 +00:00
Vito Tumas
ccd5dc5e06 fix: Keep LoanBrokerDelete valid for auth-required MPT cover (#8144) 2026-09-01 14:40:53 +00:00
Vito Tumas
b2453b626e fix: Unblock VaultSet and cash-basis LoanSet at AssetsMaximum (#8143) 2026-09-01 14:06:17 +00:00
Vito Tumas
de6e5d3a94 fix: Keep VaultDeposit share count after the assetsTotal clamp (#8140) 2026-09-01 13:51:39 +00:00
Copilot
fac20a06f3 refactor: Add common helper function for injected metadata fields in RPCs (#5706)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Mayukha Vadari <mvadari@gmail.com>
Co-authored-by: Mayukha Vadari <mvadari@ripple.com>
Co-authored-by: Timur Yalymov <36795566+tyalymov@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-08-31 17:21:25 +00:00
Denis Angell
b72ff98159 Merge remote-tracking branch 'origin/develop' into dangell7/escrow-paychan-refactor
# Conflicts:
#	include/xrpl/ledger/helpers/EscrowHelpers.h
#	src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp
#	src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp
#	src/test/app/PayChan_test.cpp
#	src/test/jtx/impl/TestHelpers.cpp
2026-08-31 11:40:42 -04:00
Denis Angell
2ba6f4cc68 Merge remote-tracking branch 'origin/develop' into token-paychan
# Conflicts:
#	include/xrpl/ledger/helpers/EscrowHelpers.h
#	src/libxrpl/tx/invariants/MPTInvariant.cpp
#	src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp
#	src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp
#	src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp
#	src/test/jtx/impl/TestHelpers.cpp
2026-08-31 11:35:47 -04:00
Ayaz Salikhov
9a7c5ea593 chore: Bump version to 3.4.0-b3 (#8132) 2026-08-27 17:26:55 +00:00
Jingchen
7281e0606a feat: Add vault invariants (#7732)
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-08-27 17:15:17 +00:00
Jingchen
71f5555873 feat: Remove pseudo account field filter (#8042)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-08-27 13:52:23 +00:00
Ayaz Salikhov
3967ed6d54 build: Update release-info to get better pkg_release (#8131) 2026-08-27 13:34:38 +00:00
Vito Tumas
e0151229b6 fix: Waive unrealized-loss discount on sole-holder VaultClawback (#8119) 2026-08-27 08:15:38 +00:00
Ayaz Salikhov
b6a899583b build: Make packaging reusable (#8126) 2026-08-26 19:44:31 +00:00
Gregory Tsipenyuk
dc3bd9cf00 fix: Fix MPT/DEX Audit/Attackathon reports (Phase 1) (#7334) 2026-08-26 18:09:46 +00:00
Vito Tumas
1e8b136bfb feat: Enable LendingProtocolV1_1 amendment (#8125) 2026-08-26 17:35:54 +00:00
Vito Tumas
3c47af779c fix: Clamp Vault Deposit, Withdraw, and Clawback to assetsTotal grid (#8057)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-08-26 17:02:05 +00:00
Ayaz Salikhov
c28d389e0e build: Refactor generate.py to make packaging_config part of config (#8115) 2026-08-26 14:04:58 +00:00
Ayaz Salikhov
d83a84510e chore: Bump version to 3.4.0-b2 (#8120) 2026-08-26 14:03:01 +00:00
Timur Yalymov
f8fba079fe fix: Refuse a pseudo-account as the vault clawback holder (#8111)
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
2026-08-26 13:55:04 +00:00
Sergey Kuznetsov
42502e4263 ci: Update CI image (#8121) 2026-08-26 13:42:19 +00:00
Vito Tumas
36c165f74d fix: Prevent early loan impairment and due-date manipulation (#6557)
Co-authored-by: Ed Hennis <ed@ripple.com>
Co-authored-by: Timur Yalymov <36795566+tyalymov@users.noreply.github.com>
2026-08-26 13:38:24 +00:00
Peter Chen
f7ea645bf4 fix: AMMClawback exact LP token boundary (#7373) 2026-08-26 13:14:53 +00:00
Ayaz Salikhov
50527485d3 build: Rename release channels: unstable->rc, experimental->beta (#8116) 2026-08-26 13:13:59 +00:00
Vito Tumas
421af6db79 fix: Reject open-ended vaults at LoanBrokerSet (#8076)
Co-authored-by: Kenny Lei <3003853+kennyzlei@users.noreply.github.com>
2026-08-26 00:08:25 +00:00
Ayaz Salikhov
fee4bfc22e build: Implement packaging in Python (#8109) 2026-08-25 19:32:03 +00:00
Vito Tumas
5e3d20b3ed fix: Prevent vault clawback and withdraw overrun (#8075) 2026-08-25 17:59:37 +00:00
Ayaz Salikhov
9e2aaf6f60 build: Add rust-toolchain.toml to .envrc (#8107) 2026-08-25 17:09:03 +00:00
Vito Tumas
ec042fefee fix: Absorb Vault invariant rounding noise (#8055) 2026-08-25 17:07:58 +00:00
Denis Angell
c5ae59c4a0 fix: gate paychan claim MPToken invariant relaxation on featureTokenPaychan 2026-08-25 11:10:39 -04:00
Ayaz Salikhov
45e4b8899d build: Update packaging images; add Python (#8106) 2026-08-25 14:34:41 +00:00
Jingchen
c5dc408596 fix: Remove explicit from std/boost hash specialisation default constructors (#8100) 2026-08-25 14:13:02 +00:00
Sergey Kuznetsov
473fe44a85 chore: Upgrade rust toolchain to 1.97.1 (#8105) 2026-08-25 13:48:26 +00:00
Bart
0fdaf69e2c chore: Bump version to 3.4.0-b1 (#8102) 2026-08-24 20:41:58 +00:00
Timur Yalymov
9d41b1bd1c fix: Exempt vault and loan broker accounts from IOU authorization (#8013)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-24 16:23:43 +00:00
Jingchen
f137d71510 test: Split Invariants_test.cpp into per-topic files (#8077) 2026-08-24 16:17:33 +00:00
Bart
8bc6e81c5f fix: Reject an inner node claimed at leaf depth in verifyProofPath (#7940)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 16:17:12 +00:00
Ed Hennis
764cbe7c29 perf: Pause online delete if there any gaps in recent ledger history (#5531)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-08-24 14:16:03 +00:00
Timur Yalymov
520650081b fix: Remove credentials pinned to Vault, LoanBroker, and AMM pseudo-accounts (#7877)
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
2026-08-24 13:06:44 +00:00
Timur Yalymov
a097ccebae fix: Tighten destination checks on vault withdrawal (#7977)
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
2026-08-24 12:50:57 +00:00
Mayukha Vadari
fe4ccdf750 fix: Add assert for account_info flags (#7987) 2026-08-21 15:20:44 +00:00
Timur Yalymov
046d4dd4af fix: Reject vault deposits that move nothing from the depositor (#8014)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 12:30:17 +00:00
Ed Hennis
d27beef500 perf: Speed up addition time for drastically different exponents (#7825) 2026-08-20 19:40:42 +00:00
Mayukha Vadari
85512541ad refactor: Collapse transactions.macro settings into a TxSettings struct (#8001)
Co-authored-by: Timur Yalymov <36795566+tyalymov@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-08-20 19:25:27 +00:00
Gregory Tsipenyuk
3ab5288ef2 fix: Enforce MPT balance invariants under the latest cleanup amendment (#7889) 2026-08-20 19:05:28 +00:00
Kassaking7
d0dbf9163c fix: Prevent AMM auction slots from being acquired at zero cost when trading fee is zero (#7430) 2026-08-20 19:04:04 +00:00
Ayaz Salikhov
a1478fac39 docs: Fix yum installation baseurl (#8066) 2026-08-20 16:28:43 +00:00
Timur Yalymov
cc76708563 fix: Return specific and consistent errors from vault_info (#8015)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 16:05:18 +00:00
Sergey Kuznetsov
422e5245e4 ci: Save cargo cache only from develop by default (#8063) 2026-08-20 16:02:26 +00:00
Shawn Xie
e3ba569187 fix: Check credential for LoanBrokerCoverWithdraw and VaultWithdraw (#7107)
Co-authored-by: Peter Chen <ychen@ripple.com>
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-08-20 15:33:46 +00:00
Jingchen
959a186a0f build: Suppress MSVC linker warning LNK4099 (#8049) 2026-08-20 13:19:07 +00:00
dependabot[bot]
3b1c9e4320 chore: [DEPENDABOT] Bump cxx from 1.0.198 to 1.0.199 in /crates in the rust-dependencies group across 1 directory (#8050)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-20 13:12:14 +00:00
Ayaz Salikhov
a3a2c85c41 build: Use debian any distribution & signed (hosted) rpm repo (#8053) 2026-08-20 13:05:18 +00:00
Ayaz Salikhov
b1ac891210 ci: Do not cache cargo binaries (#8062) 2026-08-20 11:47:27 +00:00
Ayaz Salikhov
da57183e0c build: Compress the RPM payload with zstd (#8047) 2026-08-19 15:05:04 +00:00
Sergey Kuznetsov
f370289733 chore: Rust-C++ cmake and CI integration (#7034) 2026-08-19 14:30:06 +00:00
Vito Tumas
d1dc7a6ccf refactor: Extract invariant invocation into free checkInvariants runner (#7404)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-19 14:10:11 +00:00
Ayaz Salikhov
5639863715 docs: Rewrite the install guide (#8048) 2026-08-19 14:02:42 +00:00
Ayaz Salikhov
1be4868875 build: Sign RPM packages (#8046) 2026-08-19 13:46:11 +00:00
Timur Yalymov
368ff1afce fix: Exempt loan default from asset freeze (#7932)
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-08-19 13:43:40 +00:00
Vito Tumas
3adf2d40b5 fix: Reject VaultWithdraw fixed-share amounts that round to zero (#7950) 2026-08-19 13:09:38 +00:00
Ayaz Salikhov
a6983f8bf3 build: Use AlmaLinux for the RHEL packaging image (#8045) 2026-08-19 00:25:46 +00:00
Ayaz Salikhov
4113b105a5 build: Run nix macos builds in CI; deny nix store references (#8023) 2026-08-18 23:34:16 +00:00
Olek
7442ff2dec fix: Enable reserve checking on ending sponsorship (#8044) 2026-08-18 22:39:32 +00:00
Kassaking7
666e77b22c fix: Add ValidPermissionedDEX invariant track for fully consumed offer (#6736) 2026-08-18 21:08:02 +00:00
Vito Tumas
8c12de6c56 test: Split Vault_test into topical suites under src/test/app/vault/ (#8041) 2026-08-18 17:57:12 +00:00
Shawn Xie
b21fd86f6e fix: Fix assorted NFT and pDEX bugs (#7749) 2026-08-18 17:56:33 +00:00
Ayaz Salikhov
f5f47f1cf5 chore: Publish debian/rpm packages from GitHub directly (#8031) 2026-08-18 15:03:45 +00:00
Bart
ca39bff3c8 refactor: Add SHAMapNodeID::isPrefixOf (#7939)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-08-18 12:35:32 +00:00
Vito Tumas
dd0edc19a0 fix: Conserve funds correctly when LoanPay fee payee is below reserve (#7843) 2026-08-18 11:09:33 +00:00
Copilot
820ca5b332 refactor: Convert boost::beast::string_view to std::string_view (#6306)
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@ripple.com>
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
Co-authored-by: Mayukha Vadari <mvadari@gmail.com>
Co-authored-by: Timur Yalymov <36795566+tyalymov@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
2026-08-17 23:19:56 +00:00
Gregory Tsipenyuk
1b226c8b2e perf: Optimize MPT freeze checks to reduce redundant state reads (#7411)
Co-authored-by: Chenna Keshava B S <21219765+ckeshava@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-08-17 21:15:16 +00:00
Gregory Tsipenyuk
ca6121c5b3 feat: Enforce MPT CanTransfer on AMM LPTokens transfers (#7418) 2026-08-17 20:58:46 +00:00
Gregory Tsipenyuk
c49789086a fix: Extend locked-MPToken unauthorize check to fixCleanup3_4_0 (#8004) 2026-08-17 12:52:20 +00:00
Bart
5337d028a2 refactor: Use unsigned int for branch-related operations (#7938)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 10:07:14 +00:00
Ed Hennis
43d842926a refactor: Rewrite Transactor::operator() to early return (#8003) 2026-08-14 20:18:33 +00:00
Bart
2adffaef72 refactor: Remove support for protocol version 2.1 (#7432)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-14 15:36:47 +00:00
Ayaz Salikhov
bd87edfc75 test: Check versioned tools in check-tools & print nicely (#8030) 2026-08-14 14:07:55 +00:00
Mayukha Vadari
d34aa37b3c refactor: Use std::format instead of boost::format where it fits (#7996)
Co-authored-by: Timur Yalymov <36795566+tyalymov@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-08-14 13:49:08 +00:00
Ayaz Salikhov
a0074f83d3 build: Fix versioned tools for exec wrappers (#8027) 2026-08-14 10:06:49 +00:00
Ayaz Salikhov
028ccea7a1 build: Add curl to packaging images (#8024) 2026-08-13 17:48:35 +00:00
Pratik Mankawde
df85d43d8a test: Make Drop50 message drop deterministic in LedgerReplayer test (#7964)
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-08-13 16:54:58 +00:00
Mayukha Vadari
809d92f23a Merge remote-tracking branch 'upstream/ripple/smart-escrow' into xrplf/smart-contracts 2026-08-10 11:43:13 -04:00
Peng Wang
5ae09518b8 Merge branch 'ripple/se/fees' into ripple/smart-escrow
Conflict resolution:

- sfields.macro: both sides claimed INT32 code 2. sfRemainingOwnerCountDelta
  is already in develop, so it keeps code 2 and sfVMReturnCode moves to 3.
  This changes the Smart Escrow serialization, which is safe while the
  amendment is unactivated, but is a deliberate renumber rather than a
  mechanical merge.
- EscrowFinish.cpp: took the SeqProxy form of the keylet::escrow call and
  kept this branch's comment.

Follow-on fixes the merge required:

- Adapted two keylet::escrow calls in EscrowSmart_test.cpp to SeqProxy; they
  are only on this branch, so the earlier pass over the wasm code did not
  cover them.
- Updated two gas expectations that the trace host function refactor and the
  regenerated fixtures invalidated: the codecov allowance in Wasm_test.cpp is
  now 264'467 and sfGasUsed in EscrowSmart_test.cpp is now 48'433. Both are
  measured, not estimated.
- Disabled testKeyletHostFunctions. kAllKeyletsWasmHex was built against the
  old trace ABI and is rejected with temINVALID_BYTECODE. Regenerating it
  needs the all_keylets source ported to the current stdlib first, along with
  float_tests and float_0, which are stale for the same reason. See the TODO
  on the test.
2026-08-09 18:17:53 -04:00
Peng Wang
3ab800bf47 Merge branch 'ripple/se/wasmi-tests' into ripple/se/fees
Conflict resolution:

- features.macro: both sides added an amendment at the top of the list.
  Kept both, with fixCleanup3_4_0 above SmartEscrow.
- NetworkOPs.cpp: develop moved the ledgerClosed stream publisher out of
  pubLedger and into the new publishLedgerStreams helper, while this branch
  had added the Smart Escrow fee fields to the old inline version. Took the
  helper and moved the gas_limit / bytecode_size_limit / gas_price block into
  it, keeping the featureSmartEscrow guard.
2026-08-09 17:25:25 -04:00
Peng Wang
fe1436fb3e Merge branch 'ripple/wasmi-host-functions' into ripple/se/wasmi-tests
Conflict resolution:

- fixtures.cpp: took the regenerated blobs from ripple/wasmi-host-functions
  for the fixtures both branches carry (kAllHostFunctionsWasmHex,
  kAllKeyletsWasmHex, kCodecovTestsWasmHex); kept this branch's other 57
  fixtures unchanged.
- Wasm_test.cpp: took the gas expectations from ripple/wasmi-host-functions,
  which reflect the trace host function refactor, and kept the test blocks
  that only exist on this branch.

testFloat is commented out. kFloatTestsWasmHex and kFloat0Hex were built
against the old trace ABI, where the trace_* host functions returned i32
rather than void, so neither module instantiates any more. Regenerating them
needs the float_tests/ and float_0/ sources ported to the current stdlib
first; see the TODO in Wasm_test.cpp.
2026-08-09 17:05:54 -04:00
Peng Wang
abfa572370 fix: Adapt wasm keylet calls to SeqProxy API (#7890)
develop changed every sequence-based `keylet::` factory to take
`SeqProxy const&` instead of `std::uint32_t`, and removed the
two-argument `mptokenIssuance(seq, issuer)` overload. The wasm host
functions and their tests still passed raw sequences, so the branch
merged cleanly but did not compile.

Wrap the raw sequences at the call sites, matching the idiom develop
adopted in its own tests:

- `SeqProxy::rawSequence` for check, escrow, nftokenOffer, offer,
  payChannel, permissionedDomain and vault
- `SeqProxy::rawTicket` for ticket
- `keylet::mptokenIssuance(makeMptID(seq, issuer))` for the removed
  overload

No computed keylet changes: the factories only read `seq.value()`, and
the removed overload was itself defined as `mptokenIssuance(makeMptID(
seq, issuer))`.
2026-08-09 15:52:10 -04:00
Peng Wang
d8e44687bf Merge branch 'ripple/wasmi' into ripple/wasmi-host-functions 2026-08-09 14:50:30 -04:00
pwang200
8a3363752f trace host function refactor (#7920) 2026-08-09 14:41:56 -04:00
Peng Wang
226ec160bb Merge remote-tracking branch 'origin/develop' into ripple/wasmi 2026-08-09 14:34:11 -04:00
pwang200
ef438aec26 finish fn result refactor (#7947) 2026-08-08 23:13:33 -04:00
Mayukha Vadari
6cf743dad9 Merge remote-tracking branch 'upstream/ripple/smart-escrow' into xrplf/smart-contracts 2026-08-05 14:09:45 -04:00
Sergey Kuznetsov
52d2008797 Merge branch 'ripple/wasmi' into ripple/wasmi-host-functions 2026-08-04 15:24:35 +01:00
Sergey Kuznetsov
4d685d4bad Merge branch 'develop' into ripple/wasmi 2026-08-04 15:24:06 +01:00
Denis Angell
1e5e8ef018 feat: add PaymentChannelClawback for issuer clawback of channeled tokens 2026-08-03 12:26:45 -04:00
Denis Angell
1ac1d40d06 fix: satisfy clang-tidy include-cleaner and brace style in paychan 2026-08-03 12:26:20 -04:00
Denis Angell
fb10515cff Merge remote-tracking branch 'origin/develop' into token-paychan
# Conflicts:
#	include/xrpl/protocol/detail/features.macro
2026-08-03 11:38:43 -04:00
Denis Angell
829f5f2a5a Merge branch 'develop' into dangell7/escrow-paychan-refactor 2026-08-03 10:56:06 -04:00
Denis Angell
3c85a0180f refactor: address review nits 2026-08-02 16:05:25 -04:00
Denis Angell
096fa967da fix: repair bad develop merge resolutions 2026-08-02 16:05:22 -04:00
Denis Angell
82ede27f10 style: construct unlock helper locals after early returns 2026-08-02 15:56:13 -04:00
Denis Angell
866afeee0c refactor: extract escrow lock helpers and paychan test helpers 2026-07-27 17:23:31 -07:00
Mayukha Vadari
75fac65e27 change definitions config 2026-07-27 12:21:08 -04:00
Mayukha Vadari
ecae6b6346 Merge pull request #7866 from XRPLF/mvadari/smart-escrow-merge-july
chore: Update `ripple/smart-escrow` branch from base
2026-07-27 09:12:19 -04:00
Mayukha Vadari
6f4fe178dd fix tests 2026-07-24 19:29:26 -04:00
Mayukha Vadari
083986ab82 fix clang-tidy issues 2026-07-24 14:16:36 -04:00
Mayukha Vadari
c145201538 fix tests 2026-07-24 14:15:39 -04:00
Mayukha Vadari
4fbbd6ff59 fix build 2026-07-24 12:03:43 -04:00
Mayukha Vadari
39c95fee3b Merge branch 'ripple/se/fees' of https://github.com/XRPLF/rippled into ripple/smart-escrow 2026-07-24 11:23:01 -04:00
Mayukha Vadari
db6fe77959 Merge pull request #7857 from XRPLF/mvadari/se-fees-update-july
chore: Update `ripple/se/fees` branch from its base
2026-07-24 10:11:38 -04:00
Mayukha Vadari
be58ec0cd5 fix build 2026-07-23 17:04:05 -04:00
Mayukha Vadari
4073838f66 Merge branch 'ripple/se/wasmi-tests' of https://github.com/XRPLF/rippled into ripple/se/fees 2026-07-23 16:40:44 -04:00
Mayukha Vadari
e227e2ce8b Merge pull request #7855 from XRPLF/mvadari/wasmi-tests-update-july
chore: Update `ripple/se/wasmi-tests` to the latest
2026-07-23 16:34:13 -04:00
Mayukha Vadari
383a2f8819 comment out broken tests, leave todo to fix 2026-07-23 14:09:44 -04:00
Mayukha Vadari
e64703b151 fix most tests 2026-07-23 13:54:46 -04:00
Mayukha Vadari
c91640e3ac fix build 2026-07-23 12:37:46 -04:00
Mayukha Vadari
0ceee3a013 Merge branch 'ripple/wasmi-host-functions' of https://github.com/XRPLF/rippled into ripple/se/wasmi-tests 2026-07-23 12:35:51 -04:00
Mayukha Vadari
974b17f427 Merge branch 'ripple/wasmi' into ripple/wasmi-host-functions 2026-07-23 12:29:03 -04:00
Mayukha Vadari
91de196312 Merge pull request #7834 from XRPLF/ripple/se/hf-merge-july
chore: Merge in from `ripple/wasmi`
2026-07-23 12:28:38 -04:00
Mayukha Vadari
ac71553abe Merge pull request #7851 from kuznetsss/Update_hf-merge-july
chore: Update hf merge july
2026-07-23 11:30:09 -04:00
Mayukha Vadari
9a8ec56d42 Merge branch 'develop' into ripple/wasmi 2026-07-23 11:29:49 -04:00
Sergey Kuznetsov
cb6dad0bc4 chore: Fix clang-tidy issues 2026-07-23 14:10:40 +01:00
Sergey Kuznetsov
d54ca4cd3b Merge develop 2026-07-23 13:15:00 +01:00
Mayukha Vadari
5a0269aca7 fix test 2026-07-22 18:37:10 -04:00
Mayukha Vadari
0774ca32a9 fix build 2026-07-22 18:05:56 -04:00
Mayukha Vadari
8feb75011e Merge remote-tracking branch 'upstream/ripple/wasmi-host-functions' into ripple/se/hf-merge-july 2026-07-22 16:17:14 -04:00
Mayukha Vadari
088c5b3b03 Merge remote-tracking branch 'upstream/ripple/wasmi' into ripple/se/hf-merge-july 2026-07-22 16:12:12 -04:00
Mayukha Vadari
1c4abe8c5e refactor: Remove WasmNumber class (#7833) 2026-07-22 15:56:33 -04:00
Mayukha Vadari
91a5747bf9 Merge branch 'ripple/wasmi-host-functions' into ripple/se/hf-merge-july 2026-07-21 15:16:33 -04:00
Mayukha Vadari
bc892f0bd3 feat: Change function name from finish to escrow_finish (#7840) 2026-07-21 15:12:36 -04:00
Sergey Kuznetsov
8950530b04 Merge branch 'develop' into ripple/wasmi 2026-07-21 12:39:31 +01:00
Mayukha Vadari
5cbebf3c58 fix clang-tidy issues 2026-07-20 18:23:10 -04:00
Mayukha Vadari
c634c75aee fix build issues 2026-07-20 18:07:42 -04:00
Mayukha Vadari
9801c23bad Merge branch 'ripple/wasmi' of https://github.com/XRPLF/rippled into ripple/wasmi-host-functions 2026-07-20 17:38:18 -04:00
Mayukha Vadari
f6472347e9 Merge branch 'develop' into ripple/wasmi 2026-07-20 17:33:13 -04:00
Rithvik Reddygari
a41889df31 refactor: SField and TER code renames (#7797) 2026-07-20 12:29:39 -04:00
dangell8
1ced7dc8f3 Merge branch 'develop' into token-paychan
Includes post-merge compile fixes (build-verified).
2026-07-17 15:02:03 +00:00
Denis Angell
df1458a136 test: expand token paychan transactor phase coverage 2026-07-13 19:25:43 -04:00
Denis Angell
cdd5ebf4c1 fix: validate paychan asset match in preclaim with tecWRONG_ASSET 2026-07-13 16:33:49 -04:00
Denis Angell
1a9a11fc31 style: remove includes flagged by misc-include-cleaner 2026-07-13 15:28:42 -04:00
Denis Angell
a9430d4778 style: conform doxygen comments to check-doxygen-style hook 2026-07-13 15:11:48 -04:00
Denis Angell
fed5093488 fix: adapt token paychan to develop merge helpers and sponsor reserve 2026-07-13 14:59:54 -04:00
Denis Angell
6c74fc1a7d Merge branch 'develop' into token-paychan 2026-07-13 14:05:56 -04:00
dangell8
939f8b1a49 Merge develop into token-paychan 2026-07-11 04:27:08 +00:00
Denis Angell
1f8c462c42 feat: XLS-93d Token-Enabled Payment Channels 2026-07-10 12:14:12 -04:00
Denis Angell
47df026dcc refactor: Move escrow lock/unlock helpers to EscrowHelpers.h 2026-07-10 11:55:13 -04:00
Rithvik Reddygari
2e48bb4b7f refactor: Rename sfield names, sfExtensionComputeLimit -> sfGasLimit, sfExtensionSizeLimit -> sfBytecodeSizeLimit (#7708) 2026-07-08 16:26:58 -04:00
Sergey Kuznetsov
9e427ae3ba Merge develop 2026-07-08 14:24:21 +01:00
pwang200
8022fc33cf host function error path refactor (#7639) 2026-07-02 13:35:46 -04:00
Olek
9767d86de4 Memory transfer limit (#7000)
Count bytes copied across the boundaries (Wasm VM <-> Hostfunctions) and return error if limit reached (1 mb default)
2026-06-17 12:45:01 -04:00
Mayukha Vadari
ca2d999618 refactor: rename host functions (#7338)
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-06-12 15:53:12 -04:00
Mayukha Vadari
4a01fe5aa6 Merge branch 'ripple/se/wasmi-tests' into ripple/se/fees 2026-06-09 17:11:35 -04:00
Mayukha Vadari
f60a9f1c64 Revert "remove wasm engine tests"
This reverts commit 5ee903befc.
2026-06-09 17:10:13 -04:00
Mayukha Vadari
5ee903befc remove wasm engine tests 2026-06-09 17:09:45 -04:00
Mayukha Vadari
68f0dcae53 feat: Add fee vote maxes (#7346)
This PR adds hard-cap maxes for the size and compute limits, currently set at twice the defaults.
2026-06-04 16:25:52 -04:00
Olek
d582ae7990 HF one entry point (#7393)
Add one entry point for all HF for centralized exceptions handling, gas calculation and general checks.
Add exception handling for HF
Add FieldLocator object
Switch pointers to references for HF and runtime
Max size for parameters and sfData field is 1 kb now
Fix Allhf unittest, to provide correct locator
2026-06-03 21:53:12 -04:00
Olek
0dbe51c740 Cleanup and some refactoring (#7383) 2026-06-02 21:15:58 -04:00
Olek
63fff4b518 Fix HF tests (#7365) 2026-05-29 17:49:03 -04:00
Mayukha Vadari
d3550fac60 Merge pull request #7303 from XRPLF/mvadari/se-escrow-update
chore: Update branch from develop
2026-05-27 14:12:19 -04:00
Mayukha Vadari
10ef15fff1 fix clang-tidy 2026-05-27 10:08:52 -04:00
Mayukha Vadari
2307cfdc5a fix clang-tidy 2026-05-26 20:09:46 -04:00
Mayukha Vadari
3b328cfc45 fix broken builds 2026-05-26 18:53:18 -04:00
Mayukha Vadari
e20b2430ba update gas amounts 2026-05-26 18:29:28 -04:00
Mayukha Vadari
99072fbddf one more 2026-05-26 17:59:03 -04:00
Mayukha Vadari
059cefa35a fix typos 2026-05-26 17:58:38 -04:00
Mayukha Vadari
a2205190a6 fix build 2026-05-26 17:57:28 -04:00
Mayukha Vadari
4c657bc92e fix build 2026-05-20 17:06:43 -04:00
Mayukha Vadari
ac481a0bd7 fix clang-tidy 2026-05-20 16:47:52 -04:00
Mayukha Vadari
7eacd9d735 Merge remote-tracking branch 'upstream/ripple/se/fees' into mvadari/se-escrow-update 2026-05-20 16:43:57 -04:00
Mayukha Vadari
1f9675d22f Merge pull request #7301 from XRPLF/ripple/se/fees-fix-tidy
chore: Update branch from `develop`
2026-05-20 16:36:42 -04:00
Mayukha Vadari
029fa435ee fix issues 2026-05-20 14:21:56 -04:00
Mayukha Vadari
c92ca426bf fix clang-tidy 2026-05-20 14:13:53 -04:00
Mayukha Vadari
ff896b226a fix more build issues 2026-05-20 14:10:38 -04:00
Mayukha Vadari
3c53c94e7a Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees-fix-tidy 2026-05-20 14:02:17 -04:00
Mayukha Vadari
d85bf722ea fix: Fix build issues post-clang-tidy changes (#7298) 2026-05-20 13:44:18 -04:00
Mayukha Vadari
b664989cfb fix clang-tidy issues 2026-05-19 15:11:55 -04:00
Mayukha Vadari
e77934302a Merge branch 'ripple/wasmi' of https://github.com/XRPLF/rippled into ripple/wasmi-host-functions 2026-05-19 15:10:21 -04:00
Mayukha Vadari
ef7aeca6bf Merge branch 'develop' into ripple/wasmi 2026-05-18 18:25:09 -04:00
Mayukha Vadari
eec1d29b92 Merge branch 'develop' into ripple/wasmi 2026-05-15 11:36:56 -04:00
pwang200
971ba2281e clarify XLS-0102 host function stability rule (#7146) 2026-05-14 20:18:05 -04:00
pwang200
90357eeae1 bump get_nft host function cost from 1000 to 5000 (#7200) 2026-05-14 18:53:29 -04:00
Olek
597202a6f0 Refactoring float hostfunctions (#7053) 2026-05-07 12:33:22 -04:00
pwang200
1600b3e7f3 ai review nits fixes of host functions (#6963) 2026-04-30 13:56:55 -04:00
Mayukha Vadari
d411448739 remove unused fields 2026-04-23 17:32:52 -04:00
Mayukha Vadari
ecee732187 Merge branch 'develop' into ripple/wasmi 2026-04-22 17:22:28 -04:00
Olek
ce2586c039 Review fixes (#6512) 2026-04-20 14:03:39 -04:00
Mayukha Vadari
36fb84926e Update src/test/app/FeeVote_test.cpp
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-04-14 13:00:18 -04:00
Mayukha Vadari
56decaf852 Update cfg/xrpld-example.cfg
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-04-13 17:08:07 -04:00
Mayukha Vadari
d562129e7c Merge branch 'ripple/se/fees' into ripple/smart-escrow 2026-04-13 17:01:46 -04:00
Mayukha Vadari
1d9fe9dbaf Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2026-04-13 17:01:20 -04:00
Denis Angell
e6eb6ccf6c fix merge error 2026-04-12 00:38:52 +02:00
Mayukha Vadari
5351d4f089 Fix STJson and multiple emitted transactions (#6724) 2026-04-12 00:21:56 +02:00
Olek
8cc2169939 test: Calling wrap functions from c++ side (#6699) 2026-04-09 18:48:58 -04:00
Mayukha Vadari
74beb5f80d Merge branch 'ripple/se/fees' of https://github.com/XRPLF/rippled into ripple/smart-escrow 2026-04-08 13:52:24 -04:00
Mayukha Vadari
a4dfdaf77a Merge branch 'ripple/wasmi-host-functions' of https://github.com/XRPLF/rippled into ripple/se/fees 2026-04-08 13:51:41 -04:00
Mayukha Vadari
826f613ad8 Merge branch 'ripple/wasmi' of https://github.com/XRPLF/rippled into ripple/wasmi-host-functions 2026-04-08 13:51:09 -04:00
Mayukha Vadari
1259c1d5ca Merge branch 'develop' of https://github.com/XRPLF/rippled into ripple/wasmi 2026-04-08 13:48:41 -04:00
Mayukha Vadari
4bae4d781f fix build 2026-04-08 11:43:21 -04:00
Mayukha Vadari
01a5e07830 Merge branch 'ripple/se/fees' of https://github.com/XRPLF/rippled into ripple/smart-escrow 2026-04-08 09:58:40 -04:00
Mayukha Vadari
34522bc668 Merge branch 'ripple/wasmi-host-functions' of https://github.com/XRPLF/rippled into ripple/se/fees 2026-04-08 09:58:24 -04:00
Olek
d2641d85bd New floats format, STAmount compatible (#6600) 2026-04-07 20:19:19 -04:00
Mayukha Vadari
75f66bd9fe fix build 2026-04-07 17:24:48 -04:00
Mayukha Vadari
7cd71cb659 Merge branch 'ripple/wasmi' into ripple/wasmi-host-functions 2026-04-07 16:03:02 -04:00
Mayukha Vadari
9917f96166 Merge remote-tracking branch 'upstream/develop' into ripple/wasmi 2026-04-07 16:02:56 -04:00
Mayukha Vadari
e1cc82587b Merge branch 'ripple/wasmi' of https://github.com/XRPLF/rippled into ripple/wasmi-host-functions 2026-04-07 16:02:32 -04:00
Pratik Mankawde
2cc9439fde fix: Handle WSClient write failure when server closes WebSocket (#6671)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 16:01:26 -04:00
Ayaz Salikhov
52af9582e2 ci: Change conditions for uploading artifacts in public/private/org repos (#6734) 2026-04-07 16:01:26 -04:00
Bart
46e88dc732 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 16:01:26 -04:00
Mayukha Vadari
bc24f2e211 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-07 16:01:26 -04:00
Mayukha Vadari
7a7c993b15 fix: Minor RPC fixes (#6730) 2026-04-07 16:01:26 -04:00
Zhiyuan Wang
9733ca8f91 fix: Prevent deletion of MPTokens with active escrow (#6635)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-04-07 16:01:26 -04:00
Vito Tumas
18d5e3e226 fix: Clamp VaultClawback to assetsAvailable for zero-amount clawback (#6646) 2026-04-07 16:01:25 -04:00
Vito Tumas
b30b4e1d65 fix: Add assorted Lending Protocol fixes (#6678)
Co-authored-by: Shawn Xie <35279399+shawnxie999@users.noreply.github.com>
2026-04-07 16:01:25 -04:00
Mayukha Vadari
d435893602 fix: Change variable signedness and correctly handle std::optional (#6657) 2026-04-07 16:01:25 -04:00
Olek
00b0cf50f6 Update wasmi to 1.0.9 (#6727) 2026-04-07 15:58:29 -04:00
Denis Angell
42cbecb9e4 feature
Co-authored-by: Mayukha Vadari <mvadari@gmail.com>
2026-04-06 10:42:02 -04:00
Mayukha Vadari
fe2e5ce649 fix clang-tidy issues 2026-04-03 12:33:14 -04:00
Mayukha Vadari
6afa51142d Merge branch 'ripple/se/fees' of https://github.com/XRPLF/rippled into ripple/smart-escrow 2026-04-03 11:06:16 -04:00
Mayukha Vadari
22054a573d Merge branch 'ripple/wasmi-host-functions' of https://github.com/XRPLF/rippled into ripple/se/fees 2026-04-03 09:57:23 -04:00
Mayukha Vadari
7ef256499c Merge branch 'ripple/wasmi' of https://github.com/XRPLF/rippled into wasmi-host-functions 2026-04-03 09:57:07 -04:00
Mayukha Vadari
1338062be7 Merge branch 'develop' of https://github.com/XRPLF/rippled into ripple/wasmi 2026-04-03 09:56:55 -04:00
Mayukha Vadari
4fc1778ec8 fix clang-tidy issues 2026-04-03 09:56:42 -04:00
Oleksandr
65322d9e78 fix Clang-tidy 2026-04-02 21:33:43 -04:00
Mayukha Vadari
0acfa1c4f2 fix merge issues 2026-04-02 19:22:52 -04:00
Mayukha Vadari
309fdfc3f2 Merge branch 'ripple/se/fees' of https://github.com/XRPLF/rippled into ripple/smart-escrow 2026-04-02 19:08:08 -04:00
Mayukha Vadari
63bd5fc4ee fix clang-tidy issues 2026-04-02 19:07:10 -04:00
Mayukha Vadari
82e7f7eeec Merge branch 'ripple/wasmi-host-functions' of https://github.com/XRPLF/rippled into ripple/se/fees 2026-04-02 19:06:00 -04:00
Mayukha Vadari
c5598a4284 fix clang-tidy issues 2026-04-02 19:05:34 -04:00
Mayukha Vadari
63d09f9c51 Merge branch 'ripple/wasmi-host-functions' of https://github.com/XRPLF/rippled into ripple/se/fees 2026-04-02 19:04:34 -04:00
Mayukha Vadari
0deb6bcadf fix build 2026-04-02 18:39:14 -04:00
Mayukha Vadari
d606f88e84 Merge branch 'ripple/wasmi-host-functions' of https://github.com/XRPLF/rippled into ripple/se/fees 2026-04-02 18:12:30 -04:00
Mayukha Vadari
9b013b559b Merge branch 'ripple/wasmi' of https://github.com/XRPLF/rippled into wasmi-host-functions 2026-04-02 17:54:32 -04:00
Mayukha Vadari
1d4a3c00b8 Merge branch 'develop' of https://github.com/XRPLF/rippled into ripple/wasmi 2026-04-02 17:53:53 -04:00
Mayukha Vadari
4b34102e8e test: Use proper length limits in codecov_tests (#6626) 2026-03-25 09:10:12 -07:00
Olek
d006433579 Base divison of large fixtures (#6637) 2026-03-25 09:42:33 -04:00
Mayukha Vadari
a7ab8ee923 clang-tidy fixes 2026-03-24 10:22:01 -07:00
Mayukha Vadari
e0073a4402 Merge branch 'ripple/wasmi' into ripple/wasmi-host-functions 2026-03-24 10:20:43 -07:00
Mayukha Vadari
2930ef217f Merge remote-tracking branch 'upstream/develop' into ripple/wasmi 2026-03-24 10:20:38 -07:00
Mayukha Vadari
9dbb301699 more clang-tidy fixes 2026-03-24 10:20:06 -07:00
Mayukha Vadari
531e8b6ebd fix clang-tidy 2026-03-24 09:46:01 -07:00
Mayukha Vadari
90397e1a52 more build fixes 2026-03-24 09:41:08 -07:00
Mayukha Vadari
888ca2e6d9 fix build 2026-03-24 09:29:05 -07:00
Mayukha Vadari
f8a149c675 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2026-03-24 09:10:37 -07:00
Mayukha Vadari
51458a92e2 Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2026-03-24 08:49:18 -07:00
Mayukha Vadari
b6514b680f Merge branch 'ripple/wasmi' into ripple/wasmi-host-functions 2026-03-24 08:47:12 -07:00
Mayukha Vadari
913e4b919e Merge remote-tracking branch 'upstream/develop' into ripple/wasmi 2026-03-24 08:41:12 -07:00
Olek
196e6a1b27 Clang-format fixtures.cpp (#6610) 2026-03-20 14:26:26 -04:00
Olek
27468ddbcf Add import / export sections test (#6497) 2026-03-19 12:46:58 -04:00
Mayukha Vadari
bce5d91e45 Merge branch 'develop' into ripple/wasmi 2026-03-12 14:37:01 -04:00
Olek
780380da7e Modularization fixes (#6488) 2026-03-10 11:37:12 -04:00
Mayukha Vadari
654338fa66 Merge branch 'develop' into ripple/wasmi 2026-03-06 16:27:50 -04:00
Mayukha Vadari
fdfdf4fceb fix pre-commit 2026-03-05 14:49:07 -04:00
Mayukha Vadari
a76bd834b6 Merge remote-tracking branch 'upstream/ripple/se/fees' into ripple/smart-escrow [WIP, broken] 2026-03-05 14:45:30 -04:00
Mayukha Vadari
864d88a3c2 Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2026-03-05 13:48:44 -04:00
Mayukha Vadari
9c25d18851 Merge branch 'ripple/wasmi' into ripple/wasmi-host-functions 2026-03-05 13:48:33 -04:00
Mayukha Vadari
3a825a41e1 Merge branch 'develop' into ripple/wasmi 2026-03-05 13:48:16 -04:00
Jingchen
a9ebf786c6 Modularise wasm (#6441)
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2026-03-04 20:21:51 +00:00
Olek
5afe8cc321 Fix clang tidy (#6463)
* Fix clang tidy

* Add exponent overflow test
2026-03-04 11:30:33 -05:00
Mayukha Vadari
bc5ec3c962 assorted fixes (#6376) 2026-03-04 09:30:09 -04:00
Mayukha Vadari
7004d216ed Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2026-03-03 11:19:02 -04:00
Mayukha Vadari
1775251e90 Merge branch 'ripple/wasmi' into ripple/wasmi-host-functions 2026-03-03 11:18:41 -04:00
Mayukha Vadari
61bcb7621f Merge branch 'develop' into ripple/wasmi 2026-03-03 11:18:26 -04:00
Mayukha Vadari
a3f71b1774 Merge branch 'develop' into ripple/wasmi 2026-03-02 17:06:17 -05:00
Mayukha Vadari
4df7d1a4bb rename variable 2026-03-02 16:48:02 -04:00
Mayukha Vadari
50a74b899d add defensive check for sfData length (#6449) 2026-03-02 14:47:47 -05:00
Mayukha Vadari
00eeab6d44 Merge branch 'wasmi-host-functions' into ripple/se/fees 2026-02-27 16:50:13 -05:00
Mayukha Vadari
125df7a425 Merge remote-tracking branch 'upstream/ripple/wasmi' into wasmi-host-functions 2026-02-27 16:46:43 -05:00
Mayukha Vadari
b08bcf5d21 Merge branch 'develop' into ripple/wasmi 2026-02-27 16:41:44 -05:00
Mayukha Vadari
dc413aef0c Merge branch 'ripple/wasmi' into ripple/wasmi-host-functions 2026-02-27 16:28:34 -05:00
Mayukha Vadari
77dfd56ace Merge branch 'develop' into ripple/wasmi 2026-02-27 13:49:25 -05:00
Olek
953b9a3500 Disable reusing wasm module (#6364)
* Remove ability to re-use wasm module

* Check that HFS object is always new

* Fix clang format

* Remove perf tests

* temp build fix

* Fix merge
2026-02-26 15:30:46 -05:00
Olek
1d9ec84350 Test invalid opcodes (#6392) 2026-02-26 09:59:30 -05:00
Olek
0392846a17 UT for wasm parameters (#6413) 2026-02-25 11:49:27 -05:00
Mayukha Vadari
5148098079 Merge branch 'wasmi-host-functions' into ripple/se/fees 2026-02-18 13:21:53 -05:00
Mayukha Vadari
1b4a564369 fix build issues 2026-02-18 13:20:29 -05:00
Mayukha Vadari
fd524c4be9 fix pre-commit 2026-02-18 12:41:56 -05:00
Mayukha Vadari
495dda7f58 Merge branch 'ripple/wasmi' into ripple/wasmi-host-functions 2026-02-18 12:36:07 -05:00
Mayukha Vadari
9c3c0280b1 Merge branch 'develop' into ripple/wasmi 2026-02-18 12:35:51 -05:00
Mayukha Vadari
f73d8a6cf2 clean up some hf code (#6354)
* clean up some hf code

* fix comments

* fix ubsan

* Revert "fix ubsan"
2026-02-13 11:27:50 -05:00
Mayukha Vadari
4fe508cb92 fix comments 2026-02-12 17:48:50 -05:00
Olek
6728ab52b7 Add tests for wasm functions with many parameters (#6343)
* Add functions with many parameters

* Add 10k locals function

* Module with  5k functions

* fix typo

Co-authored-by: Mayukha Vadari <mvadari@gmail.com>

---------

Co-authored-by: Mayukha Vadari <mvadari@gmail.com>
2026-02-10 18:10:33 -05:00
Mayukha Vadari
446ad36cbb Merge branch 'ripple/se/fees' into ripple/smart-escrow 2026-02-10 17:47:32 -05:00
Mayukha Vadari
eb2d44d442 Merge branch 'wasmi-host-functions' into ripple/se/fees 2026-02-10 17:44:52 -05:00
Mayukha Vadari
77673663ca fix cspell issues in tests (#6348) 2026-02-10 17:42:41 -05:00
Mayukha Vadari
c1381f8ddd Merge branch 'ripple/wasmi' into wasmi-host-functions 2026-02-10 17:27:18 -05:00
Mayukha Vadari
bd16f7989d Merge branch 'develop' into ripple/wasmi 2026-02-10 17:26:33 -05:00
Mayukha Vadari
fd14054f17 update preflight checks (#6094) 2026-02-09 17:36:02 -05:00
Mayukha Vadari
65f9cf80c0 add readme to src/xrpld/app/wasm (#6340)
* add readme to src/xrpl/app/wasm

* important block

* respond to copilot
2026-02-09 12:13:39 -05:00
Mayukha Vadari
4318b2ebf7 fix build issue 2026-02-06 12:44:05 -05:00
Mayukha Vadari
e6ee492822 try again 2026-02-05 16:27:44 -05:00
Mayukha Vadari
d4510147d1 fix build issue 2026-02-05 14:42:14 -05:00
Mayukha Vadari
a9a94fbf1a fix tests 2026-02-05 13:24:50 -05:00
Mayukha Vadari
719ba392db Merge branch 'ripple/smart-escrow' into ripple/se/fees 2026-02-04 18:41:29 -05:00
Mayukha Vadari
cd46b5d999 Merge branch 'wasmi-host-functions' into ripple/se/fees 2026-02-04 18:41:19 -05:00
Mayukha Vadari
de55a5ebfc Merge branch 'ripple/wasmi' into wasmi-host-functions 2026-02-04 18:13:15 -05:00
Mayukha Vadari
2ec4a1114e Merge branch 'develop' into ripple/wasmi 2026-02-04 18:13:00 -05:00
Mayukha Vadari
f01ac563a9 Merge remote-tracking branch 'upstream/ripple/se/fees' into ripple/smart-escrow 2026-02-04 18:07:12 -05:00
Mayukha Vadari
13707dda05 Merge remote-tracking branch 'upstream/ripple/wasmi-host-functions' into ripple/se/fees 2026-02-04 17:13:50 -05:00
Olek
ba03a8a9d2 Fix negation of int64_t (#6296) 2026-02-03 17:43:54 -05:00
Mayukha Vadari
7c8279ec83 use buffers for uint32 WASM params (#6291) 2026-02-03 16:08:46 -05:00
Mayukha Vadari
a1844086d7 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2026-02-03 15:32:21 -05:00
Mayukha Vadari
f625fb993a Merge branch 'wasmi-host-functions' into ripple/se/fees 2026-02-03 15:19:36 -05:00
Mayukha Vadari
0418ffb26a Merge branch 'ripple/wasmi' into wasmi-host-functions 2026-02-03 14:52:16 -05:00
Mayukha Vadari
b2627039f6 Merge branch 'develop' into ripple/wasmi 2026-02-03 14:51:59 -05:00
Mayukha Vadari
8f97ec3bde Merge branch 'ripple/wasmi' into wasmi-host-functions 2026-01-29 13:54:30 -05:00
Mayukha Vadari
e85e7b1b1a Merge branch 'develop' into ripple/wasmi 2026-01-29 13:53:55 -05:00
Mayukha Vadari
ac173b6827 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2026-01-28 17:14:13 -05:00
Mayukha Vadari
69c61b2235 fix merge issues 2026-01-28 16:52:27 -05:00
Mayukha Vadari
6ae0e860ff Merge remote-tracking branch 'upstream/ripple/wasmi-host-functions' into ripple/se/fees 2026-01-28 16:39:44 -05:00
Mayukha Vadari
c077e7f073 Merge commit '4eb34f3' into ripple/se/fees 2026-01-28 16:39:06 -05:00
Mayukha Vadari
803a344c65 fix clang-format 2026-01-28 16:35:02 -05:00
Mayukha Vadari
4eb34f381a Merge branch 'ripple/wasmi' into wasmi-host-functions 2026-01-28 15:56:40 -05:00
Mayukha Vadari
72fffb6e51 Merge branch 'develop' into ripple/wasmi 2026-01-28 15:56:18 -05:00
Mayukha Vadari
f7ee580f01 Merge commit '5f638f55536def0d88b970d1018a465a238e55f4' into ripple/wasmi 2026-01-28 15:56:11 -05:00
Mayukha Vadari
122d405750 Merge commit '92046785d1fea5f9efe5a770d636792ea6cab78b' into ripple/wasmi 2026-01-28 15:56:04 -05:00
Olek
c1c1b4ea67 Reject non-canonical binaries (#6277)
* Reject non-canonical binaries

* Review fixes

* Cleanup Number2 class

* Use enum instead of 0
2026-01-27 16:30:51 -05:00
Mayukha Vadari
977caea0a5 Merge branch 'ripple/wasmi' into ripple/wasmi-host-functions 2026-01-27 13:26:55 -05:00
Mayukha Vadari
d7ed6d6512 Merge branch 'develop' into ripple/wasmi 2026-01-27 13:26:39 -05:00
Olek
f1f2e2629f Fix for Big-Endian machines (#6245) 2026-01-27 13:05:54 -05:00
Olek
917c610f96 Ensure request size less than int limit (#6239)
* Ensure request size less than int limit

* Move size check to wasmParams function
2026-01-27 12:37:47 -05:00
Mayukha Vadari
317e533d81 clean up Wasm_test.cpp more (#6278) 2026-01-26 15:21:15 -05:00
Olek
4160677878 Switch to series expansion method for ln() (#6268)
* Switch to series expansion method for ln()
Add float lg() tests to Number tests;
* Rename lg -> log10
* Add check for 0 to log10()
2026-01-26 14:04:03 -05:00
Mayukha Vadari
430696682d Merge remote-tracking branch 'upstream/ripple/se/fees' into ripple/smart-escrow 2026-01-26 09:43:14 -05:00
Mayukha Vadari
4621e4eda3 Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2026-01-26 09:29:34 -05:00
Olek
df98db1452 Check wasm return type (#6240)
* Check wasm return type

* Add more tests
2026-01-23 16:12:14 -05:00
Mayukha Vadari
981ac7abf4 simplify fee code (#6249)
* simplify lambda

* clean up fee code

* fix tests, better error handling

* simplify source_location
2026-01-23 15:14:24 -05:00
Mayukha Vadari
57d2a91ad5 test large WASM modules (#6206)
* [WIP] first attempt at large wasm test

* finish large WASM modules

* fix windows build (hopefully)

* Apply suggestions from code review

* respond to comments

* add file and line to fail

* clean up test

* add source_location

* simplify

* fix windows
2026-01-23 14:45:09 -05:00
Mayukha Vadari
673476ef1b Merge branch 'ripple/wasmi' into ripple/wasmi-host-functions 2026-01-23 13:13:26 -05:00
Mayukha Vadari
8bc6f9cd70 Merge branch 'develop' into ripple/wasmi 2026-01-23 13:13:11 -05:00
Mayukha Vadari
ba5debfecd update return calculation (#6250) 2026-01-22 17:01:56 -05:00
Mayukha Vadari
f4a27c9b6d minor refactor of Wasm_test (#6229) 2026-01-21 18:05:48 -05:00
Olek
fd1cb318e3 Check that max parameters length is multiple of sizeof(int32) (#6253) 2026-01-21 17:22:47 -05:00
Olek
94b35a234e Make hostfunctions object shared (#6252) 2026-01-21 15:27:06 -05:00
Mayukha Vadari
b5d0078927 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2026-01-21 13:26:37 -05:00
Mayukha Vadari
43c80edaf4 Merge branch 'wasmi-host-functions' into ripple/se/fees 2026-01-21 12:58:24 -05:00
Mayukha Vadari
8c3544a58c Merge branch 'ripple/wasmi' into wasmi-host-functions 2026-01-21 12:57:47 -05:00
Mayukha Vadari
ed5139d4e3 Merge branch 'develop' into ripple/wasmi 2026-01-21 12:57:29 -05:00
Olek
42494dd4cf Ensure lifetime of imports (#6230) 2026-01-21 12:43:12 -05:00
Mayukha Vadari
ce84cc8b44 improve trace hf code (#6190)
* adjust trace statements

* add helper function

* use lambda instead

* use same paradigm in TestHostFunctions

* oops
2026-01-15 20:50:55 -05:00
Mayukha Vadari
9a9a7aab01 Add Vector256 support to the locator (#6131)
* add Vector256 nesting/length support

* [WIP] add tests

* fix tests

* simplify with helper function

* oops typo

* remove static variable

* respond to comments

* STBaseOrUInt256->FieldValue

* oops

* add more tests for coverage

* respond to comments
2026-01-15 20:14:42 -05:00
Olek
209a1a6ffa Don't throw from hostfunctions stack (#6221) 2026-01-15 19:52:22 -05:00
Mayukha Vadari
9538e9b34c Merge remote-tracking branch 'upstream/ripple/se/fees' into ripple/smart-escrow 2026-01-15 14:34:54 -05:00
Mayukha Vadari
384b3608d7 Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2026-01-15 14:17:57 -05:00
Oleksandr
fc35a9f9c8 Fix usage of the Number class 2026-01-14 19:36:50 -05:00
Oleksandr
c5e50aa221 Fix merge issues 2026-01-14 14:46:35 -05:00
Mayukha Vadari
074b1f00d5 Merge branch 'ripple/wasmi' into wasmi-host-functions 2026-01-14 13:04:28 -05:00
Mayukha Vadari
7a9d245950 Merge branch 'develop' into ripple/wasmi 2026-01-14 13:01:35 -05:00
Mayukha Vadari
1809fe07f2 remove test file 2026-01-14 12:43:12 -05:00
Mayukha Vadari
409c67494a move helper functions to separate file (#6178)
* move helper functions to separate file

* break it up into sections, split out float helpers

* split impls into multiple cpp files

* namespace detail

* fix build issue

* fix tests

* clean up

* put float helpers into wasm_float namespace
2026-01-13 20:34:57 -05:00
pwang200
fb97f7b596 fix unit tests failed due to fuel changes (#6174)
* fix unit tests failed due to fuel changes

* fix tests

* fix tests

---------

Co-authored-by: Mayukha Vadari <mvadari@ripple.com>
2026-01-13 16:48:25 -05:00
Olek
c626b6403a Fix unaligned access (#6208) 2026-01-13 16:40:42 -05:00
Olek
81cbc91927 Fix traces (#6127)
* Fix traces
* More tests for codecov
* Review fixes
* trace float test
* Fix return value for traces
* Remove SuiteJournalSink2
* Add explicit severity
* Move logs to ApplyView
* Add check for output strings
* Merging fix
2026-01-13 16:38:48 -05:00
Mayukha Vadari
845c503ea6 Merge remote-tracking branch 'upstream/ripple/se/fees' into ripple/smart-escrow 2026-01-13 13:48:15 -05:00
Mayukha Vadari
e1513570df Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2026-01-13 13:46:50 -05:00
pwang200
1c812a6c4d disable Wasm features added in Wasmi 1.0, and fix unit test fuel cost due to Wasmi 1.0 fuel changes (#6173)
* disable 4 more wasm features

* unit tests for disabled Wasmi 1.0 features

* fix unit tests failed due to fuel changes

* rearrange wasm feature unit tests

* fix gas costs

* Update src/test/app/wasm_fixtures/wat/custom_page_sizes.wat

---------

Co-authored-by: Mayukha Vadari <mvadari@ripple.com>
2026-01-12 22:04:33 -05:00
Mayukha Vadari
0724927799 Merge branch 'ripple/wasmi' into ripple/wasmi-host-functions 2026-01-12 15:17:36 -05:00
Mayukha Vadari
ff39fa59d9 Merge remote-tracking branch 'upstream/ripple/se/fees' into ripple/smart-escrow 2026-01-12 14:12:04 -05:00
Olek
d83ec96848 Switch to wasmi v1.0.6 (#6204) 2026-01-12 13:36:02 -05:00
Mayukha Vadari
f0d0739528 Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2026-01-12 13:28:07 -05:00
Mayukha Vadari
375dd50b35 Merge branch 'ripple/wasmi' into ripple/wasmi-host-functions 2026-01-12 13:19:17 -05:00
Mayukha Vadari
419d53ec4c Merge branch 'develop' into ripple/wasmi 2026-01-12 13:10:58 -05:00
Mayukha Vadari
d4d70d5675 Merge branch 'develop' into ripple/wasmi 2026-01-12 12:27:48 -05:00
Olek
6ab15f8377 Add checks to allocate (#6185) 2026-01-09 14:49:09 -05:00
pwang200
91f3d51f3d fix start function loop 2026-01-09 11:38:54 -05:00
pwang200
9ed60b45f8 section corruption unit tests 2026-01-08 16:15:36 -05:00
pwang200
d5c53dcfd2 fix Uninitialized import entries lead to undefined behavior During WASM Instantiation 2026-01-08 16:14:49 -05:00
Mayukha Vadari
8015088340 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2026-01-08 11:46:18 -05:00
Mayukha Vadari
103379836a Merge branch 'wasmi-host-functions' into ripple/se/fees 2026-01-08 11:45:05 -05:00
Mayukha Vadari
e94321fb41 Merge branch 'ripple/wasmi' into wasmi-host-functions 2026-01-08 11:44:15 -05:00
Mayukha Vadari
bbc28b3b1c Merge branch 'develop' into ripple/wasmi 2026-01-08 11:42:28 -05:00
Mayukha Vadari
843e981c8a Merge remote-tracking branch 'upstream/ripple/wasmi' into wasmi-host-functions 2026-01-07 16:52:56 -05:00
Mayukha Vadari
5aab274b7a Merge branch 'develop' into ripple/wasmi 2026-01-07 16:52:10 -05:00
Mayukha Vadari
2c30e41191 use the develop hashes 2026-01-07 16:50:45 -05:00
Mayukha Vadari
8ea5106b0b Merge branch 'develop' into ripple/wasmi 2026-01-07 14:34:49 -05:00
Mayukha Vadari
f57f67a8ae infinite loop test (#6064) 2026-01-07 11:51:58 -05:00
Mayukha Vadari
61b2fe4f64 fix test 2026-01-06 17:58:22 -05:00
Mayukha Vadari
7ee964f514 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2026-01-06 17:22:42 -05:00
Mayukha Vadari
397bc8781e fix more merge issues 2026-01-06 14:27:46 -05:00
pwang200
a98269f049 a batch of memory, table, and trap tests (#6100)
wasm memory, table, and trap unit tests
2026-01-06 14:03:18 -05:00
Mayukha Vadari
8bb8c2e38b Merge remote-tracking branch 'upstream/ripple/wasmi-host-functions' into ripple/se/fees 2026-01-06 13:40:53 -05:00
Mayukha Vadari
b66bc47ca9 fix more merge issues 2026-01-06 13:30:30 -05:00
Mayukha Vadari
0e9c7458bb fix more merge issues 2026-01-05 18:53:14 -05:00
Mayukha Vadari
36ecd3b52b Merge remote-tracking branch 'upstream/ripple/wasmi-host-functions' into ripple/se/fees 2026-01-05 18:51:46 -05:00
Mayukha Vadari
1d89940653 merge fixes 2026-01-05 18:48:09 -05:00
Mayukha Vadari
1a1a6806ec Merge branch 'ripple/wasmi' into ripple/wasmi-host-functions 2026-01-05 18:44:41 -05:00
Mayukha Vadari
1977df9c2e Merge remote-tracking branch 'upstream/develop' into ripple/wasmi 2026-01-05 18:43:49 -05:00
Mayukha Vadari
6ffbef09c2 fix gas in test 2025-12-23 11:00:57 -08:00
Mayukha Vadari
e05f907788 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-12-22 17:02:12 -08:00
Mayukha Vadari
9d1f51b01a Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2025-12-22 17:01:34 -08:00
Mayukha Vadari
6c95548df5 Merge remote-tracking branch 'upstream/develop' into ripple/wasmi 2025-12-22 15:51:19 -08:00
Olek
69ab39d658 Fix potential memory leaks found by srlabs (#6145) 2025-12-18 14:13:48 -05:00
Mayukha Vadari
b9eb66eecc fix parameter index desynchronization (#6148) 2025-12-17 14:19:34 -08:00
Mayukha Vadari
e916416642 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-12-15 10:47:26 -08:00
Mayukha Vadari
827ecc6e3a Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2025-12-15 10:44:17 -08:00
Mayukha Vadari
6a54ed7f14 fix fee overflow issue in EscrowFinish (#6130) 2025-12-12 15:12:43 -08:00
Mayukha Vadari
881087dd3d Merge remote-tracking branch 'upstream/ripple/wasmi' into wasmi-host-functions 2025-12-08 14:29:47 -05:00
Mayukha Vadari
90e0bbd0fc Merge branch 'develop' into ripple/wasmi 2025-12-08 14:28:41 -05:00
Olek
b57df290de Use conan repo for wasmi lib (#6109)
* Use conan repo for wasmi lib
* Generate lockfile
2025-12-08 13:02:01 -05:00
Mayukha Vadari
8a403f1241 Merge branch 'develop' into ripple/wasmi 2025-12-05 14:32:48 -05:00
Olek
1e0741690d Fix sign cost (#6103) 2025-12-03 18:27:06 -05:00
Mayukha Vadari
6d2640871d Merge branch 'develop' into ripple/wasmi 2025-12-02 18:40:54 -05:00
Olek
c5d178f152 HF cost for smart escrow (#6097) 2025-12-02 13:12:15 -05:00
Mayukha Vadari
5a17940e2a Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-12-02 07:48:22 -05:00
Mayukha Vadari
27ac30208d Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2025-12-02 07:44:22 -05:00
pwang200
c145598ff9 add memory limit and disable float and other advanced instructions 2025-12-02 00:09:20 -05:00
Olek
50e5608d86 wasmi HF cost 2025-12-01 20:21:52 -05:00
Mayukha Vadari
abfcc4ef67 fix tests 2025-11-25 04:17:42 +05:30
Mayukha Vadari
e40a4df777 Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2025-11-25 03:49:06 +05:30
Mayukha Vadari
dba187f8c5 fix build issues 2025-11-25 03:42:38 +05:30
Mayukha Vadari
7a7b96107c Merge branch 'ripple/wasmi' into ripple/wasmi-host-functions 2025-11-25 03:42:05 +05:30
Mayukha Vadari
8f2f8d53b4 update gas amounts for wasmi 2025-11-25 03:32:01 +05:30
Mayukha Vadari
49acc61961 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-11-25 03:31:10 +05:30
Olek
500bb68831 Fix win build (#6076) 2025-11-24 16:56:23 -05:00
Mayukha Vadari
95d78a8600 Merge branch 'wasmi-host-functions' into ripple/se/fees 2025-11-25 03:26:19 +05:30
Mayukha Vadari
53eb0f60bc fix another build issue 2025-11-25 03:10:58 +05:30
Mayukha Vadari
41205ae928 Merge branch 'ripple/wasmi' into wasmi-host-functions 2025-11-25 03:01:51 +05:30
Mayukha Vadari
c33b0ae463 fix build issue 2025-11-25 02:58:57 +05:30
Mayukha Vadari
16087c9680 fix merge issue 2025-11-25 02:57:47 +05:30
Mayukha Vadari
56bc6d58f6 Merge branch 'ripple/wasmi' into wasmi-host-functions 2025-11-25 02:45:00 +05:30
Mayukha Vadari
ef5d335e09 update 2025-11-25 02:44:18 +05:30
Mayukha Vadari
25c3060fef remove conan.lock (temporary) 2025-11-25 02:40:57 +05:30
Mayukha Vadari
ce9f0b38a4 Merge branch 'develop' into ripple/wasmi 2025-11-25 02:33:47 +05:30
Mayukha Vadari
35f7cbf772 update 2025-11-25 02:31:51 +05:30
Mayukha Vadari
def7758a23 remove copyright stuff 2025-11-04 17:53:13 -05:00
Mayukha Vadari
58e5b4ad25 Merge remote-tracking branch 'upstream/ripple/se/fees' into ripple/smart-escrow 2025-11-04 17:52:17 -05:00
Mayukha Vadari
578413859c Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-11-04 17:52:00 -05:00
Mayukha Vadari
0db564d261 WASMI data 2025-11-04 15:57:07 -05:00
Mayukha Vadari
427b7ea104 run rename script 2025-11-04 15:29:08 -05:00
Mayukha Vadari
fa8aa49376 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-11-04 14:51:11 -05:00
Mayukha Vadari
3195eb16b2 Merge branch 'wamr-host-functions' into ripple/se/fees 2025-11-04 14:50:31 -05:00
Mayukha Vadari
7bf6878b4b fix imports 2025-11-04 14:49:45 -05:00
Mayukha Vadari
a891b49c67 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-11-04 14:24:51 -05:00
Mayukha Vadari
eed280d169 Merge branch 'wamr-host-functions' into ripple/se/fees 2025-11-04 13:37:09 -05:00
Mayukha Vadari
0bc1a115ff Merge branch 'wamr' into wamr-host-functions 2025-11-04 13:36:22 -05:00
Mayukha Vadari
334bcfa5ef Merge branch 'develop' into wamr 2025-11-04 13:36:01 -05:00
Mayukha Vadari
106dea4559 update fixtures to use the latest version of stdlib 2025-11-04 13:35:25 -05:00
Mayukha Vadari
3ffdcf8114 allow 0-value trace amounts 2025-11-04 13:19:40 -05:00
Olek
4021a7eb28 Wamr and HF security review fixes (#5965) 2025-10-31 10:34:31 -04:00
Ayaz Salikhov
0690fda0f1 Merge branch 'develop' into ripple/wamr 2025-10-30 14:12:15 +00:00
Mayukha Vadari
d0cc48c6d3 Update cmake/RippledCore.cmake
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2025-10-29 16:41:11 -04:00
Olek
d66e3c949e Chores: Sort package list (#5963) 2025-10-29 12:55:07 -04:00
Mayukha Vadari
7e2e10f02c Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-10-24 18:01:33 -04:00
Mayukha Vadari
aebec5378c Merge branch 'wamr-host-functions' into ripple/se/fees 2025-10-24 18:01:17 -04:00
Mayukha Vadari
0c65a386b5 fix tests 2025-10-24 18:01:01 -04:00
Mayukha Vadari
22ca691e75 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-10-24 17:14:54 -04:00
Mayukha Vadari
fc6ff69752 fix tests 2025-10-24 17:14:46 -04:00
Mayukha Vadari
079e251aca fix bug 2025-10-24 16:52:17 -04:00
Mayukha Vadari
67e2c1b563 Merge branch 'wamr-host-functions' into ripple/se/fees 2025-10-24 16:06:02 -04:00
Mayukha Vadari
29f5430881 fix bug 2025-10-24 16:05:38 -04:00
Mayukha Vadari
b6bd268be2 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-10-24 16:02:23 -04:00
Mayukha Vadari
209ee25c32 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-10-24 16:02:16 -04:00
Mayukha Vadari
101f285bcd return size from updateData 2025-10-24 16:01:45 -04:00
Mayukha Vadari
566b85b3d6 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-10-23 15:41:53 -04:00
Mayukha Vadari
af6beb1d7c fix ledger used for rules 2025-10-23 15:41:32 -04:00
Mayukha Vadari
7d22fe804d Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-10-23 15:38:46 -04:00
Mayukha Vadari
ce19c13059 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-10-23 15:38:37 -04:00
Mayukha Vadari
286dc6322b Merge branch 'ripple/wamr' into ripple/wamr-host-functions 2025-10-23 15:38:28 -04:00
Mayukha Vadari
c9346cd40d Merge branch 'develop' into ripple/wamr 2025-10-23 15:38:04 -04:00
Mayukha Vadari
9cfb7ac340 fix build issue 2025-10-20 17:20:35 -04:00
Mayukha Vadari
3a0e9aab4f Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-10-20 14:51:15 -04:00
Mayukha Vadari
43caa1ef29 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-10-20 11:53:56 -04:00
Mayukha Vadari
1c5683ec78 Merge branch 'ripple/wamr' into ripple/wamr-host-functions 2025-10-20 11:53:22 -04:00
Mayukha Vadari
9bee155d59 Merge branch 'develop' into ripple/wamr 2025-10-20 11:53:03 -04:00
Mayukha Vadari
f34b05f4de Merge branch 'ripple/wamr' into ripple/wamr-host-functions 2025-10-16 12:12:05 -04:00
Mayukha Vadari
97ce25f4ce Merge branch 'develop' into ripple/wamr 2025-10-16 12:11:55 -04:00
Mayukha Vadari
3b6cd22e32 fix 2025-10-14 18:10:11 -04:00
Mayukha Vadari
c9c35780d2 reduce diff more 2025-10-14 18:00:58 -04:00
Mayukha Vadari
17f401f374 reduce diff 2025-10-14 17:58:41 -04:00
Mayukha Vadari
c6c54b3282 resolve todos 2025-10-14 17:56:12 -04:00
Mayukha Vadari
91455b6860 respond to comments 2025-10-13 15:20:03 -04:00
Olek
9e14c14a26 Use xrplf conan repo for wamr (#5862) 2025-10-13 15:11:21 -04:00
Mayukha Vadari
f16f243c22 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-10-13 14:01:11 -04:00
Mayukha Vadari
fe601308e7 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-10-13 13:58:09 -04:00
Mayukha Vadari
c507880d8f Merge branch 'ripple/wamr' into ripple/wamr-host-functions 2025-10-13 13:57:22 -04:00
Mayukha Vadari
3f8328bbf8 Merge branch 'develop' into ripple/wamr 2025-10-13 13:55:07 -04:00
Mayukha Vadari
e41f6a71b7 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-10-09 17:13:13 -04:00
Mayukha Vadari
51f1be7f5b Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-10-09 17:10:52 -04:00
Mayukha Vadari
c10a5f9ef6 Merge branch 'ripple/wamr' into ripple/wamr-host-functions 2025-10-09 17:10:31 -04:00
Mayukha Vadari
3c141de695 Merge branch 'develop' into ripple/wamr 2025-10-09 16:52:25 -04:00
Mayukha Vadari
db263b696c Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-10-06 17:01:32 -04:00
Mayukha Vadari
f57b855d74 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-10-06 17:01:17 -04:00
Mayukha Vadari
da2b9455f2 fix: remove get_ledger_account_hash and get_ledger_tx_hash host functions (#5850)
* remove `get_ledger_account_hash` and `get_ledger_tx_hash`

* fix build+tests
2025-10-06 16:38:40 -04:00
Mayukha Vadari
86525d8583 test: add tests for fee voting (#5747) 2025-10-06 16:32:04 -04:00
Mayukha Vadari
c41e52f57a Move Smart Escrow tests to separate file (#5849) 2025-10-06 16:27:21 -04:00
Mayukha Vadari
55772a0d07 add sfData preflight checks + tests (#5839) 2025-10-02 17:50:43 -04:00
Mayukha Vadari
965a9e89ac Merge remote-tracking branch 'upstream/ripple/se/fees' into ripple/smart-escrow 2025-10-02 15:51:35 -04:00
Mayukha Vadari
51ee06429b Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-10-02 14:35:36 -04:00
Mayukha Vadari
cb622488c0 Merge branch 'ripple/wamr' into ripple/wamr-host-functions 2025-10-02 14:35:25 -04:00
Mayukha Vadari
32f971fec6 Merge branch 'develop' into ripple/wamr 2025-10-02 14:35:13 -04:00
Mayukha Vadari
ca85d09f02 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-09-30 14:43:24 -04:00
Mayukha Vadari
8dea76baa4 Merge branch 'ripple/wamr' into ripple/wamr-host-functions 2025-09-30 14:42:49 -04:00
Mayukha Vadari
299fbe04c4 Merge branch 'develop' into ripple/wamr 2025-09-30 14:42:24 -04:00
Mayukha Vadari
57fc1df7d7 switch from wasm32-unknown-unknown to wasm32v1-none (#5814) 2025-09-29 15:43:22 -04:00
Mayukha Vadari
8d266d3941 remove STInt64 (#5815) 2025-09-29 15:43:10 -04:00
Mayukha Vadari
a865b4da1c Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-09-26 17:10:10 -04:00
Mayukha Vadari
e59f5f3b01 fix tests 2025-09-26 17:09:53 -04:00
Mayukha Vadari
8729688feb Merge remote-tracking branch 'upstream/ripple/se/fees' into ripple/smart-escrow 2025-09-26 16:56:51 -04:00
Mayukha Vadari
c8b06e7de1 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-09-26 16:50:34 -04:00
Mayukha Vadari
eaba76f9e6 Merge branch 'ripple/wamr' into ripple/wamr-host-functions 2025-09-26 16:37:25 -04:00
Mayukha Vadari
cb702cc238 Merge branch 'develop' into ripple/wamr 2025-09-26 16:37:04 -04:00
Mayukha Vadari
f1f798bb85 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-09-26 15:52:22 -04:00
Mayukha Vadari
c3fd52c177 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-09-26 15:51:56 -04:00
Mayukha Vadari
b69b4a0a4a Merge branch 'ripple/wamr' into ripple/wamr-host-functions 2025-09-26 15:51:48 -04:00
Mayukha Vadari
50d6072a73 Merge branch 'develop' into ripple/wamr 2025-09-26 15:51:40 -04:00
Olek
d24cd50e61 Switch to own wamr fork (#5808) 2025-09-23 16:39:21 -04:00
Mayukha Vadari
85bff20ae5 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-09-23 10:22:30 -04:00
Mayukha Vadari
737fab5471 fix issues 2025-09-22 23:55:57 -04:00
Mayukha Vadari
e6592e93a9 Merge branch 'ripple/se/fees' into ripple/smart-escrow 2025-09-22 18:32:36 -04:00
Mayukha Vadari
5a6c4e8ae0 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-09-22 18:23:54 -04:00
Mayukha Vadari
9f5875158c Merge branch 'ripple/wamr' into ripple/wamr-host-functions 2025-09-22 18:23:45 -04:00
Mayukha Vadari
c3dc33c861 Merge branch 'develop' into ripple/wamr 2025-09-22 18:23:35 -04:00
Mayukha Vadari
7420f47658 SmartEscrow fee voting changes 2025-09-22 18:22:44 -04:00
Olek
6be8f2124c Latests HF perf test (#5789) 2025-09-18 15:51:39 -04:00
Mayukha Vadari
edfed06001 fix merge issues 2025-09-18 15:39:49 -04:00
Mayukha Vadari
1c646dba91 Merge remote-tracking branch 'upstream/ripple/wamr' into wamr-host-functions 2025-09-18 15:29:02 -04:00
Mayukha Vadari
6781068058 Merge branch 'develop' into ripple/wamr 2025-09-18 15:27:54 -04:00
Mayukha Vadari
cfe57c1dfe Merge branch 'ripple/wamr' into ripple/wamr-host-functions 2025-09-18 14:37:58 -04:00
Mayukha Vadari
c34d09a971 Merge branch 'develop' into ripple/wamr 2025-09-18 14:24:34 -04:00
Mayukha Vadari
ebd90c4742 chore: remove unneeded float stuff (#5729) 2025-09-11 18:41:24 -04:00
Mayukha Vadari
ba52d34828 test: improve codecov in HostFuncWrapper.cpp (#5730) 2025-09-11 18:09:08 -04:00
Mayukha Vadari
2f869b3cfc Merge branch 'develop' into ripple/smart-escrow 2025-09-11 16:41:14 -04:00
Mayukha Vadari
ffa21c27a7 fix test 2025-09-11 16:40:59 -04:00
Mayukha Vadari
1b6312afb3 rearrange files 2025-09-11 16:34:03 -04:00
Mayukha Vadari
bf32dc2e72 add fixtures files 2025-09-11 16:28:11 -04:00
Mayukha Vadari
a15d65f7a2 update tests 2025-09-11 16:20:33 -04:00
Mayukha Vadari
2de8488855 add temBAD_WASM 2025-09-11 16:02:17 -04:00
Mayukha Vadari
129aa4bfaa bring out IOUAmount.h 2025-09-11 13:18:42 -04:00
Mayukha Vadari
b1d70db63b limits 2025-09-10 15:05:06 -04:00
Mayukha Vadari
f03c3aafe4 misc host function files 2025-09-10 15:02:48 -04:00
Mayukha Vadari
51a9f106d1 CODEOWNERS 2025-09-10 14:59:09 -04:00
Mayukha Vadari
bfc048e3fe add tests 2025-09-10 14:57:23 -04:00
Mayukha Vadari
83418644f7 add host functions 2025-09-10 14:56:21 -04:00
Mayukha Vadari
dbc9dd5bfc Add WAMR integration code 2025-09-10 14:56:08 -04:00
Mayukha Vadari
5c480cf883 Merge branch 'develop' into ripple/smart-escrow 2025-09-10 14:51:45 -04:00
Mayukha Vadari
45ab15d4b5 add WAMR dependency 2025-09-10 14:40:48 -04:00
Mayukha Vadari
adc64e7866 Merge branch 'develop' into ripple/smart-escrow 2025-09-10 10:46:51 -04:00
Mayukha Vadari
4d4a1cfe82 Merge branch 'develop' into ripple/smart-escrow 2025-09-09 16:19:27 -04:00
Mayukha Vadari
f2c7da3705 Merge branch 'develop' into ripple/smart-escrow 2025-09-09 14:51:25 -04:00
Mayukha Vadari
3ab0a82cd3 Merge branch 'develop' into ripple/smart-escrow 2025-09-08 15:20:01 -04:00
Mayukha Vadari
a46d772147 fix build and tests (#5768)
* fix conan.lock

* add conan.lock to triggers

* update on-trigger.yml too

* fix tests

* roll back unrelated changes
2025-09-04 17:05:39 -04:00
Mayukha Vadari
f3c50318e8 Merge branch 'develop' into ripple/smart-escrow 2025-09-04 13:42:59 -04:00
Mayukha Vadari
e7aa924c0e Merge branch 'develop' into ripple/smart-escrow 2025-09-03 15:54:57 -04:00
Mayukha Vadari
5266f04970 chore: rollback unrelated changes (#5737) 2025-09-02 18:26:01 -04:00
Mayukha Vadari
db957cf191 Merge branch 'develop' into ripple/smart-escrow 2025-08-29 16:54:17 -04:00
Mayukha Vadari
8ac514363d get new fees and reserves working (#5714) 2025-08-29 10:58:52 -04:00
Mayukha Vadari
c2ea68cca4 Merge branch 'develop' into ripple/smart-escrow 2025-08-28 14:02:10 -04:00
Mayukha Vadari
3d86881ce7 Merge branch 'develop' into ripple/smart-escrow 2025-08-27 13:58:38 -04:00
Mayukha Vadari
697d1470f4 change: adjust the function signatures for get_ledger_sqn and get_parent_ledger_time (#5733) 2025-08-27 13:58:27 -04:00
Mayukha Vadari
0b5f8f4051 Merge remote-tracking branch 'upstream/develop' into ripple/smart-escrow 2025-08-26 17:59:43 -04:00
Mayukha Vadari
0fed78fbcc Merge branch 'develop' into ripple/smart-escrow 2025-08-26 15:04:33 -04:00
Mayukha Vadari
8c38ef726b chore: exclude a bunch of code that doesn't need to be tested from codecov (#5721)
* exclude the bulk of HostFunc.h from codecov

* fix codecov (maybe)

* adjust

* more codecov excl
2025-08-26 15:04:27 -04:00
Mayukha Vadari
2399d90334 Merge branch 'develop' into ripple/smart-escrow 2025-08-25 10:42:48 -04:00
Mayukha Vadari
6367d68d1e Merge branch 'develop' into ripple/smart-escrow 2025-08-22 14:02:12 -04:00
Mayukha Vadari
155a84c8a3 Merge branch 'develop' into ripple/smart-escrow 2025-08-22 13:24:43 -04:00
Mayukha Vadari
10558c9eff Merge remote-tracking branch 'upstream/develop' into develop5.5 2025-08-22 10:38:10 -04:00
Mayukha Vadari
dd30d811e6 feat: last set of host functions (#5674) 2025-08-15 16:51:30 -04:00
Mayukha Vadari
293d8e4ddb test: store Rust source code in rippled, instead of just opaque hex strings (#5653) 2025-08-15 15:32:36 -04:00
Mayukha Vadari
77875c9133 fix: actually return int instead of bool (#5651) 2025-08-15 13:58:38 -04:00
Olek
647b47567e Fix float point binary format (#5688) 2025-08-15 09:51:40 -04:00
Olek
b0a1ad3b06 Disable float point instructions (#5679) 2025-08-14 14:59:55 -04:00
Mayukha Vadari
1d141bf2e8 chore: move WASM files to separate folder (#5666) 2025-08-14 11:46:10 -04:00
Olek
0d0e279ae2 Float point Hostfunctions unit tests (#5656)
* Added direct unittests for float hostfunctions
2025-08-14 10:21:21 -04:00
Mayukha Vadari
5dc0cee28a cache data instead of setting it in updateData (#5642)
Co-authored-by: Oleksandr <115580134+oleks-rip@users.noreply.github.com>
2025-08-11 15:52:21 -04:00
Mayukha Vadari
c15947da56 fix CI 2025-08-06 12:41:12 -04:00
Mayukha Vadari
9bc04244e7 Merge remote-tracking branch 'upstream/ripple/smart-escrow' into develop5 2025-08-06 12:36:25 -04:00
Mayukha Vadari
38c7a27010 clean up WASM functions a bit (#5628) 2025-08-05 18:06:34 -04:00
Mayukha Vadari
58741d2791 feat: return an int instead of boolean from finish, display in metadata (#5641)
* create STInt32 and STInt64, use it for sfWasmReturnCode in metadata

* get it actually working

* add tests

* update comment

* change type

* respond to comments
2025-08-04 09:25:47 -04:00
Mayukha Vadari
8426470506 feat: add other misc host functions (#5574) 2025-07-31 18:39:21 -04:00
Olek
ccc3280b1a Update wamr to 2.4.1 (#5640) 2025-07-31 13:42:53 -04:00
Mayukha Vadari
2847075705 fix: ensure GasUsed shows up in the metadata even on tecWASM_REJECTED (#5633)
* always set gas used

* fix

* add tests

* clean up
2025-07-31 10:57:56 -04:00
Olek
3108ca0549 Float point HF (#5611)
- added support for 8-byte  float point
2025-07-30 14:38:03 +00:00
Mayukha Vadari
3b849ff497 Add unit tests for host functions (#5578) 2025-07-29 17:54:48 -04:00
Mayukha Vadari
66776b6a85 test: codecov for WasmHostFuncWrapper.cpp (#5601) 2025-07-29 16:06:21 -04:00
Mayukha Vadari
c8c241b50d Merge remote-tracking branch 'upstream/develop' into develop4.6 2025-07-29 11:34:44 -04:00
Bronek Kozicki
44cb588371 Build options cleanup (#5581)
As we no longer support old compiler versions, we are bringing back some warnings by removing no longer relevant `-Wno-...` options.
2025-07-28 13:02:41 -04:00
Oleksandr
6f91b8f8d1 Fix windows 2025-07-28 12:29:39 -04:00
Mayukha Vadari
3d93379132 add header 2025-07-25 15:10:47 -04:00
Mayukha Vadari
84fd7d0126 Merge remote-tracking branch 'upstream/develop' into develop4.6 2025-07-25 14:56:36 -04:00
Mayukha Vadari
7f52287aae rename variables (#5609)
* rename variables

* instanceWrapper -> runtime

* size -> srcSize

* begin -> ptr
2025-07-25 11:54:31 -04:00
Mayukha Vadari
98b8986868 fix merge issues (mostly with Conan2 upgrade) 2025-07-23 15:52:03 -04:00
Mayukha Vadari
250f2842ee Merge remote-tracking branch 'upstream/develop' into develop4.5 2025-07-23 13:43:47 -04:00
Olek
9eca1a3a0c MPT and IOU support for amount and issue (#5573)
* MPT and IOU support for ammount and issue

* Fix tests
Update wasm code to the latest version
Remove deprecated tests
Remove deprecated wasm
2025-07-22 17:43:21 +00:00
Mayukha Vadari
24b7a03224 feat: add more keylet host functions (#5522) 2025-07-17 12:37:41 -04:00
Mayukha Vadari
9007097d24 Simplify host function boilerplate (#5534)
* enum for HF errors

* switch getData functions to be templates

* getData<SField> working

* Slice -> Bytes in host functions

* RET -> helper function instead of macro

* get template function working

* more organization/cleanup

* fix failures

* more cleanup

* Bytes -> Slice

* SFieldParam macro -> type alias

* fix return type

* fix bugs

* replace std::make_index_sequence

* remove `failed` from output

* remove complex function

* more uniformity

* respond to comments

* enum class HostFunctionError

* rename variable

* respond to comments

* remove templating

* [WIP] basic getData tests

* weird linker error

* fix issue
2025-07-15 04:28:59 +05:30
Olek
bc445ec6a2 Add hostfunctions schedule table
Remove opcode schedule table from wamr
2025-07-11 18:08:36 -04:00
Mayukha Vadari
4fa0ae521e disallow a computation allowance of 0 (#5541) 2025-07-09 00:34:17 +05:30
Olek
7bdf5fa8b8 Fix build.md wamr version (#5535) 2025-07-04 00:48:03 +05:30
Olek
65b0b976d9 Sync error codes (#5527)
* Sync error codes
2025-07-02 17:33:39 -04:00
Elliot.
a0d275feec chore: Clear CODEOWNERS (#5528) 2025-07-02 10:39:57 -07:00
Mayukha Vadari
ece3a8d7be Merge branch 'develop' into develop4 2025-06-30 21:33:30 +05:30
Olek
463acf51b5 preflight checks for wasm (#5517) 2025-06-30 09:34:38 -04:00
Olek
1cd16fab87 Host-functions perf test fixes (#5514) 2025-06-27 09:59:28 -04:00
Olek
add55c4f33 Host functions gas cost for wasm_runtime interface (#5500) 2025-06-25 14:04:04 +00:00
Olek
51a9c0ff59 Host function gas cost (#5488)
* Update Wamr to 2.3.1
* Add gas cost per host-function
* Fix windows build
* Fix wasm test
* Add no import test
2025-06-12 15:54:49 -04:00
Mayukha Vadari
6e8a5f0f4e fix: make host function traces easier to use, fix get_NFT bug (#5466)
Co-authored-by: Olek <115580134+oleks-rip@users.noreply.github.com>
2025-06-05 14:24:13 -04:00
Mayukha Vadari
8a33702f26 fix merge issues 2025-06-05 12:38:26 -04:00
Mayukha Vadari
a072d49802 Merge remote-tracking branch 'upstream/ripple/smart-escrow' into develop3.5 2025-06-05 11:51:53 -04:00
Mayukha Vadari
a0aeeb8e07 Merge remote-tracking branch 'upstream/develop' into develop3.5 2025-06-05 11:50:38 -04:00
Olek
383b225690 Fix processing nonexistent field (#5467) 2025-06-04 17:32:11 -04:00
Mayukha Vadari
ace2247800 Merge remote-tracking branch 'upstream/ripple/smart-escrow' into develop3.5 2025-06-04 14:15:17 -04:00
Olek
6a6fed5dce More hostfunctions (#5451)
* Bug fixes:
- Fix bugs found during schedule table tests
- Add more tests
- Add parameters passing for runEscrowWasm function

* Add new host-functions
 fix wamr logging
 add runtime passing through HF
 fix runEscrowWasm interface

* Improve logs

* Fix logging bug

* Set 4k limit for update_data HF

* allHF wasm module fixes
2025-05-30 19:01:27 -04:00
Mayukha Vadari
1f8aece8cd feat: add a GasUsed parameter to the metadata (#5456) 2025-05-29 16:36:55 -04:00
Mayukha Vadari
6c6f8cd4f9 Merge remote-tracking branch 'upstream/develop' into develop3 2025-05-29 13:05:11 -04:00
Mayukha Vadari
fb1311e013 uncomment???? 2025-05-28 14:00:50 -04:00
Mayukha Vadari
ce31acf030 debug comments 2025-05-28 13:48:38 -04:00
Mayukha Vadari
31ad5ac63b Merge remote-tracking branch 'upstream/ripple/smart-escrow' into develop3 2025-05-27 18:29:41 -04:00
Mayukha Vadari
1ede0bdec4 fix: fix fixtures (#5445) 2025-05-23 17:37:14 -04:00
Mayukha Vadari
aef32ead2c better WASM logging to match rippled (#5395)
* basic logging

* pass in Journal

* log level based on journal level

* clean up

* attempt at adding WAMR logging properly

* improve logline

* maybe_unused

* fix

* fix

* fix segfault

* add test
2025-05-23 10:31:02 -04:00
Mayukha Vadari
5b43ec7f73 refactor: switch function name from ready to finish (#5430) 2025-05-20 16:12:19 -04:00
Olek
1e9ff88a00 Fix CI build issues
* Mac build fix
* Windows build fix
* Windows instruction counter fix
2025-05-08 12:39:37 -04:00
Mayukha Vadari
bb9bb5f5c5 Merge branch 'ripple/smart-escrow' into develop2 2025-05-01 18:44:06 -04:00
Mayukha Vadari
c533abd8b6 Update size and compute cap defaults (#5417) 2025-05-01 18:41:51 -04:00
Olek
bb9bc764bc Switch to WAMR (#5416)
* Switch to WAMR
2025-05-01 18:02:06 -04:00
Mayukha Vadari
b4b53a6cb7 Merge branch 'ripple/smart-escrow' into develop2 2025-04-29 15:25:54 -04:00
Mayukha Vadari
9c0204906c fix reference fee tests 2025-04-29 15:25:00 -04:00
Mayukha Vadari
4670b373c1 try to fix tests 2025-04-29 14:10:27 -04:00
Mayukha Vadari
f03b5883bd More host functions (#5411)
* getNFT

* escrow keylet

* account keylet

* credential keylet

* oracle keylet

* hook everything in

* fix stuff
2025-04-29 12:39:12 -04:00
Mayukha Vadari
f8b2fe4dd5 fix imports 2025-04-28 17:43:15 -04:00
Mayukha Vadari
be4a0c9c2b Merge remote-tracking branch 'upstream/ripple/smart-escrow' into develop2 2025-04-28 17:14:28 -04:00
Mayukha Vadari
f37d52d8e9 Set up fees for WASM processing (#5393)
* set up fields

* throw error if allowance is too high

* votable gas price

* fix comments

* hook everything together

* make test less flaky (hopefully)

* fix other tests

* fix some tests

* fix tests

* clean up

* add more tests

* uncomment other tests

* respond to comments

* fix build

* respond to comments
2025-04-24 08:47:13 -04:00
Mayukha Vadari
177cdaf550 Connect votable gas limit into VM (#5360)
* [WIP] add gas limit

* [WIP] host function escrow tests

* finish test

* uncomment out tests
2025-03-25 10:55:33 -04:00
pwang200
1573a443b7 smart escrow devnet 1 host functions (#5353)
* devnet 1 host functions

* clang-format

* fix build issues
2025-03-24 17:07:17 -04:00
Mayukha Vadari
911c0466c0 Merge develop into ripple/smart-escrow (#5357)
* Set version to 2.4.0

* refactor: Remove unused and add missing includes (#5293)

The codebase is filled with includes that are unused, and which thus can be removed. At the same time, the files often do not include all headers that contain the definitions used in those files. This change uses clang-format and clang-tidy to clean up the includes, with minor manual intervention to ensure the code compiles on all platforms.

* refactor: Calculate numFeatures automatically (#5324)

Requiring manual updates of numFeatures is an annoying manual process that is easily forgotten, and leads to frequent merge conflicts. This change takes advantage of the `XRPL_FEATURE` and `XRPL_FIX` macros, and adds a new `XRPL_RETIRE` macro to automatically set `numFeatures`.

* refactor: Improve ordering of headers with clang-format (#5343)

Removes all manual header groupings from source and header files by leveraging clang-format options.

* Rename "deadlock" to "stall" in `LoadManager` (#5341)

What the LoadManager class does is stall detection, which is not the same as deadlock detection. In the condition of severe CPU starvation, LoadManager will currently intentionally crash rippled reporting `LogicError: Deadlock detected`. This error message is misleading as the condition being detected is not a deadlock. This change fixes and refactors the code in response.

* Adds hub.xrpl-commons.org as a new Bootstrap Cluster (#5263)

* fix: Error message for ledger_entry rpc (#5344)

Changes the error to `malformedAddress` for `permissioned_domain` in the `ledger_entry` rpc, when the account is not a string. This change makes it more clear to a user what is wrong with their request.

* fix: Handle invalid marker parameter in grpc call (#5317)

The `end_marker` is used to limit the range of ledger entries to fetch. If `end_marker` is less than `marker`, a crash can occur. This change adds an additional check.

* fix: trust line RPC no ripple flag (#5345)

The Trustline RPC `no_ripple` flag gets set depending on `lsfDefaultRipple` flag, which is not a flag of a trustline but of the account root. The `lsfDefaultRipple` flag does not provide any insight if this particular trust line has `lsfLowNoRipple` or `lsfHighNoRipple` flag set, so it should not be used here at all. This change simplifies the logic.

* refactor: Updates Conan dependencies: RocksDB (#5335)

Updates RocksDB to version 9.7.3, the latest version supported in Conan 1.x. A patch for 9.7.4 that fixes a memory leak is included.

* fix: Remove null pointer deref, just do abort (#5338)

This change removes the existing undefined behavior from `LogicError`, so we can be certain that there will be always a stacktrace.

De-referencing a null pointer is an old trick to generate `SIGSEGV`, which would typically also create a stacktrace. However it is also an undefined behaviour and compilers can do something else. A more robust way to create a stacktrace while crashing the program is to use `std::abort`, which we have also used in this location for a long time. If we combine the two, we might not get the expected behaviour - namely, the nullpointer deref followed by `std::abort`, as handled in certain compiler versions may not immediately cause a crash. We have observed stacktrace being wiped instead, and thread put in indeterminate state, then stacktrace created without any useful information.

* chore: Add PR number to payload (#5310)

This PR adds one more payload field to the libXRPL compatibility check workflow - the PR number itself.

* chore: Update link to ripple-binary-codec (#5355)

The link to ripple-binary-codec's definitions.json appears to be outdated. The updated link is also documented here: https://xrpl.org/docs/references/protocol/binary-format#definitions-file

* Prevent consensus from getting stuck in the establish phase (#5277)

- Detects if the consensus process is "stalled". If it is, then we can declare a 
  consensus and end successfully even if we do not have 80% agreement on
  our proposal.
  - "Stalled" is defined as:
    - We have a close time consensus
    - Each disputed transaction is individually stalled:
      - It has been in the final "stuck" 95% requirement for at least 2
        (avMIN_ROUNDS) "inner rounds" of phaseEstablish,
      - and either all of the other trusted proposers or this validator, if proposing,
        have had the same vote(s) for at least 4 (avSTALLED_ROUNDS) "inner
        rounds", and at least 80% of the validators (including this one, if
        appropriate) agree about the vote (whether yes or no).
- If we have been in the establish phase for more than 10x the previous
  consensus establish phase's time, then consensus is considered "expired",
  and we will leave the round, which sends a partial validation (indicating
  that the node is moving on without validating). Two restrictions avoid
  prematurely exiting, or having an extended exit in extreme situations.
  - The 10x time is clamped to be within a range of 15s
    (ledgerMAX_CONSENSUS) to 120s (ledgerABANDON_CONSENSUS).
  - If consensus has not had an opportunity to walk through all avalanche
    states (defined as not going through 8 "inner rounds" of phaseEstablish),
    then ConsensusState::Expired is treated as ConsensusState::No.
- When enough nodes leave the round, any remaining nodes will see they've
  fallen behind, and move on, too, generally before hitting the timeout. Any
  validations or partial validations sent during this time will help the
  consensus process bring the nodes back together.

---------

Co-authored-by: Michael Legleux <mlegleux@ripple.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
Co-authored-by: Ed Hennis <ed@ripple.com>
Co-authored-by: Bronek Kozicki <brok@incorrekt.com>
Co-authored-by: Darius Tumas <Tokeiito@users.noreply.github.com>
Co-authored-by: Sergey Kuznetsov <skuznetsov@ripple.com>
Co-authored-by: cyan317 <120398799+cindyyan317@users.noreply.github.com>
Co-authored-by: Vlad <129996061+vvysokikh1@users.noreply.github.com>
Co-authored-by: Alex Kremer <akremer@ripple.com>
2025-03-20 16:47:14 -04:00
Mayukha Vadari
b6a95f9970 PoC Smart Escrows (#5340)
* wasmedge in unittest

* add WashVM.h and cpp

* accountID comparison (vector<u8>) working

* json decode tx and ledger object with two buffers working

* wasm return a buffer working

* add a failure test case to P2P3

* host function return ledger sqn

* instruction gas and host function gas

* basics

* add scaffold

* add amendment check

* working PoC

* get test working

* fix clang-format

* prototype #2

* p2p3

* [WIP] P4

* P5

* add calculateBaseFee

* add FinishFunction preflight checks (+ tests)

* additional reserve for sfFinishFunction

* higher fees for EscrowFinish

* rename amendment to SmartEscrow

* make fee voting changes, add basic tests

* clean up

* clean up

* clean up

* more cleanup

* add subscribe tests

* add more tests

* undo formatting

* undo formatting

* remove bad comment

* more debugging statements

* fix clang-format

* fix rebase issues

* fix more rebase issues

* more rebase fixes

* add source code for wasm

* respond to comments

* add const

---------

Co-authored-by: Peng Wang <pwang200@gmail.com>
2025-03-20 14:08:06 -04:00
1008 changed files with 205894 additions and 21599 deletions

View File

@@ -1,10 +1,32 @@
codecov:
require_ci_to_pass: true
# The C++ and Rust uploads land minutes apart; without this gate Codecov
# publishes a near-zero total from whichever one arrives first.
notify:
after_n_builds: 2
wait_for_ci: true
comment:
behavior: default
layout: reach,diff,flags,tree,reach
show_carryforward_flags: false
show_carryforward_flags: true
after_n_builds: 2
# C++ and Rust coverage upload from independent workflows under the `cpp` and
# `rust` flags; carryforward keeps one language's total when only the other reran.
flag_management:
default_rules:
carryforward: true
individual_flags:
- name: cpp
carryforward: true
paths:
- include/
- src/
- name: rust
carryforward: true
paths:
- crates/
coverage:
range: "70..85"

View File

@@ -7,6 +7,9 @@ ignorePaths:
- cmake/**
- LICENSE.md
- .clang-tidy
- src/test/app/wasm_fixtures/**/*.wat
- src/test/app/wasm_fixtures/*.c
- nix/check-tools/*.txt # generated, and full of Nix store hashes
language: en
allowCompoundWords: true # TODO (#6334)
ignoreRandomStrings: true
@@ -42,6 +45,7 @@ suggestWords:
- synched->synced
- synch->sync
words:
- cusip
- abempty
- AMMID
- AMMMPT
@@ -67,7 +71,11 @@ words:
- Btrfs
- Buildx
- canonicality
- cdylib
- canonicalised
- canonicality
- cctools
- CGNAT
- changespq
- checkme
- choco
@@ -109,9 +117,10 @@ words:
- disablerepo
- distro
- doxyfile
- dsymutil
- dxrpl
- elgamal
- enabled
- emittance
- enablerepo
- endmacro
- envrc
@@ -167,17 +176,18 @@ words:
- LOCALGOOD
- logwstream
- Lombrozo
- lresolv
- lseq
- lsmf
- ltype
- mathbunnyru
- mcmodel
- MEMORYSTATUSEX
- MPTAMM
- MPTDEX
- Merkle
- misprediction
- mispricing
- missingok
- MPTAMM
- mptbalance
- MPTDEX
- mptflags
@@ -220,6 +230,7 @@ words:
- Nyffenegger
- onlatest
- ostr
- otool
- oxalica
- pargs
- partitioner
@@ -249,11 +260,15 @@ words:
- Raphson
- rcflags
- replayer
- rerandomize
- repodata
- repomd
- rerandomization
- rerandomize
- rerandomized
- rerandomizes
- rerere
- retargeted
- retargets
- retriable
- RIPD
- ripdtop
@@ -271,8 +286,8 @@ words:
- rustup
- sahyadri
- Satoshi
- scons
- Schnorr
- scons
- secp
- sendq
- seqit
@@ -289,6 +304,7 @@ words:
- sles
- soci
- socidb
- Sonatype
- sponsee
- sponsees
- SRPMS
@@ -296,7 +312,9 @@ words:
- statsd
- STATSDCOLLECTOR
- stissue
- stjson
- stnum
- stnumber
- stobj
- stobject
- stpath
@@ -308,6 +326,7 @@ words:
- summands
- superpeer
- superpeers
- Swatinem
- takergets
- takerpays
- ters
@@ -322,8 +341,8 @@ words:
- txn
- txns
- txs
- ubsan
- UBSAN
- ubsan
- ufdio
- umant
- unacquired
@@ -335,7 +354,9 @@ words:
- unfindable
- unflatten
- unfund
- ungated
- unimpair
- unmetered
- unroutable
- unscalable
- unserviced
@@ -361,8 +382,11 @@ words:
- writeme
- wsrch
- wthread
- Xahau
- xbridge
- xchain
- xcrun
- xfloat
- ximinez
- XMACRO
- xored
@@ -372,4 +396,4 @@ words:
- xrplf
- xxhash
- xxhasher
- CGNAT
- zstdio

3
.envrc
View File

@@ -1,5 +1,8 @@
watch_file nix/*.nix
# Pinned Rust toolchain, read by nix/packages.nix via fromRustupToolchainFile.
watch_file rust-toolchain.toml
# The dev shell derivation includes all of conan/ (see nix/devshell.nix), so any
# change in there has to invalidate direnv's cached environment.
watch_dir conan

2
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1,2 @@
# Allow anyone to review any change by default.
*

39
.github/actions/cargo-cache/action.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
name: Use cargo artifacts cache
description: >
Cache the cargo build artifacts with rust-cache. Never caches ~/.cargo/bin:
when saving the cache, rust-cache deletes all binaries that were already
present there, which on persistent self-hosted runners wipes the tools
installed by prepare-runner. Harmless on ephemeral runners, but kept
consistent everywhere.
inputs:
workspaces:
description: "Workspaces to cache, as 'workspace -> target' lines."
required: false
default: crates
key:
description: "Additional part of the cache key."
required: false
default: ""
cache-directories:
description: "Additional non-workspace directories to cache."
required: false
default: ""
save-if:
description: >
Condition for saving the cache after the job. Defaults to save only from develop branch
required: false
default: ${{ github.ref == 'refs/heads/develop' }}
runs:
using: composite
steps:
- name: Use cargo artifacts cache
uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
with:
cache-bin: "false"
cache-directories: ${{ inputs.cache-directories }}
key: ${{ inputs.key }}
save-if: ${{ inputs.save-if }}
workspaces: ${{ inputs.workspaces }}

View File

@@ -1,44 +0,0 @@
name: Generate build version number
description: "Generate build version number."
outputs:
version:
description: "The generated build version number."
value: ${{ steps.version.outputs.version }}
runs:
using: composite
steps:
# When a tag is pushed, the version is used as-is.
- name: Generate version for tag event
if: ${{ startsWith(github.ref, 'refs/tags/') }}
shell: bash
env:
VERSION: ${{ github.ref_name }}
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: ${{ !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
fi
echo 'Appending shortened commit hash to version.'
SHA='${{ github.sha }}'
VERSION="${VERSION}+${SHA:0:7}"
echo "VERSION=${VERSION}" >>"${GITHUB_ENV}"
- name: Output version
id: version
shell: bash
run: echo "version=${VERSION}" >>"${GITHUB_OUTPUT}"

44
.github/actions/release-info/action.yml vendored Normal file
View File

@@ -0,0 +1,44 @@
name: Release info
description: "Derive the version, release channel and package release number for this build."
outputs:
version:
description: "The build version number."
value: ${{ steps.version.outputs.version }}
channel:
description: "The release channel this build belongs to."
value: ${{ steps.release_info.outputs.channel }}
pkg_release:
description: "The package release number: 1 for a tag, <run number>.<commit date>git<short commit hash> otherwise."
value: ${{ steps.release_info.outputs.pkg_release }}
runs:
using: composite
steps:
# A tag names its own version. Anything else takes it from BuildInfo.cpp and
# appends the commit hash as build metadata, joined with a plus sign because a
# Conan version cannot contain two hyphens.
- name: Determine version
id: version
shell: bash
env:
IS_TAG: ${{ startsWith(github.ref, 'refs/tags/') }}
REF_NAME: ${{ github.ref_name }}
SHA: ${{ github.sha }}
run: |
if [[ "${IS_TAG}" == "true" ]]; then
version="${REF_NAME}"
else
version="$(awk -F'"' '/versionString =/ { print $2 }' src/libxrpl/protocol/BuildInfo.cpp)"
if [[ -z "${version}" ]]; then
echo "Unable to read versionString from BuildInfo.cpp." >&2
exit 1
fi
version="${version}+${SHA:0:7}"
fi
echo "version=${version}" | tee -a "${GITHUB_OUTPUT}"
- name: Determine release channel and package release
id: release_info
uses: XRPLF/actions/release-info@7cc0e4a8d9d0b838f92c48d312856b190341bbba

View File

@@ -0,0 +1,70 @@
name: Setup Nix environment
description: "Build the flake's CI environment and put its tools on PATH."
# The environment from nix/ci-env.nix, the same one the Linux CI images bake in
# (see nix/docker). Exported onto PATH rather than entered with `nix develop`:
# the composite actions below run plain `bash` and would escape a dev shell.
runs:
using: composite
steps:
- name: Build the CI environment
id: build
shell: bash
env:
# --out-link doubles as a GC root for the length of the job.
OUT_LINK: ${{ runner.temp }}/xrpld-ci-env
run: |
# --extra-experimental-features: flakes may not be on in the runner's nix.conf.
nix --extra-experimental-features "nix-command flakes" \
build .#default --out-link "${OUT_LINK}" --print-build-logs
echo "path=$(readlink -f "${OUT_LINK}")" >>"${GITHUB_OUTPUT}"
- name: Export the environment
shell: bash
env:
ENV_PATH: ${{ steps.build.outputs.path }}
run: |
echo "${ENV_PATH}/bin" >>"${GITHUB_PATH}"
# Already KEY=VALUE per line. See `darwinEnv` in nix/ci-env.nix.
ENV_FILE="${ENV_PATH}/share/xrpld-ci-env/env"
if [ -f "${ENV_FILE}" ]; then
cat "${ENV_FILE}" >>"${GITHUB_ENV}"
fi
# XrplSanity.cmake otherwise rejects a Nix compiler as one that leaked.
echo "XRPL_DEVSHELL=ci-env" >>"${GITHUB_ENV}"
# Unlike the Linux nix images, macOS needs no SSL_CERT_FILE: it has its
# own trust store, and pinning would break TLS to hosts relying on it.
# In RUNNER_TEMP, which the runner empties per job, like the `.conan2`
# prepare-runner hands the system toolchain - but under its own name:
# that Conan is a different version, and the two would migrate each
# other's cache.
echo "CONAN_HOME=${RUNNER_TEMP}/.conan2-nix" >>"${GITHUB_ENV}"
# Config, profiles and remote, exactly as the dev shell sets them up on
# entry; the `setup-conan` action is skipped for this toolchain.
- name: Setup Conan
shell: bash
run: ./conan/init.sh
# `Check tools` runs later but swallows failures; a bad export would just
# build with the system toolchain.
- name: Verify the toolchain resolves into the Nix store
shell: bash
run: |
for tool in clang clang++ cmake ninja conan; do
path="$(command -v "${tool}" || true)"
echo "${tool} -> ${path:-<not found>}"
case "${path}" in
/nix/store/*) ;;
*)
echo "::error::${tool} does not resolve into the Nix store"
exit 1
;;
esac
done

View File

@@ -4,7 +4,8 @@ updates:
directories:
- /
- .github/actions/build-deps/
- .github/actions/generate-version/
- .github/actions/cargo-cache/
- .github/actions/release-info/
- .github/actions/set-compiler-env/
- .github/actions/setup-conan/
schedule:
@@ -19,3 +20,19 @@ updates:
github-actions:
patterns:
- "*"
- package-ecosystem: cargo
directory: /crates
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
commit-message:
prefix: "chore: [DEPENDABOT] "
target-branch: develop
open-pull-requests-limit: 10
groups:
rust-dependencies:
patterns:
- "*"

View File

@@ -18,7 +18,7 @@ If too broad, please consider splitting into multiple PRs.
If there is a relevant task or issue, please link it here.
-->
### Context of Change
## Context of Change
<!--
Please include the context of a change.
@@ -29,7 +29,7 @@ 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.
-->
### API Impact
## API Impact
<!--
Please check [x] relevant options, delete irrelevant ones.

View File

@@ -19,6 +19,7 @@ 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
@@ -206,6 +207,7 @@ xrpl.core > xrpl.json
xrpl.core > xrpl.protocol
xrpl.json > xrpl.basics
xrpl.ledger > xrpl.basics
xrpl.ledger > xrpl.core
xrpl.ledger > xrpl.json
xrpl.ledger > xrpl.nodestore
xrpl.ledger > xrpl.protocol

View File

@@ -49,7 +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
${SED_COMMAND} -i -E 's@XRPLF/xrpld@XRPLF/rippled@g' docs/install.md
popd
echo "Processing complete."

View File

@@ -77,8 +77,8 @@ ${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/install.md
${SED_COMMAND} -i 's@github.com/XRPLF/xrpld@github.com/XRPLF/rippled@g' docs/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

View File

@@ -7,7 +7,13 @@ from pathlib import Path
THIS_DIR = Path(__file__).parent.resolve()
_BASE_CMAKE_ARGS = ["-Dtests=ON", "-Dwerr=ON", "-Dxrpld=ON", "-Dwextra=ON"]
_BASE_CMAKE_ARGS = [
"-Dtests=ON",
"-Dwerr=ON",
"-Dxrpld=ON",
"-Dwextra=ON",
"-Drust=ON",
]
# Maps sanitizer names (as used in cmake) to short config-name suffixes.
_SANITIZER_SUFFIX: dict[str, str] = {
@@ -17,6 +23,19 @@ _SANITIZER_SUFFIX: dict[str, str] = {
}
def config_name(
distro: str,
compiler: str,
build_type: str,
arch: str,
suffix: str = "",
sanitizer: str = "",
) -> str:
"""Name a config. Its artifacts are named after it, so packaging reuses this."""
parts = [s for s in [suffix, _SANITIZER_SUFFIX.get(sanitizer, "")] if s]
return "-".join([f"{distro}-{compiler}-{build_type.lower()}-{arch}", *parts])
def get_cmake_args(build_type: str, extra_args: str) -> str:
"""Get the full list of CMake arguments for a config."""
args = _BASE_CMAKE_ARGS.copy()
@@ -31,17 +50,27 @@ def get_cmake_args(build_type: str, extra_args: str) -> str:
# Every config must declare 'minimal'. Minimal configs form the reduced matrix
# built for pull requests by default; the full matrix adds the rest. Packaging
# configs declare it too, but packaging is gated in the workflow, not by it.
# built for pull requests by default; the full matrix adds the rest.
#
# Configs may also opt into 'benchmark' to smoke-run the benchmarks. Note that
# the flag applies to every entry a config expands into, so only set it on
# configs that expand to a single combination.
# Configs may also opt into 'benchmark' to smoke-run the benchmarks, or carry a
# 'package' map to be packaged as well. Note that either applies to every entry
# a config expands into, so only set them on configs that expand to a single
# combination.
@dataclasses.dataclass
class PackageConfig:
"""The 'package' map of a config whose binaries are also packaged."""
type: str # "deb" or "rpm"; has to match what the image provides
# The packaging container image: a vanilla distro image, not the nix image
# the config itself builds in.
image: str
@dataclasses.dataclass
class LinuxConfig:
"""One entry in linux.json's 'configs' or 'package_configs' arrays."""
"""One entry in a linux.json 'configs' array."""
compiler: list[str]
build_type: list[str]
@@ -51,7 +80,13 @@ class LinuxConfig:
sanitizers: list[str] = dataclasses.field(default_factory=list)
suffix: str = ""
extra_cmake_args: str = ""
image: str = "" # only used by package_configs entries
package: PackageConfig | None = None # set to also package this config
# Flip every amendment to Supported::Yes before building (perf/test only).
force_supported: bool = False
def __post_init__(self) -> None:
if isinstance(self.package, dict):
self.package = PackageConfig(**self.package)
@dataclasses.dataclass
@@ -60,22 +95,16 @@ class LinuxFile:
image_tag: str
configs: dict[str, list[LinuxConfig]] # distro → configs
package_configs: dict[str, list[LinuxConfig]] # distro → packaging configs
@classmethod
def load(cls, path: Path) -> "LinuxFile":
data = json.loads(path.read_text())
def parse(section: dict) -> dict[str, list[LinuxConfig]]:
return {
distro: [LinuxConfig(**c) for c in cfgs]
for distro, cfgs in section.items()
}
return cls(
image_tag=data["image_tag"],
configs=parse(data["configs"]),
package_configs=parse(data.get("package_configs", {})),
configs={
distro: [LinuxConfig(**c) for c in cfgs]
for distro, cfgs in data["configs"].items()
},
)
@@ -88,6 +117,9 @@ class PlatformConfig:
build_only: bool = False # if true, skip tests (e.g. macos/Windows Debug)
benchmark: bool = False # if true, smoke-run the benchmarks after testing
extra_cmake_args: str = ""
# "" is the runner's system compiler, "nix" the flake's CI environment.
# macOS only: Linux always builds in a Nix image, Windows has no Nix.
toolchain: str = ""
def __post_init__(self) -> None:
if isinstance(self.build_type, str):
@@ -137,6 +169,8 @@ class MatrixEntry:
sanitizers: str
image: str = "" # container image; empty for macOS/Windows (runs natively)
compiler: str = "" # compiler name ("gcc" or "clang"); empty for macOS/Windows
toolchain: str = "" # "nix" for the flake's CI environment; see PlatformConfig
force_supported: bool = False # flip amendments to Supported::Yes before build
@dataclasses.dataclass
@@ -146,7 +180,7 @@ class PackagingEntry:
xrpld_artifact_name: str
validator_keys_artifact_name: str
image: str
distro: str # e.g. "debian" or "rhel"; drives package-format-specific steps
package_type: str # "deb" or "rpm"; drives the format-specific steps
# ---------------------------------------------------------------------------
@@ -187,13 +221,9 @@ def expand_linux_matrix(linux: LinuxFile, minimal: bool) -> list[MatrixEntry]:
effective_sanitizers,
effective_archs.items(),
):
name = f"{distro}-{compiler}-{build_type.lower()}-{arch}"
suffix_parts = [
s for s in [cfg.suffix, _SANITIZER_SUFFIX.get(sanitizer, "")] if s
]
if suffix_parts:
name += "-" + "-".join(suffix_parts)
name = config_name(
distro, compiler, build_type, arch, cfg.suffix, sanitizer
)
entries.append(
MatrixEntry(
config_name=name,
@@ -206,6 +236,7 @@ def expand_linux_matrix(linux: LinuxFile, minimal: bool) -> list[MatrixEntry]:
architecture=arch_info,
sanitizers=sanitizer,
compiler=compiler,
force_supported=cfg.force_supported,
)
)
@@ -213,27 +244,33 @@ def expand_linux_matrix(linux: LinuxFile, minimal: bool) -> list[MatrixEntry]:
def expand_linux_packaging(linux: LinuxFile) -> list[PackagingEntry]:
"""Generate the packaging matrix from a LinuxFile's package_configs section.
"""Generate the packaging matrix from the configs that carry a 'package' map.
Packaging uses vanilla distro images (debian:bookworm, ubi9, …) instead of
the nix-based build images, because deb/rpm tooling (debhelper, rpm-build)
is taken from the distro's archive rather than from nixpkgs. Each config
entry carries its own 'image'.
Packaging consumes the binaries that config's build job uploaded, so the
artifact names come from the same config name, and a packaged config is one
that passes -Dvalidator_keys=ON.
The artifact names must match what the build job uploads: one artifact per
binary, each named after the build config.
Packaging itself runs in vanilla distro images (debian:trixie, almalinux:10)
instead of the nix-based build images, because deb/rpm tooling (debhelper,
rpm-build) is taken from the distro's archive rather than from nixpkgs.
"""
entries = []
for distro, configs in linux.package_configs.items():
for distro, configs in linux.configs.items():
for cfg in configs:
for compiler, build_type in itertools.product(cfg.compiler, cfg.build_type):
config_name = f"{distro}-{compiler}-{build_type.lower()}-amd64"
if cfg.package is None:
continue
for compiler, build_type, arch in itertools.product(
cfg.compiler, cfg.build_type, cfg.arch
):
# The packaging workflow hardcodes an amd64 runner.
assert arch == "amd64", f"cannot package {distro} on {arch}"
name = config_name(distro, compiler, build_type, arch, cfg.suffix)
entries.append(
PackagingEntry(
xrpld_artifact_name=f"xrpld-{config_name}",
validator_keys_artifact_name=f"validator-keys-{config_name}",
image=cfg.image,
distro=distro,
xrpld_artifact_name=f"xrpld-{name}",
validator_keys_artifact_name=f"validator-keys-{name}",
image=cfg.package.image,
package_type=cfg.package.type,
)
)
@@ -253,9 +290,12 @@ def expand_platform_matrix(pf: PlatformFile, minimal: bool) -> list[MatrixEntry]
if minimal and not cfg.minimal:
continue
for build_type in cfg.build_type:
name = f"{platform_name}-{arch}-{build_type.lower()}"
if cfg.toolchain:
name += f"-{cfg.toolchain}"
entries.append(
MatrixEntry(
config_name=f"{platform_name}-{arch}-{build_type.lower()}",
config_name=name,
cmake_args=get_cmake_args(build_type, cfg.extra_cmake_args),
cmake_target="install" if is_windows else "all",
build_only=cfg.build_only,
@@ -263,6 +303,7 @@ def expand_platform_matrix(pf: PlatformFile, minimal: bool) -> list[MatrixEntry]
build_type=build_type,
architecture=Architecture(platform=pf.platform, runner=pf.runner),
sanitizers="",
toolchain=cfg.toolchain,
)
)
return entries

View File

@@ -1,5 +1,5 @@
{
"image_tag": "sha-fecfc0c",
"image_tag": "sha-060957e",
"configs": {
"ubuntu": [
{
@@ -17,7 +17,6 @@
"minimal": true,
"benchmark": true
},
{
"compiler": ["gcc"],
"build_type": ["Release"],
@@ -30,7 +29,6 @@
"arch": ["arm64"],
"minimal": false
},
{
"compiler": ["gcc", "clang"],
"build_type": ["Debug", "Release"],
@@ -38,7 +36,6 @@
"minimal": false,
"sanitizers": ["address", "undefinedbehavior"]
},
{
"compiler": ["clang"],
"build_type": ["Debug"],
@@ -62,47 +59,45 @@
"minimal": false,
"suffix": "unity",
"extra_cmake_args": "-Dunity=ON"
},
{
"compiler": ["gcc"],
"build_type": ["Release"],
"arch": ["amd64"],
"minimal": false,
"suffix": "supported",
"force_supported": true,
"extra_cmake_args": "-Dvalidator_keys=ON",
"package": {
"type": "deb",
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-49cdc10"
}
}
],
"debian": [
{
"compiler": ["gcc"],
"build_type": ["Release"],
"arch": ["amd64"],
"minimal": false,
"extra_cmake_args": "-Dvalidator_keys=ON"
"extra_cmake_args": "-Dvalidator_keys=ON",
"package": {
"type": "deb",
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-49cdc10"
}
}
],
"rhel": [
{
"compiler": ["gcc"],
"build_type": ["Release"],
"arch": ["amd64"],
"minimal": false,
"extra_cmake_args": "-Dvalidator_keys=ON"
}
]
},
"package_configs": {
"debian": [
{
"compiler": ["gcc"],
"build_type": ["Release"],
"arch": ["amd64"],
"minimal": false,
"image": "ghcr.io/xrplf/xrpld/packaging-debian:sha-577d745"
}
],
"rhel": [
{
"compiler": ["gcc"],
"build_type": ["Release"],
"arch": ["amd64"],
"minimal": false,
"image": "ghcr.io/xrplf/xrpld/packaging-rhel:sha-577d745"
"extra_cmake_args": "-Dvalidator_keys=ON",
"package": {
"type": "rpm",
"image": "ghcr.io/xrplf/xrpld/packaging-rhel:sha-49cdc10"
}
}
]
}

View File

@@ -12,6 +12,19 @@
"extra_cmake_args": "-DCMAKE_POLICY_VERSION_MINIMUM=3.5",
"build_only": true,
"minimal": false
},
{
"build_type": "Release",
"extra_cmake_args": "-DCMAKE_POLICY_VERSION_MINIMUM=3.5",
"toolchain": "nix",
"minimal": false
},
{
"build_type": "Debug",
"extra_cmake_args": "-DCMAKE_POLICY_VERSION_MINIMUM=3.5",
"toolchain": "nix",
"build_only": true,
"minimal": false
}
]
}

View File

@@ -5,14 +5,13 @@ on:
branches:
- develop
paths:
- ".github/workflows/build-nix-images.yml"
- "flake.nix"
- "flake.lock"
- "rust-toolchain.toml"
- "nix/**"
- "!nix/docker/README.md"
- "!nix/devshell.nix"
- "bin/check-tools.sh"
- "!nix/check-tools/**"
- "bin/default-loader-path.sh"
- "bin/install-sanitizer-libs.sh"
pull_request:
@@ -24,6 +23,7 @@ on:
- "nix/**"
- "!nix/docker/README.md"
- "!nix/devshell.nix"
- "!nix/check-tools/**"
- "bin/check-tools.sh"
- "bin/default-loader-path.sh"
- "bin/install-sanitizer-libs.sh"
@@ -58,7 +58,7 @@ jobs:
base_image: debian:bookworm
- name: rhel
base_image: registry.access.redhat.com/ubi9/ubi:latest
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@9e7e4e80af9e684c116b38369add8eea64451f32
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@034e87065fcd0100214cf0672923bd38d193cf78
with:
image_name: xrpld/nix-${{ matrix.distro.name }}
dockerfile: nix/docker/Dockerfile

View File

@@ -6,13 +6,13 @@ on:
- develop
paths:
- ".github/workflows/build-packaging-images.yml"
- "package/Dockerfile"
- "package/install-packaging-tools.sh"
- "bin/install-packaging-tools.sh"
- "package/docker/**"
pull_request:
paths:
- ".github/workflows/build-packaging-images.yml"
- "package/Dockerfile"
- "package/install-packaging-tools.sh"
- "bin/install-packaging-tools.sh"
- "package/docker/**"
workflow_dispatch:
concurrency:
@@ -33,14 +33,17 @@ jobs:
strategy:
fail-fast: false
matrix:
# Newest of each distro: these images only wrap pre-built binaries, so
# they set no floor for consumers. build_pkg.py pins the RPM dist tag.
distro:
- name: debian
base_image: debian:bookworm
base_image: debian:trixie
# AlmaLinux rather than UBI, which does not ship rpm-sign.
- name: rhel
base_image: registry.access.redhat.com/ubi9/ubi:latest
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@9e7e4e80af9e684c116b38369add8eea64451f32
base_image: almalinux:10
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@034e87065fcd0100214cf0672923bd38d193cf78
with:
image_name: xrpld/packaging-${{ matrix.distro.name }}
dockerfile: package/Dockerfile
dockerfile: package/docker/Dockerfile
base_image: ${{ matrix.distro.base_image }}
push: ${{ github.event_name == 'push' }}

View File

@@ -30,7 +30,7 @@ jobs:
permissions:
contents: read
packages: write
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@9e7e4e80af9e684c116b38369add8eea64451f32
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@034e87065fcd0100214cf0672923bd38d193cf78
with:
image_name: xrpld/pre-commit
dockerfile: bin/pre-commit/Dockerfile

View File

@@ -0,0 +1,103 @@
# Package the "all amendments Supported::Yes" build into a runtime Docker image
# and push it to GHCR, as a drop-in for the rippleci/xrpld image xrpl.js uses
# for standalone testing -- except every amendment is built Supported::Yes.
#
# This does NOT build or package anything: the Trigger workflow already builds
# the supported binary and the supported .deb (the force_supported build config
# and the matching supported package config in linux.json). This workflow waits
# for a successful Trigger run on develop, downloads that run's supported .deb
# artifact, installs it into a slim base (docker/supported.Dockerfile, which
# replicates rippleci's layout), and pushes ghcr.io/xrplf/xrpld/supported.
#
# Perf/test artifact only -- never run it on a production validator.
name: Build supported Docker image
on:
workflow_run:
workflows: ["Trigger"]
types: [completed]
branches: [develop]
# Manual runs: point at a specific completed Trigger run via its run id.
workflow_dispatch:
inputs:
trigger_run_id:
description: "Run id of the Trigger workflow whose supported .deb to package."
required: true
type: string
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
env:
IMAGE_NAME: ghcr.io/xrplf/xrpld/supported
# The supported .deb artifact uploaded by reusable-package.yml:
# <artifact_name>-pkg, where artifact_name carries the -supported suffix.
DEB_ARTIFACT: xrpld-ubuntu-gcc-release-amd64-supported-pkg
SOURCE_RUN_ID: ${{ github.event.workflow_run.id || github.event.inputs.trigger_run_id }}
jobs:
image:
# Only for successful Trigger runs (workflow_run), and only on the canonical
# repo where GITHUB_TOKEN can push to ghcr.io/xrplf/*.
if: ${{ github.repository == 'XRPLF/rippled' && (github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success') }}
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
actions: read
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Download the supported .deb from the Trigger run
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: ${{ env.DEB_ARTIFACT }}
path: dl
run-id: ${{ env.SOURCE_RUN_ID }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Assemble build context
run: |
set -euo pipefail
mkdir -p docker-context
deb="$(find dl -name '*.deb' | head -n1)"
[ -n "${deb}" ] || {
echo "::error::no supported .deb found in run ${SOURCE_RUN_ID}"
exit 1
}
mv "${deb}" docker-context/xrpld.deb
echo "Packaging $(basename "${deb}") into ${IMAGE_NAME}"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- 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: 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: Build and push
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: docker-context
file: docker/supported.Dockerfile
platforms: linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

80
.github/workflows/cargo-audit.yml vendored Normal file
View File

@@ -0,0 +1,80 @@
name: Cargo audit
on:
schedule:
# 06:32 UTC every Monday.
- cron: "32 6 * * 1"
push:
branches:
- "develop"
- "release/*"
paths:
- "crates/**/Cargo.toml"
- "crates/Cargo.lock"
- ".github/workflows/cargo-audit.yml"
pull_request:
paths:
- "crates/**/Cargo.toml"
- "crates/Cargo.lock"
- ".github/workflows/cargo-audit.yml"
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
working-directory: crates
permissions:
contents: read
jobs:
audit:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
permissions:
contents: read
# Needed to open an issue on scheduled failures.
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Run cargo audit
id: audit
continue-on-error: true
run: |
set -o pipefail
cargo audit | tee /tmp/cargo-audit.txt
- name: Prepare issue body
if: ${{ steps.audit.outcome != 'success' && github.event_name == 'schedule' }}
run: |
{
echo "## \`cargo audit\` found advisories"
echo
echo '```'
cat /tmp/cargo-audit.txt
echo '```'
echo
echo "---"
echo "*This issue was automatically created by the cargo-audit workflow.*"
} >/tmp/cargo-audit-issue.md
- name: Create issue
if: ${{ steps.audit.outcome != 'success' && github.event_name == 'schedule' }}
uses: XRPLF/actions/create-issue@2b8bc36af85b88bca0dd7bfac2e2dc05f94ad712
with:
title: "cargo audit found vulnerabilities"
body_file: /tmp/cargo-audit-issue.md
labels: "Bug,Security"
- name: Fail if advisories were found
if: ${{ steps.audit.outcome != 'success' }}
run: |
echo "cargo audit found advisories!"
cat /tmp/cargo-audit.txt
exit 1

View File

@@ -79,7 +79,7 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@c00c22ada3bd6bcda48fcb0d62fbbab49fec8a0f
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
with:
enable_ccache: false

View File

@@ -77,24 +77,28 @@ jobs:
# Keep the paths below in sync with those in `on-trigger.yml`.
.github/actions/build-deps/**
.github/actions/generate-version/**
.github/actions/release-info/**
.github/actions/setup-conan/**
.github/actions/setup-nix-env/**
.github/scripts/strategy-matrix/**
.github/workflows/reusable-build-test-config.yml
.github/workflows/reusable-build-test.yml
.github/workflows/reusable-check-autogen.yml
.github/workflows/reusable-clang-tidy.yml
.github/workflows/reusable-package.yml
.github/workflows/reusable-rust.yml
.github/workflows/reusable-strategy-matrix.yml
.github/workflows/reusable-test.yml
.github/workflows/reusable-upload-recipe.yml
.clang-tidy
.codecov.yml
bin/check-nix-store-refs.sh
bin/check-tools.sh
bin/default-loader-path.sh
cfg/**
cmake/**
conan/**
crates/**
external/**
include/**
src/**
@@ -102,6 +106,9 @@ jobs:
CMakeLists.txt
conanfile.py
conan.lock
flake.lock
flake.nix
nix/**
LICENSE.md
package/**
README.md
@@ -168,6 +175,13 @@ jobs:
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
rust:
needs: should-run
if: ${{ needs.should-run.outputs.go == 'true' }}
uses: ./.github/workflows/reusable-rust.yml
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
package:
needs: [should-run, build-test]
# Packaging consumes the debian/rhel release binaries, which are only built
@@ -211,6 +225,7 @@ jobs:
- check-rename
- clang-tidy
- build-test
- rust
- package
- upload-recipe
- notify-clio

View File

@@ -1,5 +1,9 @@
# This workflow uploads the libxrpl recipe to the Conan remote and builds
# release packages when a versioned tag is pushed.
# When a versioned tag is pushed, this workflow:
#
# - uploads the libxrpl recipe to the Conan remote
# - builds and tests the release binaries
# - builds the DEB and RPM packages
# - publishes those packages to the XRPLF package repositories
name: Tag
on:
@@ -24,7 +28,7 @@ jobs:
remote_password: ${{ secrets.NEXUS_REMOTE_PASSWORD }}
build-test:
if: ${{ github.repository == 'XRPLF/rippled' }}
if: ${{ github.repository_owner == 'XRPLF' }}
uses: ./.github/workflows/reusable-build-test.yml
strategy:
fail-fast: true
@@ -37,6 +41,12 @@ jobs:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
package:
if: ${{ github.repository == 'XRPLF/rippled' }}
if: ${{ github.repository_owner == 'XRPLF' }}
needs: build-test
uses: ./.github/workflows/reusable-package.yml
with:
publish: true
secrets:
remote_username: ${{ secrets.NEXUS_REMOTE_USERNAME }}
remote_password: ${{ secrets.NEXUS_REMOTE_PASSWORD }}
signing_key: ${{ secrets.NEXUS_PACKAGES_PRIVATE_KEY }}

View File

@@ -15,24 +15,28 @@ on:
# Keep the paths below in sync with those in `on-pr.yml`.
- ".github/actions/build-deps/**"
- ".github/actions/generate-version/**"
- ".github/actions/release-info/**"
- ".github/actions/setup-conan/**"
- ".github/actions/setup-nix-env/**"
- ".github/scripts/strategy-matrix/**"
- ".github/workflows/reusable-build-test-config.yml"
- ".github/workflows/reusable-build-test.yml"
- ".github/workflows/reusable-check-autogen.yml"
- ".github/workflows/reusable-clang-tidy.yml"
- ".github/workflows/reusable-package.yml"
- ".github/workflows/reusable-rust.yml"
- ".github/workflows/reusable-strategy-matrix.yml"
- ".github/workflows/reusable-test.yml"
- ".github/workflows/reusable-upload-recipe.yml"
- ".clang-tidy"
- ".codecov.yml"
- "bin/check-nix-store-refs.sh"
- "bin/check-tools.sh"
- "bin/default-loader-path.sh"
- "cfg/**"
- "cmake/**"
- "conan/**"
- "crates/**"
- "external/**"
- "include/**"
- "src/**"
@@ -40,6 +44,9 @@ on:
- "CMakeLists.txt"
- "conanfile.py"
- "conan.lock"
- "flake.lock"
- "flake.nix"
- "nix/**"
- "LICENSE.md"
- "package/**"
- "README.md"
@@ -96,6 +103,11 @@ jobs:
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
rust:
uses: ./.github/workflows/reusable-rust.yml
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
upload-recipe:
needs: build-test
# Only run when pushing to the develop branch.
@@ -108,3 +120,11 @@ jobs:
package:
needs: build-test
uses: ./.github/workflows/reusable-package.yml
with:
# Packages are built on every trigger; only develop pushes in XRPLF/rippled
# publish them, matching upload-recipe above.
publish: ${{ github.repository == 'XRPLF/rippled' && github.event_name == 'push' && github.ref == 'refs/heads/develop' }}
secrets:
remote_username: ${{ secrets.NEXUS_REMOTE_USERNAME }}
remote_password: ${{ secrets.NEXUS_REMOTE_PASSWORD }}
signing_key: ${{ secrets.NEXUS_PACKAGES_PRIVATE_KEY }}

View File

@@ -14,7 +14,7 @@ on:
jobs:
# Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks.
run-hooks:
uses: XRPLF/actions/.github/workflows/pre-commit.yml@3ba08d6ddf114092891d48491fc2e26c3ba15552
uses: XRPLF/actions/.github/workflows/pre-commit.yml@279ec358f4a1be4088be3e024b07916fa97c75b6
with:
runs_on: ubuntu-latest
container: '{ "image": "ghcr.io/xrplf/xrpld/pre-commit:sha-f56b79f" }'
container: '{ "image": "ghcr.io/xrplf/xrpld/pre-commit:sha-473fe44" }'

View File

@@ -41,13 +41,13 @@ env:
jobs:
build:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-fecfc0c
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@c00c22ada3bd6bcda48fcb0d62fbbab49fec8a0f
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
with:
enable_ccache: false
@@ -91,4 +91,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deploy
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1

View File

@@ -69,6 +69,17 @@ on:
type: string
default: ""
toolchain:
description: 'Where the toolchain comes from ("nix" to build the flake CI environment on the runner, empty for the system one). macOS only: Linux always builds in a Nix image, and Nix has no Windows support.'
required: false
type: string
default: ""
force_supported:
description: "Flip every amendment to Supported::Yes before building. For perf/test builds only; never for release artifacts."
required: false
type: boolean
default: false
secrets:
CODECOV_TOKEN:
description: "The Codecov token to use for uploading coverage reports."
@@ -111,6 +122,9 @@ jobs:
VOIDSTAR_ENABLED: ${{ contains(inputs.cmake_args, '-Dvoidstar=ON') }}
VALIDATOR_KEYS_ENABLED: ${{ contains(inputs.cmake_args, '-Dvalidator_keys=ON') }}
SANITIZERS_ENABLED: ${{ inputs.sanitizers != '' }}
# The binaries reusable-package.yml consumes. A private repository skips
# them except on a tag push, which is what produces its release packages.
PACKAGING_ARTIFACTS_ENABLED: ${{ github.event.repository.visibility == 'public' || startsWith(github.ref, 'refs/tags/') }}
steps:
- name: Cleanup workspace (macOS and Windows)
if: ${{ runner.os == 'macOS' || runner.os == 'Windows' }}
@@ -119,11 +133,30 @@ jobs:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Force all amendments to Supported::Yes
if: ${{ inputs.force_supported && runner.os == 'Linux' }}
run: |
set -euo pipefail
MACRO="include/xrpl/protocol/detail/features.macro"
echo "Flipping Supported::No -> Supported::Yes in ${MACRO}:"
grep -n 'Supported::No,' "${MACRO}" || echo " (none found)"
sed -i 's/Supported::No,/Supported::Yes,/g' "${MACRO}"
if grep -q 'Supported::No,' "${MACRO}"; then
echo "::error::Supported::No entries remain after sed"
exit 1
fi
git diff -- "${MACRO}" || true
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@c00c22ada3bd6bcda48fcb0d62fbbab49fec8a0f
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
with:
enable_ccache: ${{ inputs.ccache_enabled }}
# Before any step that uses a build tool, composite actions included.
- name: Setup Nix environment
if: ${{ inputs.toolchain == 'nix' }}
uses: ./.github/actions/setup-nix-env
- name: Set ccache log file
if: ${{ inputs.ccache_enabled && runner.debug == '1' }}
run: echo "CCACHE_LOGFILE=${{ runner.temp }}/ccache.log" >>"${GITHUB_ENV}"
@@ -148,7 +181,21 @@ jobs:
with:
compiler: ${{ inputs.compiler }}
- name: Use cargo artifacts cache
uses: ./.github/actions/cargo-cache
with:
cache-directories: ${{ env.BUILD_DIR }}/corrosion
key: ${{ inputs.config_name }}
# two workspaces here because build artifacts are located in 2 places:
# - crates/target when cargo is called directly
# - build/cargo when cargo is called by cmake
workspaces: |
crates
crates -> ${{ runner.os == 'Windows' && format('../{0}/x64/{1}/cargo', env.BUILD_DIR, inputs.build_type) || format('../{0}/cargo', env.BUILD_DIR) }}
# `setup-nix-env` already did this for the Nix toolchain.
- name: Setup Conan
if: ${{ inputs.toolchain != 'nix' }}
env:
SANITIZERS: ${{ inputs.sanitizers }}
uses: ./.github/actions/setup-conan
@@ -212,6 +259,24 @@ jobs:
--target "${CMAKE_TARGET}" \
2>&1 | tee "${GITHUB_WORKSPACE}/build.log"
# Nothing may reference the store, so whole trees are checked - the Conan
# cache included, since what it holds is what gets uploaded and reused.
- name: Check the build output for Nix store references (Nix toolchain)
if: ${{ inputs.toolchain == 'nix' }}
run: ./bin/check-nix-store-refs.sh "${BUILD_DIR}"
- name: Check the Conan cache for Nix store references (Nix toolchain)
if: ${{ inputs.toolchain == 'nix' }}
run: ./bin/check-nix-store-refs.sh "${CONAN_HOME}"
# Only what PatchNixBinary.cmake retargets: the toolchain in the Linux
# images always references the store. Same condition it uses.
- name: Check for Nix store references (Linux)
if: ${{ runner.os == 'Linux' && env.SANITIZERS_ENABLED == 'false' }}
run: |
./bin/check-nix-store-refs.sh "${BUILD_DIR}/xrpld"
./bin/check-nix-store-refs.sh "${BUILD_DIR}/xrpl_tests"
- name: Show ccache statistics
if: ${{ inputs.ccache_enabled }}
run: |
@@ -222,7 +287,7 @@ jobs:
fi
- name: Upload the binary (Linux)
if: ${{ github.event.repository.visibility == 'public' && runner.os == 'Linux' }}
if: ${{ env.PACKAGING_ARTIFACTS_ENABLED == 'true' && runner.os == 'Linux' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: xrpld-${{ inputs.config_name }}
@@ -236,7 +301,7 @@ jobs:
run: ./validator-keys --unittest
- name: Upload the validator-keys binary
if: ${{ github.event.repository.visibility == 'public' && env.VALIDATOR_KEYS_ENABLED == 'true' }}
if: ${{ env.PACKAGING_ARTIFACTS_ENABLED == 'true' && env.VALIDATOR_KEYS_ENABLED == 'true' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: validator-keys-${{ inputs.config_name }}
@@ -323,6 +388,11 @@ jobs:
LD_PRELOAD="$PRELOAD" ./xrpld --unittest --unittest-jobs "${BUILD_NPROC}" 2>&1 | tee "${GITHUB_WORKSPACE}/unittest.log"
- name: Run Rust tests
if: ${{ !inputs.build_only }}
working-directory: crates
run: cargo nextest run --workspace --all-features --locked --no-tests=warn
# Smoke-run every benchmark module with a single repetition to confirm the
# benchmarks still build and execute. This is a correctness check, not a
# performance measurement, so there is nothing to gain from repeating it
@@ -394,6 +464,7 @@ jobs:
disable_telem: true
fail_ci_if_error: true
files: ${{ env.BUILD_DIR }}/coverage.xml
flags: cpp
plugins: noop
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true

View File

@@ -51,5 +51,7 @@ jobs:
config_name: ${{ matrix.config_name }}
sanitizers: ${{ matrix.sanitizers }}
compiler: ${{ matrix.compiler || '' }}
toolchain: ${{ matrix.toolchain || '' }}
force_supported: ${{ matrix.force_supported || false }}
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -27,14 +27,14 @@ jobs:
determine-files:
permissions:
contents: read
uses: XRPLF/actions/.github/workflows/determine-tidy-files.yml@d041ac9f1fa9f07a4ba335eb4c1c82233fb3fef6
uses: XRPLF/actions/.github/workflows/determine-tidy-files.yml@70145243b905dc3e040a61d39c00e178cfb96f71
run-clang-tidy:
name: Run clang tidy
needs: [determine-files]
if: ${{ needs.determine-files.outputs.cpp_changed_files != '' || needs.determine-files.outputs.need_full_run == 'true' }}
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-fecfc0c"
container: "ghcr.io/xrplf/xrpld/nix-debian:sha-060957e"
permissions:
contents: read
issues: write
@@ -43,7 +43,7 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@c00c22ada3bd6bcda48fcb0d62fbbab49fec8a0f
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
with:
enable_ccache: false
@@ -59,6 +59,12 @@ jobs:
with:
compiler: ${{ env.COMPILER }}
- name: Use cargo artifacts cache
uses: ./.github/actions/cargo-cache
with:
cache-directories: ${{ env.BUILD_DIR }}/corrosion
workspaces: crates -> ../${{ env.BUILD_DIR }}/cargo
- name: Setup Conan
uses: ./.github/actions/setup-conan
@@ -80,13 +86,13 @@ jobs:
-Dwerr=ON \
-Dxrpld=ON \
-Dverify_headers=ON \
-Drust=ON \
..
# clang-tidy needs headers generated from proto files
- name: Build libxrpl.libpb
- name: Build clang-tidy prerequisites
working-directory: ${{ env.BUILD_DIR }}
run: |
ninja -j ${{ steps.nproc.outputs.nproc }} xrpl.libpb
ninja -j ${{ steps.nproc.outputs.nproc }} tidy_prerequisites
- name: Run clang tidy
id: run_clang_tidy

View File

@@ -1,17 +1,40 @@
# Build Linux packages (DEB and RPM) from pre-built binary artifacts (xrpld and
# validator-keys). Discovers which configurations to package from linux.json
# (configs in "package_configs") and fans out one job per distro. Only
# linux/amd64 is supported; the runner is hardcoded in the job below.
# Build, verify and publish Linux packages from the pre-built xrpld and
# validator-keys artifacts, in three stages:
#
# - 'package' builds and signs one format per config that carries a "package"
# map in linux.json; that map names the container image and the format
# - 'test-install' installs what was built on a range of distros and runs the
# binaries there, so a package that cannot be installed never reaches Nexus
# - 'publish' uploads with the image's publish_pkg.py, doing a --dry-run
# unless 'publish: true'
#
# Only linux/amd64 is supported; the runner is hardcoded in the jobs below.
name: Package
on:
workflow_call:
inputs:
pkg_release:
description: "Package release number. Increment when repackaging the same executable."
publish:
description: "Whether to publish the packages after building them."
required: false
type: boolean
default: false
nexus_url:
description: "The base URL of the Nexus instance hosting the deb and rpm repositories."
required: false
type: string
default: "1"
default: https://packages.xrplf.org
secrets:
remote_username:
description: "The username of a Nexus account with write access to the repositories."
required: false
remote_password:
description: "The password or token for that Nexus account."
required: false
signing_key:
description: "Armoured PGP private key used to sign the RPMs. Required when publishing."
required: false
defaults:
run:
@@ -19,6 +42,7 @@ defaults:
env:
BUILD_DIR: build
PACKAGE_DIR: packages
jobs:
generate-matrix:
@@ -41,7 +65,7 @@ jobs:
package:
needs: [generate-matrix]
if: ${{ github.event.repository.visibility == 'public' }}
if: ${{ github.event.repository.visibility == 'public' || startsWith(github.ref, 'refs/tags/') }}
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
@@ -50,12 +74,17 @@ jobs:
contents: read
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
container: ${{ matrix.image }}
timeout-minutes: 30
timeout-minutes: 10
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
with:
enable_ccache: false
- name: Download pre-built xrpld binary
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
@@ -71,17 +100,210 @@ jobs:
- name: Make binaries executable
run: chmod +x "${BUILD_DIR}/xrpld" "${BUILD_DIR}/validator-keys"
- name: Determine release info
id: release_info
uses: ./.github/actions/release-info
- name: Build package
env:
PKG_RELEASE: ${{ inputs.pkg_release }}
run: ./package/build_pkg.sh
PACKAGE_TYPE: ${{ matrix.package_type }}
PKG_RELEASE: ${{ steps.release_info.outputs.pkg_release }}
CHANNEL: ${{ steps.release_info.outputs.channel }}
run: |
./package/build_pkg.py \
--package-type "${PACKAGE_TYPE}" \
--build-dir "${BUILD_DIR}" \
--pkg-release "${PKG_RELEASE}" \
--channel "${CHANNEL}"
# Before the upload, so the artifact, the tested package and the published
# package are the same bytes.
- name: Sign RPM
if: ${{ inputs.publish && matrix.package_type == 'rpm' }}
env:
PKG_SIGNING_KEY: ${{ secrets.signing_key }}
run: ./package/sign_rpm.py --package-dir "${BUILD_DIR}"
# Split from the debug symbols, which are an order of magnitude larger, so
# that test-install downloads only what it installs.
- name: Upload package artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ matrix.xrpld_artifact_name }}-pkg
path: |
${{ env.BUILD_DIR }}/debbuild/*.deb
${{ env.BUILD_DIR }}/debbuild/*.ddeb
${{ env.BUILD_DIR }}/rpmbuild/RPMS/**/*.rpm
${{ env.BUILD_DIR }}/debbuild/xrpld_*.deb
${{ env.BUILD_DIR }}/rpmbuild/RPMS/**/xrpld-[0-9]*.rpm
if-no-files-found: error
- name: Upload debug symbol artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ matrix.xrpld_artifact_name }}-pkg-debug
path: |
${{ env.BUILD_DIR }}/debbuild/xrpld-dbgsym_*.deb
${{ env.BUILD_DIR }}/debbuild/xrpld-dbgsym_*.ddeb
${{ env.BUILD_DIR }}/rpmbuild/RPMS/**/xrpld-debuginfo-*.rpm
if-no-files-found: error
# Every distro family the packages target, oldest release first, so both ends
# of the dependency range they declare are exercised.
test-install:
needs: [package]
strategy:
fail-fast: false
matrix:
include:
- package_type: deb
image: debian:11
- package_type: deb
image: debian:12
- package_type: deb
image: debian:13
- package_type: deb
image: ubuntu:20.04
- package_type: deb
image: ubuntu:22.04
- package_type: deb
image: ubuntu:24.04
- package_type: deb
image: ubuntu:26.04
- package_type: rpm
image: almalinux:9
- package_type: rpm
image: almalinux:10
- package_type: rpm
image: rockylinux/rockylinux:9
- package_type: rpm
image: rockylinux/rockylinux:10
- package_type: rpm
image: registry.access.redhat.com/ubi9/ubi
- package_type: rpm
image: registry.access.redhat.com/ubi10/ubi
name: "install ${{ matrix.package_type }} on ${{ matrix.image }}"
permissions:
contents: read
runs-on: ubuntu-latest
container: ${{ matrix.image }}
timeout-minutes: 5
steps:
# Both formats land in one directory; the step below picks its own by
# extension, so this stays independent of the artifact names.
- name: Download package artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: "*-pkg"
merge-multiple: true
path: ${{ env.PACKAGE_DIR }}
- name: Find the package
id: find
env:
PACKAGE_TYPE: ${{ matrix.package_type }}
run: |
package="$(find "${PACKAGE_DIR}" -type f -name "*.${PACKAGE_TYPE}" -print -quit)"
test -n "${package}" || {
echo "no .${PACKAGE_TYPE} found in ${PACKAGE_DIR}" >&2
exit 1
}
echo "package=${package}" >>"${GITHUB_OUTPUT}"
# Debian 11 went end-of-life on 2026-08-31
# (https://www.debian.org/News/2026/20260831) and its packages are
# already partly gone from deb.debian.org, so switch to the
# snapshot.debian.org entries the image ships commented out in its
# sources.list: they are pinned to the snapshot the image was built
# from, so they serve every version it needs and never go away.
# Snapshots keep their original, long-passed Valid-Until, hence the
# disabled check; the retries absorb snapshot.debian.org's throttling.
- name: Switch Debian 11 to snapshot.debian.org
if: ${{ matrix.image == 'debian:11' }}
run: |
sed -i 's|^deb |# deb |; s|^# deb http://snapshot|deb http://snapshot|' /etc/apt/sources.list
printf '%s\n' \
'Acquire::Check-Valid-Until "false";' \
'Acquire::Retries "3";' \
>/etc/apt/apt.conf.d/99snapshot
- name: Install the DEB
if: ${{ matrix.package_type == 'deb' }}
env:
DEBIAN_FRONTEND: noninteractive
PACKAGE: ${{ steps.find.outputs.package }}
run: |
# Stock Debian and Ubuntu images carry no package lists, so apt has
# nothing to resolve the systemd dependency from until it fetches them.
apt-get update -qq
apt-get install -y "./${PACKAGE}"
- name: Install the RPM
if: ${{ matrix.package_type == 'rpm' }}
env:
PACKAGE: ${{ steps.find.outputs.package }}
run: dnf install -y "./${PACKAGE}"
- name: Run xrpld
run: xrpld --version
- name: Run validator-keys
run: validator-keys --version
- name: Run rippled, the legacy compatibility symlink
run: rippled --version
- name: Check the service account
run: id xrpld
- name: Check the state directory
run: test -d /var/lib/xrpld
- name: Check the log directory
run: test -d /var/log/xrpld
publish:
needs: [generate-matrix, package, test-install]
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
name: "publish ${{ matrix.xrpld_artifact_name }}"
permissions:
contents: read
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
container: ${{ matrix.image }}
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
with:
enable_ccache: false
# Both artifacts, so the debug symbols are published alongside the package.
- name: Download package artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: ${{ matrix.xrpld_artifact_name }}-pkg*
merge-multiple: true
path: ${{ env.PACKAGE_DIR }}
- name: Determine release info
id: release_info
uses: ./.github/actions/release-info
- name: Publish package
env:
CHANNEL: ${{ steps.release_info.outputs.channel }}
DRY_RUN_OPTION: ${{ !inputs.publish && '--dry-run' || '' }}
NEXUS_URL: ${{ inputs.nexus_url }}
NEXUS_USERNAME: ${{ inputs.publish && secrets.remote_username || '' }}
NEXUS_PASSWORD: ${{ inputs.publish && secrets.remote_password || '' }}
run: |
publish_pkg.py \
--channel "${CHANNEL}" \
--package-dir "${PACKAGE_DIR}" \
--nexus-url "${NEXUS_URL}" \
${DRY_RUN_OPTION}

84
.github/workflows/reusable-rust.yml vendored Normal file
View File

@@ -0,0 +1,84 @@
# Clippy, coverage and documentation for the Rust crates in crates/. Each runs
# as an independent job on a GitHub-hosted runner, but inside the same container
# image used to build the crates in the C++/Corrosion path, so the toolchain
# (and therefore the lints and the cargo cache) matches what production builds
# use. Coverage is the exception: it needs the nightly rustc that honours
# #[coverage(off)], which the image carries alongside the pinned stable.
#
# Rust unit tests are deliberately NOT run here. They run as part of the C++
# build (reusable-build-test-config.yml), which already compiles the crates on a
# self-hosted runner, so there is no need to provision a toolchain again.
name: Rust
on:
workflow_call:
secrets:
CODECOV_TOKEN:
description: "The Codecov token to use for uploading coverage reports."
required: true
defaults:
run:
shell: bash
working-directory: crates
permissions:
contents: read
jobs:
clippy:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Use cargo artifacts cache
uses: ./.github/actions/cargo-cache
- name: Run clippy
run: cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
coverage:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Use the nightly Rust toolchain
run: rust-nightly path >>"${GITHUB_PATH}"
- name: Use cargo artifacts cache
uses: ./.github/actions/cargo-cache
- name: Generate coverage report
run: cargo llvm-cov nextest --workspace --all-features --locked --no-tests=warn --lcov --output-path lcov.info
- name: Upload coverage report
if: ${{ github.repository == 'XRPLF/rippled' }}
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with:
disable_search: true
disable_telem: true
fail_ci_if_error: true
files: crates/lcov.info
flags: rust
plugins: noop
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
doc:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Use cargo artifacts cache
uses: ./.github/actions/cargo-cache
- name: Build documentation
env:
RUSTDOCFLAGS: "-D warnings"
run: cargo doc --workspace --no-deps --all-features --locked

View File

@@ -40,7 +40,7 @@ defaults:
jobs:
upload:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-fecfc0c
container: ghcr.io/xrplf/xrpld/nix-ubuntu:sha-060957e
env:
REMOTE_NAME: ${{ inputs.remote_name }}
CONAN_LOGIN_USERNAME_XRPLF: ${{ secrets.remote_username }}
@@ -49,9 +49,14 @@ jobs:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Generate build version number
id: version
uses: ./.github/actions/generate-version
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
with:
enable_ccache: false
- name: Determine release info
id: release_info
uses: ./.github/actions/release-info
- name: Set up Conan
uses: ./.github/actions/setup-conan
@@ -64,8 +69,8 @@ jobs:
- name: Upload Conan recipe (version)
run: |
conan export . --version=${{ steps.version.outputs.version }}
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/${{ steps.version.outputs.version }}
conan export . --version=${{ steps.release_info.outputs.version }}
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/${{ steps.release_info.outputs.version }}
# When this workflow is triggered by a push event, it will always be when merging into the
# 'develop' branch, see on-trigger.yml.
@@ -92,4 +97,4 @@ jobs:
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/release
outputs:
ref: xrpl/${{ steps.version.outputs.version }}
ref: xrpl/${{ steps.release_info.outputs.version }}

View File

@@ -68,10 +68,15 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@c00c22ada3bd6bcda48fcb0d62fbbab49fec8a0f
uses: XRPLF/actions/prepare-runner@b3e255d74d785d053e4903da8ac90983cd7d9e82
with:
enable_ccache: false
# Before any step that uses a build tool, composite actions included.
- name: Setup Nix environment
if: ${{ matrix.toolchain == 'nix' }}
uses: ./.github/actions/setup-nix-env
- name: Print build environment
uses: XRPLF/actions/print-build-env@59dec886e4afb05a1724443af08baccbc045b574
@@ -87,7 +92,9 @@ jobs:
with:
compiler: ${{ matrix.compiler }}
# `setup-nix-env` already did this for the Nix toolchain.
- name: Setup Conan
if: ${{ matrix.toolchain != 'nix' }}
env:
SANITIZERS: ${{ matrix.sanitizers }}
uses: ./.github/actions/setup-conan
@@ -106,6 +113,10 @@ jobs:
log_verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }}
sanitizers: ${{ matrix.sanitizers }}
- name: Check the Conan cache for Nix store references (Nix toolchain)
if: ${{ matrix.toolchain == 'nix' }}
run: ./bin/check-nix-store-refs.sh "${CONAN_HOME}"
- name: Log into Conan remote
if: ${{ github.repository == 'XRPLF/rippled' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
run: conan remote login "${CONAN_REMOTE_NAME}" "${{ secrets.NEXUS_REMOTE_USERNAME }}" --password "${{ secrets.NEXUS_REMOTE_PASSWORD }}"

12
.gitignore vendored
View File

@@ -72,11 +72,16 @@ DerivedData
/.zed/
# AI tools.
# Shared/committable AI agent config (AGENTS.md, CLAUDE.md, GEMINI.md, .claude/settings.json,
# tool-specific rules files, etc.) should be checked in — see CONTRIBUTING.md. Only the
# personal/local variants below are ignored.
/.agent
/.agents
/.augment
/.claude
/CLAUDE.md
/.claude/settings.local.json
AGENTS.override.md
CLAUDE.local.md
GEMINI.local.md
# Python
__pycache__
@@ -89,3 +94,6 @@ target/
# clangd cache
/.cache
# Rust build directory
crates/target

View File

@@ -62,6 +62,20 @@ repos:
types_or: [c++, c, proto]
exclude: ^include/xrpl/protocol_autogen/(transactions|ledger_entries)/
- repo: local
hooks:
- id: cargo-fmt
name: cargo fmt
entry: cargo fmt --manifest-path crates/Cargo.toml --all
language: system
types: [rust]
pass_filenames: false # rustfmt formats the whole workspace
- id: check-coverage-attrs
name: check Rust coverage attributes
entry: ./bin/pre-commit/check_rust_coverage_attrs.py
language: python
files: ^crates/.*\.rs$
- repo: https://github.com/BlankSpruce/gersemi-pre-commit
rev: e98930bdc210d3387007f9252d8c1694ea7e410f # frozen: 0.27.7
hooks:
@@ -73,11 +87,27 @@ repos:
- id: prettier
args: [--end-of-line=auto]
# Scoped to package/: the rest of the repo's Python has pre-existing findings,
# so widening these is its own change.
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 7c55798a78262d14b2074abf623d8a992ebb70d4 # frozen: v0.16.2
hooks:
- id: ruff-check
args: [--fix]
files: ^package/.*\.py$
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 4160603246a6b365d4a2af661c6d71b0a0f50478 # frozen: 26.5.1
hooks:
- id: black
- repo: https://github.com/pre-commit/mirrors-mypy
rev: 41e691678310dfd3833f7ab4e180ddb014310356 # frozen: v2.3.0
hooks:
- id: mypy
args: [--strict]
files: ^package/.*\.py$
- repo: https://github.com/scop/pre-commit-shfmt
rev: 05c1426671b9237fb5e1444dd63aa5731bec0dfb # frozen: v3.13.1-1
hooks:

42
AGENTS.md Normal file
View File

@@ -0,0 +1,42 @@
# AGENTS.md
This file provides guidance to AI coding agents (Claude Code, and other AGENTS.md-compatible tools) when working with code in this repository.
## Build
Required on Linux/macOS: use the Nix devshell, which sets up the compiler, Conan, ccache, and (optionally) Rust automatically.
```bash
nix develop
```
For alternate devshell variants (specific compiler, no-compiler, coverage), see [docs/build/nix.md](./docs/build/nix.md). For the manual build steps, CMake options, and protocol codegen commands, see [BUILD.md](./BUILD.md) (`## Steps`, `## Options`, `## Code generation`).
Rust crate tests (independent of the CMake build): `cargo test --manifest-path crates/Cargo.toml --workspace` (CI uses `cargo nextest`).
## Testing
Unit tests are a custom framework built into the `xrpld` binary itself (not Boost.Test/GTest/Catch); see [CONTRIBUTING.md](./CONTRIBUTING.md#unit-tests) for the basic invocation. Notes not covered there:
- A suite's `--unittest` name is built from the arguments to its `BEAST_DEFINE_TESTSUITE`/`BEAST_DEFINE_TESTSUITE_PRIO` macro (usually at the bottom of the test file), in reverse order and joined with `.`: `BEAST_DEFINE_TESTSUITE(Credentials, app, xrpl)``xrpl.app.Credentials`.
- `--unittest-arg` does nothing — don't use it.
- Tests that run offline in under a minute should be automatic `--unittest` suites; anything else is a manual/integration test.
- New tests should be written using `gtest` under `src/tests/` unless that isn't possible, in which case fall back to the legacy Beast framework under `src/test/`. `tests/` (top-level) holds integration tests exercised against `libxrpl`/`xrpld`.
## Lint/Format
See [CONTRIBUTING.md](./CONTRIBUTING.md#pre-commit-hooks) for `pre-commit` setup and [CONTRIBUTING.md](./CONTRIBUTING.md#clang-tidy) for `clang-tidy` (opt-in, needs local `clang-tidy` and generated headers).
## Code Style
New file placement and header levelization: see [CONTRIBUTING.md](./CONTRIBUTING.md#before-making-a-pull-request). Braces, whitespace, member order, and other conventions: see [docs/CodingStyle.md](./docs/CodingStyle.md). `XRPL_ASSERT`/`UNREACHABLE` contracts: see [CONTRIBUTING.md](./CONTRIBUTING.md#contracts-and-instrumentation). Commit messages: see [CONTRIBUTING.md](./CONTRIBUTING.md#good-commit-messages).
## Architecture
Paths below reflect the current layout; update this section if modularization moves a subsystem to a different directory.
- `include/xrpl/` + `src/libxrpl/` — the core protocol library: ledger, shamap, consensus, crypto, json, resource, nodestore, rdb, peerfinder, and `tx/` (transaction application: `Transactor.cpp`, `applySteps.cpp`, invariants, payment paths). `tx/transactors/` has one file per transaction type, grouped by subsystem: `escrow/`, `vault/`, `lending/`, `sponsor/`, `nft/`, `token/` (MPT), `payment_channel/`, `permissioned_domain/`, `dex/`, `oracle/`, `did/`, `credentials/`, `bridge/`, `check/`, `delegate/`, `account/`, `system/`. Any change to transaction-processing behavior must be gated behind an Amendment.
- `src/xrpld/` — the server application built on top of `libxrpl`: `app`, `core`, `overlay` (P2P networking), `peerfinder`, `perflog`, `rpc`, `shamap`. `main` builds an `ApplicationImp` implementing `Application`; most components hold a reference to it (`app_`), giving broad cross-component access — expect to trace call chains through `Application&`.
- `src/test/` — unit tests mirroring the subsystems above, plus `jtx/` (the transaction-building test DSL — e.g. `jtx/escrow.h`, `jtx/vault.h`, `jtx/sponsor.h`, `jtx/permissioned_dex.h`) and `unit_test/` (the custom test framework itself, derived from Beast).
- `src/tests/` — unit tests for `libxrpl` written in `gtest`, gradually replacing the `src/test` equivalents.
- `crates/` — a Rust workspace (only built with `-Dxrpld -Drust=ON`) bridged into C++ via `cxxbridge`/the `cxx` crate; currently just a `hello_world` interop scaffold. Requires the Rust toolchain pinned in `rust-toolchain.toml` (the Nix devshell provides it automatically).

View File

@@ -22,17 +22,56 @@ API version 2 is available in `xrpld` version 2.0.0 and later. See [API-VERSION-
This version is supported by all `xrpld` versions. For WebSocket and HTTP JSON-RPC requests, it is currently the default API version used when no `api_version` is specified.
## Unreleased
## XRP Ledger server version 3.4.0
This section contains changes targeting a future version.
Version 3.4.0 is not yet released. These changes are available in the 3.4.0 beta releases.
### Additions
### Additions in 3.4.0
- `book_offers`, `account_offers`: With the `OfferQualifiers` amendment, an offer entry may now include `all_or_none: true` (the offer carries the `lsfAllOrNone` flag) and/or `min_quantity` (the offer's `MinQuantity` amount). These mark execution-qualified ("contingent") offers that cannot be taken to arbitrary depth; clients should exclude them from quoted/takeable depth. The `OfferCreate` transaction gains the `tfAllOrNone` and `tfPostOnly` flags and an optional `MinQuantity` field, and a marketable `tfPostOnly` offer is rejected with the new `tecWOULD_CROSS` result.
- `account_tx`: Added an optional `delegate` request object to filter delegated transactions. The object requires `delegate_filter`, which must be either `actor` for transactions owned by the requested account but signed by another account, or `authorizer` for transactions signed by the requested account on behalf of another account. The optional `counter_party` account narrows the results to a specific signer/delegate for `actor` or a specific owner/delegator for `authorizer`. Malformed `delegate`, `delegate_filter`, and `counter_party` values return standard invalid field errors, and invalid account IDs return `actMalformed`.
When paginating delegate-filtered queries, a marker from a delegate-filtered query includes a `delegate` flag and is only valid for follow-up requests that also supply `delegate` (mixing marker conventions returns `invalidParams`). Because filtering is applied after the ledger scan, a page may contain fewer results than `limit` (possibly zero) while still returning a marker, so callers must continue until no marker is present.
- `ledger`: `nftoken_id`, `nftoken_ids`, and `offer_id` are now included in transaction metadata when transactions are expanded (`expand`, or admin-only `full`), matching the `tx`, `account_tx`, and `subscribe` (`transactions` stream) responses. ([#5706](https://github.com/XRPLF/rippled/pull/5706))
### Bugfixes in 3.4.0
- `sign`, `sign_for`, `submit`: `signature_target` now returns `invalidParams` unless it names `CounterpartySignature` or `SponsorSignature`. It previously accepted any inner object field, such as `Book` or `NFToken`, and signed into it.
- `sign`, `sign_for`, `submit`, `submit_multisigned`: With `fixCleanup3_4_0` enabled, a signature in `CounterpartySignature` or `SponsorSignature` covers a different prefix than the transaction's own signature, so a signature can no longer be moved from one of those roles into another. Clients that build these signatures themselves must use the new prefixes: `CPT` and `CPM` (single- and multi-signing) for `CounterpartySignature`, and `SPN` and `SPM` for `SponsorSignature`.
- `get_aggregate_price`: Duplicate entries in the `oracles` request array are now ignored. [#6586](https://github.com/XRPLF/rippled/pull/6586)
- `vault_info`: Errors now identify what the request got wrong instead of reporting every failure as the unregistered token `malformedRequest`, and the `error`, `error_code` and `error_message` fields now agree with each other. An invalid `vault_id` or `seq` returns `invalidParams`, an invalid `owner` returns `actMalformed`, and a request that mixes `vault_id` with `owner`/`seq` or supplies neither returns `invalidParams` with a message naming the accepted combinations. [#8015](https://github.com/XRPLF/rippled/pull/8015)
- `vault_info`: A well-formed all-zero `vault_id` now returns `entryNotFound` instead of being rejected as malformed, and `entryNotFound` responses now include `error_code` and `error_message`. Clients that request `ripplerpc` 3.0 or above therefore receive HTTP 400 with that error rather than HTTP 200. [#8015](https://github.com/XRPLF/rippled/pull/8015)
- `vault_info`: `vault_id` and `owner` must now be strings, matching how `ledger_entry` reads the same fields. An object or an array in either field previously produced an internal error, and a number was silently converted to its decimal text; `vault_id` now returns `invalidParams` and `owner` returns `actMalformed`. [#8015](https://github.com/XRPLF/rippled/pull/8015)
- `gateway_balances`: The `account` and `ident` fields now return an `invalidParams` error if the value is not a string, instead of an `internal` error. [#7655](https://github.com/XRPLF/rippled/pull/7655)
- `account_lines`: The `peer` field now returns an error if the value is not a string. [#7728](https://github.com/XRPLF/rippled/pull/7728)
- `ledger`: `delivered_amount` is now included in the metadata of successful `AccountDelete` transactions when transactions are expanded (`expand`, or admin-only `full`). Previously it was only added for `Payment` and `CheckCash`, which made `ledger` inconsistent with `tx` and `account_tx`. [#5706](https://github.com/XRPLF/rippled/pull/5706)
## XRP Ledger server version 3.3.0
[Version 3.3.0](https://github.com/XRPLF/rippled/releases/tag/3.3.0) was released on Aug 6, 2026.
### Additions in 3.3.0
- `account_tx`: Added an optional `delegate` request object to filter delegated transactions. The object requires `delegate_filter`, which must be either `actor` for transactions owned by the requested account but signed by another account, or `authorizer` for transactions signed by the requested account on behalf of another account. The optional `counter_party` account narrows the results to a specific signer/delegate for `actor` or a specific owner/delegator for `authorizer`. Malformed `delegate`, `delegate_filter`, and `counter_party` values return standard invalid field errors, and invalid account IDs return `actMalformed`. When paginating delegate-filtered queries, a marker from a delegate-filtered query includes a `delegate` flag and is only valid for follow-up requests that also supply `delegate` (mixing marker conventions returns `invalidParams`). Because filtering is applied after the ledger scan, a page may contain fewer results than `limit` (possibly zero) while still returning a marker, so callers must continue until no marker is present. ([#6126](https://github.com/XRPLF/rippled/pull/6126))
## XRP Ledger server version 3.2.1
[Version 3.2.1](https://github.com/XRPLF/rippled/releases/tag/3.2.1) was released on Aug 1, 2026.
This release contains bug fixes only and no API changes.
## XRP Ledger server version 3.2.0
[Version 3.2.0](https://github.com/XRPLF/rippled/releases/tag/3.2.0) was released on Jun 16, 2026.
### Additions in 3.2.0
- `ledger_entry`, `account_objects`: Added the `Ballot` and `BallotVote` ledger entry types introduced by the `ConfidentialVoting` amendment. `ledger_entry` accepts a `ballot` request object (`owner` + `seq`) and a `ballot_vote` request object (`ballot_id` + `account`), or a hex object ID for either. `account_objects` returns these entries and accepts them as `type` filters.
- `account_tx`: Added an optional `delegate` request object to filter delegated transactions. The object requires `delegate_filter`, which must be either `actor` for transactions owned by the requested account but signed by another account, or `authorizer` for transactions signed by the requested account on behalf of another account. The optional `counter_party` account narrows the results to a specific signer/delegate for `actor` or a specific owner/delegator for `authorizer`. Malformed `delegate`, `delegate_filter`, and `counter_party` values return standard invalid field errors, and invalid account IDs return `actMalformed`.
When paginating delegate-filtered queries, a marker from a delegate-filtered query includes a `delegate` flag and is only valid for follow-up requests that also supply `delegate` (mixing marker conventions returns `invalidParams`). Because filtering is applied after the ledger scan, a page may contain fewer results than `limit` (possibly zero) while still returning a marker, so callers must continue until no marker is present.
- `ledger_entry`, `account_objects`: The `Delegate` ledger entry now includes an optional `DestinationNode` field, which stores the index into the authorized account's owner directory. This field is present on entries created after bidirectional directory tracking was introduced and may appear in RPC responses for those entries. ([#6681](https://github.com/XRPLF/rippled/pull/6681))
- `server_definitions`: Added the following new sections to the response ([#6321](https://github.com/XRPLF/rippled/pull/6321)):
- `TRANSACTION_FORMATS`: Describes the fields and their optionality for each transaction type, including common fields shared across all transactions.
- `LEDGER_ENTRY_FORMATS`: Describes the fields and their optionality for each ledger entry type, including common fields shared across all ledger entries.
@@ -40,9 +79,8 @@ This section contains changes targeting a future version.
- `LEDGER_ENTRY_FLAGS`: Maps ledger entry type names to their flags and flag values.
- `ACCOUNT_SET_FLAGS`: Maps AccountSet flag names (asf flags) to their numeric values.
### Bugfixes
### Bugfixes in 3.2.0
- `get_aggregate_price`: Duplicate entries in the `oracles` request array are now ignored. [#6586](https://github.com/XRPLF/rippled/pull/6586)
- Peer Crawler: The `port` field in `overlay.active[]` now consistently returns an integer instead of a string for outbound peers. [#6318](https://github.com/XRPLF/rippled/pull/6318)
- `ping`: The `ip` field is no longer returned as an empty string for proxied connections without a forwarded-for header. It is now omitted, consistent with the behavior for identified connections. [#6730](https://github.com/XRPLF/rippled/pull/6730)
- gRPC `GetLedgerDiff`: Fixed error message that incorrectly said "base ledger not validated" when the desired ledger was not validated. [#6730](https://github.com/XRPLF/rippled/pull/6730)
@@ -54,8 +92,24 @@ This section contains changes targeting a future version.
- `submit`: The `fail_hard` field now returns an error if the value is not a boolean. [#6529](https://github.com/XRPLF/rippled/pull/6529)
- `subscribe`: The `taker` field in the `books` array now returns `actMalformed` instead of `badIssuer` if the value is not a valid account. [#6529](https://github.com/XRPLF/rippled/pull/6529)
- Fixed a bug in `Forwarded` HTTP header parsing where the extracted IP address could be incorrect when no comma or semicolon delimiter follows the address. This could cause the server to misidentify a client's IP address when operating behind a reverse proxy. [#6529](https://github.com/XRPLF/rippled/pull/6529)
- `gateway_balances`: The `account` and `ident` fields now return an `invalidParams` error if the value is not a string, instead of an `internal` error. [#7655](https://github.com/XRPLF/rippled/pull/7655)
- `account_lines`: The `peer` field now returns an error if the value is not a string. [#7728](https://github.com/XRPLF/rippled/pull/7728)
## XRP Ledger server version 3.1.3
[Version 3.1.3](https://github.com/XRPLF/rippled/releases/tag/3.1.3) was released on May 8, 2026.
This release contains bug fixes only and no API changes.
## XRP Ledger server version 3.1.2
[Version 3.1.2](https://github.com/XRPLF/rippled/releases/tag/3.1.2) was released on Mar 12, 2026.
This release contains bug fixes only and no API changes.
## XRP Ledger server version 3.1.1
[Version 3.1.1](https://github.com/XRPLF/rippled/releases/tag/3.1.1) was released on Feb 23, 2026.
This release contains bug fixes only and no API changes.
## XRP Ledger server version 3.1.0

View File

@@ -304,6 +304,7 @@ See [Sanitizers docs](./docs/build/sanitizers.md) for more details.
| ---------------- | ------------- | ----------------------------------------------------------------------------- |
| `assert` | OFF | Force enabling assertions. |
| `coverage` | OFF | Prepare the coverage report. |
| `rust` | OFF | Build the Rust crates and the C++ code that depends on them. |
| `tests` | OFF | Build tests. |
| `unity` | OFF | Configure a unity build. |
| `verify_headers` | ON | Make the `verify-headers` target available to compile each header on its own. |
@@ -316,6 +317,30 @@ memory) since they concatenate sources into fewer translation units. Non-unity
builds may be faster for incremental builds, and can be helpful for detecting
`#include` omissions.
### Rust crates
The Rust crates in `crates/` are only part of the build when `rust` is ON. With
`-Drust=OFF` (the default) the `crates` directory is not added to the build, no
cxxbridge bindings are generated, and the C++ tests that exercise the Rust
interop are not compiled — so no Rust toolchain is needed. CI builds always pass
`-Drust=ON`.
With `-Drust=ON` you need one extra dependency: a Rust toolchain (`cargo`,
`rustc`) matching the channel pinned in
[`rust-toolchain.toml`](./rust-toolchain.toml), which compiles the crates and
generates the cxxbridge bindings. It is provided by the
[Nix development shell](./docs/build/nix.md), so `-Drust=ON` works there without
any extra setup; otherwise install it as described in
[Rust](./docs/build/environment.md#rust).
The crates also have their own Rust unit tests. Those are run with `cargo` and
need only the Rust toolchain, independently of CMake and of the `rust` option
(CI runs them with `cargo nextest`):
```bash
cargo test --manifest-path crates/Cargo.toml --workspace
```
### Verifying headers
The regular build only compiles `.cpp` files, so a header is only ever checked

1
CLAUDE.md Symbolic link
View File

@@ -0,0 +1 @@
AGENTS.md

View File

@@ -99,6 +99,7 @@ if(only_docs)
return()
endif()
include(deps/dilithium)
include(deps/Boost)
add_subdirectory(external/antithesis-sdk)
@@ -114,6 +115,7 @@ find_package(OpenSSL REQUIRED)
find_package(secp256k1 REQUIRED)
find_package(SOCI REQUIRED)
find_package(SQLite3 REQUIRED)
find_package(wasmi REQUIRED)
find_package(xxHash REQUIRED)
target_link_libraries(
@@ -158,7 +160,13 @@ if(coverage)
include(XrplCov)
endif()
add_custom_target(tidy_prerequisites)
if(rust)
add_subdirectory(crates)
endif()
include(XrplCore)
include(XrplProtocolAutogen)
include(XrplInstall)
include(XrplValidatorKeys)

View File

@@ -59,6 +59,17 @@ to an existing XLS. Neither change will be released (in an amendment's
case, marked as `Supported::yes`) until the corresponding XLS's status
is `Final`.
## AI coding agents
[`AGENTS.md`](./AGENTS.md) (and its `CLAUDE.md` symlink, for Claude Code) holds shared, checked-in guidance for AI coding agents working in this repository — build/test/lint commands and architecture notes. Additional `AGENTS.md` files may exist in subdirectories to give agents context specific to that part of the codebase; whenever you add one, also add a `CLAUDE.md` symlink pointing to it (`ln -s AGENTS.md CLAUDE.md`) so Claude Code picks it up too.
If you want to give an agent personal instructions that shouldn't be shared with other contributors (e.g. your own workflow preferences), those are gitignored, not checked in:
- `CLAUDE.local.md` — read by Claude Code alongside `CLAUDE.md`.
- `AGENTS.override.md` — read by AGENTS.md-compatible tools that support a personal override file layered on top of `AGENTS.md`.
Likewise, `.claude/settings.local.json` is for personal, untracked Claude Code settings, while `.claude/settings.json` is shared.
## Before making a pull request
(Or marking a draft pull request as ready.)
@@ -82,7 +93,7 @@ If you create new source files, they must be organized as follows:
under `include/xrpl`, and source (`.cpp`) files must go under
`src/libxrpl`.
- All other non-test files must go under `src/xrpld`.
- All test source files must go under `src/test`.
- New test source files should use `gtest` and go under `src/tests`, unless that isn't possible, in which case they should use our legacy test framework and go under `src/test`.
- All benchmark source files must go under `src/benchmarks`.
The source must be formatted according to the style guide below. The easiest
@@ -225,8 +236,9 @@ environment, so you don't need to install most of the individual tools
yourself. The version of each hook sourced from an external repository
(`clang-format`, `gersemi`, etc.) is pinned in that file, so running the hooks
locally uses exactly the same versions as CI. A few `local` hooks — most notably
`clang-tidy` — run tools from your own environment; see
[Installing clang-tidy](#installing-clang-tidy) for how to get those.
`clang-tidy` and `cargo fmt` — run tools from your own environment; see
[Installing clang-tidy](#installing-clang-tidy) and
[Rust](./docs/build/environment.md#rust) for how to get those.
To get started, install `pre-commit` and enable the git hook scripts:
@@ -255,6 +267,7 @@ The hooks configured in this repository include, among others:
- `clang-tidy` — C++ static analysis (see [Clang-tidy](#clang-tidy)); opt in with `TIDY=1`
- `fix-include-style`, `fix-pragma-once`, `check-doxygen-style` — C++ hygiene
- `gersemi` — CMake formatting
- `cargo fmt` — Rust formatting for the crates in `crates/`
- `prettier`, `black`, `shfmt` — formatting for JavaScript/JSON/Markdown, Python, and shell
- `cspell` — spell checking
@@ -319,7 +332,11 @@ See the [environment setup guide](./docs/build/environment.md#clang-tidy) for ho
### Running clang-tidy locally
Before running clang-tidy, you must build the project to generate required files (particularly protobuf headers). Refer to [`BUILD.md`](./BUILD.md) for build instructions.
Before running clang-tidy, you must generate the files it depends on (protobuf headers, and, when the project is configured with `-Drust=ON`, the cxxbridge headers from the Rust crates). Configure the project as described in [`BUILD.md`](./BUILD.md), then build the `tidy_prerequisites` target, which generates all of them:
```bash
cmake --build build --target tidy_prerequisites
```
#### Via pre-commit (recommended)

View File

@@ -54,6 +54,7 @@ Here are some good places to start learning the source code:
| `./docs` | Source documentation files and doxygen config. |
| `./cfg` | Example configuration files. |
| `./src` | Source code. |
| `./crates` | Rust source code. |
Some of the directories under `src` are external repositories included using
git-subtree. See those directories' README files for more details.

111
bin/check-nix-store-refs.sh Executable file
View File

@@ -0,0 +1,111 @@
#!/usr/bin/env bash
# Fail if a binary under <path> records a /nix/store path it resolves at run
# time. See docs/build/nix.md#prebuilt-packages for why that matters.
#
# <path> is a file or a directory. macOS: nothing may reference the store, so
# point it at whole trees. Linux: the toolchain always writes the store into
# PT_INTERP and RUNPATH, so only at what cmake/PatchNixBinary.cmake retargets.
#
# Only Mach-O / ELF is inspected. Static archives hold store paths in debug info
# alone; the scripts in a Conan cache are all git hook samples and autotools
# scratch, 36 false positives to 0 real.
#
# Usage: bin/check-nix-store-refs.sh <path>
set -euo pipefail
if [ "$#" -ne 1 ]; then
echo "usage: $0 <path>" >&2
exit 2
fi
if [ ! -e "$1" ]; then
echo "$0: no such path: $1" >&2
exit 2
fi
case "$(uname -s)" in
Darwin)
format=Mach-O
recorded_paths=macho_recorded_paths
tool=otool
;;
Linux)
format=ELF
recorded_paths=elf_recorded_paths
tool=readelf
;;
*)
echo "Unsupported OS - skipping the Nix store reference check."
exit 0
;;
esac
# `pipefail` would catch this too, but only as a bare nonzero exit.
if ! command -v "${tool}" >/dev/null; then
echo "$0: ${tool} not found; cannot inspect binaries" >&2
exit 2
fi
# Both list what the file records. `ldd` would answer what this machine resolves
# now, which is wrong both ways: store paths for a correctly patched binary,
# silence for a store RUNPATH that resolves nowhere.
# `name` covers LC_ID_DYLIB and LC_LOAD*_DYLIB, `path` covers LC_RPATH.
macho_recorded_paths() {
otool -l "$1" | sed -nE 's#^ *(name|path) ([^ ]*).*#\2#p'
}
# RPATH and RUNPATH are colon-separated.
elf_recorded_paths() {
readelf -ldW "$1" |
sed -nE \
-e 's#.*program interpreter: ([^]]*)\].*#\1#p' \
-e 's#.*\((RPATH|RUNPATH|NEEDED)\).*\[([^]]*)\].*#\2#p' |
tr ':' '\n'
}
checked=0
skipped=0
leaked=0
while IFS= read -r file; do
case "$(file -b "${file}" 2>/dev/null)" in
*"${format}"*) ;;
*)
skipped=$((skipped + 1))
continue
;;
esac
checked=$((checked + 1))
# Filter after extracting, or a search path starting elsewhere ($ORIGIN)
# hides the rest. `sed` not `grep`: grep calls "no matches" a failure, and
# the `|| true` that would need masks a broken pipeline too.
refs="$("${recorded_paths}" "${file}" | sed -n '\#^/nix/store/#p' | sort -u)"
if [ -n "${refs}" ]; then
leaked=$((leaked + 1))
echo "::error file=${file}::references the Nix store at run time"
echo "${file}"
echo "${refs}" | sed 's/^/ /'
fi
done < <(find "$1" -type f \( -perm -u+x -o -name '*.dylib' -o -name '*.so*' \))
echo "$1: checked ${checked}, skipped ${skipped}, ${leaked} with Nix store references."
if [ "${leaked}" -ne 0 ]; then
cat >&2 <<'EOF'
Fixes, in order of preference:
- A Conan package built before this check existed: drop it
(`conan remove '<name>/*'`) and rebuild.
- A binary that should have been retargeted to the system loader: check that
cmake/PatchNixBinary.cmake ran for it.
- Link the macOS system library instead of the Nix one - see
libresolvSystemStub in nix/darwin.nix.
- No system library exists (libstdc++): link it statically.
- None of the above: pin the toolchain into the package ID, following
`user.package:libc_version` in conan/profiles/ci.
EOF
exit 1
fi

View File

@@ -15,10 +15,14 @@
# - Windows: the core build tools only (CMake, Conan, Git, Python).
# MSVC is expected to be provided separately and is not checked here.
#
# Some tools (clang-format, doxygen, gcovr, gh, git-cliff, gpg, pre-commit,
# run-clang-tidy) are present in our Linux CI images and in local development
# setups, but not in the macOS CI environment. They are checked everywhere
# except when running in CI on macOS.
# Some tools (clang-format, clang-tidy, doxygen, gcovr, gh, git-cliff, gpg,
# pre-commit, run-clang-tidy) are present in our Linux CI images and in local
# development setups, but not in the macOS CI environment. They are checked
# everywhere except when running in CI on macOS.
#
# Tools that Nix also exposes under a version-suffixed name (`clang-tidy-22`,
# `g++-15`, ...) are probed under both names: a suffixed name can break while
# the plain one still works (see mkVersionedToolLinks in nix/packages.nix).
#
# Environment variables:
# CI if set, skip the tools above when on macOS.
@@ -26,14 +30,27 @@
set -uo pipefail
# Version suffixes of the Nix tool links, tracking nix/packages.nix.
gcc_version=15
llvm_version=22
missing=()
checked=0
# tool_path <name>
# Fully resolved path of a tool, so the snapshots record which derivation
# provides it. Prints nothing when it isn't on PATH.
tool_path() {
local path
path="$(command -v "$1" 2>/dev/null)" || return 0
readlink -f "${path}" 2>/dev/null || printf '%s' "${path}"
}
# check <name> [probe-command...]
# Runs the probe (default: "<name> --version"), capturing both stdout and
# stderr, and prints one aligned line: the status, the name, and the first
# non-blank line of the probe output (its version). Records <name> as missing
# if the command is not found or exits non-zero.
# stderr, and prints three lines: the status and name, the first non-blank line
# of the probe output (its version, or the error when it failed), and the tool's
# resolved path. Records <name> as missing if it is not found or exits non-zero.
check() {
local name="$1"
shift
@@ -43,14 +60,17 @@ check() {
fi
checked=$((checked + 1))
local output version
local output version path
path="$(tool_path "${name}")"
if output="$("${probe[@]}" 2>&1)"; then
version="$(printf '%s\n' "${output}" | grep -m1 '[^[:space:]]' || true)"
printf ' [ ok ] %-20s %s\n' "${name}" "${version}"
printf '%s\n' "${name}"
else
printf ' [MISS] %s\n' "${name}"
printf ' %s\n' "${name}"
missing+=("${name}")
fi
version="$(printf '%s\n' "${output}" | grep -m1 '[^[:space:]]' || true)"
printf ' %s\n' "${version:-(no output)}"
printf ' %s\n' "${path:-(not found)}"
}
case "$(uname -s)" in
@@ -82,7 +102,9 @@ if [ "${os}" = "linux" ] || [ "${os}" = "macos" ]; then
echo "Development tooling:"
check ccache
check clang
check "clang-${llvm_version}"
check clang++
check "clang++-${llvm_version}"
check ClangBuildAnalyzer
check curl
check file
@@ -101,7 +123,14 @@ if [ "${os}" = "linux" ] || [ "${os}" = "macos" ]; then
# setups, but not in the macOS CI environment. So check them everywhere
# except when running in CI on macOS.
if [ "${os}" = "linux" ] || [ -z "${CI:-}" ]; then
check clang-apply-replacements
check "clang-apply-replacements-${llvm_version}"
check clang-format
check "clang-format-${llvm_version}"
# clang-tidy leads --version with the LLVM banner, not the version.
tidy_probe="--version | grep -m1 -oE 'LLVM version [0-9.]+'"
check clang-tidy sh -c "clang-tidy ${tidy_probe}"
check "clang-tidy-${llvm_version}" sh -c "clang-tidy-${llvm_version} ${tidy_probe}"
check dot
check doxygen
check gcovr
@@ -112,6 +141,7 @@ if [ "${os}" = "linux" ] || [ "${os}" = "macos" ]; then
# pre-commit, or its alternative implementation prek
check pre-commit sh -c 'pre-commit --version || prek --version'
check run-clang-tidy run-clang-tidy --help
check "run-clang-tidy-${llvm_version}" "run-clang-tidy-${llvm_version}" --help
fi
fi
@@ -126,8 +156,9 @@ if [ "${os}" = "linux" ] || [ "${os}" = "macos" ]; then
check cargo-audit cargo audit --version
check cargo-llvm-cov cargo llvm-cov --version
check cargo-nextest cargo nextest --version
check clippy clippy-driver --version
check clippy-driver
check rust-analyzer
check rust-nightly rust-nightly run rustc --version
check rustc
check rustfmt
fi
@@ -138,7 +169,11 @@ if [ "${os}" = "linux" ]; then
echo
echo "GCC toolchain:"
check gcc
check "gcc-${gcc_version}"
check g++
check "g++-${gcc_version}"
check cpp
check "cpp-${gcc_version}"
check gcov
echo
@@ -163,9 +198,9 @@ else
checked=$((checked + 1))
tmp_clone="$(mktemp -d)"
if git clone --depth 1 https://github.com/XRPLF/actions.git "${tmp_clone}/actions" >/dev/null 2>&1; then
printf ' [ ok ] git clone over HTTPS\n'
printf ' git clone over HTTPS\n'
else
printf ' [MISS] git clone over HTTPS\n'
printf ' git clone over HTTPS\n'
missing+=("git-https-clone")
fi
rm -rf "${tmp_clone}"
@@ -173,9 +208,9 @@ fi
echo
if [ "${#missing[@]}" -eq 0 ]; then
echo "All ${checked} checked tools are present and runnable."
echo "All ${checked} checked tools are present and runnable."
else
echo "Missing or non-functional tools (${#missing[@]} of ${checked}):" >&2
echo "Missing or non-functional tools (${#missing[@]} of ${checked}):" >&2
for tool in "${missing[@]}"; do
echo " - ${tool}" >&2
done

View File

@@ -22,23 +22,41 @@ case "${ID}" in
;;
esac
# Packaging runs in a vanilla distro image, so the tooling comes from the distro's
# archive rather than from nixpkgs:
#
# - debhelper and dpkg-dev build the DEB, and lintian checks it
# - binutils gives debian/rules the readelf its glibc-floor check runs; it
# already arrives via dpkg-dev, but that tool is called directly
# - rpm-build builds the RPM, with systemd-rpm-macros and redhat-rpm-config
# supplying the systemd and find-debuginfo macros the spec uses
# - rpm-sign and gnupg2 sign the built RPM
# - python3 runs the packaging scripts
# - git gives build_pkg.py the commit timestamp it stamps files with
# - ca-certificates lets git and the packaging scripts verify TLS
function install() {
case "${ID}" in
debian | ubuntu)
apt-get update -y
apt-get install -y --no-install-recommends \
binutils \
ca-certificates \
debhelper \
debhelper-compat \
dpkg-dev \
git
git \
lintian \
python3
;;
rhel | centos | rocky | almalinux)
dnf install -y --setopt=install_weak_deps=False \
git \
rpm-build \
gnupg2 \
python3 \
redhat-rpm-config \
rpm-build \
rpm-sign \
systemd-rpm-macros
;;
esac

View File

@@ -0,0 +1,149 @@
#!/usr/bin/env python3
"""
Check that Rust unit tests stay out of the coverage report.
cargo-llvm-cov instruments the test code along with everything else, so a test
module that is not excluded counts its own body as covered and inflates the
reported number. Excluding it takes two attributes:
* every `#[cfg(test)]` module carries
`#[cfg_attr(coverage_nightly, coverage(off))]`;
* every crate root (lib.rs, main.rs) carries
`#![cfg_attr(coverage_nightly, feature(coverage_attribute))]`, which the
attribute above needs in order to compile.
Both are inert outside the coverage job: cargo-llvm-cov defines
`coverage_nightly` only when it runs on a nightly toolchain.
The crate-root gate is checked even in a crate that has no tests yet, because
that is what lets the first test module added later carry the attribute without
a build failure. Missing it is a hard error, so it cannot go unnoticed; a
missing `coverage(off)` fails open, which is why this check exists.
Matching is on exact attribute text, which works because `cargo fmt` runs over
the whole workspace in the hook ahead of this one: rustfmt puts every attribute
on its own line and normalizes what is inside it, turning `#[cfg( test )]`
and `#[cfg(test,)]` alike into `#[cfg(test)]`. So there is nothing here that
parses Rust. The price is that a cfg this file does not spell out literally --
`all(test, ...)`, `any(test, ...)`, `not(test)` -- is reported rather than
classified, on the grounds that guessing at coverage semantics is how a check
like this ends up quietly wrong.
Usage: ./bin/pre-commit/check_rust_coverage_attrs.py <file1> <file2> ...
Exit status is non-zero if any violation is found.
"""
import re
import sys
from dataclasses import dataclass
from pathlib import Path
CRATE_ROOTS = {"lib.rs", "main.rs"}
FEATURE_ATTR = "#![cfg_attr(coverage_nightly, feature(coverage_attribute))]"
COVERAGE_OFF_ATTR = "#[cfg_attr(coverage_nightly, coverage(off))]"
CFG_TEST_ATTR = "#[cfg(test)]"
# Any other cfg that mentions `test`. String literals are blanked before this
# runs, so `feature = "test"` does not read as the `test` cfg.
RE_CFG_MENTIONS_TEST = re.compile(r"^#\[cfg\(.*\btest\b.*\)\]$")
RE_STRING = re.compile(r'"(?:[^"\\]|\\.)*"')
RE_MOD = re.compile(r"^(?:pub(?:\([^)]*\))?\s+)?mod\s+([A-Za-z_]\w*)")
@dataclass(frozen=True)
class Finding:
line: int
label: str
message: str
def _check_module(attrs: list[str], line: int, name: str) -> list[Finding]:
"""Findings for one module, given the attributes attached to it."""
if COVERAGE_OFF_ATTR in attrs:
return [] # excluded from coverage; which cfg gates it does not matter
if CFG_TEST_ATTR in attrs:
return [
Finding(
line,
"missing-coverage-off",
f"`mod {name}` is #[cfg(test)] but not excluded from coverage; "
f"add {COVERAGE_OFF_ATTR}",
)
]
unclassified = [
attr for attr in attrs if RE_CFG_MENTIONS_TEST.match(RE_STRING.sub('""', attr))
]
if unclassified:
return [
Finding(
line,
"unclassified-cfg",
f"`mod {name}` is gated on {unclassified[0]}, which this check "
f"cannot tell apart from a module that ships in the library; "
f"add {COVERAGE_OFF_ATTR} if it is test-only, or teach this "
f"check the cfg if it is not",
)
]
return []
def _check_test_modules(lines: list[str]) -> list[Finding]:
"""Findings for every test module that is not excluded from coverage."""
findings: list[Finding] = []
attrs: list[str] = []
attrs_line = 0
for number, raw in enumerate(lines, start=1):
stripped = raw.strip()
# Blank lines and comments are allowed between an attribute and its item.
if not stripped or stripped.startswith("//"):
continue
if stripped.startswith("#["):
if not attrs:
attrs_line = number
attrs.append(stripped)
continue
module = RE_MOD.match(stripped)
if module is not None and attrs:
findings += _check_module(attrs, attrs_line, module.group(1))
attrs = []
return findings
def _check_crate_root(name: str, lines: list[str]) -> list[Finding]:
"""A finding if a crate root is missing the coverage_attribute feature gate."""
if name not in CRATE_ROOTS:
return []
if any(line.strip() == FEATURE_ATTR for line in lines):
return []
return [
Finding(
1,
"missing-feature-gate",
f"crate root is missing {FEATURE_ATTR}",
)
]
def check_source(name: str, text: str) -> list[Finding]:
"""Findings for one file's contents; `name` is its base name (lib.rs, ...)."""
lines = text.splitlines()
return _check_crate_root(name, lines) + _check_test_modules(lines)
def check_file(path: Path) -> list[Finding]:
return check_source(path.name, path.read_text(encoding="utf-8"))
def main() -> int:
total = 0
for path in (Path(name) for name in sys.argv[1:]):
for finding in check_file(path):
total += 1
print(f"{path}:{finding.line}: {finding.label}: {finding.message}")
return 1 if total else 0
if __name__ == "__main__":
sys.exit(main())

View File

@@ -1094,8 +1094,8 @@
# Default is 100.
#
# back_off_milliseconds
# Number of milliseconds to wait between
# online_delete batches to allow other functions
# Number of milliseconds to wait between online_delete
# SQL deletion batches to allow other functions
# to catch up.
# Default is 100.
#
@@ -1109,10 +1109,22 @@
# The online delete process checks periodically
# that xrpld is still in sync with the network,
# and that the validated ledger is less than
# 'age_threshold_seconds' old. If not, then continue
# 'age_threshold_seconds' old, and that all
# recent ledgers are available. If not, then continue
# sleeping for this number of seconds and
# checking until healthy.
# Default is 5.
# Default is 2.
#
# max_waiting_ledgers
# The maximum number of ledgers that may be validated
# while online deletion is waiting for the node to get
# fully synced with the rest of the network. If more than
# this number of ledgers are validated while waiting, then
# online deletion gives up on the current ledger and tries
# again later. Note this only affects situations that cause
# rotation to wait, such as going out of sync, or missing
# ledgers. Forward progress is not penalized. Minimum is 64.
# Default is the online_delete value.
#
# Notes:
# The 'node_db' entry configures the primary, persistent storage.
@@ -1348,6 +1360,39 @@
# Example:
# owner_reserve = 200000 # 0.2 XRP
#
# gas_limit = <gas>
#
# The gas limit is the maximum amount of gas that can be
# consumed by a single transaction. The gas limit is used to prevent
# transactions from consuming too many resources.
#
# If this parameter is unspecified, xrpld will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
# gas_limit = 1000000 # 1 million gas
#
# bytecode_size_limit = <bytes>
#
# The bytecode size limit is the maximum size of a WASM extension in
# bytes. The size limit is used to prevent extensions from consuming
# too many resources.
#
# If this parameter is unspecified, xrpld will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
# bytecode_size_limit = 100000 # 100 kb
#
# gas_price = <micro-drops>
#
# The gas price is the conversion between WASM gas and its price in drops.
#
# If this parameter is unspecified, xrpld will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
# gas_price = 1000000 # 1 drop per gas
#-------------------------------------------------------------------------------
#
# 9. Misc Settings

View File

@@ -120,7 +120,10 @@ if(MSVC)
_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:Debug>>:_CRTDBG_MAP_ALLOC>
)
target_link_libraries(common INTERFACE -errorreport:none -machine:X64)
target_link_libraries(
common
INTERFACE -errorreport:none -machine:X64 -ignore:4099
)
else()
target_compile_options(
common

View File

@@ -51,6 +51,8 @@ target_compile_options(
target_link_libraries(xrpl.libpb PUBLIC protobuf::libprotobuf gRPC::grpc++)
add_dependencies(tidy_prerequisites xrpl.libpb)
# TODO: Clean up the number of library targets later.
add_library(xrpl.imports.main INTERFACE)
@@ -67,6 +69,8 @@ target_link_libraries(
Xrpl::opts
Xrpl::syslibs
secp256k1::secp256k1
wasmi::wasmi
NIH::dilithium2_ref
xrpl.libpb
xxHash::xxhash
$<$<BOOL:${voidstar}>:antithesis-sdk-cpp>

View File

@@ -1,7 +1,7 @@
#[===================================================================[
Linux packaging support: 'package' target.
The packaging script (package/build_pkg.sh) installs to FHS-standard
The packaging script (package/build_pkg.py) installs to FHS-standard
paths (/usr/bin, /etc/xrpld, etc.) regardless of CMAKE_INSTALL_PREFIX,
so no prefix guard is needed here.
#]===================================================================]
@@ -38,19 +38,20 @@ if(NOT TARGET validator-keys)
return()
endif()
set(package_env
SRC_DIR=${CMAKE_SOURCE_DIR}
BUILD_DIR=${CMAKE_BINARY_DIR}
PKG_RELEASE=${pkg_release}
)
if(DPKG_BUILDPACKAGE_EXECUTABLE)
set(pkg_type deb)
else()
set(pkg_type rpm)
endif()
add_custom_target(
package
COMMAND
${CMAKE_COMMAND} -E env ${package_env}
${CMAKE_SOURCE_DIR}/package/build_pkg.sh
${CMAKE_SOURCE_DIR}/package/build_pkg.py --package-type=${pkg_type}
--build-dir=${CMAKE_BINARY_DIR} --pkg-release=${pkg_release}
--channel=UNRELEASED
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
DEPENDS xrpld validator-keys
COMMENT "Building Linux package (deb/rpm inferred from host tooling)"
COMMENT "Building Linux ${pkg_type} package"
VERBATIM
)

View File

@@ -32,6 +32,11 @@ endif()
option(benchmark "Build benchmarks" ON)
# When OFF, the crates directory is not added to the build at all: no Rust
# toolchain is required, no cxxbridge bindings are generated, and the C++ tests
# that consume those bindings are left out of the build tree.
option(rust "Build the Rust crates and the C++ code that depends on them" OFF)
# Enabled by default so every header is compiled on its own as the main file of
# its own compile_commands.json entry - this is what lets clang-tidy (and clangd
# and IDEs) analyse a header's own includes directly. The per-header objects are

View File

@@ -0,0 +1,62 @@
include(FetchContent)
ExternalProject_Add(
dilithium_src
PREFIX ${nih_cache_path}
# Pin to an explicit commit, not a moving branch ref. Bumping this SHA
# is a supply-chain decision that must be reviewed; never revert to a
# branch tag here. Upstream:
# https://github.com/Transia-RnD/dilithium/commit/3032292cfd4d94e0df9bd49a0098669ca9166aa1
GIT_REPOSITORY https://github.com/Transia-RnD/dilithium.git
GIT_TAG 3032292cfd4d94e0df9bd49a0098669ca9166aa1
GIT_SHALLOW FALSE
CONFIGURE_COMMAND ""
LOG_BUILD ON
BUILD_IN_SOURCE 0
BUILD_COMMAND
COMMAND ${CMAKE_COMMAND} -E copy_directory <SOURCE_DIR>/ref <BINARY_DIR>/ref
COMMAND make -C <BINARY_DIR>/ref clean
COMMAND /bin/sh -c "CFLAGS='-DDILITHIUM_MODE=2 -DDILITHIUM_RANDOMIZED_SIGNING' make -C <BINARY_DIR>/ref libdilithium2_ref.a libfips202_ref.a"
INSTALL_COMMAND ""
BUILD_BYPRODUCTS
<BINARY_DIR>/ref/libdilithium2_ref.a
<BINARY_DIR>/ref/libfips202_ref.a
)
ExternalProject_Get_Property(dilithium_src SOURCE_DIR BINARY_DIR)
set(dilithium_src_SOURCE_DIR "${SOURCE_DIR}")
set(dilithium_src_BINARY_DIR "${BINARY_DIR}")
# Include the reference implementation headers from source
include_directories("${dilithium_src_SOURCE_DIR}/ref")
# Create imported targets for each static library using BINARY_DIR
add_library(dilithium::dilithium2_ref STATIC IMPORTED GLOBAL)
set_target_properties(dilithium::dilithium2_ref PROPERTIES
IMPORTED_LOCATION "${dilithium_src_BINARY_DIR}/ref/libdilithium2_ref.a"
INTERFACE_INCLUDE_DIRECTORIES "${dilithium_src_SOURCE_DIR}/ref/"
)
add_library(dilithium::libfips202_ref STATIC IMPORTED GLOBAL)
set_target_properties(dilithium::libfips202_ref PROPERTIES
IMPORTED_LOCATION "${dilithium_src_BINARY_DIR}/ref/libfips202_ref.a"
INTERFACE_INCLUDE_DIRECTORIES "${dilithium_src_SOURCE_DIR}/ref/"
)
# Add dependencies to ensure the external project is built first
add_dependencies(dilithium::dilithium2_ref dilithium_src)
add_dependencies(dilithium::libfips202_ref dilithium_src)
# Note: We do NOT link the Dilithium library's randombytes.c because we provide
# our own thread-safe implementation in src/libxrpl/protocol/SecretKey.cpp
# that uses xrpld's crypto_prng() instead of direct /dev/urandom access.
# Create an interface library that links to the Dilithium libraries
# Note: Link order matters - libraries that provide symbols must come AFTER libraries that use them
target_link_libraries(xrpl_libs INTERFACE
dilithium::dilithium2_ref
dilithium::libfips202_ref
)
# Create alias for convenience
add_library(NIH::dilithium2_ref ALIAS dilithium::dilithium2_ref)

View File

@@ -8,6 +8,7 @@ Uses pcpp to preprocess the macro file and pyparsing to parse the DSL.
import io
import argparse
import re
from pathlib import Path
import pyparsing as pp
@@ -53,28 +54,91 @@ def create_transaction_parser():
return macro_parser
# Defaults for xrpl::TxSettings members, mirroring
# include/xrpl/protocol/TxSettings.h. A transaction's settings blob only names
# the members that differ from these.
SETTING_DEFAULTS = {
"delegable": "Delegation::NotDelegable",
"amendment": "uint256{}",
"privileges": "Privilege::NoPriv",
"emittance": "Emittance::Emitable",
"firewall": "FirewallAction::Allow",
}
def parse_settings(settings_str):
"""Parse a TxSettings blob into a dict, filling in defaults.
Args:
settings_str: A string like '({.delegable = Delegation::NotDelegable,
.privileges = Privilege::CreateAcct})', or '({})'.
Returns:
A dict with a value for every key in SETTING_DEFAULTS.
"""
body = settings_str.strip()
if not (body.startswith("(") and body.endswith(")")):
raise ValueError(
f"Malformed settings blob, expected '({{...}})': {settings_str!r}"
)
body = body[1:-1].strip()
if not (body.startswith("{") and body.endswith("}")):
raise ValueError(
f"Malformed settings blob, expected '({{...}})': {settings_str!r}"
)
body = body[1:-1]
# Strip comments, which may be interleaved with the designated initializers.
body = re.sub(r"//[^\n]*", "", body)
settings = dict(SETTING_DEFAULTS)
seen = set()
# Each entry runs from '.key =' up to the next '.key =' or the end.
for key, value in re.findall(
r"\.(\w+)\s*=\s*(.*?)(?=,\s*\.\w+\s*=|,?\s*$)", body, re.S
):
if key not in SETTING_DEFAULTS:
raise ValueError(f"Unknown TxSettings member '.{key}' in {settings_str!r}")
settings[key] = " ".join(value.split()).rstrip(",")
seen.add(key)
# Catch a typo'd or unparsed initializer rather than silently defaulting it.
# Every '.member' in the blob must have been consumed above.
if len(re.findall(r"\.\w+", body)) != len(seen):
raise ValueError(f"Could not parse every setting in {settings_str!r}")
# A blob with content but no designated initializer is positional, which
# would otherwise be read as "all defaults" and silently generate the
# wrong output.
if body.strip() and not seen:
raise ValueError(
"TxSettings requires designated initializers (.member = value), "
f"got {settings_str!r}"
)
return settings
def parse_transaction_args(args_list):
"""Parse the arguments of a TRANSACTION macro call.
Args:
args_list: A list of parsed arguments from pyparsing, e.g.,
['ttPAYMENT', '0', 'Payment', 'Delegation::delegable',
'uint256{}', 'createAcct', '({...})']
['ttPAYMENT', '0', 'Payment',
'({.privileges = Privilege::CreateAcct})', '({...})']
Returns:
A dict with parsed transaction information.
"""
if len(args_list) < 7:
if len(args_list) < 5:
raise ValueError(
f"Expected at least 7 parts in TRANSACTION, got {len(args_list)}: {args_list}"
f"Expected at least 5 parts in TRANSACTION, got {len(args_list)}: {args_list}"
)
tag = args_list[0]
value = args_list[1]
name = args_list[2]
delegable = args_list[3]
amendments = args_list[4]
privileges = args_list[5]
settings = parse_settings(args_list[3])
fields_str = args_list[-1]
# Parse fields: ({field1, field2, ...})
@@ -84,9 +148,9 @@ def parse_transaction_args(args_list):
"tag": tag,
"value": value,
"name": name,
"delegable": delegable,
"amendments": amendments,
"privileges": privileges,
"delegable": settings["delegable"],
"amendments": settings["amendment"],
"privileges": settings["privileges"],
"fields": fields,
}

View File

@@ -3,6 +3,7 @@
"requires": [
"zlib/1.3.2#1cb806da49011867778ffb6ac7190fcb%1782392402.122708",
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1782392402.420688",
"wasmi/1.0.9#1fecdab9b90c96698eb35ea99ca4f5cb%1782307153.343419",
"sqlite3/3.53.0#324ada52333108388a9a6108bfa96734%1782392403.185447",
"soci/4.0.3#e726491a03468795453f7c83fc924a96%1782392402.679521",
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1782307151.633168",
@@ -23,6 +24,7 @@
"fast_float/8.2.10#f6f28d6bb22112078e7dbda611caf681%1782494504.298",
"ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1782307148.15562",
"date/3.0.4#862e11e80030356b53c2c38599ceb32b%1782392402.538492",
"corrosion/0.6.1#bfa292df0a957bc70a450ff316cd9435%1786119416.131296",
"c-ares/1.34.6#545240bb1c40e2cacd4362d6b8967650%1782392402.681654",
"bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1782392402.296732",
"boost/1.91.0#ea540ca2133d831b560036aa24dece3c%1782392419.475605",

View File

@@ -28,6 +28,7 @@ class Xrpl(ConanFile):
}
requires = [
"corrosion/0.6.1",
"ed25519/2015.03",
"fast_float/8.2.10",
"grpc/1.81.1",
@@ -35,6 +36,7 @@ class Xrpl(ConanFile):
"nudb/2.0.9",
"openssl/3.6.3",
"soci/4.0.3",
"wasmi/1.0.9",
"zlib/1.3.2",
]
@@ -223,6 +225,7 @@ class Xrpl(ConanFile):
"soci::soci",
"secp256k1::secp256k1",
"sqlite3::sqlite",
"wasmi::wasmi",
"xxhash::xxhash",
"zlib::zlib",
]

17
crates/.cargo/config.toml Normal file
View File

@@ -0,0 +1,17 @@
# The Rust static libraries are linked into C++ targets, so the runtime linkage
# here has to match what the C++ build uses (see cmake/XrplCompiler.cmake).
#
# macOS needs nothing: AppleClang cannot link libgcc/libc++ statically, so the
# C++ build skips those flags on Apple as well.
# Both amd64 and arm64 Linux builds link libgcc statically. This only affects
# links that rustc itself drives (`cargo test` binaries and the like) — the
# `staticlib` crates consumed by CMake are archived, not linked, so rustc
# silently ignores link args for them. Keeping libgcc_s.so.1 off the xrpld link
# line is handled in crates/CMakeLists.txt instead.
[target.'cfg(target_os = "linux")']
rustflags = ["-C", "link-args=-static-libgcc"]
# Windows builds use the static MSVC runtime.
[target.'cfg(windows)']
rustflags = ["-C", "target-feature=+crt-static"]

104
crates/CMakeLists.txt Normal file
View File

@@ -0,0 +1,104 @@
find_package(Corrosion REQUIRED)
corrosion_import_crate(MANIFEST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml)
# The generated C++ lands in the build tree, so put a .clang-tidy next to it to
# keep clang-tidy from analyzing code we don't own.
configure_file(
generated.clang-tidy
"${CMAKE_CURRENT_BINARY_DIR}/.clang-tidy"
COPYONLY
)
add_custom_target(xrpl_crates)
add_dependencies(tidy_prerequisites xrpl_crates)
# On macOS, ld warns `ignoring duplicate libraries` when linking a crate.
# Corrosion is the source of both duplicates it names:
#
# * The crate archive and its cxxbridge archive, because
# `corrosion_add_cxxbridge` makes the two depend on each other, and CMake
# repeats a static library cycle on the link line so single-pass linkers can
# resolve it. (LINK_INTERFACE_MULTIPLICITY can only raise that count.)
# * `-lSystem`, which Corrosion copies from rustc's `native-static-libs` even
# though the compiler driver always links libSystem.
#
# ld needs neither: it resolves the cycle from one copy of each archive and
# links libSystem once. So silence the warning rather than rewrite Corrosion's
# link interface, which the cycle is also part of. The option itself is old —
# Xcode 15 is only where the warning became the default — and the check below
# leaves it out on a linker that does not know it.
if(is_macos)
include(CheckLinkerFlag)
check_linker_flag(
CXX
-Wl,-no_warn_duplicate_libraries
have_no_warn_duplicate_libraries
)
endif()
function(_unlink_libgcc_s crate)
if(NOT (is_linux AND static))
return()
endif()
# Corrosion exposes a crate's staticlib as an imported `<crate>-static`
# target and puts the native libs in its INTERFACE_LINK_LIBRARIES. If either
# of those changes, warn instead of silently letting libgcc_s.so.1 return.
set(imported "${crate}-static")
if(NOT TARGET ${imported})
message(
FATAL_ERROR
"Corrosion did not create the imported target '${imported}', so "
"libgcc_s cannot be removed from the link interface of '${crate}'. "
"xrpld will link libgcc_s.so.1 dynamically. Check where Corrosion "
"${CORROSION_VERSION} now records `native-static-libs`."
)
return()
endif()
get_target_property(libs ${imported} INTERFACE_LINK_LIBRARIES)
if(NOT "gcc_s" IN_LIST libs)
message(
WARNING
"'gcc_s' was not in the link interface of '${imported}' as "
"expected. If the Rust toolchain stopped reporting it this "
"workaround is obsolete and can be deleted; otherwise xrpld may "
"link libgcc_s.so.1 dynamically. Verify with: "
"objdump -p xrpld | grep NEEDED"
)
return()
endif()
list(REMOVE_ITEM libs gcc_s)
set_property(TARGET ${imported} PROPERTY INTERFACE_LINK_LIBRARIES ${libs})
endfunction()
function(add_xrpl_crate name)
cmake_parse_arguments(ARG "" "CRATE" "FILES" ${ARGN})
_unlink_libgcc_s(${ARG_CRATE})
# `cc` picks its runtime flag from `crt-static` alone, so it compiles a
# crate's C++ with `-MT`; Debug needs `-MTd` (to match cmake/XrplCompiler.cmake).
if(is_msvc)
corrosion_set_env_vars(
${ARG_CRATE}
"$<$<CONFIG:Debug>:CXXFLAGS=-MTd>"
)
endif()
corrosion_add_cxxbridge(${name}_cxxbridge CRATE ${ARG_CRATE} FILES
${ARG_FILES}
)
# Generated cxxbridge headers don't exist at configure time; CMake 3.28+
# validates INTERFACE_SOURCES on consuming targets. Clear it to skip the
# existence check — build-time ordering is enforced by the custom commands.
set_target_properties(${name}_cxxbridge PROPERTIES INTERFACE_SOURCES "")
if(have_no_warn_duplicate_libraries)
target_link_options(
${name}_cxxbridge
INTERFACE -Wl,-no_warn_duplicate_libraries
)
endif()
add_dependencies(xrpl_crates ${name}_cxxbridge)
endfunction()
add_xrpl_crate(rs_hello_world CRATE rs_hello_world FILES lib.rs)

301
crates/Cargo.lock generated Normal file
View File

@@ -0,0 +1,301 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "anstyle"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
[[package]]
name = "cc"
version = "1.2.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d"
dependencies = [
"find-msvc-tools",
"shlex",
]
[[package]]
name = "clap"
version = "4.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
dependencies = [
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_lex"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
[[package]]
name = "codespan-reporting"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681"
dependencies = [
"serde",
"termcolor",
"unicode-width",
]
[[package]]
name = "cxx"
version = "1.0.199"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824894a4a85dca76d4c95c2b9098c036f5a29f627b30c12780774f6654e60974"
dependencies = [
"cc",
"cxx-build",
"cxxbridge-cmd",
"cxxbridge-flags",
"cxxbridge-macro",
"foldhash",
"link-cplusplus",
]
[[package]]
name = "cxx-build"
version = "1.0.199"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1ae0b651ea5b0000b19513aef5a03f194d7e3486f2d9258b658da8677fe9036"
dependencies = [
"cc",
"codespan-reporting",
"indexmap",
"proc-macro2",
"quote",
"scratch",
"syn 3.0.3",
]
[[package]]
name = "cxxbridge-cmd"
version = "1.0.199"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb05f91d3fb8435d9bab6ac5ce6ac1868be774325fb7fb2a91be39393b21388e"
dependencies = [
"clap",
"codespan-reporting",
"indexmap",
"proc-macro2",
"quote",
"syn 3.0.3",
]
[[package]]
name = "cxxbridge-flags"
version = "1.0.199"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf293202e0e3e98495785745389e8d0755b217e66f19194a5c695c25e03282ef"
[[package]]
name = "cxxbridge-macro"
version = "1.0.199"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca001d746947c7249ed9d332a10f7a59daedbafeb0ec68c5c18a7db7a93f6ccc"
dependencies = [
"indexmap",
"proc-macro2",
"quote",
"syn 3.0.3",
]
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "foldhash"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
[[package]]
name = "hashbrown"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
[[package]]
name = "indexmap"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "link-cplusplus"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f78c730aaa7d0b9336a299029ea49f9ee53b0ed06e9202e8cb7db9bae7b8c82"
dependencies = [
"cc",
]
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rs-hello_world"
version = "0.1.0"
dependencies = [
"cxx",
]
[[package]]
name = "scratch"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d68f2ec51b097e4c1a75b681a8bec621909b5e91f15bb7b840c4f2f7b01148b2"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "termcolor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
dependencies = [
"winapi-util",
]
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "unicode-width"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
[[package]]
name = "winapi-util"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys",
]
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link",
]

18
crates/Cargo.toml Normal file
View File

@@ -0,0 +1,18 @@
[workspace]
members = ["hello_world"]
resolver = "3"
[workspace.dependencies]
cxx = { version = "1.0.198", features = ["c++20"] }
[workspace.package]
edition = "2024"
[workspace.lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = [ 'cfg(coverage)', 'cfg(coverage_nightly)' ] }
[profile.release]
opt-level = 3
overflow-checks = true
lto = true
debug = true

View File

@@ -0,0 +1,10 @@
---
# Neutralizes clang-tidy for the corrosion/cxxbridge-generated C++. Copied into
# the crates build directory by crates/CMakeLists.txt, next to the generated
# sources, so clang-tidy picks it up instead of the top-level configuration.
#
# One check is kept enabled to avoid clang-tidy's "no checks enabled" error.
Checks: "-*,google-readability-todo"
WarningsAsErrors: ""
HeaderFilterRegex: ""
InheritParentConfig: false

View File

@@ -0,0 +1,13 @@
[package]
name = "rs-hello_world"
version = "0.1.0"
edition.workspace = true
[lib]
crate-type = ["staticlib"]
[dependencies]
cxx.workspace = true
[lints]
workspace = true

View File

@@ -0,0 +1,23 @@
#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
#[cxx::bridge(namespace = "rs::hello_world")]
mod ffi {
extern "Rust" {
fn hello_world() -> String;
}
}
pub fn hello_world() -> String {
"hello_world".to_string()
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
#[test]
fn hello_world_returns_hello_world() {
assert_eq!(hello_world(), "hello_world")
}
}

View File

@@ -0,0 +1,25 @@
# Runtime image for the perf/test xrpld build with all amendments Supported::Yes.
# Installs the .deb into ubuntu:jammy (matching rippleci/xrpld): gives
# /usr/bin/xrpld, /etc/xrpld/xrpld.cfg, and the xrpld user.
# NOT for production validators.
ARG BASE_IMAGE=ubuntu:jammy
FROM ${BASE_IMAGE}
# Build context must contain the supported package as xrpld.deb.
COPY xrpld.deb /tmp/xrpld.deb
RUN set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends ca-certificates jq /tmp/xrpld.deb; \
rm -rf /var/lib/apt/lists/* /tmp/xrpld.deb; \
id -u xrpld >/dev/null 2>&1 || \
useradd --system --home-dir /var/lib/xrpld --shell /sbin/nologin --user-group xrpld; \
mkdir -p /var/log/xrpld /var/lib/xrpld; \
chown -R xrpld:xrpld /var/log/xrpld /var/lib/xrpld; \
# Symlink for consumers that exec /opt/xrpld/bin/xrpld.
mkdir -p /opt/xrpld/bin; \
ln -sf /usr/bin/xrpld /opt/xrpld/bin/xrpld
EXPOSE 2459/tcp 5005/tcp 6006/tcp
USER xrpld
ENTRYPOINT ["/usr/bin/xrpld"]

279
docs/AMMCurveTemplate.md Normal file
View File

@@ -0,0 +1,279 @@
# AMM Curve Implementation Template
Guide for adding a new curve type to the XRPL pluggable AMM curve framework.
## Architecture Overview
Each token pair can have **multiple AMM pools**, one per curve type. The keylet
hash includes `curveType`, so `RLUSD/USD ConstantProduct` and `RLUSD/USD
StableSwap` are separate ledger entries with separate pseudo-accounts and LP
tokens. BookStep automatically routes through the deepest-liquidity pool.
### Key Components
| Component | File | Purpose |
| --------------------- | --------------------------------------------------- | --------------------------------------- |
| CurveInterface | `include/xrpl/ledger/helpers/AMMCurve.h` | Abstract base for all curves |
| Curve implementations | `src/libxrpl/ledger/helpers/AMMCurve.cpp` | CP, CL, StableSwap, Weighted |
| Tick math | `src/libxrpl/ledger/helpers/AMMTickMath.cpp` | CL tick/sqrt price conversions |
| Fee collection | `src/libxrpl/tx/transactors/dex/AMMCollectFees.cpp` | CL position fee harvesting |
| Multi-curve routing | `src/libxrpl/tx/paths/BookStep.cpp` | Picks best pool per pair |
| Keylet hashing | `src/libxrpl/protocol/Indexes.cpp` | `amm(asset1, asset2, curveType)` |
| LP token identity | `src/libxrpl/protocol/AMMCore.cpp` | `ammLPTCurrency(cur1, cur2, curveType)` |
## Step 1: Define the Curve Type
Add to `include/xrpl/protocol/AMMCore.h`:
```cpp
enum CurveType : std::uint8_t
{
ctCONSTANT_PRODUCT = 0,
ctCONCENTRATED_LIQUIDITY = 1,
ctSTABLE_SWAP = 2,
ctWEIGHTED = 3,
ctYOUR_CURVE = N, // next available ID
};
```
## Step 2: Define SFields for Curve Parameters
Add to `include/xrpl/protocol/detail/sfields.macro`:
```cpp
// Use the appropriate type (UINT8, UINT16, UINT32, UINT64, UINT256, AMOUNT, etc.)
// Check existing field codes to avoid collisions.
TYPED_SFIELD(sfYourParam, UINT32, <next_available_code>)
```
## Step 3: Implement the CurveInterface
Add a new class in `src/libxrpl/ledger/helpers/AMMCurve.cpp`:
```cpp
class YourCurve final : public CurveInterface
{
public:
Expected<STAmount, TER>
swapIn(
STAmount const& poolIn,
STAmount const& poolOut,
STAmount const& assetIn,
std::uint16_t tfee,
STObject const* curveParams) const override
{
if (!curveParams)
return Unexpected(tecINTERNAL);
auto const param = curveParams->getFieldU32(sfYourParam);
auto const f = feeMult(tfee); // fee multiplier (1 - fee)
Number const x = poolIn; // STAmount -> Number via implicit conversion
Number const y = poolOut;
Number const dx = Number(assetIn) * f;
// --- YOUR INVARIANT MATH HERE ---
// Compute output amount `dy` from your invariant
// F(x, y) = k => F(x + dx, y - dy) = k => solve for dy
Number const dy = /* ... */;
if (dy <= Number{0})
return Unexpected(tecAMM_FAILED);
// Round output DOWN (favorable to pool)
NumberRoundModeGuard const mg(Number::downward);
return toSTAmount(poolOut.issue(), dy);
}
Expected<STAmount, TER>
swapOut(
STAmount const& poolIn,
STAmount const& poolOut,
STAmount const& assetOut,
std::uint16_t tfee,
STObject const* curveParams) const override
{
if (!curveParams)
return Unexpected(tecINTERNAL);
auto const param = curveParams->getFieldU32(sfYourParam);
auto const f = feeMult(tfee);
Number const x = poolIn;
Number const y = poolOut;
// --- YOUR INVARIANT MATH (INVERSE) ---
// Given desired output, compute required input
// F(x, y) = k => F(x + dx, y - assetOut) = k => solve for dx
Number const dx = /* ... */ / f;
if (dx <= Number{0})
return Unexpected(tecAMM_FAILED);
// Round input UP (favorable to pool)
NumberRoundModeGuard const mg(Number::upward);
return toSTAmount(poolIn.issue(), dx);
}
Expected<Number, TER>
spotPrice(
STAmount const& poolIn,
STAmount const& poolOut,
std::uint16_t tfee,
STObject const* curveParams) const override
{
if (!curveParams)
return Unexpected(tecINTERNAL);
auto const param = curveParams->getFieldU32(sfYourParam);
auto const f = feeMult(tfee);
// Marginal price: -dF/dx / dF/dy evaluated at current reserves
// Divided by (1 - fee) for the taker-facing price
Number const price = /* partial derivatives of your invariant */;
return price / f;
}
TER
validateParams(STObject const& curveParams) const override
{
// Validate curve-specific parameters at pool creation
if (!curveParams.isFieldPresent(sfYourParam))
return temMALFORMED;
auto const param = curveParams.getFieldU32(sfYourParam);
if (param < MIN_YOUR_PARAM || param > MAX_YOUR_PARAM)
return temMALFORMED;
return tesSUCCESS;
}
Expected<STAmount, TER>
initialLPTokens(
STAmount const& asset1,
STAmount const& asset2,
Issue const& lptIssue,
STObject const* curveParams) const override
{
if (!curveParams)
return Unexpected(tecINTERNAL);
// Compute initial LP token amount from deposits
// For many curves: geometric mean sqrt(asset1 * asset2)
// Or curve-specific: D for StableSwap, weighted geometric mean, etc.
Number const lp = /* ... */;
return toSTAmount(lptIssue, lp);
}
};
```
## Step 4: Register the Singleton and Dispatch
In `AMMCurve.cpp`, add the singleton and switch case:
```cpp
// At file scope (inside anonymous namespace)
static YourCurve const yourCurve_;
// In getCurve():
case ctYOUR_CURVE:
if (rules.enabled(featureAMMCurves))
return &yourCurve_;
return nullptr;
```
## Step 5: Update AMMCreate Validation
In `src/libxrpl/tx/transactors/dex/AMMCreate.cpp`:
1. Update the max curve type check: `if (curveType > ctYOUR_CURVE)`
2. Add params setup in the `applyGuts` section:
```cpp
else if (curveType == ctYOUR_CURVE)
{
ammSle->setFieldU32(
sfYourParam, ctx_.tx.getFieldU32(sfYourParam));
}
```
## Step 6: Multi-Curve Routing (BookStep)
BookStep automatically discovers and routes through the best pool for each
token pair. When a new curve type is added, update the loop upper bound in
`src/libxrpl/tx/paths/BookStep.cpp`:
```cpp
for (std::uint8_t ct = 0; ct <= ctYOUR_CURVE; ++ct)
{
auto const ammSle = ctx.view.read(keylet::amm(in, out, ct));
if (!ammSle || ammSle->getFieldAmount(sfLPTokenBalance) == beast::zero)
continue;
if (!bestAmm ||
ammSle->getFieldAmount(sfLPTokenBalance) >
bestAmm->getFieldAmount(sfLPTokenBalance))
bestAmm = ammSle;
}
```
The pool with the highest LP token balance wins. Curve-specific swap dispatch
happens automatically via `getCurve()` in `AMMLiquidity`/`AMMOffer`.
## Step 7: Keylet and LP Token Identity
Each curve type for the same token pair gets a unique ledger key and LP token:
- **Keylet**: `keylet::amm(asset1, asset2, curveType)` hashes `curveType` into
the AMM's ledger key (when curveType != 0, for backward compatibility)
- **LP token**: `ammLPTCurrency(cur1, cur2, curveType)` hashes `curveType` into
the LP token currency code
No changes needed here when adding a new curve — the default parameter
propagates automatically.
## Concentrated Liquidity Extras
The CL curve type uses additional infrastructure not needed by other curves:
- **AMMTickMath** (`AMMTickMath.h/cpp`): `tickToSqrtPrice()`, `sqrtPriceToTick()`,
`isValidTick()` for tick-based price representation
- **AMMCollectFees** (`AMMCollectFees.h/cpp`): Transactor for position owners to
collect accumulated swap fees using the Uniswap V3 fee growth formula
- **Ledger entries**: `ltAMM_POSITION` (per-user tick range + liquidity) and
`ltAMM_TICK` (per-tick fee growth and liquidity tracking)
- **SFields**: `sfFeeGrowthGlobal0/1`, `sfFeeGrowthOutside0/1`,
`sfFeeGrowthInsideLast0/1` (UINT256, Q128.128 fixed-point),
`sfActiveLiquidity`, `sfPositionLiquidity`, `sfLiquidityGross/Net` (UINT64)
## Math Utilities Available
- `Number`: arbitrary-precision decimal arithmetic (see `include/xrpl/basics/Number.h`)
- `power(f, n)`: f^n (integer exponent)
- `power(f, n, d)`: f^(n/d) (rational exponent)
- `root(f, d)`: f^(1/d)
- `root2(f)`: sqrt(f)
- `feeMult(tfee)`: returns `1 - fee` as Number
- `feeMultHalf(tfee)`: returns `1 - fee/2` as Number
- `toSTAmount(issue, number)`: convert Number to STAmount
- `NumberRoundModeGuard`: RAII guard for rounding direction
## Rounding Convention
- `swapIn` output: round DOWN (pool keeps the rounding dust)
- `swapOut` input: round UP (taker pays the rounding dust)
- Use `NumberRoundModeGuard` to set the rounding mode before `toSTAmount()`
## Testing
Add tests in `src/test/app/AMMCurves_test.cpp`:
1. `swapIn` and `swapOut` are inverses (within rounding tolerance)
2. Invariant is preserved: `F(reserves_new) >= F(reserves_old)` after every swap
3. `spotPrice` matches actual swap rate at infinitesimal amounts
4. Edge cases: zero input, max input, min reserves
5. Parameter validation: `validateParams` rejects out-of-range values
6. Integration: create pool, deposit, swap, withdraw full cycle
E2E tests go in `src/test/app/AMMCurvesE2E_test.cpp` for full transaction
lifecycle tests (AMMCreate with curve params, swap through payment engine,
deposit/withdraw).

View File

@@ -46,6 +46,9 @@ Besides a compiler, building `xrpld` requires:
On Linux and macOS, the [Nix development shell](./nix.md) provides all of them
(see below). On Windows they have to be installed manually.
Building with `-Drust=ON` additionally requires a Rust toolchain, see
[Rust](#rust). A default build does not, so it is not in the table above.
Once they are in place, verify that everything is installed and runnable with:
```bash
@@ -121,6 +124,25 @@ manually:
- [Git for Windows](https://git-scm.com/download/win)
- Python, Conan, and CMake, at the versions listed in
[Required tools](#required-tools).
- a [Rust toolchain](https://rustup.rs) — only needed to build with
`-Drust=ON`, see [Rust](#rust)
## Rust
The repository contains a Rust workspace in [`crates/`](../../crates), whose
crates are exposed to C++ through [cxx](https://cxx.rs) bindings. It is **not**
part of a default build: the CMake `rust` option is OFF by default, and with it
off no Rust toolchain is needed. It is only required when configuring with
`-Drust=ON` (which is what CI does), see [Options](../../BUILD.md#options).
The toolchain (`cargo`, `rustc`) is pinned to the channel in
[`rust-toolchain.toml`](../../rust-toolchain.toml) at the repository root. If
you install Rust with [rustup](https://rustup.rs), that file is picked up
automatically, and `cargo`/`rustc` in the repository will use the pinned
version.
Everything else the Rust build needs on the CMake side comes from Conan along
with the rest of the dependencies, so there is nothing further to install.
## Clang-tidy

84
docs/build/nix.md vendored
View File

@@ -7,7 +7,7 @@ This guide explains how to use Nix to set up a reproducible development environm
## Benefits of Using Nix
- **Reproducible environment**: Everyone gets the same versions of tools and compilers
- **Matches CI**: The Linux CI runs in Docker images built from this exact Nix environment
- **Matches CI**: The Linux CI runs in Docker images built from this exact Nix environment, and CI builds some macOS configurations in it as well
- **No system pollution**: Dependencies are isolated and don't affect your system packages
- **Consistent compilers**: The GCC and Clang shells use the same versions as CI
- **Quick setup**: Get started with a single command
@@ -68,7 +68,7 @@ A compiler can be chosen by providing its name with the `.#` prefix, e.g. `nix d
On Linux, `.#gcc` and `.#clang` provide the exact toolchain CI uses:
the compiler (pinned in [`nix/packages.nix`](../../nix/packages.nix))
rebuilt against the pinned custom glibc (see [`nix/compilers.nix`](../../nix/compilers.nix)).
rebuilt against the pinned custom glibc (see [`nix/linux.nix`](../../nix/linux.nix)).
Building that toolchain the first time is slow unless it is fetched from a Nix binary cache.
If you don't need the custom glibc, the Linux-only `.#gcc-plain` and `.#clang-plain`
give you the stock nixpkgs compilers of the same versions.
@@ -128,6 +128,12 @@ Coverage builds (`-Dcoverage=ON`) work in the `gcc` shell (and `gcc-plain` on Li
each ships a `gcov` matching its compiler, since Nix's cc-wrapper does not expose one.
The `clang` shells do not include `llvm-cov`, so use a `gcc` shell for coverage.
Builds of the Rust crates (`-Drust=ON`) also work out of the box: every shell
provides the Rust toolchain pinned in
[`rust-toolchain.toml`](../../rust-toolchain.toml) (see
[Rust](./environment.md#rust)), plus the `cargo-audit`, `cargo-llvm-cov` and
`cargo-nextest` plugins.
## Conan configuration
The shell runs [`conan/init.sh`](../../conan/init.sh) on entry, so
@@ -142,14 +148,80 @@ environment — CI runs in Docker images that bundle the dev shell's toolchain (
`-plain` shells do not match that toolchain's glibc, so binaries from the remote
are not a reliable match there.
On **macOS**, CI builds with Apple Clang, so the remote holds nothing for the Nix
`clang` toolchain and dependencies are compiled locally. We do not publish
Nix-built macOS binaries because a Conan package ID records the compiler version
but not the nixpkgs revision.
On **macOS**, CI also builds in this Nix environment, in Debug and Release (the
`macos-arm64-*-nix` configurations — Debug because the profile defaults to it).
The Nix build resolves to `compiler=clang`, so it gets its own package IDs,
separate from the Apple Clang ones. The
[dependency upload](../../.github/workflows/upload-conan-deps.yml) publishes them
on pushes to `develop` and on manual runs — its nightly run rebuilds everything
from source but uploads nothing — so once a set has been published `nix develop`
can reuse it instead of compiling every dependency locally. These configurations
run outside the reduced pull-request matrix, so label a PR `Full CI build` when it
touches `flake.lock` or `nix/`.
To compile everything from source, add `--build '*'` to the `conan install`
command.
### Why the nixpkgs revision is not part of the package ID
A Conan package ID records the compiler and its major version, but nothing about
the nixpkgs revision the toolchain came from — and `flake.lock` moves far more
often than the toolchain meaningfully changes, so folding it in would rebuild
every dependency on every bump for nothing.
That is safe as long as no cached artifact resolves a `/nix/store` path at run
time, because store paths change on every update and the old ones disappear with
`nix-collect-garbage`. With the `clang` toolchain macOS CI and the dev shell use,
they do not: it links against `/usr/lib/libc++` and `/usr/lib/libSystem`, and
store paths reach the `.a` files only through debug info, which nothing resolves
at link or run time.
> [!WARNING]
> This does not hold for `nix develop .#gcc` on macOS. There is no system
> libstdc++, so GCC links its own from the store and every binary keeps a
> `/nix/store` reference. That shell is fine for tooling, but it is not a build
> configuration CI covers, and no dependency binaries are published for it.
This is checked rather than assumed.
[`bin/check-nix-store-refs.sh`](../../bin/check-nix-store-refs.sh) takes one file
or directory and fails if a binary under it resolves a store path at run time.
CI runs it over the build output and the Conan cache, and again in the upload job
before anything is published. You can run it yourself:
```bash
bin/check-nix-store-refs.sh build
bin/check-nix-store-refs.sh ~/.conan2-nix
```
It works on Linux too, but asserts something narrower there: the toolchain always
writes the store into `PT_INTERP` and `RUNPATH`, and CI builds inside an image
whose store is fixed for its lifetime, so that is fine. Only the binaries
[`PatchNixBinary.cmake`](../../cmake/PatchNixBinary.cmake) retargets to the
system loader have to be clean, and those are what CI checks:
```bash
bin/check-nix-store-refs.sh build/xrpld
```
### The libresolv stub
This is not hypothetical: `xrpld` used to be caught by it. The c-ares package
tells the linker to pass `-lresolv`, and nixpkgs keeps `libresolv` out of the
macOS SDK and ships it as an ordinary store dylib — so every Nix-built `xrpld`
recorded a `/nix/store/…-libresolv-93/lib/libresolv.9.dylib` load command and
stopped running once that path was collected. Nothing in the link uses a single
symbol from it.
Both environments now put a stub on the linker search path
(`libresolvSystemStub` in [`nix/darwin.nix`](../../nix/darwin.nix)): the
same library with its install name set to `/usr/lib/libresolv.9.dylib`, which is
exactly the load command the Apple Clang build records.
Package IDs did not change, so Conan keeps serving anything built before the
stub landed. If a binary fails to start with `Library not loaded: /nix/store/…`,
see [that entry](./nix_troubleshooting.md#library-not-loaded-nixstore-from-a-binary-that-used-to-work)
in the troubleshooting guide.
## Automatic Activation with direnv
[direnv](https://direnv.net/) or [nix-direnv](https://github.com/nix-community/nix-direnv) can automatically activate the Nix development shell when you enter the repository directory.

View File

@@ -131,3 +131,91 @@ once it picks up that rebuild, then re-run the `grep libgit2` check above to
confirm it reports `1.9.4` or newer.
Until then, prefer the workarounds above.
## `wint_t` / `uint32_t` errors from the Nix libc++ headers
A build that mixes the Nix toolchain with the system SDK fails in libc++ itself,
with errors that look nothing like your code:
```
/nix/store/...-libcxx-.../include/c++/v1/cwchar:136:9: error: target of using declaration conflicts with declaration already in scope
136 | using ::wint_t _LIBCPP_USING_IF_EXISTS;
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types/_wint_t.h:32:25: note: target of using declaration
...
error: use of undeclared identifier 'UINT32_C'
```
The give-away is the second path: Nix's libc++ headers are being combined with
the **Xcode Command Line Tools** SDK instead of the Nix one.
### Why it happens
`SDKROOT` and `DEVELOPER_DIR` are what point the toolchain at the Nix SDK, and
they are not baked into the compiler — a dev shell gets them from the
`apple-sdk` setup hook. CMake, finding neither, asks `xcrun`, which answers with
the system SDK. Nix's `libc++` and Apple's headers then declare the same types
twice.
### Fix
Run the build from inside the dev shell (`nix develop`), or from an environment
that exports both variables. To confirm which SDK a configured build is using:
```bash
grep -o '\-isysroot [^ ]*' build/compile_commands.json | sort -u
```
It should print a `/nix/store/...-apple-sdk-*` path. If it prints
`/Library/Developer/CommandLineTools/...`, re-configure from within the shell —
CMake caches the sysroot, so an existing `build/` directory keeps the wrong one.
## `Library not loaded: /nix/store/…` from a binary that used to work
A binary stops starting after a `nix flake update`, or after
`nix-collect-garbage` removes the paths the previous toolchain used:
```
dyld[57271]: Library not loaded: /nix/store/…-libresolv-93/lib/libresolv.9.dylib
```
[`bin/check-nix-store-refs.sh`](../../bin/check-nix-store-refs.sh) finds the same
thing without having to run anything, and names the file:
```
$ bin/check-nix-store-refs.sh ~/.conan2-nix
::error file=/Users/you/.conan2-nix/p/b/c-area24ded30c388c/p/bin/adig::references the Nix store at run time
/Users/you/.conan2-nix/p/b/c-area24ded30c388c/p/bin/adig
/nix/store/p4lp3xq4imd1qzqh08x8vcq2zfhi7rca-libresolv-93/lib/libresolv.9.dylib
/Users/you/.conan2-nix: checked 135, skipped 2495, 1 with Nix store references.
```
Conan's cache folders are named after a truncated package name plus a hash, so
ask Conan which package the offending one belongs to — pass the folder holding
the hash, not the file itself:
```
$ conan cache ref ~/.conan2-nix/p/b/c-area24ded30c388c
c-ares/1.34.6#545240bb1c40e2cacd4362d6b8967650:dab5992496abe6d219defb7986ecbf367615a5e5#…
```
### Why it happens
The binary records a store path that no longer exists. Nothing we build should:
see [Prebuilt packages](./nix.md#prebuilt-packages) for why, and
`libresolvSystemStub` in [`nix/darwin.nix`](../../nix/darwin.nix) for the one
dependency that needed help to comply.
A Conan package ID does not encode the nixpkgs revision, so a package built
before that stub existed stays in your local cache and keeps being reused. The
dev shell is also what tends to produce one: it is a slightly _less_ isolated
build environment than CI's, because `mkShell` puts every tool's headers and
libraries on the compiler's search path — which is how c-ares found the Nix
`libresolv` in the first place.
### Fix
Drop that package and let Conan refetch or rebuild it:
```bash
conan remove 'c-ares/*'
```

View File

@@ -1,3 +1,10 @@
# Installing xrpld 3.3.0 and earlier
> [!IMPORTANT]
> These instructions apply to xrpld 3.3.0 and earlier, published to
> repos.ripple.com.
> For later releases see [install.md](./install.md).
This document contains instructions for installing xrpld.
The APT package manager is common on Debian-based Linux distributions like
Ubuntu,
@@ -52,7 +59,7 @@ The default [prefix][1] is typically `/usr/local` on Linux and macOS and
5. Add the appropriate XRPL repository for your operating system version:
echo "deb [signed-by=/usr/local/share/keyrings/ripple-key.gpg] https://repos.ripple.com/repos/xrpld-deb focal stable" | \
echo "deb [signed-by=/usr/local/share/keyrings/ripple-key.gpg] https://repos.ripple.com/repos/rippled-deb focal stable" | \
sudo tee -a /etc/apt/sources.list.d/ripple.list
The above example is appropriate for **Ubuntu 20.04 Focal Fossa**. For other operating systems, replace the word `focal` with one of the following:
@@ -106,8 +113,8 @@ The default [prefix][1] is typically `/usr/local` on Linux and macOS and
enabled=1
gpgcheck=0
repo_gpgcheck=1
baseurl=https://repos.ripple.com/repos/xrpld-rpm/stable/
gpgkey=https://repos.ripple.com/repos/xrpld-rpm/stable/repodata/repomd.xml.key
baseurl=https://repos.ripple.com/repos/rippled-rpm/stable/
gpgkey=https://repos.ripple.com/repos/rippled-rpm/stable/repodata/repomd.xml.key
REPOFILE
_Unstable_
@@ -118,8 +125,8 @@ The default [prefix][1] is typically `/usr/local` on Linux and macOS and
enabled=1
gpgcheck=0
repo_gpgcheck=1
baseurl=https://repos.ripple.com/repos/xrpld-rpm/unstable/
gpgkey=https://repos.ripple.com/repos/xrpld-rpm/unstable/repodata/repomd.xml.key
baseurl=https://repos.ripple.com/repos/rippled-rpm/unstable/
gpgkey=https://repos.ripple.com/repos/rippled-rpm/unstable/repodata/repomd.xml.key
REPOFILE
_Nightly_
@@ -130,8 +137,8 @@ The default [prefix][1] is typically `/usr/local` on Linux and macOS and
enabled=1
gpgcheck=0
repo_gpgcheck=1
baseurl=https://repos.ripple.com/repos/xrpld-rpm/nightly/
gpgkey=https://repos.ripple.com/repos/xrpld-rpm/nightly/repodata/repomd.xml.key
baseurl=https://repos.ripple.com/repos/rippled-rpm/nightly/
gpgkey=https://repos.ripple.com/repos/rippled-rpm/nightly/repodata/repomd.xml.key
REPOFILE
2. Fetch the latest repo updates:

144
docs/install.md Normal file
View File

@@ -0,0 +1,144 @@
# Installing xrpld
> [!NOTE]
> These instructions apply to packages published from 2026-08-19 onwards.
> For xrpld 3.3.0 and earlier see [install-legacy.md](./install-legacy.md).
`xrpld` is published as DEB and RPM packages for 64-bit x86 Linux.
Use APT on Debian-based distributions such as Debian and Ubuntu,
and YUM on Red Hat-based distributions such as RHEL, AlmaLinux, and Rocky Linux.
To build from source instead, see [BUILD.md](../BUILD.md).
## Release channels
Packages are published to four channels:
- `stable` - production releases
- `rc` - release candidates
- `beta` - beta builds
- `develop` - every push to the [`develop` branch](https://github.com/XRPLF/rippled/tree/develop)
See [Publishing packages](../package/README.md#publishing-packages) for how channels are produced.
The instructions below use `stable`.
To follow another channel, replace `stable` with its name
wherever it appears in the repository configuration.
> [!WARNING]
> Channels other than `stable` may be broken at any time.
> Do not use them for production servers.
## Install the xrpld package
### With the APT package manager
1. Install utilities:
```bash
sudo apt update -y
sudo apt install -y apt-transport-https ca-certificates curl gnupg
```
2. Add the XRPL Foundation package-signing key to your list of trusted keys:
```bash
sudo install -d -m 0755 /etc/apt/keyrings
sudo curl -fsS https://packages.xrplf.org/xrplf.asc -o /etc/apt/keyrings/xrplf.asc
```
3. Check the fingerprint of the newly-added key:
```bash
gpg --show-keys /etc/apt/keyrings/xrplf.asc
```
The output should be:
```text
pub rsa4096 2026-08-18 [SC]
B655416741221F780FBCFBC9AA84D41A11D29FA9
uid XRPLF Packages <distribution@xrplf.org>
```
In particular, make sure that the fingerprint matches.
4. Add the repository, using the channel you picked in [Release channels](#release-channels):
```bash
echo "deb [signed-by=/etc/apt/keyrings/xrplf.asc] https://packages.xrplf.org/repository/deb-stable any main" | \
sudo tee /etc/apt/sources.list.d/xrplf.list
```
5. Fetch the repository:
```bash
sudo apt -y update
```
6. Install the `xrpld` software package:
```bash
sudo apt -y install xrpld
```
### With the YUM package manager
1. Add the XRPL Foundation package-signing key:
```bash
sudo rpm --import https://packages.xrplf.org/xrplf.asc
```
2. Add the repository, using the channel you picked in [Release channels](#release-channels):
```bash
cat << 'REPOFILE' | sudo tee /etc/yum.repos.d/xrplf.repo
[xrplf-stable]
name=XRP Ledger Packages
enabled=1
baseurl=https://packages.xrplf.org/repository/rpm-stable/$basearch/
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.xrplf.org/xrplf.asc
REPOFILE
```
`gpgcheck=1` verifies each package against the key above.
`repo_gpgcheck=1` verifies the repository metadata, which the server signs with the same key.
3. Install the `xrpld` package:
```bash
sudo yum install -y xrpld
```
## The xrpld service
Both package managers install a systemd unit and enable it, so `xrpld` starts on boot.
Check whether it is already running:
```bash
systemctl status xrpld.service
```
The APT packages start it immediately as well; the YUM packages do not, so start it yourself:
```bash
sudo systemctl start xrpld.service
```
### Optional: binding to privileged ports
To serve incoming API requests on port 80 or 443, grant the service the capability to bind them.
You must also update the config file's port settings.
```bash
sudo install -d -m 0755 /etc/systemd/system/xrpld.service.d
sudo tee /etc/systemd/system/xrpld.service.d/privileged-ports.conf >/dev/null <<'EOF'
[Service]
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
EOF
sudo systemctl daemon-reload
sudo systemctl restart xrpld.service
```

View File

@@ -543,8 +543,21 @@ public:
setround(RoundingMode inMode);
/**
* Returns which mantissa scale is currently in use for normalization.
* Convert an integer to a RoundingMode, validating that it is in range.
*
* Returns std::nullopt if the value does not correspond to a valid
* RoundingMode.
*/
static std::optional<RoundingMode>
checkedRoundingMode(int mode) noexcept
{
if (mode < static_cast<int>(RoundingMode::ToNearest) ||
mode > static_cast<int>(RoundingMode::Upward))
return std::nullopt;
return static_cast<RoundingMode>(mode);
}
/**
* If you think you need to call this outside of unit tests, no you don't.
*/
static MantissaRange::MantissaScale

View File

@@ -2,7 +2,6 @@
#include <xrpl/basics/Blob.h>
#include <boost/format.hpp>
#include <boost/utility/string_view.hpp>
#include <array>

View File

@@ -82,4 +82,10 @@ base64Encode(std::string_view s)
std::string
base64Decode(std::string_view data);
/** Decode a base64url-encoded string (RFC 4648 S5).
Converts '-' to '+' and '_' to '/', adds padding, then decodes.
*/
std::string
base64urlDecode(std::string_view data);
} // namespace xrpl

View File

@@ -103,7 +103,7 @@ namespace boost {
template <>
struct hash<::beast::ip::Address>
{
explicit hash() = default;
hash() = default;
std::size_t
operator()(::beast::ip::Address const& addr) const

View File

@@ -11,6 +11,7 @@
#include <cstddef>
#include <iterator>
#include <string>
#include <string_view>
#include <vector>
namespace beast::rfc2616 {
@@ -186,7 +187,7 @@ splitCommas(FwdIt first, FwdIt last)
template <class Result = std::vector<std::string>>
Result
splitCommas(boost::beast::string_view const& s)
splitCommas(std::string_view s)
{
return splitCommas(s.begin(), s.end());
}

View File

@@ -2,7 +2,6 @@
#include <xrpl/basics/contract.h>
#include <boost/beast/core/string.hpp>
#include <boost/lexical_cast.hpp>
#include <algorithm>

View File

@@ -11,6 +11,7 @@ struct Sections
static constexpr auto kCompression = "compression";
static constexpr auto kCrawl = "crawl";
static constexpr auto kDatabasePath = "database_path";
static constexpr auto kDatagramMonitor = "datagram_monitor";
static constexpr auto kDebugLogfile = "debug_logfile";
static constexpr auto kElbSupport = "elb_support";
static constexpr auto kFeatures = "features";
@@ -67,6 +68,7 @@ struct Sections
static constexpr auto kValidationSeed = "validation_seed";
static constexpr auto kValidatorKeys = "validator_keys";
static constexpr auto kValidatorKeyRevocation = "validator_key_revocation";
static constexpr auto kValidatorKeyType = "validator_key_type";
static constexpr auto kValidatorListKeys = "validator_list_keys";
static constexpr auto kValidatorListSites = "validator_list_sites";
static constexpr auto kValidatorListThreshold = "validator_list_threshold";
@@ -94,6 +96,7 @@ struct Keys
static constexpr auto kBbtOptions = "bbt_options";
static constexpr auto kBgThreads = "bg_threads";
static constexpr auto kBlockSize = "block_size";
static constexpr auto kBytecodeSizeLimit = "bytecode_size_limit";
static constexpr auto kCacheAge = "cache_age";
static constexpr auto kCacheMb = "cache_mb";
static constexpr auto kCacheSize = "cache_size";
@@ -108,6 +111,8 @@ struct Keys
static constexpr auto kFileSizeMult = "file_size_mult";
static constexpr auto kFilterBits = "filter_bits";
static constexpr auto kFilterFull = "filter_full";
static constexpr auto kGasLimit = "gas_limit";
static constexpr auto kGasPrice = "gas_price";
static constexpr auto kHardSet = "hard_set";
static constexpr auto kHighThreads = "high_threads";
static constexpr auto kHoldTime = "hold_time";
@@ -125,6 +130,7 @@ struct Keys
static constexpr auto kMaximumTxnInLedger = "maximum_txn_in_ledger";
static constexpr auto kMaximumTxnPerAccount = "maximum_txn_per_account";
static constexpr auto kMemoryLevel = "memory_level";
static constexpr auto kMaxWaitingLedgers = "max_waiting_ledgers";
static constexpr auto kMinLedgersToComputeSizeLimit = "min_ledgers_to_compute_size_limit";
static constexpr auto kMinimumEscalationMultiplier = "minimum_escalation_multiplier";
static constexpr auto kMinimumLastLedgerBuffer = "minimum_last_ledger_buffer";

View File

@@ -34,7 +34,10 @@ enum class HashRouterFlags : std::uint16_t {
PRIVATE4 = 0x0800,
// Used in EscrowFinish.cpp
PRIVATE5 = 0x1000,
PRIVATE6 = 0x2000
PRIVATE6 = 0x2000,
// Used in apply.cpp
PRIVATE7 = 0x4000,
PRIVATE8 = 0x8000
};
constexpr HashRouterFlags

View File

@@ -6,6 +6,7 @@
#include <xrpl/basics/TaggedCache.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/protocol/Fees.h>
#include <boost/asio.hpp>
@@ -246,6 +247,9 @@ public:
virtual DatabaseCon&
getWalletDB() = 0;
[[nodiscard]] virtual Fees
getFees() const = 0;
// Temporary: Get the underlying Application for functions that haven't
// been migrated yet. This should be removed once all code is migrated.
virtual Application&

View File

@@ -1,20 +1,19 @@
#pragma once
#include <boost/beast/core/string.hpp>
#include <functional>
#include <string>
#include <string_view>
namespace json {
class Value;
using Output = std::function<void(boost::beast::string_view const&)>;
using Output = std::function<void(std::string_view)>;
inline Output
stringOutput(std::string& s)
{
return [&](boost::beast::string_view const& b) { s.append(b.data(), b.size()); };
return [&](std::string_view b) { s.append(b.data(), b.size()); };
}
/**

View File

@@ -528,6 +528,7 @@ public:
using iterator_category = std::bidirectional_iterator_tag;
using size_t = unsigned int;
using difference_type = int;
using value_type = Value;
using SelfType = ValueIteratorBase;
ValueIteratorBase();

View File

@@ -13,6 +13,7 @@
#include <xrpl/protocol/TxMeta.h>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <optional>
@@ -68,6 +69,18 @@ public:
deliver_ = amount;
}
void
setGasUsed(std::optional<std::uint32_t> const gasUsed)
{
gasUsed_ = gasUsed;
}
void
setVMReturnCode(std::int32_t const vmReturnCode)
{
vmReturnCode_ = vmReturnCode;
}
/**
* Get the number of modified entries
*/
@@ -88,6 +101,8 @@ public:
private:
std::optional<STAmount> deliver_;
std::optional<std::uint32_t> gasUsed_;
std::optional<std::int32_t> vmReturnCode_;
};
} // namespace xrpl

View File

@@ -78,6 +78,12 @@ public:
return base_.succ(key, last);
}
std::optional<key_type>
pred(key_type const& key, std::optional<key_type> const& first = std::nullopt) const override
{
return base_.pred(key, first);
}
std::unique_ptr<SlesType::iter_base>
slesBegin() const override
{

View File

@@ -186,6 +186,9 @@ public:
std::optional<uint256>
succ(uint256 const& key, std::optional<uint256> const& last = std::nullopt) const override;
std::optional<uint256>
pred(uint256 const& key, std::optional<uint256> const& first = std::nullopt) const override;
SLE::const_pointer
read(Keylet const& k) const override;

View File

@@ -221,6 +221,9 @@ public:
std::optional<key_type>
succ(key_type const& key, std::optional<key_type> const& last = std::nullopt) const override;
std::optional<key_type>
pred(key_type const& key, std::optional<key_type> const& first = std::nullopt) const override;
SLE::const_pointer
read(Keylet const& k) const override;

View File

@@ -0,0 +1,82 @@
#pragma once
#include <xrpl/ledger/OpenView.h>
#include <memory>
namespace xrpl {
class OpenViewSandbox
{
private:
OpenView& parent_;
std::unique_ptr<OpenView> sandbox_;
public:
using key_type = ReadView::key_type;
OpenViewSandbox(OpenView& parent)
: parent_(parent), sandbox_(std::make_unique<OpenView>(kBatchView, parent))
{
}
void
rawErase(std::shared_ptr<SLE> const& sle)
{
sandbox_->rawErase(sle);
}
void
rawInsert(std::shared_ptr<SLE> const& sle)
{
sandbox_->rawInsert(sle);
}
void
rawReplace(std::shared_ptr<SLE> const& sle)
{
sandbox_->rawReplace(sle);
}
void
rawDestroyXRP(XRPAmount const& fee)
{
sandbox_->rawDestroyXRP(fee);
}
void
rawTxInsert(
key_type const& key,
std::shared_ptr<Serializer const> const& txn,
std::shared_ptr<Serializer const> const& metaData)
{
sandbox_->rawTxInsert(key, txn, metaData);
}
void
commit()
{
sandbox_->apply(parent_);
sandbox_ = std::make_unique<OpenView>(kBatchView, parent_);
}
void
discard()
{
sandbox_ = std::make_unique<OpenView>(kBatchView, parent_);
}
OpenView const&
view() const
{
return *sandbox_;
}
OpenView&
view()
{
return *sandbox_;
}
};
} // namespace xrpl

View File

@@ -154,6 +154,19 @@ public:
[[nodiscard]] virtual std::optional<key_type>
succ(key_type const& key, std::optional<key_type> const& last = std::nullopt) const = 0;
/** Return the key of the previous state item.
This returns the key of the first state item
whose key is less than the specified key. If
no such key is present, std::nullopt is returned.
If `first` is engaged, returns std::nullopt when
the key returned would be outside the open
interval (first, key).
*/
[[nodiscard]] virtual std::optional<key_type>
pred(key_type const& key, std::optional<key_type> const& first = std::nullopt) const = 0;
/**
* Return the state item associated with a key.
*

View File

@@ -5,6 +5,10 @@
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
#include <xrpl/ledger/helpers/OfferHelpers.h>
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
#include <xrpl/ledger/helpers/TokenHelpers.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/Keylet.h>
@@ -24,6 +28,7 @@
#include <optional>
#include <set>
#include <utility>
#include <vector>
namespace xrpl {
@@ -78,6 +83,13 @@ isVaultPseudoAccountFrozen(
MPTIssue const& mptShare,
std::uint8_t depth);
[[nodiscard]] bool
isVaultPseudoAccountFrozen(
ReadView const& view,
AccountID const& account,
SLE const& issuanceSle,
std::uint8_t depth);
[[nodiscard]] bool
isLPTokenFrozen(
ReadView const& view,
@@ -85,6 +97,26 @@ isLPTokenFrozen(
Asset const& asset,
Asset const& asset2);
/**
* Check whether an AMM LPToken may be transferred between @p from and @p to.
*
* @p lpTokenIssuer is the issuer of the LPToken being moved. If it is not an
* AMM account the token is not an LPToken and the transfer is unconditionally
* permitted. Otherwise, for each MPT pool asset of that AMM, canTransfer() must
* permit the transfer (which exempts the MPT issuer). Non-MPT pool assets are
* always transferable by this check, so it is implicitly gated by
* featureMPTokensV2 (MPTs can only be AMM pool assets once V2 is enabled).
*
* @return tesSUCCESS if permitted, otherwise the canTransfer() failure code
* (e.g. tecNO_AUTH) of the first MPT pool asset that disallows it.
*/
[[nodiscard]] TER
canTransferLPToken(
ReadView const& view,
AccountID const& from,
AccountID const& to,
AccountID const& lpTokenIssuer);
// Return the list of enabled amendments
[[nodiscard]] std::set<uint256>
getEnabledAmendments(ReadView const& view);
@@ -171,7 +203,10 @@ dirLink(
* if withdrawing to self.
* - If withdrawing to self, succeed.
* - If not, checks if the receiver requires deposit authorization, and if
* the sender has it.
* the sender has it (account-based or credential-based).
* - Expects any credentials passed in to already exist in the ledger, and
* returns an internal error otherwise. Validate them beforehand with
* credentials::valid().
* - Checks that the receiver will not exceed the limit (IOU trustline limit
* or MPT MaximumAmount).
*/
@@ -182,7 +217,8 @@ canWithdraw(
AccountID const& to,
SLE::const_ref toSle,
STAmount const& amount,
bool hasDestinationTag);
bool hasDestinationTag,
std::optional<std::vector<uint256>> const& credentialIDs = std::nullopt);
/**
* Checks that can withdraw funds from an object to itself or a destination.
@@ -195,7 +231,10 @@ canWithdraw(
* if withdrawing to self.
* - If withdrawing to self, succeed.
* - If not, checks if the receiver requires deposit authorization, and if
* the sender has it.
* the sender has it (account-based or credential-based).
* - Expects any credentials passed in to already exist in the ledger, and
* returns an internal error otherwise. Validate them beforehand with
* credentials::valid().
* - Checks that the receiver will not exceed the limit (IOU trustline limit
* or MPT MaximumAmount).
*/
@@ -205,20 +244,25 @@ canWithdraw(
AccountID const& from,
AccountID const& to,
STAmount const& amount,
bool hasDestinationTag);
bool hasDestinationTag,
std::optional<std::vector<uint256>> const& credentialIDs = std::nullopt);
/**
* Checks that can withdraw funds from an object to itself or a destination.
*
* The receiver may be either the submitting account (sfAccount) or a different
* destination account (sfDestination).
* destination account (sfDestination). Credentials, if any, are taken from the
* transaction's sfCredentialIDs field.
*
* - Checks that the receiver account exists.
* - If the receiver requires a destination tag, check that one exists, even
* if withdrawing to self.
* - If withdrawing to self, succeed.
* - If not, checks if the receiver requires deposit authorization, and if
* the sender has it.
* the sender has it (account-based or credential-based).
* - Expects any credentials in sfCredentialIDs to already exist in the
* ledger, and returns an internal error otherwise. Validate them
* beforehand with credentials::valid().
* - Checks that the receiver will not exceed the limit (IOU trustline limit
* or MPT MaximumAmount).
*/
@@ -235,6 +279,27 @@ doWithdraw(
STAmount const& amount,
beast::Journal j);
enum class SendIssuerHandling { ihSENDER_NOT_ALLOWED, ihRECEIVER_NOT_ALLOWED, ihIGNORE };
enum class SendEscrowHandling { ehIGNORE, ehCHECK };
enum class SendAuthHandling { ahCHECK_SENDER, ahCHECK_RECEIVER, ahBOTH, ahNEITHER };
enum class SendFreezeHandling { fhCHECK_SENDER, fhCHECK_RECEIVER, fhBOTH, fhNEITHER };
enum class SendTransferHandling { thIGNORE, thCHECK };
enum class SendBalanceHandling { bhIGNORE, bhCHECK };
TER
canTransferFT(
ReadView const& view,
AccountID const& sender,
AccountID const& receiver,
STAmount const& amount,
beast::Journal j,
SendIssuerHandling issuerHandling,
SendEscrowHandling escrowHandling,
SendAuthHandling authHandling,
SendFreezeHandling freezeHandling,
SendTransferHandling transferHandling,
SendBalanceHandling balanceHandling);
/**
* Deleter function prototype. Returns the status of the entry deletion
* (if should not be skipped) and if the entry should be skipped. The status

View File

@@ -16,6 +16,7 @@
#include <xrpl/protocol/XRPAmount.h>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <map>
#include <optional>
@@ -62,6 +63,8 @@ public:
TER ter,
std::optional<STAmount> const& deliver,
std::optional<uint256 const> const& parentBatchId,
std::optional<std::uint32_t> const& gasUsed,
std::optional<std::int32_t> const& vmReturnCode,
bool isDryRun,
beast::Journal j);
@@ -71,6 +74,9 @@ public:
[[nodiscard]] std::optional<key_type>
succ(ReadView const& base, key_type const& key, std::optional<key_type> const& last) const;
[[nodiscard]] std::optional<key_type>
pred(ReadView const& base, key_type const& key, std::optional<key_type> const& first) const;
[[nodiscard]] SLE::const_pointer
read(ReadView const& base, Keylet const& k) const;

View File

@@ -50,6 +50,9 @@ public:
[[nodiscard]] std::optional<key_type>
succ(key_type const& key, std::optional<key_type> const& last = std::nullopt) const override;
[[nodiscard]] std::optional<key_type>
pred(key_type const& key, std::optional<key_type> const& first = std::nullopt) const override;
[[nodiscard]] SLE::const_pointer
read(Keylet const& k) const override;

View File

@@ -56,6 +56,9 @@ public:
[[nodiscard]] std::optional<key_type>
succ(ReadView const& base, key_type const& key, std::optional<key_type> const& last) const;
[[nodiscard]] std::optional<key_type>
pred(ReadView const& base, key_type const& key, std::optional<key_type> const& first) const;
void
erase(SLE::ref sle);

View File

@@ -0,0 +1,249 @@
// Pluggable AMM curve architecture.
// Concentrated liquidity (CurveType 1) based on XRPL-Standards Discussion #427
// by Roman Thpt (@RomThpt), which adapted Uniswap v3 tick math, fee tier
// structure, and fee accounting to the XRPL. This implementation extends that
// work with a pluggable curve interface, StableSwap, and Smart AMM.
// See: https://github.com/XRPLF/XRPL-Standards/discussions/427
#pragma once
#include <expected>
#include <xrpl/basics/Number.h>
#include <xrpl/ledger/helpers/AMMHelpers.h>
#include <xrpl/protocol/AMMCore.h>
#include <xrpl/protocol/AmountConversions.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Quality.h>
#include <xrpl/protocol/Rules.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/STObject.h>
#include <xrpl/protocol/TER.h>
namespace xrpl {
class ReadView;
class ApplyView;
struct CurveContext
{
ReadView const* view = nullptr;
uint256 const* ammID = nullptr;
// Optional out: set to true if a CL swap-walk terminated because it hit
// maxTickCrossings. Callers pass a pointer when they want to detect
// the cap (e.g. to emit tecAMM_TICK_CAP_HIT); pass nullptr to ignore.
bool* tickCapHit = nullptr;
};
class CurveInterface
{
public:
virtual ~CurveInterface() = default;
virtual std::expected<STAmount, TER>
swapIn(
STAmount const& poolIn,
STAmount const& poolOut,
STAmount const& assetIn,
std::uint16_t tfee,
STObject const* ammSle,
CurveContext const& ctx = {}) const = 0;
virtual std::expected<STAmount, TER>
swapOut(
STAmount const& poolIn,
STAmount const& poolOut,
STAmount const& assetOut,
std::uint16_t tfee,
STObject const* ammSle,
CurveContext const& ctx = {}) const = 0;
virtual std::expected<Number, TER>
spotPrice(
STAmount const& poolIn,
STAmount const& poolOut,
std::uint16_t tfee,
STObject const* ammSle,
CurveContext const& ctx = {}) const = 0;
[[nodiscard]] virtual TER
validateParams(STObject const& tx) const = 0;
virtual std::expected<STAmount, TER>
initialLPTokens(
STAmount const& asset1,
STAmount const& asset2,
Issue const& lptIssue,
STObject const* txParams) const = 0;
virtual bool
checkInvariant(
STAmount const& oldIn,
STAmount const& oldOut,
STAmount const& newIn,
STAmount const& newOut,
STObject const* ammSle) const = 0;
// Apply a realized swap to the AMM SLE. Trustline balances are updated
// by the caller (BookStep). For CP and StableSwap the pool state is fully
// implicit in trustline balances, so the default is a no-op. CL must
// mutate currentTick/activeLiquidity/feeGrowthGlobal and flip
// feeGrowthOutside on crossed ticks, because none of that state is
// derivable from the trustlines alone.
virtual TER
applySwap(
ApplyView& /*view*/,
uint256 const& /*ammID*/,
STAmount const& /*assetIn*/,
STAmount const& /*assetOut*/,
std::uint16_t /*tfee*/,
STObject const* /*curveParams*/) const
{
return tesSUCCESS;
}
};
CurveInterface const*
getCurve(std::uint8_t curveType, Rules const& rules);
// Max output the pool can deliver before crossing the next initialised
// tick boundary in the swap direction. Audit #19: caller (AMMLiquidity's
// offer generation) uses this to cap an advertised AMM offer at the
// current tick range, so the offer's quality reflects only the marginal
// range — not a blended average across multiple tick crossings.
//
// Returns std::nullopt if there is no further tick in the swap direction
// (no cap; offer is bounded only by reserves) or if the pool has no
// active liquidity. Returns 0 if the swap is already at the boundary.
// Caller should treat nullopt as "no cap".
std::optional<Number>
maxClOutputWithinCurrentRange(
ReadView const& view,
uint256 const& ammID,
STObject const& ammSle,
bool zeroForOne);
// Equivalent for CtBinned: cap the advertised AMMOffer output at the
// active bin's reserve. Without this cap, AMMLiquidity quotes against
// the pool's aggregate balance — which spans multiple bins at different
// prices — and BookStep mispricesthe offer's quality vs CLOB. Capping
// per active bin lets BookStep iterate naturally, getting each bin's
// marginal price one offer at a time.
//
// Returns std::nullopt if no active bin exists (empty pool) or the
// active bin lacks the output asset.
std::optional<Number>
maxBinnedOutputAtActiveBin(
ReadView const& view,
uint256 const& ammID,
STObject const& ammSle,
bool inIsAsset0);
// ─── CL tick bitmap ─────────────────────────────────────────────────────
//
// Sparse 256-tick-per-word presence bitmap. See spec §3.6.
// Convert a tick to its (wordIndex, bitInWord) position. Offset-binary so
// arithmetic stays in unsigned domain. Uses kTickBitmapOffset (= -minTick)
// from AMMCore.h — single source of truth, do NOT duplicate inline.
inline std::pair<std::uint16_t, std::uint8_t>
tickToBitmapPos(std::int32_t tick) noexcept
{
auto const offsetT = static_cast<std::uint32_t>(
tick + static_cast<std::int32_t>(kTickBitmapOffset));
return {static_cast<std::uint16_t>(offsetT >> 8),
static_cast<std::uint8_t>(offsetT & 0xFFu)};
}
inline std::int32_t
bitmapPosToTick(std::uint16_t wordIndex, std::uint8_t bitInWord) noexcept
{
auto const offsetT =
(static_cast<std::uint32_t>(wordIndex) << 8) | bitInWord;
return static_cast<std::int32_t>(offsetT) -
static_cast<std::int32_t>(kTickBitmapOffset);
}
// Bit-test for the bitmap word storage. `bits` is the raw `sfBitmapBits`
// value read off the SLE. Convention: bit i = LSB of byte (i/8), little-
// endian within bytes. The convention is internal — callers that write
// bits must use the same scheme (and do, via the maintenance helpers).
inline bool
bitmapBitIsSet(uint256 const& bits, std::uint8_t pos) noexcept
{
return ((bits.data()[pos / 8]) >> (pos % 8)) & 1u;
}
// AMMDeposit and AMMWithdraw call these when a tick crosses the
// "initialised / uninitialised" boundary (sfLiquidityGross transitioning
// 0↔>0). Each pool has a sparse set of `ltAMM_TICK_BITMAP` SLEs covering
// 256 ticks each; setting / clearing creates and deletes those SLEs on
// demand. Idempotent — calling set on an already-set bit is a no-op.
//
// Returns tesSUCCESS on the happy path. The current implementation has
// no failure path beyond the AMM SLE being missing; reserved as TER for
// forward compatibility.
TER
setTickBitmap(ApplyView& view, uint256 const& ammID, std::int32_t tick, beast::Journal j);
TER
clearTickBitmap(ApplyView& view, uint256 const& ammID, std::int32_t tick, beast::Journal j);
inline std::uint8_t
getCurveType(SLE const& ammSle)
{
if (ammSle.isFieldPresent(sfCurveType))
return ammSle.getFieldU8(sfCurveType);
return CtConstantProduct;
}
template <typename TIn, typename TOut>
TOut
curveSwapIn(
TAmounts<TIn, TOut> const& pool,
TIn const& assetIn,
std::uint16_t tfee,
std::uint8_t curveType,
STObject const* ammSle,
CurveContext const& cctx = {})
{
if (curveType == CtConstantProduct)
return swapAssetIn(pool, assetIn, tfee);
if (auto const* curve = getCurve(curveType, *getCurrentTransactionRules()))
{
auto const stPoolIn = toSTAmount(pool.in);
auto const stPoolOut = toSTAmount(pool.out);
auto const stAssetIn = toSTAmount(assetIn);
if (auto const result = curve->swapIn(stPoolIn, stPoolOut, stAssetIn, tfee, ammSle, cctx))
return get<TOut>(*result);
}
return toAmount<TOut>(getAsset(pool.out), 0);
}
template <typename TIn, typename TOut>
TIn
curveSwapOut(
TAmounts<TIn, TOut> const& pool,
TOut const& assetOut,
std::uint16_t tfee,
std::uint8_t curveType,
STObject const* ammSle,
CurveContext const& cctx = {})
{
if (curveType == CtConstantProduct)
return swapAssetOut(pool, assetOut, tfee);
if (auto const* curve = getCurve(curveType, *getCurrentTransactionRules()))
{
auto const stPoolIn = toSTAmount(pool.in);
auto const stPoolOut = toSTAmount(pool.out);
auto const stAssetOut = toSTAmount(assetOut);
if (auto const result = curve->swapOut(stPoolIn, stPoolOut, stAssetOut, tfee, ammSle, cctx))
return get<TIn>(*result);
}
return toMaxAmount<TIn>(getAsset(pool.in));
}
} // namespace xrpl

View File

@@ -837,7 +837,8 @@ ammLPHolds(
Asset const& asset2,
AccountID const& ammAccount,
AccountID const& lpAccount,
beast::Journal const j);
beast::Journal const j,
std::uint8_t curveType = CtConstantProduct);
STAmount
ammLPHolds(
@@ -865,7 +866,12 @@ ammAccountHolds(ReadView const& view, AccountID const& ammAccountID, Asset const
* AMM object and account are deleted. Otherwise tecINCOMPLETE is returned.
*/
TER
deleteAMMAccount(Sandbox& view, Asset const& asset, Asset const& asset2, beast::Journal j);
deleteAMMAccount(
Sandbox& view,
Asset const& asset,
Asset const& asset2,
beast::Journal j,
std::uint8_t curveType = 0);
/**
* Initialize Auction and Voting slots and set the trading/discounted fee.

View File

@@ -0,0 +1,19 @@
#pragma once
#include <xrpl/basics/Number.h>
#include <xrpl/protocol/AMMCore.h>
#include <cstdint>
namespace xrpl {
Number
tickToSqrtPrice(std::int32_t tick);
std::int32_t
sqrtPriceToTick(Number const& sqrtPrice);
bool
isValidTick(std::int32_t tick, std::int32_t tickSpacing);
} // namespace xrpl

View File

@@ -15,7 +15,6 @@
#include <cstdint>
#include <expected>
#include <optional>
#include <set>
#include <vector>
namespace xrpl {
@@ -339,6 +338,17 @@ adjustLoanBrokerOwnerCount(
[[nodiscard]] Rate
transferRate(ReadView const& view, AccountID const& issuer);
/**
* Returns the transfer fee charged for a specific currency of the issuer.
* A per-currency TransferFee on the currency's TokenIssuance overrides the
* account-wide TransferRate.
*/
[[nodiscard]] Rate
transferRate(ReadView const& view, AccountID const& issuer, Currency const& currency);
[[nodiscard]] Rate
transferRate(ReadView const& view, Issue const& issue);
/**
* Generate a pseudo-account address from a pseudo owner key.
* @param pseudoOwnerKey The key to generate the address from
@@ -353,14 +363,14 @@ pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey);
*
* The list is constructed during initialization and is const after that.
* Pseudo-account designator fields MUST be maintained by including the
* SField::sMD_PseudoAccount flag in the SField definition.
* SField::kSmdPseudoAccount flag in the SField definition.
*/
[[nodiscard]] std::vector<SField const*> const&
getPseudoAccountFields();
/**
* Returns true if and only if sleAcct is a pseudo-account or specific
* pseudo-accounts in pseudoFieldFilter.
* Returns true if and only if sleAcct is a pseudo-account of any kind
* (i.e. carries at least one field flagged with SField::kSmdPseudoAccount).
*
* Returns false if sleAcct is:
* - NOT a pseudo-account OR
@@ -368,18 +378,15 @@ getPseudoAccountFields();
* - null pointer
*/
[[nodiscard]] bool
isPseudoAccount(SLE::const_pointer sleAcct, std::set<SField const*> const& pseudoFieldFilter = {});
isPseudoAccount(SLE::const_pointer sleAcct);
/**
* Convenience overload that reads the account from the view.
*/
[[nodiscard]] inline bool
isPseudoAccount(
ReadView const& view,
AccountID const& accountId,
std::set<SField const*> const& pseudoFieldFilter = {})
isPseudoAccount(ReadView const& view, AccountID const& accountId)
{
return isPseudoAccount(view.read(keylet::account(accountId)), pseudoFieldFilter);
return isPseudoAccount(view.read(keylet::account(accountId)));
}
/**

View File

@@ -0,0 +1,102 @@
#pragma once
#include <xrpl/basics/Log.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/core/ServiceRegistry.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/STData.h>
#include <xrpl/protocol/STJson.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFlags.h>
#include <map>
namespace xrpl {
class ContractDataMap : public std::map<xrpl::AccountID, std::pair<bool, STJson>>
{
public:
uint32_t modifiedCount = 0;
};
class ContractEventMap : public std::map<std::string, STJson>
{
};
namespace contract {
/** The maximum number of data modifications in a single function. */
int64_t constexpr maxDataModifications = 1000;
/** The maximum number of bytes the data can occupy. */
int64_t constexpr maxContractDataSize = 1024;
/** The multiplier for contract data size calculations. */
int64_t constexpr dataByteMultiplier = 512;
/** The cost multiplier of creating a contract in bytes. */
int64_t constexpr createByteMultiplier = 500ULL;
/** The value to return when the fee calculation failed. */
int64_t constexpr feeCalculationFailed = 0x7FFFFFFFFFFFFFFFLL;
/** The maximum number of contract parameters that can be in a transaction. */
std::size_t constexpr maxContractParams = 8;
/** The maximum number of contract functions that can be in a transaction. */
std::size_t constexpr maxContractFunctions = 32;
int64_t
contractCreateFee(uint64_t byteCount);
NotTEC
preflightFunctions(STTx const& tx, beast::Journal j);
NotTEC
preflightInstanceParameters(STTx const& tx, beast::Journal j);
bool
validateParameterMapping(STArray const& params, STArray const& values, beast::Journal j);
NotTEC
preflightInstanceParameterValues(STTx const& tx, beast::Journal j);
NotTEC
preflightFlagParameters(STArray const& parameters, beast::Journal j);
bool
isValidParameterFlag(std::uint32_t flags);
TER
preclaimFlagParameters(
ReadView const& view,
AccountID const& sourceAccount,
AccountID const& contractAccount,
STArray const& parameters,
beast::Journal j);
TER
doApplyFlagParameters(
ApplyView& view,
STTx const& tx,
AccountID const& sourceAccount,
AccountID const& contractAccount,
STArray const& parameters,
XRPAmount const& priorBalance,
beast::Journal j);
TER
finalizeContractData(
ServiceRegistry& registry,
ApplyView& view,
AccountID const& contractAccount,
ContractDataMap const& dataMap,
ContractEventMap const& eventMap,
uint256 const& txnID);
} // namespace contract
} // namespace xrpl

View File

@@ -0,0 +1,49 @@
#pragma once
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/TER.h>
#include <cstdint>
namespace xrpl {
/**
* Settle a holder's accrued coupons on their MPToken.
*
* Adds units * (AccruedPerUnit - CouponIndex) to CouponAccrued, rounded
* once downward to the coupon asset, then advances CouponIndex to
* AccruedPerUnit. Units are MPTAmount + LockedAmount. Increments the
* schedule's ClaimantCount when CouponAccrued becomes non-zero on a
* holder that had none. The caller must view.update() both entries on
* tesSUCCESS.
*/
[[nodiscard]] TER
couponSettleMPToken(SLE::ref schedule, SLE::ref mptoken, beast::Journal j);
/**
* Settle a holder against the schedule of the issuance their MPToken
* belongs to, if that issuance carries lsfMPTCouponSchedule. Does
* nothing when the flag is clear, which is the case for every issuance
* without a coupon schedule.
*
* This is the entry point called from the MPT unit-change helpers.
*/
[[nodiscard]] TER
couponSettleIfScheduled(
ApplyView& view,
SLE::const_ref issuance,
SLE::ref mptoken,
beast::Journal j);
/**
* The units a holder is credited for: MPTAmount + LockedAmount.
*/
[[nodiscard]] std::uint64_t
couponHolderUnits(SLE::const_ref mptoken);
} // namespace xrpl

View File

@@ -2,8 +2,10 @@
#include <xrpl/basics/Log.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/Zero.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
@@ -25,8 +27,295 @@
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/UintTypes.h>
#include <cstdint>
namespace xrpl {
/**
* Validate that @p account may lock @p amount of a token for later delivery
* to @p dest.
*
* The lock-side counterpart of escrowUnlockPreclaimHelper: every issuer
* control (locking opt-in, authorization, freeze/lock, transferability,
* spendable balance) that gates locking token value lives here, so any
* transactor that locks funds applies the same rules. The signature is
* view-based rather than PreclaimContext-based so it can also run from
* doApply.
*/
template <ValidIssueType T>
TER
escrowLockPreclaimHelper(
ReadView const& view,
AccountID const& account,
AccountID const& dest,
STAmount const& amount,
beast::Journal j);
template <>
inline TER
escrowLockPreclaimHelper<Issue>(
ReadView const& view,
AccountID const& account,
AccountID const& dest,
STAmount const& amount,
beast::Journal j)
{
auto const& issue = amount.get<Issue>();
auto const& issuer = amount.getIssuer();
// If the issuer is the same as the account, return tecNO_PERMISSION
if (issuer == account)
return tecNO_PERMISSION;
// If the lsfAllowTrustLineLocking is not enabled, return tecNO_PERMISSION
auto const sleIssuer = view.read(keylet::account(issuer));
if (!sleIssuer)
return tecNO_ISSUER;
if (!sleIssuer->isFlag(lsfAllowTrustLineLocking))
return tecNO_PERMISSION;
// If the account does not have a trustline to the issuer, return tecNO_LINE
auto const sleRippleState = view.read(keylet::trustLine(account, issuer, issue.currency));
if (!sleRippleState)
return tecNO_LINE;
STAmount const balance = (*sleRippleState)[sfBalance];
// If balance is positive, issuer must have higher address than account
if (balance > beast::kZero && issuer < account)
return tecNO_PERMISSION; // LCOV_EXCL_LINE
// If balance is negative, issuer must have lower address than account
if (balance < beast::kZero && issuer > account)
return tecNO_PERMISSION; // LCOV_EXCL_LINE
// If the issuer has requireAuth set, check if the account is authorized
if (auto const ter = requireAuth(view, issue, account); !isTesSuccess(ter))
return ter;
// If the issuer has requireAuth set, check if the destination is authorized
if (auto const ter = requireAuth(view, issue, dest); !isTesSuccess(ter))
return ter;
// If the issuer has frozen the account, return tecFROZEN
if (isFrozen(view, account, issue))
return tecFROZEN;
// If the issuer has frozen the destination, return tecFROZEN
if (isFrozen(view, dest, issue))
return tecFROZEN;
STAmount const spendableAmount =
accountHolds(view, account, issue.currency, issuer, FreezeHandling::IgnoreFreeze, j);
// If the balance is less than or equal to 0, return tecINSUFFICIENT_FUNDS
if (spendableAmount <= beast::kZero)
return tecINSUFFICIENT_FUNDS;
// If the spendable amount is less than the amount, return
// tecINSUFFICIENT_FUNDS
if (spendableAmount < amount)
return tecINSUFFICIENT_FUNDS;
// If the amount is not addable to the balance, return tecPRECISION_LOSS
if (!canAdd(spendableAmount, amount))
return tecPRECISION_LOSS;
return tesSUCCESS;
}
template <>
inline TER
escrowLockPreclaimHelper<MPTIssue>(
ReadView const& view,
AccountID const& account,
AccountID const& dest,
STAmount const& amount,
beast::Journal j)
{
AccountID const issuer = amount.getIssuer();
// If the issuer is the same as the account, return tecNO_PERMISSION
if (issuer == account)
return tecNO_PERMISSION;
// If the mpt does not exist, return tecOBJECT_NOT_FOUND
auto const issuanceKey = keylet::mptokenIssuance(amount.get<MPTIssue>().getMptID());
auto const sleIssuance = view.read(issuanceKey);
if (!sleIssuance)
return tecOBJECT_NOT_FOUND;
// If the lsfMPTCanEscrow is not enabled, return tecNO_PERMISSION
if (!sleIssuance->isFlag(lsfMPTCanEscrow))
return tecNO_PERMISSION;
// If the issuer is not the same as the issuer of the mpt, return
// tecNO_PERMISSION
if (sleIssuance->getAccountID(sfIssuer) != issuer)
return tecNO_PERMISSION; // LCOV_EXCL_LINE
// If the account does not have the mpt, return tecOBJECT_NOT_FOUND
if (!view.exists(keylet::mptoken(issuanceKey.key, account)))
return tecOBJECT_NOT_FOUND;
// If the issuer has requireAuth set, check if the account is
// authorized
auto const& mptIssue = amount.get<MPTIssue>();
if (auto const ter = requireAuth(view, mptIssue, account, AuthType::WeakAuth);
!isTesSuccess(ter))
return ter;
// If the issuer has requireAuth set, check if the destination is
// authorized
if (auto const ter = requireAuth(view, mptIssue, dest, AuthType::WeakAuth); !isTesSuccess(ter))
return ter;
// If the issuer has frozen the account, return tecLOCKED
if (isFrozen(view, account, *sleIssuance))
return tecLOCKED;
// If the issuer has frozen the destination, return tecLOCKED
if (isFrozen(view, dest, *sleIssuance))
return tecLOCKED;
// If the mpt cannot be transferred, return tecNO_AUTH
if (auto const ter = canTransfer(view, mptIssue, account, dest); !isTesSuccess(ter))
return ter;
STAmount const spendableAmount = accountHolds(
view,
account,
amount.get<MPTIssue>(),
FreezeHandling::IgnoreFreeze,
AuthHandling::IgnoreAuth,
j);
// If the balance is less than or equal to 0, return tecINSUFFICIENT_FUNDS
if (spendableAmount <= beast::kZero)
return tecINSUFFICIENT_FUNDS;
// If the spendable amount is less than the amount, return
// tecINSUFFICIENT_FUNDS
if (spendableAmount < amount)
return tecINSUFFICIENT_FUNDS;
return tesSUCCESS;
}
template <ValidIssueType T>
TER
escrowLockApplyHelper(
ApplyView& view,
AccountID const& issuer,
AccountID const& sender,
STAmount const& amount,
beast::Journal journal);
template <>
inline TER
escrowLockApplyHelper<Issue>(
ApplyView& view,
AccountID const& issuer,
AccountID const& sender,
STAmount const& amount,
beast::Journal journal)
{
// Defensive: Issuer cannot create an escrow
if (issuer == sender)
return tecINTERNAL; // LCOV_EXCL_LINE
auto const ter =
directSendNoFee(view, sender, issuer, amount, !amount.holds<MPTIssue>(), journal);
if (!isTesSuccess(ter))
return ter; // LCOV_EXCL_LINE
return tesSUCCESS;
}
template <>
inline TER
escrowLockApplyHelper<MPTIssue>(
ApplyView& view,
AccountID const& issuer,
AccountID const& sender,
STAmount const& amount,
beast::Journal journal)
{
// Defensive: Issuer cannot create an escrow
if (issuer == sender)
return tecINTERNAL; // LCOV_EXCL_LINE
auto const ter = lockEscrowMPT(view, sender, amount, journal);
if (!isTesSuccess(ter))
return ter; // LCOV_EXCL_LINE
return tesSUCCESS;
}
template <ValidIssueType T>
TER
escrowUnlockPreclaimHelper(
ReadView const& view,
AccountID const& account,
STAmount const& amount,
bool checkFreeze = true);
template <>
inline TER
escrowUnlockPreclaimHelper<Issue>(
ReadView const& view,
AccountID const& account,
STAmount const& amount,
bool checkFreeze)
{
AccountID const& issuer = amount.getIssuer();
// If the issuer is the same as the account, return tesSUCCESS
if (issuer == account)
return tesSUCCESS;
// If the issuer has requireAuth set, check if the destination is authorized
if (auto const ter = requireAuth(view, amount.get<Issue>(), account); !isTesSuccess(ter))
return ter;
// If the issuer has deep frozen the destination, return tecFROZEN
if (checkFreeze &&
isDeepFrozen(view, account, amount.get<Issue>().currency, amount.getIssuer()))
return tecFROZEN;
return tesSUCCESS;
}
template <>
inline TER
escrowUnlockPreclaimHelper<MPTIssue>(
ReadView const& view,
AccountID const& account,
STAmount const& amount,
bool checkFreeze)
{
AccountID const& issuer = amount.getIssuer();
// If the issuer is the same as the account, return tesSUCCESS
if (issuer == account)
return tesSUCCESS;
// If the mpt does not exist, return tecOBJECT_NOT_FOUND
auto const issuanceKey = keylet::mptokenIssuance(amount.get<MPTIssue>().getMptID());
auto const sleIssuance = view.read(issuanceKey);
if (!sleIssuance)
return tecOBJECT_NOT_FOUND;
// If the issuer has requireAuth set, check if the account is
// authorized
auto const& mptIssue = amount.get<MPTIssue>();
if (auto const ter = requireAuth(view, mptIssue, account, AuthType::WeakAuth);
!isTesSuccess(ter))
return ter;
// If the issuer has frozen the account, return tecLOCKED
if (checkFreeze && isFrozen(view, account, *sleIssuance))
return tecLOCKED;
return tesSUCCESS;
}
//------------------------------------------------------------------------------
template <ValidIssueType T>
TER
escrowUnlockApplyHelper(
@@ -55,9 +344,6 @@ escrowUnlockApplyHelper<Issue>(
bool createAsset,
beast::Journal journal)
{
auto const& issue = amount.get<Issue>();
Keylet const trustLineKey = keylet::trustLine(receiver, issue);
bool const recvLow = issuer > receiver;
bool const senderIssuer = issuer == sender;
bool const receiverIssuer = issuer == receiver;
@@ -67,6 +353,10 @@ escrowUnlockApplyHelper<Issue>(
if (receiverIssuer)
return tesSUCCESS;
auto const& issue = amount.get<Issue>();
Keylet const trustLineKey = keylet::trustLine(receiver, issue);
bool const recvLow = issuer > receiver;
if (!ctx.view.exists(trustLineKey) && createAsset)
{
// Can the account cover the trust line's reserve?
@@ -272,4 +562,18 @@ escrowUnlockApplyHelper<MPTIssue>(
journal);
}
// calculateAdditionalReserve computes the owner count impact of an Escrow.
// An escrow without a FinishFunction costs 1 reserve. With a FinishFunction,
// each additional 500 bytes beyond the first 500 adds another reserve slot.
template <class T>
static int32_t
calculateAdditionalReserve(T const& finishFunction)
{
if (!finishFunction)
return 1;
// First 500 bytes included in the normal reserve
// Each additional 500 bytes requires an additional reserve
return 1 + (finishFunction->size() / 500);
}
} // namespace xrpl

View File

@@ -7,6 +7,7 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/LedgerFormats.h> // IWYU pragma: keep
#include <xrpl/protocol/Protocol.h>
@@ -21,6 +22,7 @@
#include <cstdint>
#include <expected>
#include <optional>
#include <string_view>
#include <utility>
@@ -58,11 +60,65 @@ canApplyToBrokerCover(
bool
checkLendingProtocolDependencies(Rules const& rules, STTx const& tx);
/**
* The accounts and asset that LoanManage::defaultLoan's fixCleanup3_4_0
* freeze/lock exemption applies to.
*
* `defaultLoan` moves funds from the LoanBroker pseudo-account to the Vault
* pseudo-account via `accountSend`. Since neither is the vault asset's
* issuer, this is a third-party transfer that transits through the issuer in
* two hops (broker -> issuer, issuer -> vault; see
* `directSendNoLimitIOU`/`directSendNoLimitMPT`), so the exemption must cover
* both the issuer/broker and issuer/vault pairs, not a direct broker/vault
* pair. `asset` scopes it further to the vault's own currency/MPT issuance,
* so an unrelated one the same accounts happen to hold is still protected.
*/
struct LoanDefaultFreezeExemptAccounts
{
AccountID issuer;
AccountID broker;
AccountID vault;
Asset asset;
};
/**
* Resolves the accounts and asset a LoanManage default transaction is
* exempt from freeze/lock for.
*
* @param view Ledger view used to resolve the Loan -> LoanBroker -> Vault
* chain.
* @param tx The transaction under invariant review.
* @return The exempt accounts and asset if `tx` is a `ttLOAN_MANAGE`
* transaction with the `tfLoanDefault` flag set, `fixCleanup3_4_0` is
* enabled, and the loan/broker/vault objects it references can all be
* resolved; `std::nullopt` otherwise.
*/
[[nodiscard]] std::optional<LoanDefaultFreezeExemptAccounts>
getLoanDefaultFreezeExemptAccounts(ReadView const& view, STTx const& tx);
static constexpr std::uint32_t kSecondsInYear = 365 * 24 * 60 * 60;
Number
loanPeriodicRate(TenthBips32 interestRate, std::uint32_t paymentInterval);
/**
* Assets a loan earns per second at this principal outstanding.
*
* Equation (27) of XLS-66 is linear in elapsed time, and sfPaymentInterval
* cancels out of it, so a loan's accrual rate depends only on its principal
* and interest rate. Principal is flat between payments, which makes the rate
* piecewise-constant with breakpoints exactly at the events that update it —
* summing it across a vault's loans is therefore exact, not an approximation.
*/
inline Number
loanAccrualRate(Number const& principalOutstanding, TenthBips32 interestRate)
{
if (interestRate == TenthBips32{0} || principalOutstanding <= Number{})
return Number{};
return tenthBipsOfValue(principalOutstanding, interestRate) / Number{kSecondsInYear};
}
/**
* Ensure the periodic payment is always rounded consistently
*/
@@ -286,6 +342,12 @@ computeFullPaymentInterest(
std::uint32_t startDate,
TenthBips32 closeInterestRate);
// Returns true if the loan's next payment is late per protocol rules. The
// boundary is amendment-gated: with fixCleanup3_4_0 the due date must be
// strictly in the past, otherwise the exact due-date instant counts as late.
[[nodiscard]] bool
isPaymentLate(ReadView const& view, SLE::const_ref loanSle);
// Deltas applied to Vault.AssetsTotal and LoanBroker.DebtTotal at a single
// accounting touch point (origination, payment, impair/unimpair/default).
struct AccountingDeltas

View File

@@ -29,6 +29,9 @@ namespace xrpl {
[[nodiscard]] bool
isGlobalFrozen(ReadView const& view, MPTIssue const& mptIssue);
[[nodiscard]] bool
isGlobalFrozen(SLE const& issuanceSle);
/**
* Returns true if @p account's MPToken for @p mptIssue carries the
* individual-lock flag (lsfMPTLocked).
@@ -40,9 +43,29 @@ isGlobalFrozen(ReadView const& view, MPTIssue const& mptIssue);
* receive tokens — it combines isIndividualFrozen, isGlobalFrozen, and
* isVaultPseudoAccountFrozen into a single complete check.
*/
[[nodiscard]] bool
isIndividualFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue);
[[nodiscard]] bool
isIndividualFrozen(SLE const& mptSle);
/**
* Returns true if @p account cannot send or receive tokens of @p mptIssue
* because a freeze applies. This is the complete check callers should use
* before moving MPT value: it combines @ref isGlobalFrozen (issuance-level
* lock), @ref isIndividualFrozen (per-holder lock bit), and the transitive
* vault pseudo-account check (if @p mptIssue is a vault share, the underlying
* asset is checked, and so on recursively up to @c maxAssetCheckDepth).
*
* The @c SLE overload takes an already-loaded ltMPTOKEN or ltMPTOKEN_ISSUANCE
* ledger entry; for ltMPTOKEN it can skip the per-holder individual-lock lookup.
* @ref isAnyFrozen answers the same question for a set of accounts and returns true
* if the freeze applies to any of them.
*
* @param depth Current recursion depth for the vault-share walk. Callers
* outside this module should leave it at the default.
*/
[[nodiscard]] bool
isFrozen(
ReadView const& view,
@@ -50,6 +73,18 @@ isFrozen(
MPTIssue const& mptIssue,
std::uint8_t depth = 0);
/**
* SLE overload: pass an already-loaded ltMPTOKEN (holder row) or
* ltMPTOKEN_ISSUANCE to reuse it for the freeze checks and avoid re-reading
* the same object. For an ltMPTOKEN, @p sle is used directly for the
* individual-lock check and the issuance is read once for global-freeze and
* vault-pseudo-account. For an ltMPTOKEN_ISSUANCE, @p sle is used directly
* for global-freeze and vault-pseudo-account, and the caller's holder row is
* read for the individual-lock check.
*/
[[nodiscard]] bool
isFrozen(ReadView const& view, AccountID const& account, SLE const& sle, std::uint8_t depth = 0);
[[nodiscard]] bool
isAnyFrozen(
ReadView const& view,
@@ -97,6 +132,29 @@ authorizeMPToken(
std::uint32_t flags = 0,
std::optional<AccountID> holderID = std::nullopt);
// Authorize an AMM-issued MPT and apply the reserve-exemption rule in
// one shot: standard authorize (which increments owner count) followed
// by an immediate adjustOwnerCount(-1) so the LP doesn't pay reserve
// for the AMM-issued holding. Returns the same TER as authorizeMPToken.
//
// Callers must ensure the MPT's issuance is owned by an AMM pseudo-
// account; mis-using this helper for non-AMM-issued MPTs would let an
// LP hold an arbitrary issuer's MPT for free.
[[nodiscard]] TER
authorizeAMMIssuedMPT(
ApplyViewContext ctx,
XRPAmount const& priorBalance,
MPTID const& mptIssuanceID,
AccountID const& account,
beast::Journal journal);
// Symmetric for snapshot-style SLEs the AMM owns on behalf of an LP
// (e.g. ltAMM_BIN_HOLDING). The SLE is inserted into the LP's owner
// directory by the caller; this helper compensates the owner-count
// increment so the LP doesn't pay reserve.
void
exemptAMMOwnedSLE(ApplyView& view, AccountID const& account, beast::Journal journal);
/**
* Check if the account lacks required authorization for MPT.
*

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