Compare commits

...

85 Commits

Author SHA1 Message Date
Ed Hennis
c65794da36 Merge remote-tracking branch 'XRPLF/develop' into ximinez/acquireAsyncDispatch
* XRPLF/develop: (81 commits)
  ci: Only publish docs in public repos (6687)
  chore: Enable remaining clang-tidy `performance` checks (6648)
  refactor: Address PR comments after the modularisation PRs (6389)
  chore: Fix clang-tidy header filter (6686)
  ci: [DEPENDABOT] bump actions/deploy-pages from 4.0.5 to 5.0.0 (6684)
  ci: [DEPENDABOT] bump codecov/codecov-action from 5.5.3 to 6.0.0 (6685)
  fix: Guard Coro::resume() against completed coroutines (6608)
  refactor: Split LoanInvariant into LoanBrokerInvariant and LoanInvariant (6674)
  ci: Don't publish docs on release branches (6673)
  refactor: Make function naming in ServiceRegistry consistent (6390)
  chore: Shorten job names to stay within Linux 15-char thread limit (6669)
  fix: Improve loan invariant message (6668)
  ci: Upload artifacts only in public repositories (6670)
  ci: Add conflicting-pr workflow (6656)
  chore: Add more AI tools to .gitignore (6658)
  chore: Show warning message if user may need to connect to VPN (6619)
  feat: Add placeholder amendment for assorted bug fixes (6652)
  chore: Update sqlite3->3.51.0, protobuf->6.33.5, openssl->3.6.1, grpc->1.78.1 (6653)
  refactor: Modularise ledger (6536)
  chore: Use unpatched version of soci (6649)
  ...
2026-03-30 22:38:24 -04:00
Ayaz Salikhov
5c8dfe5456 ci: Only publish docs in public repos (#6687) 2026-03-30 17:15:40 +00:00
Alex Kremer
ab8c168e3b chore: Enable remaining clang-tidy performance checks (#6648)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-30 17:08:47 +00:00
Jingchen
3a477e4d01 refactor: Address PR comments after the modularisation PRs (#6389)
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-03-30 15:22:38 +00:00
Alex Kremer
96bfc32fe2 chore: Fix clang-tidy header filter (#6686) 2026-03-30 14:59:53 +00:00
dependabot[bot]
de671863e2 ci: [DEPENDABOT] bump actions/deploy-pages from 4.0.5 to 5.0.0 (#6684)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 14:09:57 +00:00
dependabot[bot]
e0cabb9f8c ci: [DEPENDABOT] bump codecov/codecov-action from 5.5.3 to 6.0.0 (#6685)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 13:57:32 +00:00
Pratik Mankawde
3d9c545f59 fix: Guard Coro::resume() against completed coroutines (#6608)
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-27 18:52:18 +00:00
Vito Tumas
9b944ee8c2 refactor: Split LoanInvariant into LoanBrokerInvariant and LoanInvariant (#6674) 2026-03-27 18:35:42 +00:00
Ayaz Salikhov
509677abfd ci: Don't publish docs on release branches (#6673) 2026-03-26 14:11:37 +00:00
Jingchen
addc1e8e25 refactor: Make function naming in ServiceRegistry consistent (#6390)
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
Co-authored-by: Ed Hennis <ed@ripple.com>
2026-03-26 14:11:16 +00:00
Valentin Balaschenko
faf69da4b0 chore: Shorten job names to stay within Linux 15-char thread limit (#6669) 2026-03-26 14:10:51 +00:00
Vito Tumas
76e3b4fb0f fix: Improve loan invariant message (#6668) 2026-03-26 12:40:26 +00:00
Ayaz Salikhov
e8bdbf975a ci: Upload artifacts only in public repositories (#6670) 2026-03-26 12:37:37 +00:00
Ayaz Salikhov
2c765f6eb0 ci: Add conflicting-pr workflow (#6656)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-03-26 00:18:17 +00:00
Mayukha Vadari
a9269fa846 chore: Add more AI tools to .gitignore (#6658)
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-03-25 23:55:50 +00:00
Jingchen
15fd9feae5 chore: Show warning message if user may need to connect to VPN (#6619)
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2026-03-25 23:54:49 +00:00
Vito Tumas
b9d07730f3 feat: Add placeholder amendment for assorted bug fixes (#6652) 2026-03-25 23:54:33 +00:00
Ayaz Salikhov
85b65c8e9a chore: Update sqlite3->3.51.0, protobuf->6.33.5, openssl->3.6.1, grpc->1.78.1 (#6653) 2026-03-25 18:22:50 +00:00
Jingchen
8f182e825a refactor: Modularise ledger (#6536)
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
Co-authored-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-03-25 16:32:45 +00:00
Ayaz Salikhov
cd78569d94 chore: Use unpatched version of soci (#6649) 2026-03-25 16:06:31 +00:00
Mayukha Vadari
2c7af360c2 fix: Remove unused/unreachable transactor code (#6612) 2026-03-25 16:02:14 +00:00
Alex Kremer
403fd7c649 fix: More clang-tidy issues found after merging to develop (#6640)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-03-25 14:28:28 +00:00
Ayaz Salikhov
dfed0481f7 docs: Rewrite conan docs for custom recipes (#6647) 2026-03-25 14:25:33 +00:00
Bart
0dc0c8e912 docs: Update LICENSE.md year to present (#6636)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-03-25 14:24:10 +00:00
Ayaz Salikhov
0510ee47d7 chore: Update some external dependencies (#6642) 2026-03-25 10:44:14 +00:00
Ayaz Salikhov
589c9c694c chore: Update external dependencies due to upstream merge (#6630) 2026-03-24 23:18:41 +00:00
Jingchen
4096623ae1 chore: Remove the forward declarations that cause build errors when unity build is enabled (#6633)
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2026-03-24 23:00:41 +00:00
Alex Kremer
dda162087f docs: Add note about clang-tidy installation (#6634) 2026-03-24 21:18:03 +00:00
Mayukha Vadari
85a4015a64 fix: Assorted Permissioned Domain fixes (#6587) 2026-03-24 18:53:57 +00:00
Mayukha Vadari
f7bb4018fa fix: Assorted Vault fixes (#6607) 2026-03-24 18:53:49 +00:00
Alex Kremer
0eedefbf45 refactor: Enable more clang-tidy readability checks (#6595)
Co-authored-by: Sergey Kuznetsov <kuzzz99@gmail.com>
2026-03-24 15:42:12 +00:00
Ed Hennis
30716646d7 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-03-12 15:05:10 -04:00
Ed Hennis
49b69a59eb Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-03-10 13:38:46 -04:00
Ed Hennis
5e37aa63c2 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-03-06 13:04:22 -04:00
Ed Hennis
979beeb162 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-03-04 17:11:47 -04:00
Ed Hennis
75e134a1fd Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-03-03 20:46:56 -04:00
Ed Hennis
828bcb3a7d Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-03-03 15:54:51 -04:00
Ed Hennis
6fc972746d Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-02-24 17:35:00 -04:00
Ed Hennis
930afbdea8 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-02-20 18:50:00 -04:00
Ed Hennis
95c5bef48b Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-02-20 18:26:19 -04:00
Ed Hennis
b489b6c3ce Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-02-20 17:32:02 -04:00
Ed Hennis
70765acef4 Merge remote-tracking branch 'upstream/develop' into ximinez/acquireAsyncDispatch
* upstream/develop:
  ci: [DEPENDABOT] bump tj-actions/changed-files from 46.0.5 to 47.0.4 (6394)
  ci: [DEPENDABOT] bump codecov/codecov-action from 5.4.3 to 5.5.2 (6398)
  ci: Build docs in PRs and in private repos (6400)
  ci: Add dependabot config (6379)
  Fix tautological assertion (6393)
  chore: Apply clang-format width 100 (6387)
2026-02-20 16:30:42 -05:00
Ed Hennis
77aa90bd0e Update formatting 2026-02-20 16:27:59 -05:00
Ed Hennis
4758bb6dc9 Merge commit '25cca465538a56cce501477f9e5e2c1c7ea2d84c' into ximinez/acquireAsyncDispatch
* commit '25cca465538a56cce501477f9e5e2c1c7ea2d84c':
  chore: Set clang-format width to 100 in config file (6387)
2026-02-20 16:27:39 -05:00
Ed Hennis
46e3dcb5fb Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-02-19 16:24:54 -05:00
Ed Hennis
d57579f10b Merge remote-tracking branch 'XRPLF/develop' into ximinez/acquireAsyncDispatch
* XRPLF/develop:
  refactor: Modularize app/tx (6228)
  refactor: Decouple app/tx from `Application` and `Config` (6227)
  chore: Update clang-format to 21.1.8 (6352)
  refactor: Modularize `HashRouter`, `Conditions`, and `OrderBookDB` (6226)
  chore: Fix minor issues in comments (6346)
  refactor: Modularize the NetworkOPs interface (6225)
  chore: Fix `gcov` lib coverage build failure on macOS (6350)
  refactor: Modularize RelationalDB (6224)
  refactor: Modularize WalletDB and Manifest (6223)
  fix: Update invariant checks for Permissioned Domains (6134)
  refactor: Change main thread name to `xrpld-main` (6336)
  refactor: Fix spelling issues in tests (6199)
  test: Add file and line location to Env (6276)
  chore: Remove CODEOWNERS (6337)
  perf: Remove unnecessary caches (5439)
  chore: Restore unity builds (6328)
  refactor: Update secp256k1 to 0.7.1 (6331)
  fix: Increment sequence when accepting new manifests (6059)
  fix typo in LendingHelpers unit-test (6215)
2026-02-18 19:52:18 -05:00
Ed Hennis
d8dd376d1c Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-02-04 16:30:10 -04:00
Ed Hennis
a8c03e2e6c Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-02-03 16:08:06 -04:00
Ed Hennis
2167a66bc7 Fix formatting 2026-01-28 19:39:15 -05:00
Ed Hennis
ed948a858c Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-01-28 18:49:15 -04:00
Ed Hennis
608c102743 Merge commit '5f638f55536def0d88b970d1018a465a238e55f4' into ximinez/acquireAsyncDispatch
* commit '5f638f55536def0d88b970d1018a465a238e55f4':
  chore: Set ColumnLimit to 120 in clang-format (6288)
2026-01-28 17:47:53 -05:00
Ed Hennis
36d1607a4e Merge commit '92046785d1fea5f9efe5a770d636792ea6cab78b' into ximinez/acquireAsyncDispatch
* commit '92046785d1fea5f9efe5a770d636792ea6cab78b':
  test: Fix the `xrpl.net` unit test using async read (6241)
  ci: Upload Conan recipes for develop, release candidates, and releases (6286)
  fix: Stop embedded tests from hanging on ARM by using `atomic_flag` (6248)
  fix:  Remove DEFAULT fields that change to the default in associateAsset (6259) (6273)
  refactor: Update Boost to 1.90 (6280)
  refactor: clean up uses of `std::source_location` (6272)
  ci: Pass missing sanitizers input to actions (6266)
  ci: Properly propagate Conan credentials (6265)
  ci: Explicitly set version when exporting the Conan recipe (6264)
  ci: Use plus instead of hyphen for Conan recipe version suffix (6261)
  chore: Detect uninitialized variables in CMake files (6247)
  ci: Run on-trigger and on-pr when generate-version is modified (6257)
  refactor: Enforce 15-char limit and simplify labels for thread naming (6212)
  docs: Update Ripple Bug Bounty public key (6258)
  ci: Add missing commit hash to Conan recipe version (6256)
  fix: Include `<functional>` header in `Number.h` (6254)
  ci: Upload Conan recipe for merges into develop and commits to release (6235)
  Limit reply size on `TMGetObjectByHash` queries (6110)
  ci: remove 'master' branch as a trigger (6234)
  Improve ledger_entry lookups for fee, amendments, NUNL, and hashes (5644)
2026-01-28 17:47:47 -05:00
Ed Hennis
53ebb86d60 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-01-15 13:03:36 -04:00
Ed Hennis
1d989bc6de Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-01-15 12:06:00 -04:00
Ed Hennis
64c0cb8c7e Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-01-13 18:19:11 -04:00
Ed Hennis
c77cfef41c Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-01-13 15:28:01 -04:00
Ed Hennis
08aa8c06d1 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-01-12 14:52:16 -04:00
Ed Hennis
9498672f8e Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-01-11 00:50:43 -04:00
Ed Hennis
e91d55a0e0 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-01-08 17:06:11 -04:00
Ed Hennis
afdc452cfc Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-01-08 13:04:20 -04:00
Ed Hennis
a0d4ef1a54 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2026-01-06 14:02:15 -05:00
Ed Hennis
8bc384f8bf Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-12-22 17:39:59 -05:00
Ed Hennis
bd961c484b Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-12-18 19:59:52 -05:00
Ed Hennis
aee242a8d4 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-12-12 20:34:59 -05:00
Ed Hennis
fcae74de58 Merge remote-tracking branch 'XRPLF/develop' into ximinez/acquireAsyncDispatch
* XRPLF/develop:
  refactor: Rename `ripple` namespace to `xrpl` (5982)
  refactor: Move JobQueue and related classes into xrpl.core module (6121)
  refactor: Rename `rippled` binary to `xrpld` (5983)
  refactor: rename info() to header() (6138)
  refactor: rename `LedgerInfo` to `LedgerHeader` (6136)
  refactor: clean up `RPCHelpers` (5684)
  chore: Fix docs readme and cmake (6122)
  chore: Clean up .gitignore and .gitattributes (6001)
  chore: Use updated secp256k1 recipe (6118)
2025-12-11 15:33:12 -05:00
Ed Hennis
a56effcb00 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-12-05 21:13:10 -05:00
Ed Hennis
64c2eca465 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-12-02 17:37:29 -05:00
Ed Hennis
e56f750e1d Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-12-01 14:40:45 -05:00
Ed Hennis
fde000f3eb Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-11-28 15:46:44 -05:00
Ed Hennis
d0a62229da Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-11-27 01:48:56 -05:00
Ed Hennis
d5932cc7d4 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-11-26 00:25:17 -05:00
Ed Hennis
0b534da781 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-11-25 14:55:06 -05:00
Ed Hennis
71a70d343b Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-11-24 21:49:11 -05:00
Ed Hennis
0899e65030 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-11-24 21:30:22 -05:00
Ed Hennis
31ba529761 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-11-21 12:47:58 -05:00
Ed Hennis
e2c6e5ebb6 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-11-18 22:39:29 -05:00
Ed Hennis
9d807fce48 Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-11-15 03:08:41 -05:00
Ed Hennis
9ef160765c Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-11-13 12:19:21 -05:00
Ed Hennis
d6c0eb243b Merge branch 'develop' into ximinez/acquireAsyncDispatch 2025-11-12 14:12:55 -05:00
Ed Hennis
84c9fc123c Fix formatting 2025-11-10 19:53:05 -05:00
Ed Hennis
00a2a58cfa Add missing header 2025-11-10 19:53:05 -05:00
Ed Hennis
bb2098d873 Add a unit test for CanProcess
- Delete the copy ctor & operator
2025-11-10 19:53:05 -05:00
Ed Hennis
46a5bc74db refactor: acquireAsync will dispatch the job, not the other way around 2025-11-10 19:53:05 -05:00
Ed Hennis
7b72b9cc82 Improve job queue collision checks and logging
- Improve logging related to ledger acquisition and operating mode
  changes
- Class "CanProcess" to keep track of processing of distinct items
2025-11-10 19:53:05 -05:00
438 changed files with 3492 additions and 2863 deletions

View File

@@ -1,4 +1,6 @@
---
# This entire group of checks was applied to all cpp files but not all header files.
# ---
Checks: "-*,
bugprone-argument-comment,
bugprone-assert-side-effect,
@@ -8,26 +10,26 @@ Checks: "-*,
bugprone-chained-comparison,
bugprone-compare-pointer-to-member-virtual-function,
bugprone-copy-constructor-init,
bugprone-crtp-constructor-accessibility,
# bugprone-crtp-constructor-accessibility, # has issues
bugprone-dangling-handle,
bugprone-dynamic-static-initializers,
bugprone-empty-catch,
# bugprone-empty-catch, # has issues
bugprone-fold-init-type,
bugprone-forward-declaration-namespace,
bugprone-inaccurate-erase,
bugprone-inc-dec-in-conditions,
bugprone-incorrect-enable-if,
bugprone-incorrect-roundings,
bugprone-infinite-loop,
bugprone-integer-division,
# bugprone-forward-declaration-namespace, # has issues
# bugprone-inaccurate-erase,
# bugprone-inc-dec-in-conditions,
# bugprone-incorrect-enable-if,
# bugprone-incorrect-roundings,
# bugprone-infinite-loop,
# bugprone-integer-division,
bugprone-lambda-function-name,
bugprone-macro-parentheses,
# bugprone-macro-parentheses, # has issues
bugprone-macro-repeated-side-effects,
bugprone-misplaced-operator-in-strlen-in-alloc,
bugprone-misplaced-pointer-arithmetic-in-alloc,
bugprone-misplaced-widening-cast,
bugprone-move-forwarding-reference,
bugprone-multi-level-implicit-pointer-conversion,
# bugprone-multi-level-implicit-pointer-conversion, # has issues
bugprone-multiple-new-in-one-expression,
bugprone-multiple-statement-macro,
bugprone-no-escape,
@@ -37,13 +39,13 @@ Checks: "-*,
bugprone-pointer-arithmetic-on-polymorphic-object,
bugprone-posix-return,
bugprone-redundant-branch-condition,
bugprone-reserved-identifier,
bugprone-return-const-ref-from-parameter,
# bugprone-reserved-identifier, # has issues
# bugprone-return-const-ref-from-parameter, # has issues
bugprone-shared-ptr-array-mismatch,
bugprone-signal-handler,
bugprone-signed-char-misuse,
bugprone-sizeof-container,
bugprone-sizeof-expression,
# bugprone-sizeof-expression, # has issues
bugprone-spuriously-wake-up-functions,
bugprone-standalone-empty,
bugprone-string-constructor,
@@ -60,7 +62,7 @@ Checks: "-*,
bugprone-suspicious-string-compare,
bugprone-suspicious-stringview-data-usage,
bugprone-swapped-arguments,
bugprone-switch-missing-default-case,
# bugprone-switch-missing-default-case, # has issues
bugprone-terminating-continue,
bugprone-throw-keyword-missing,
bugprone-too-small-loop-variable,
@@ -71,70 +73,75 @@ Checks: "-*,
bugprone-unhandled-self-assignment,
bugprone-unique-ptr-array-mismatch,
bugprone-unsafe-functions,
bugprone-use-after-move,
# bugprone-use-after-move, # has issues
bugprone-unused-raii,
bugprone-unused-return-value,
bugprone-unused-local-non-trivial-variable,
bugprone-virtual-near-miss,
cppcoreguidelines-init-variables,
cppcoreguidelines-misleading-capture-default-by-value,
# cppcoreguidelines-init-variables, # has issues
# cppcoreguidelines-misleading-capture-default-by-value, # has issues
cppcoreguidelines-no-suspend-with-lock,
cppcoreguidelines-pro-type-member-init,
# cppcoreguidelines-pro-type-member-init, # has issues
cppcoreguidelines-pro-type-static-cast-downcast,
cppcoreguidelines-rvalue-reference-param-not-moved,
cppcoreguidelines-use-default-member-init,
cppcoreguidelines-virtual-class-destructor,
# cppcoreguidelines-rvalue-reference-param-not-moved, # has issues
# cppcoreguidelines-use-default-member-init, # has issues
# cppcoreguidelines-virtual-class-destructor, # has issues
hicpp-ignored-remove-result,
misc-definitions-in-headers,
# misc-definitions-in-headers, # has issues
misc-header-include-cycle,
misc-misplaced-const,
misc-static-assert,
misc-throw-by-value-catch-by-reference,
# misc-throw-by-value-catch-by-reference, # has issues
misc-unused-alias-decls,
misc-unused-using-decls,
modernize-deprecated-headers,
modernize-make-shared,
modernize-make-unique,
performance-faster-string-find,
performance-for-range-copy,
performance-implicit-conversion-in-loop,
performance-inefficient-vector-operation,
performance-move-const-arg,
performance-move-constructor-init,
performance-no-automatic-move,
performance-trivially-destructible,
readability-avoid-nested-conditional-operator,
readability-avoid-return-with-void-value,
readability-braces-around-statements,
readability-const-return-type,
readability-container-contains,
readability-container-size-empty,
# readability-avoid-nested-conditional-operator, # has issues
# readability-avoid-return-with-void-value, # has issues
# readability-braces-around-statements, # has issues
# readability-const-return-type, # has issues
# readability-container-contains, # has issues
# readability-container-size-empty, # has issues
# readability-convert-member-functions-to-static, # has issues
readability-duplicate-include,
readability-else-after-return,
readability-enum-initial-value,
readability-make-member-function-const,
# readability-else-after-return, # has issues
# readability-enum-initial-value, # has issues
# readability-implicit-bool-conversion, # has issues
# readability-make-member-function-const, # has issues
# readability-math-missing-parentheses, # has issues
readability-misleading-indentation,
readability-non-const-parameter,
readability-redundant-casting,
readability-redundant-declaration,
readability-redundant-inline-specifier,
readability-redundant-member-init,
# readability-redundant-casting, # has issues
# readability-redundant-declaration, # has issues
# readability-redundant-inline-specifier, # has issues
# readability-redundant-member-init, # has issues
readability-redundant-string-init,
readability-reference-to-constructed-temporary,
readability-static-definition-in-anonymous-namespace,
# readability-simplify-boolean-expr, # has issues
# readability-static-definition-in-anonymous-namespace, # has issues
# readability-suspicious-call-argument, # has issues
readability-use-std-min-max
"
# ---
# checks that have some issues that need to be resolved:
# other checks that have issues that need to be resolved:
#
# llvm-namespace-comment,
# misc-const-correctness,
# misc-include-cleaner,
# misc-redundant-expression,
#
# readability-convert-member-functions-to-static,
# readability-implicit-bool-conversion,
# readability-inconsistent-declaration-parameter-name,
# readability-identifier-naming,
# readability-math-missing-parentheses,
# readability-simplify-boolean-expr,
# readability-suspicious-call-argument,
# readability-static-accessed-through-instance,
# readability-inconsistent-declaration-parameter-name, # in this codebase this check will break a lot of arg names
# readability-static-accessed-through-instance, # this check is probably unnecessary. it makes the code less readable
# readability-identifier-naming, # https://github.com/XRPLF/rippled/pull/6571
#
# modernize-concat-nested-namespaces,
# modernize-pass-by-value,
@@ -148,12 +155,6 @@ Checks: "-*,
# modernize-use-starts-ends-with,
# modernize-use-std-numbers,
# modernize-use-using,
#
# performance-faster-string-find,
# performance-for-range-copy,
# performance-inefficient-vector-operation,
# performance-move-const-arg,
# performance-no-automatic-move,
# ---
#
CheckOptions:
@@ -195,5 +196,6 @@ CheckOptions:
bugprone-unused-return-value.CheckedReturnTypes: ::std::error_code;::std::error_condition;::std::errc
# misc-include-cleaner.IgnoreHeaders: '.*/(detail|impl)/.*;.*(expected|unexpected).*;.*ranges_lower_bound\.h;time.h;stdlib.h;__chrono/.*;fmt/chrono.h;boost/uuid/uuid_hash.hpp'
#
# HeaderFilterRegex: '^.*/(src|tests)/.*\.(h|hpp)$'
HeaderFilterRegex: '^.*/(test|xrpl|xrpld)/.*\.(h|hpp)$'
ExcludeHeaderFilterRegex: '^.*/protocol_autogen/.*\.(h|hpp)$'
WarningsAsErrors: "*"

View File

@@ -21,6 +21,7 @@ libxrpl.protocol > xrpl.json
libxrpl.protocol > xrpl.protocol
libxrpl.protocol_autogen > xrpl.protocol_autogen
libxrpl.rdb > xrpl.basics
libxrpl.rdb > xrpl.core
libxrpl.rdb > xrpl.rdb
libxrpl.resource > xrpl.basics
libxrpl.resource > xrpl.json
@@ -90,6 +91,7 @@ test.core > xrpl.server
test.csf > xrpl.basics
test.csf > xrpld.consensus
test.csf > xrpl.json
test.csf > xrpl.ledger
test.csf > xrpl.protocol
test.json > test.jtx
test.json > xrpl.json
@@ -108,7 +110,6 @@ test.jtx > xrpl.tx
test.ledger > test.jtx
test.ledger > test.toplevel
test.ledger > xrpl.basics
test.ledger > xrpld.app
test.ledger > xrpld.core
test.ledger > xrpl.ledger
test.ledger > xrpl.protocol
@@ -125,6 +126,7 @@ test.overlay > xrpl.basics
test.overlay > xrpld.app
test.overlay > xrpld.overlay
test.overlay > xrpld.peerfinder
test.overlay > xrpl.ledger
test.overlay > xrpl.nodestore
test.overlay > xrpl.protocol
test.overlay > xrpl.shamap
@@ -183,7 +185,6 @@ xrpl.conditions > xrpl.basics
xrpl.conditions > xrpl.protocol
xrpl.core > xrpl.basics
xrpl.core > xrpl.json
xrpl.core > xrpl.ledger
xrpl.core > xrpl.protocol
xrpl.json > xrpl.basics
xrpl.ledger > xrpl.basics
@@ -234,6 +235,7 @@ xrpld.app > xrpl.shamap
xrpld.app > xrpl.tx
xrpld.consensus > xrpl.basics
xrpld.consensus > xrpl.json
xrpld.consensus > xrpl.ledger
xrpld.consensus > xrpl.protocol
xrpld.core > xrpl.basics
xrpld.core > xrpl.core

25
.github/workflows/conflicting-pr.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: Label PRs with merge conflicts
on:
# So that PRs touching the same files as the push are updated.
push:
# So that the `dirtyLabel` is removed if conflicts are resolved.
# We recommend `pull_request_target` so that github secrets are available.
# In `pull_request` we wouldn't be able to change labels of fork PRs.
pull_request_target:
types: [synchronize]
permissions:
pull-requests: write
jobs:
main:
runs-on: ubuntu-latest
steps:
- name: Check if PRs are dirty
uses: eps1lon/actions-label-merge-conflict@1df065ebe6e3310545d4f4c4e862e43bdca146f0 # v3.0.3
with:
dirtyLabel: "PR: has conflicts"
repoToken: "${{ secrets.GITHUB_TOKEN }}"
commentOnDirty: "This PR has conflicts, please resolve them in order for the PR to be reviewed."
commentOnClean: "All conflicts have been resolved. Assigned reviewers can now start or resume their review."

View File

@@ -6,7 +6,6 @@ on:
push:
branches:
- "develop"
- "release*"
paths:
- ".github/workflows/publish-docs.yml"
- "*.md"
@@ -82,13 +81,13 @@ jobs:
cmake --build . --target docs --parallel ${BUILD_NPROC}
- name: Create documentation artifact
if: ${{ github.event_name == 'push' }}
if: ${{ github.event.repository.visibility == 'public' && github.event_name == 'push' }}
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0
with:
path: ${{ env.BUILD_DIR }}/docs/html
deploy:
if: ${{ github.event_name == 'push' }}
if: ${{ github.event.repository.visibility == 'public' && github.event_name == 'push' }}
needs: build
runs-on: ubuntu-latest
permissions:
@@ -100,4 +99,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deploy
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0

View File

@@ -199,7 +199,7 @@ jobs:
fi
- name: Upload the binary (Linux)
if: ${{ github.repository == 'XRPLF/rippled' && runner.os == 'Linux' }}
if: ${{ github.event.repository.visibility == 'public' && runner.os == 'Linux' }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: xrpld-${{ inputs.config_name }}
@@ -298,7 +298,7 @@ jobs:
- name: Upload coverage report
if: ${{ github.repository == 'XRPLF/rippled' && !inputs.build_only && env.COVERAGE_ENABLED == 'true' }}
uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5.5.3
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
with:
disable_search: true
disable_telem: true

View File

@@ -83,7 +83,7 @@ jobs:
run-clang-tidy -j ${{ steps.nproc.outputs.nproc }} -p "${BUILD_DIR}" ${TARGETS} 2>&1 | tee clang-tidy-output.txt
- name: Upload clang-tidy output
if: steps.run_clang_tidy.outcome != 'success'
if: ${{ github.event.repository.visibility == 'public' && steps.run_clang_tidy.outcome != 'success' }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: clang-tidy-results

View File

@@ -51,5 +51,5 @@ jobs:
if: ${{ always() && !cancelled() && (!inputs.check_only_changed || needs.determine-files.outputs.any_cpp_changed == 'true' || needs.determine-files.outputs.clang_tidy_config_changed == 'true') }}
uses: ./.github/workflows/reusable-clang-tidy-files.yml
with:
files: ${{ needs.determine-files.outputs.clang_tidy_config_changed == 'true' && '' || (inputs.check_only_changed && needs.determine-files.outputs.all_changed_files || '') }}
files: ${{ (needs.determine-files.outputs.clang_tidy_config_changed != 'true' && inputs.check_only_changed) && needs.determine-files.outputs.all_changed_files || '' }}
create_issue_on_failure: ${{ inputs.create_issue_on_failure }}

2
.gitignore vendored
View File

@@ -71,6 +71,8 @@ DerivedData
/.zed/
# AI tools.
/.agent
/.agents
/.augment
/.claude
/CLAUDE.md

View File

@@ -125,9 +125,9 @@ default profile.
### Patched recipes
The recipes in Conan Center occasionally need to be patched for compatibility
with the latest version of `xrpld`. We maintain a fork of the Conan Center
[here](https://github.com/XRPLF/conan-center-index/) containing the patches.
Occasionally, we need patched recipes or recipes not present in Conan Center.
We maintain a fork of the Conan Center Index
[here](https://github.com/XRPLF/conan-center-index/) containing the modified and newly added recipes.
To ensure our patched recipes are used, you must add our Conan remote at a
higher index than the default Conan Center remote, so it is consulted first. You
@@ -137,19 +137,11 @@ can do this by running:
conan remote add --index 0 xrplf https://conan.ripplex.io
```
Alternatively, you can pull the patched recipes into the repository and use them
locally:
Alternatively, you can pull our recipes from the repository and export them locally:
```bash
# Extract the version number from the lockfile.
function extract_version {
version=$(cat conan.lock | sed -nE "s@.+${1}/(.+)#.+@\1@p" | head -n1)
echo ${version}
}
# Define which recipes to export.
recipes=('ed25519' 'grpc' 'nudb' 'openssl' 'secp256k1' 'snappy' 'soci')
folders=('all' 'all' 'all' '3.x.x' 'all' 'all' 'all')
recipes=('abseil' 'ed25519' 'grpc' 'm4' 'mpt-crypto' 'nudb' 'openssl' 'secp256k1' 'snappy' 'soci' 'wasm-xrplf' 'wasmi')
# Selectively check out the recipes from our CCI fork.
cd external
@@ -158,29 +150,19 @@ cd conan-center-index
git init
git remote add origin git@github.com:XRPLF/conan-center-index.git
git sparse-checkout init
for ((index = 1; index <= ${#recipes[@]}; index++)); do
recipe=${recipes[index]}
folder=${folders[index]}
echo "Checking out recipe '${recipe}' from folder '${folder}'..."
git sparse-checkout add recipes/${recipe}/${folder}
for recipe in "${recipes[@]}"; do
echo "Checking out recipe '${recipe}'..."
git sparse-checkout add recipes/${recipe}
done
git fetch origin master
git checkout master
cd ../..
# Export the recipes into the local cache.
for ((index = 1; index <= ${#recipes[@]}; index++)); do
recipe=${recipes[index]}
folder=${folders[index]}
version=$(extract_version ${recipe})
echo "Exporting '${recipe}/${version}' from '${recipe}/${folder}'..."
conan export --version $(extract_version ${recipe}) \
external/conan-center-index/recipes/${recipe}/${folder}
done
./export_all.sh
cd ../../
```
In the case we switch to a newer version of a dependency that still requires a
patch, it will be necessary for you to pull in the changes and re-export the
patch or add a new dependency, it will be necessary for you to pull in the changes and re-export the
updated dependencies with the newer version. However, if we switch to a newer
version that no longer requires a patch, no action is required on your part, as
the new recipe will be automatically pulled from the official Conan Center.
@@ -189,6 +171,8 @@ the new recipe will be automatically pulled from the official Conan Center.
> You might need to add `--lockfile=""` to your `conan install` command
> to avoid automatic use of the existing `conan.lock` file when you run
> `conan export` manually on your machine
>
> This is not recommended though, as you might end up using different revisions of recipes.
### Conan profile tweaks
@@ -204,39 +188,14 @@ Possible values are ['5.0', '5.1', '6.0', '6.1', '7.0', '7.3', '8.0', '8.1',
Read "http://docs.conan.io/2/knowledge/faq.html#error-invalid-setting"
```
you need to amend the list of compiler versions in
`$(conan config home)/settings.yml`, by appending the required version number(s)
you need to add your compiler to the list of compiler versions in
`$(conan config home)/settings_user.yml`, by adding the required version number(s)
to the `version` array specific for your compiler. For example:
```yaml
apple-clang:
version:
[
"5.0",
"5.1",
"6.0",
"6.1",
"7.0",
"7.3",
"8.0",
"8.1",
"9.0",
"9.1",
"10.0",
"11.0",
"12.0",
"13",
"13.0",
"13.1",
"14",
"14.0",
"15",
"15.0",
"16",
"16.0",
"17",
"17.0",
]
compiler:
apple-clang:
version: ["17.0"]
```
#### Multiple compilers

View File

@@ -259,6 +259,10 @@ There is a Continuous Integration job that runs clang-tidy on pull requests. The
This ensures that configuration changes don't introduce new warnings across the codebase.
### Installing clang-tidy
See the [environment setup guide](./docs/build/environment.md#clang-tidy) for platform-specific installation instructions.
### 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.
@@ -266,10 +270,15 @@ Before running clang-tidy, you must build the project to generate required files
Then run clang-tidy on your local changes:
```
run-clang-tidy -p build src tests
run-clang-tidy -p build src include tests
```
This will check all source files in the `src` and `tests` directories using the compile commands from your `build` directory.
This will check all source files in the `src`, `include` and `tests` directories using the compile commands from your `build` directory.
If you wish to automatically fix whatever clang-tidy finds _and_ is capable of fixing, add `-fix` to the above command:
```
run-clang-tidy -p build -fix src include tests
```
## Contracts and instrumentation

View File

@@ -1,7 +1,7 @@
ISC License
Copyright (c) 2011, Arthur Britto, David Schwartz, Jed McCaleb, Vinnie Falco, Bob Way, Eric Lombrozo, Nikolaos D. Bougalis, Howard Hinnant.
Copyright (c) 2012-2025, the XRP Ledger developers.
Copyright (c) 2012-present, the XRP Ledger developers.
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above

View File

@@ -140,6 +140,28 @@ function(setup_protocol_autogen)
)
endif()
# Check pip index URL configuration
execute_process(
COMMAND ${VENV_PIP} config get global.index-url
OUTPUT_VARIABLE PIP_INDEX_URL
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
# Default PyPI URL
set(DEFAULT_PIP_INDEX "https://pypi.org/simple")
# Show warning if using non-default index
if(PIP_INDEX_URL AND NOT PIP_INDEX_URL STREQUAL "")
if(NOT PIP_INDEX_URL STREQUAL DEFAULT_PIP_INDEX)
message(
WARNING
"Private pip index URL detected: ${PIP_INDEX_URL}\n"
"You may need to connect to VPN to access this URL."
)
endif()
endif()
message(STATUS "Installing Python dependencies...")
execute_process(
COMMAND ${VENV_PIP} install --upgrade pip

View File

@@ -1,16 +1,16 @@
{
"version": "0.5",
"requires": [
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1765850150.075",
"zlib/1.3.1#cac0f6daea041b0ccf42934163defb20%1774439233.809",
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1765850149.987",
"sqlite3/3.49.1#8631739a4c9b93bd3d6b753bac548a63%1765850149.926",
"soci/4.0.3#a9f8d773cd33e356b5879a4b0564f287%1765850149.46",
"sqlite3/3.51.0#66aa11eabd0e34954c5c1c061ad44abe%1763899256.358",
"soci/4.0.3#fe32b9ad5eb47e79ab9e45a68f363945%1774450067.231",
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1765850147.878",
"secp256k1/0.7.1#3a61e95e220062ef32c48d019e9c81f7%1770306721.686",
"secp256k1/0.7.1#481881709eb0bdd0185a12b912bbe8ad%1770910500.329",
"rocksdb/10.5.1#4a197eca381a3e5ae8adf8cffa5aacd0%1765850186.86",
"re2/20230301#ca3b241baec15bd31ea9187150e0b333%1765850148.103",
"protobuf/6.32.1#f481fd276fc23a33b85a3ed1e898b693%1765850161.038",
"openssl/3.5.5#05a4ac5b7323f7a329b2db1391d9941f%1769599205.414",
"re2/20251105#8579cfd0bda4daf0683f9e3898f964b4%1774398111.888",
"protobuf/6.33.5#d96d52ba5baaaa532f47bda866ad87a5%1773224203.27",
"openssl/3.6.1#e6399de266349245a4542fc5f6c71552%1774458290.139",
"nudb/2.0.9#0432758a24204da08fee953ec9ea03cb%1769436073.32",
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1765850143.914",
"libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1765842973.492",
@@ -18,27 +18,26 @@
"libarchive/3.8.1#ffee18995c706e02bf96e7a2f7042e0d%1765850144.736",
"jemalloc/5.3.0#e951da9cf599e956cebc117880d2d9f8%1729241615.244",
"gtest/1.17.0#5224b3b3ff3b4ce1133cbdd27d53ee7d%1768312129.152",
"grpc/1.72.0#f244a57bff01e708c55a1100b12e1589%1765850193.734",
"grpc/1.78.1#b1a9e74b145cc471bed4dc64dc6eb2c1%1772623605.068",
"ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1765850143.772",
"date/3.0.4#862e11e80030356b53c2c38599ceb32b%1765850143.772",
"c-ares/1.34.5#5581c2b62a608b40bb85d965ab3ec7c8%1765850144.336",
"c-ares/1.34.6#545240bb1c40e2cacd4362d6b8967650%1774439234.681",
"bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1765850143.837",
"boost/1.90.0#d5e8defe7355494953be18524a7f135b%1769454080.269",
"abseil/20250127.0#99262a368bd01c0ccca8790dfced9719%1766517936.993"
"abseil/20250127.0#bb0baf1f362bc4a725a24eddd419b8f7%1774365460.196"
],
"build_requires": [
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1765850150.075",
"strawberryperl/5.32.1.1#707032463aa0620fa17ec0d887f5fe41%1765850165.196",
"protobuf/6.32.1#f481fd276fc23a33b85a3ed1e898b693%1765850161.038",
"zlib/1.3.1#cac0f6daea041b0ccf42934163defb20%1774439233.809",
"strawberryperl/5.32.1.1#8d114504d172cfea8ea1662d09b6333e%1774447376.964",
"protobuf/6.33.5#d96d52ba5baaaa532f47bda866ad87a5%1773224203.27",
"nasm/2.16.01#31e26f2ee3c4346ecd347911bd126904%1765850144.707",
"msys2/cci.latest#eea83308ad7e9023f7318c60d5a9e6cb%1770199879.083",
"m4/1.4.19#70dc8bbb33e981d119d2acc0175cf381%1763158052.846",
"cmake/4.2.0#ae0a44f44a1ef9ab68fd4b3e9a1f8671%1765850153.937",
"cmake/3.31.10#313d16a1aa16bbdb2ca0792467214b76%1765850153.479",
"b2/5.3.3#107c15377719889654eb9a162a673975%1765850144.355",
"msys2/cci.latest#d22fe7b2808f5fd34d0a7923ace9c54f%1770657326.649",
"m4/1.4.19#5d7a4994e5875d76faf7acf3ed056036%1774365463.87",
"cmake/4.3.0#b939a42e98f593fb34d3a8c5cc860359%1774439249.183",
"b2/5.4.2#ffd6084a119587e70f11cd45d1a386e2%1774439233.447",
"automake/1.16.5#b91b7c384c3deaa9d535be02da14d04f%1755524470.56",
"autoconf/2.71#51077f068e61700d65bb05541ea1e4b0%1731054366.86",
"abseil/20250127.0#99262a368bd01c0ccca8790dfced9719%1766517936.993"
"abseil/20250127.0#bb0baf1f362bc4a725a24eddd419b8f7%1774365460.196"
],
"python_requires": [],
"overrides": {
@@ -46,14 +45,14 @@
null,
"boost/1.90.0"
],
"protobuf/5.27.0": [
"protobuf/6.32.1"
"protobuf/[>=5.27.0 <7]": [
"protobuf/6.33.5"
],
"lz4/1.9.4": [
"lz4/1.10.0"
],
"sqlite3/3.44.2": [
"sqlite3/3.49.1"
"sqlite3/[>=3.44 <4]": [
"sqlite3/3.51.0"
],
"boost/1.83.0": [
"boost/1.90.0"

View File

@@ -1,10 +1,9 @@
import re
import os
import re
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
from conan import ConanFile
from conan import __version__ as conan_version
class Xrpl(ConanFile):
@@ -30,10 +29,10 @@ class Xrpl(ConanFile):
requires = [
"ed25519/2015.03",
"grpc/1.72.0",
"grpc/1.78.1",
"libarchive/3.8.1",
"nudb/2.0.9",
"openssl/3.5.5",
"openssl/3.6.1",
"secp256k1/0.7.1",
"soci/4.0.3",
"zlib/1.3.1",
@@ -44,7 +43,7 @@ class Xrpl(ConanFile):
]
tool_requires = [
"protobuf/6.32.1",
"protobuf/6.33.5",
]
default_options = {
@@ -137,20 +136,16 @@ class Xrpl(ConanFile):
self.default_options["fPIC"] = False
def requirements(self):
# Conan 2 requires transitive headers to be specified
transitive_headers_opt = (
{"transitive_headers": True} if conan_version.split(".")[0] == "2" else {}
)
self.requires("boost/1.90.0", force=True, **transitive_headers_opt)
self.requires("date/3.0.4", **transitive_headers_opt)
self.requires("boost/1.90.0", force=True, transitive_headers=True)
self.requires("date/3.0.4", transitive_headers=True)
self.requires("lz4/1.10.0", force=True)
self.requires("protobuf/6.32.1", force=True)
self.requires("sqlite3/3.49.1", force=True)
self.requires("protobuf/6.33.5", force=True)
self.requires("sqlite3/3.51.0", force=True)
if self.options.jemalloc:
self.requires("jemalloc/5.3.0")
if self.options.rocksdb:
self.requires("rocksdb/10.5.1")
self.requires("xxhash/0.8.3", **transitive_headers_opt)
self.requires("xxhash/0.8.3", transitive_headers=True)
exports_sources = (
"CMakeLists.txt",

View File

@@ -297,6 +297,7 @@ words:
- venv
- vfalco
- vinnie
- wasmi
- wextra
- wptr
- writeme

View File

@@ -109,3 +109,32 @@ Install CMake with Homebrew too:
```
brew install cmake
```
## Clang-tidy
Clang-tidy is required to run static analysis checks locally (see [CONTRIBUTING.md](../../CONTRIBUTING.md)).
It is not required to build the project. Currently this project uses clang-tidy version 21.
### Linux
LLVM 21 is not available in the default Debian 12 (Bookworm) repositories.
Install it using the official LLVM apt installer:
```
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 21
sudo apt install --yes clang-tidy-21
```
Then use `run-clang-tidy-21` when running clang-tidy locally.
### macOS
Install LLVM 21 via Homebrew:
```
brew install llvm@21
```
Then use `run-clang-tidy` from the LLVM 21 Homebrew prefix when running clang-tidy locally.

View File

@@ -0,0 +1,139 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2024 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_BASICS_CANPROCESS_H_INCLUDED
#define RIPPLE_BASICS_CANPROCESS_H_INCLUDED
#include <functional>
#include <mutex>
#include <set>
/** RAII class to check if an Item is already being processed on another thread,
* as indicated by it's presence in a Collection.
*
* If the Item is not in the Collection, it will be added under lock in the
* ctor, and removed under lock in the dtor. The object will be considered
* "usable" and evaluate to `true`.
*
* If the Item is in the Collection, no changes will be made to the collection,
* and the CanProcess object will be considered "unusable".
*
* It's up to the caller to decide what "usable" and "unusable" mean. (e.g.
* Process or skip a block of code, or set a flag.)
*
* The current use is to avoid lock contention that would be involved in
* processing something associated with the Item.
*
* Examples:
*
* void IncomingLedgers::acquireAsync(LedgerHash const& hash, ...)
* {
* if (CanProcess check{acquiresMutex_, pendingAcquires_, hash})
* {
* acquire(hash, ...);
* }
* }
*
* bool
* NetworkOPsImp::recvValidation(
* std::shared_ptr<STValidation> const& val,
* std::string const& source)
* {
* CanProcess check(
* validationsMutex_, pendingValidations_, val->getLedgerHash());
* BypassAccept bypassAccept =
* check ? BypassAccept::no : BypassAccept::yes;
* handleNewValidation(app_, val, source, bypassAccept, m_journal);
* }
*
*/
class CanProcess
{
public:
template <class Mutex, class Collection, class Item>
CanProcess(Mutex& mtx, Collection& collection, Item const& item)
: cleanup_(insert(mtx, collection, item))
{
}
~CanProcess()
{
if (cleanup_)
cleanup_();
}
CanProcess(CanProcess const&) = delete;
CanProcess&
operator=(CanProcess const&) = delete;
explicit
operator bool() const
{
return static_cast<bool>(cleanup_);
}
private:
template <bool useIterator, class Mutex, class Collection, class Item>
std::function<void()>
doInsert(Mutex& mtx, Collection& collection, Item const& item)
{
std::unique_lock<Mutex> lock(mtx);
// TODO: Use structured binding once LLVM 16 is the minimum supported
// version. See also: https://github.com/llvm/llvm-project/issues/48582
// https://github.com/llvm/llvm-project/commit/127bf44385424891eb04cff8e52d3f157fc2cb7c
auto const insertResult = collection.insert(item);
auto const it = insertResult.first;
if (!insertResult.second)
return {};
if constexpr (useIterator)
return [&, it]() {
std::unique_lock<Mutex> lock(mtx);
collection.erase(it);
};
else
return [&]() {
std::unique_lock<Mutex> lock(mtx);
collection.erase(item);
};
}
// Generic insert() function doesn't use iterators because they may get
// invalidated
template <class Mutex, class Collection, class Item>
std::function<void()>
insert(Mutex& mtx, Collection& collection, Item const& item)
{
return doInsert<false>(mtx, collection, item);
}
// Specialize insert() for std::set, which does not invalidate iterators for
// insert and erase
template <class Mutex, class Item>
std::function<void()>
insert(Mutex& mtx, std::set<Item>& collection, Item const& item)
{
return doInsert<true>(mtx, collection, item);
}
// If set, then the item is "usable"
std::function<void()> cleanup_;
};
#endif

View File

@@ -15,7 +15,7 @@
#define ALWAYS_OR_UNREACHABLE(cond, message) assert((message) && (cond))
#define SOMETIMES(cond, message, ...)
#define REACHABLE(message, ...)
#define UNREACHABLE(message, ...) assert((message) && false)
#define UNREACHABLE(message, ...) assert((message) && false) // NOLINT(misc-static-assert)
#endif
#define XRPL_ASSERT ALWAYS_OR_UNREACHABLE

View File

@@ -70,14 +70,24 @@ JobQueue::Coro::resume()
running_ = true;
}
{
std::lock_guard lock(jq_.m_mutex);
std::lock_guard lk(jq_.m_mutex);
--jq_.nSuspend_;
}
auto saved = detail::getLocalValues().release();
detail::getLocalValues().reset(&lvs_);
std::lock_guard lock(mutex_);
XRPL_ASSERT(static_cast<bool>(coro_), "xrpl::JobQueue::Coro::resume : is runnable");
coro_();
// A late resume() can arrive after the coroutine has already completed.
// This is an expected (if rare) outcome of the race condition documented
// in JobQueue.h:354-377 where post() schedules a resume job before the
// coroutine yields — the mutex serializes access, but by the time this
// resume() acquires the lock the coroutine may have already run to
// completion. Calling operator() on a completed boost::coroutine2 is
// undefined behavior, so we must check and skip invoking the coroutine
// body if it has already completed.
if (coro_)
{
coro_();
}
detail::getLocalValues().release();
detail::getLocalValues().reset(saved);
std::lock_guard lk(mutex_run_);

View File

@@ -199,7 +199,7 @@ public:
/** Add a suppression peer and get message's relay status.
* Return pair:
* element 1: true if the peer is added.
* element 1: true if the key is added.
* element 2: optional is seated to the relay time point or
* is unseated if has not relayed yet. */
std::pair<bool, std::optional<Stopwatch::time_point>>

View File

@@ -99,8 +99,8 @@ public:
Effects:
The coroutine continues execution from where it last left off
using this same thread.
Undefined behavior if called after the coroutine has completed
with a return (as opposed to a yield()).
If the coroutine has already completed, returns immediately
(handles the documented post-before-yield race condition).
Undefined behavior if resume() or post() called consecutively
without a corresponding yield.
*/
@@ -316,7 +316,7 @@ private:
// Returns the limit of running jobs for the given job type.
// For jobs with no limit, we return the largest int. Hopefully that
// will be enough.
int
static int
getJobLimit(JobType type);
};
@@ -357,8 +357,10 @@ private:
If the post() job were to be executed before yield(), undefined behavior
would occur. The lock ensures that coro_ is not called again until we exit
the coroutine. At which point a scheduled resume() job waiting on the lock
would gain entry, harmlessly call coro_ and immediately return as we have
already completed the coroutine.
would gain entry. resume() checks if the coroutine has already completed
(coro_ converts to false) and, if so, skips invoking operator() since
calling operator() on a completed boost::coroutine2 pull_type is undefined
behavior.
The race condition occurs as follows:

View File

@@ -3,7 +3,6 @@
#include <xrpl/basics/Blob.h>
#include <xrpl/basics/SHAMapHash.h>
#include <xrpl/basics/TaggedCache.h>
#include <xrpl/ledger/CachedSLEs.h>
#include <boost/asio.hpp>
@@ -23,6 +22,20 @@ class PerfLog;
// This is temporary until we migrate all code to use ServiceRegistry.
class Application;
template <
class Key,
class T,
bool IsKeyCache,
class SharedWeakUnionPointer,
class SharedPointerType,
class Hash,
class KeyEqual,
class Mutex>
class TaggedCache;
class STLedgerEntry;
using SLE = STLedgerEntry;
using CachedSLEs = TaggedCache<uint256, SLE const>;
// Forward declarations
class AcceptedLedger;
class AmendmentTable;
@@ -45,7 +58,7 @@ class NetworkIDService;
class OpenLedger;
class OrderBookDB;
class Overlay;
class PathRequests;
class PathRequestManager;
class PeerReservationTable;
class PendingSaves;
class RelationalDatabase;
@@ -89,7 +102,7 @@ public:
getNodeFamily() = 0;
virtual TimeKeeper&
timeKeeper() = 0;
getTimeKeeper() = 0;
virtual JobQueue&
getJobQueue() = 0;
@@ -98,7 +111,7 @@ public:
getTempNodeCache() = 0;
virtual CachedSLEs&
cachedSLEs() = 0;
getCachedSLEs() = 0;
virtual NetworkIDService&
getNetworkIDService() = 0;
@@ -120,26 +133,26 @@ public:
getValidations() = 0;
virtual ValidatorList&
validators() = 0;
getValidators() = 0;
virtual ValidatorSite&
validatorSites() = 0;
getValidatorSites() = 0;
virtual ManifestCache&
validatorManifests() = 0;
getValidatorManifests() = 0;
virtual ManifestCache&
publisherManifests() = 0;
getPublisherManifests() = 0;
// Network services
virtual Overlay&
overlay() = 0;
getOverlay() = 0;
virtual Cluster&
cluster() = 0;
getCluster() = 0;
virtual PeerReservationTable&
peerReservations() = 0;
getPeerReservations() = 0;
virtual Resource::Manager&
getResourceManager() = 0;
@@ -174,13 +187,13 @@ public:
getLedgerReplayer() = 0;
virtual PendingSaves&
pendingSaves() = 0;
getPendingSaves() = 0;
virtual OpenLedger&
openLedger() = 0;
getOpenLedger() = 0;
virtual OpenLedger const&
openLedger() const = 0;
getOpenLedger() const = 0;
// Transaction and operation services
virtual NetworkOPs&
@@ -195,8 +208,8 @@ public:
virtual TxQ&
getTxQ() = 0;
virtual PathRequests&
getPathRequests() = 0;
virtual PathRequestManager&
getPathRequestManager() = 0;
// Server services
virtual ServerHandler&
@@ -210,16 +223,16 @@ public:
isStopping() const = 0;
virtual beast::Journal
journal(std::string const& name) = 0;
getJournal(std::string const& name) = 0;
virtual boost::asio::io_context&
getIOContext() = 0;
virtual Logs&
logs() = 0;
getLogs() = 0;
virtual std::optional<uint256> const&
trapTxID() const = 0;
getTrapTxID() const = 0;
/** Retrieve the "wallet database" */
virtual DatabaseCon&
@@ -228,7 +241,7 @@ public:
// Temporary: Get the underlying Application for functions that haven't
// been migrated yet. This should be removed once all code is migrated.
virtual Application&
app() = 0;
getApp() = 0;
};
} // namespace xrpl

View File

@@ -5,7 +5,7 @@
namespace xrpl {
enum class StartUpType { FRESH, NORMAL, LOAD, LOAD_FILE, REPLAY, NETWORK };
enum class StartUpType { Fresh, Normal, Load, LoadFile, Replay, Network };
inline std::ostream&
operator<<(std::ostream& os, StartUpType const& type)

View File

@@ -1,13 +1,12 @@
#pragma once
#include <xrpld/core/Config.h>
#include <xrpld/core/TimeKeeper.h>
#include <xrpl/basics/CountedObject.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/ledger/CachedView.h>
#include <xrpl/ledger/View.h>
#include <xrpl/protocol/Fees.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Rules.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/TxMeta.h>
@@ -15,7 +14,7 @@
namespace xrpl {
class Application;
class ServiceRegistry;
class Job;
class TransactionMaster;
@@ -83,21 +82,26 @@ public:
*/
Ledger(
create_genesis_t,
Config const& config,
Rules const& rules,
Fees const& fees,
std::vector<uint256> const& amendments,
Family& family);
Ledger(LedgerHeader const& info, Config const& config, Family& family);
Ledger(LedgerHeader const& info, Rules const& rules, Family& family);
/** Used for ledgers loaded from JSON files
@param acquire If true, acquires the ledger if not found locally
@note The fees parameter provides default values, but setup() may
override them from the ledger state if fee-related SLEs exist.
*/
Ledger(
LedgerHeader const& info,
bool& loaded,
bool acquire,
Config const& config,
Rules const& rules,
Fees const& fees,
Family& family,
beast::Journal j);
@@ -113,7 +117,8 @@ public:
Ledger(
std::uint32_t ledgerSeq,
NetClock::time_point closeTime,
Config const& config,
Rules const& rules,
Fees const& fees,
Family& family);
~Ledger() = default;
@@ -322,7 +327,7 @@ public:
walkLedger(beast::Journal j, bool parallel = false) const;
bool
assertSensible(beast::Journal ledgerJ) const;
isSensible() const;
void
invariants() const;
@@ -379,8 +384,26 @@ private:
bool
setup();
void
defaultFees(Config const& config);
/** @brief Deserialize a SHAMapItem containing a single STTx.
*
* @param item The SHAMapItem to deserialize.
* @return A shared pointer to the deserialized transaction.
* @throw May throw on deserialization error.
*/
static std::shared_ptr<STTx const>
deserializeTx(SHAMapItem const& item);
/** @brief Deserialize a SHAMapItem containing STTx + STObject metadata.
*
* The SHAMapItem must contain two variable length serialization objects.
*
* @param item The SHAMapItem to deserialize.
* @return A pair containing shared pointers to the deserialized transaction
* and metadata.
* @throw May throw on deserialization error.
*/
static std::pair<std::shared_ptr<STTx const>, std::shared_ptr<STObject const>>
deserializeTxPlusMeta(SHAMapItem const& item);
bool mImmutable;
@@ -402,54 +425,4 @@ private:
/** A ledger wrapped in a CachedView. */
using CachedLedger = CachedView<Ledger>;
//------------------------------------------------------------------------------
//
// API
//
//------------------------------------------------------------------------------
extern bool
pendSaveValidated(
Application& app,
std::shared_ptr<Ledger const> const& ledger,
bool isSynchronous,
bool isCurrent);
std::shared_ptr<Ledger>
loadLedgerHelper(LedgerHeader const& sinfo, Application& app, bool acquire);
std::shared_ptr<Ledger>
loadByIndex(std::uint32_t ledgerIndex, Application& app, bool acquire = true);
std::shared_ptr<Ledger>
loadByHash(uint256 const& ledgerHash, Application& app, bool acquire = true);
// Fetch the ledger with the highest sequence contained in the database
extern std::tuple<std::shared_ptr<Ledger>, std::uint32_t, uint256>
getLatestLedger(Application& app);
/** Deserialize a SHAMapItem containing a single STTx
Throw:
May throw on deserializaton error
*/
std::shared_ptr<STTx const>
deserializeTx(SHAMapItem const& item);
/** Deserialize a SHAMapItem containing STTx + STObject metadata
The SHAMap must contain two variable length
serialization objects.
Throw:
May throw on deserializaton error
*/
std::pair<std::shared_ptr<STTx const>, std::shared_ptr<STObject const>>
deserializeTxPlusMeta(SHAMapItem const& item);
uint256
calculateLedgerHash(LedgerHeader const& info);
} // namespace xrpl

View File

@@ -76,16 +76,33 @@ public:
@return true if a book from this issue to XRP exists
*/
virtual bool
isBookToXRP(Issue const& issue, std::optional<Domain> domain = std::nullopt) = 0;
isBookToXRP(Issue const& issue, std::optional<Domain> const& domain = std::nullopt) = 0;
/**
* Process a transaction for order book tracking.
* @param ledger The ledger the transaction was applied to
* @param alTx The transaction to process
* @param jvObj The JSON object of the transaction
*/
virtual void
processTxn(
std::shared_ptr<ReadView const> const& ledger,
AcceptedLedgerTx const& alTx,
MultiApiJson const& jvObj) = 0;
/**
* Get the book listeners for a book.
* @param book The book to get the listeners for
* @return The book listeners for the book
*/
virtual BookListeners::pointer
getBookListeners(Book const&) = 0;
/**
* Create a new book listeners for a book.
* @param book The book to create the listeners for
* @return The new book listeners for the book
*/
virtual BookListeners::pointer
makeBookListeners(Book const&) = 0;
};

View File

@@ -4,6 +4,10 @@
namespace xrpl {
// Deprecated constant for backwards compatibility with pre-XRPFees amendment.
// This was the reference fee units used in the old fee calculation.
inline constexpr std::uint32_t FEE_UNITS_DEPRECATED = 10;
/** Reflects the fee settings for a particular ledger.
The fees are always the same for any transactions applied
@@ -11,15 +15,25 @@ namespace xrpl {
*/
struct Fees
{
XRPAmount base{0}; // Reference tx cost (drops)
XRPAmount reserve{0}; // Reserve base (drops)
XRPAmount increment{0}; // Reserve increment (drops)
/** @brief Cost of a reference transaction in drops. */
XRPAmount base{0};
/** @brief Minimum XRP an account must hold to exist on the ledger. */
XRPAmount reserve{0};
/** @brief Additional XRP reserve required per owned ledger object. */
XRPAmount increment{0};
explicit Fees() = default;
Fees(Fees const&) = default;
Fees&
operator=(Fees const&) = default;
Fees(XRPAmount base_, XRPAmount reserve_, XRPAmount increment_)
: base(base_), reserve(reserve_), increment(increment_)
{
}
/** Returns the account reserve given the owner count, in drops.
The reserve is calculated as the reserve base plus

View File

@@ -35,6 +35,8 @@ struct LedgerHeader
// If validated is false, it means "not yet validated."
// Once validated is true, it will never be set false at a later time.
// NOTE: If you are accessing this directly, you are probably doing it
// wrong. Use LedgerMaster::isValidated().
// VFALCO TODO Make this not mutable
bool mutable validated = false;
bool accepted = false;
@@ -72,4 +74,8 @@ deserializeHeader(Slice data, bool hasHash = false);
LedgerHeader
deserializePrefixedHeader(Slice data, bool hasHash = false);
/** Calculate the hash of a ledger header. */
uint256
calculateLedgerHash(LedgerHeader const& info);
} // namespace xrpl

View File

@@ -72,12 +72,12 @@ public:
isDelegable(std::uint32_t const& permissionValue, Rules const& rules) const;
// for tx level permission, permission value is equal to tx type plus one
uint32_t
txToPermissionType(TxType const& type) const;
static uint32_t
txToPermissionType(TxType const& type);
// tx type value is permission value minus one
TxType
permissionToTxType(uint32_t const& value) const;
static TxType
permissionToTxType(uint32_t const& value);
};
} // namespace xrpl

View File

@@ -69,9 +69,6 @@ public:
std::vector<uint256>::iterator
insert(std::vector<uint256>::const_iterator pos, uint256 const& value);
std::vector<uint256>::iterator
insert(std::vector<uint256>::const_iterator pos, uint256&& value);
void
push_back(uint256 const& v);
@@ -184,12 +181,6 @@ STVector256::insert(std::vector<uint256>::const_iterator pos, uint256 const& val
return mValue.insert(pos, value);
}
inline std::vector<uint256>::iterator
STVector256::insert(std::vector<uint256>::const_iterator pos, uint256&& value)
{
return mValue.insert(pos, std::move(value));
}
inline void
STVector256::push_back(uint256 const& v)
{

View File

@@ -336,7 +336,7 @@ public:
static_assert(N > 0, "");
}
std::size_t
[[nodiscard]] bool
empty() const noexcept
{
return remain_ == 0;

View File

@@ -2,6 +2,6 @@
namespace xrpl {
enum class TxSearched { all, some, unknown };
enum class TxSearched { All, Some, Unknown };
}

View File

@@ -16,6 +16,7 @@
// Add new amendments to the top of this list.
// Keep it sorted in reverse chronological order.
XRPL_FIX (Security3_1_3, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (PermissionedDomainInvariant, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (ExpiredNFTokenOfferRemoval, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (BatchInnerSigs, Supported::no, VoteBehavior::DefaultNo)

View File

@@ -1,6 +1,7 @@
#pragma once
#include <xrpl/core/PerfLog.h>
#include <xrpl/core/ServiceRegistry.h>
#include <xrpl/core/StartUpType.h>
#include <xrpl/rdb/DBInit.h>
#include <xrpl/rdb/SociDB.h>
@@ -69,7 +70,7 @@ public:
{
explicit Setup() = default;
StartUpType startUp = StartUpType::NORMAL;
StartUpType startUp = StartUpType::Normal;
bool standAlone = false;
boost::filesystem::path dataDir;
// Indicates whether or not to return the `globalPragma`
@@ -94,7 +95,7 @@ public:
struct CheckpointerSetup
{
JobQueue* jobQueue;
Logs* logs;
std::reference_wrapper<ServiceRegistry> registry;
};
template <std::size_t N, std::size_t M>
@@ -106,9 +107,8 @@ public:
beast::Journal journal)
// Use temporary files or regular DB files?
: DatabaseCon(
setup.standAlone && setup.startUp != StartUpType::LOAD &&
setup.startUp != StartUpType::LOAD_FILE &&
setup.startUp != StartUpType::REPLAY
setup.standAlone && setup.startUp != StartUpType::Load &&
setup.startUp != StartUpType::LoadFile && setup.startUp != StartUpType::Replay
? ""
: (setup.dataDir / dbName),
setup.commonPragma(),
@@ -129,7 +129,7 @@ public:
beast::Journal journal)
: DatabaseCon(setup, dbName, pragma, initSQL, journal)
{
setupCheckpointing(checkpointerSetup.jobQueue, *checkpointerSetup.logs);
setupCheckpointing(checkpointerSetup.jobQueue, checkpointerSetup.registry.get());
}
template <std::size_t N, std::size_t M>
@@ -154,7 +154,7 @@ public:
beast::Journal journal)
: DatabaseCon(dataDir, dbName, pragma, initSQL, journal)
{
setupCheckpointing(checkpointerSetup.jobQueue, *checkpointerSetup.logs);
setupCheckpointing(checkpointerSetup.jobQueue, checkpointerSetup.registry.get());
}
~DatabaseCon();
@@ -177,7 +177,7 @@ public:
private:
void
setupCheckpointing(JobQueue*, Logs&);
setupCheckpointing(JobQueue*, ServiceRegistry&);
template <std::size_t N, std::size_t M>
DatabaseCon(

View File

@@ -49,8 +49,9 @@ public:
struct AccountTxOptions
{
AccountID const& account;
std::uint32_t minLedger;
std::uint32_t maxLedger;
/// Ledger sequence range to search. A value of 0 for min or max
/// means unbounded in that direction (no constraint applied).
LedgerRange ledgerRange;
std::uint32_t offset;
std::uint32_t limit;
bool bUnlimited;
@@ -59,8 +60,7 @@ public:
struct AccountTxPageOptions
{
AccountID const& account;
std::uint32_t minLedger;
std::uint32_t maxLedger;
LedgerRange ledgerRange;
std::optional<AccountTxMarker> marker;
std::uint32_t limit;
bool bAdmin;
@@ -247,7 +247,7 @@ public:
* @return Struct CountMinMax which contains the minimum sequence,
* maximum sequence and number of ledgers.
*/
virtual struct CountMinMax
virtual CountMinMax
getLedgerCountMinMax() = 0;
/**
@@ -405,10 +405,10 @@ public:
* @param id Hash of the transaction.
* @param range Range of ledgers to check, if present.
* @param ec Default error code value.
* @return Transaction and its metadata if found, otherwise TxSearched::all
* @return Transaction and its metadata if found, otherwise TxSearched::All
* if a range is provided and all ledgers from the range are present
* in the database, TxSearched::some if a range is provided and not
* all ledgers are present, TxSearched::unknown if the range is not
* in the database, TxSearched::Some if a range is provided and not
* all ledgers are present, TxSearched::Unknown if the range is not
* provided or a deserializing error occurred. In the last case the
* error code is returned via the ec parameter, in other cases the
* default error code is not changed.
@@ -455,9 +455,10 @@ public:
closeTransactionDB() = 0;
};
template <class T, class C>
template <typename T, typename C>
T
rangeCheckedCast(C c)
requires(std::is_arithmetic_v<T> && std::is_arithmetic_v<C> && std::convertible_to<C, T>)
{
if ((c > std::numeric_limits<T>::max()) || (!std::numeric_limits<T>::is_signed && c < 0) ||
(std::numeric_limits<T>::is_signed && std::numeric_limits<C>::is_signed &&

View File

@@ -13,8 +13,8 @@
#pragma clang diagnostic ignored "-Wdeprecated"
#endif
#include <xrpl/basics/Log.h>
#include <xrpl/core/JobQueue.h>
#include <xrpl/core/ServiceRegistry.h>
#define SOCI_USE_BOOST
#include <soci/soci.h>
@@ -111,7 +111,7 @@ public:
and so must outlive them both.
*/
std::shared_ptr<Checkpointer>
makeCheckpointer(std::uintptr_t id, std::weak_ptr<soci::session>, JobQueue&, Logs&);
makeCheckpointer(std::uintptr_t id, std::weak_ptr<soci::session>, JobQueue&, ServiceRegistry&);
} // namespace xrpl

View File

@@ -185,7 +185,7 @@ public:
virtual bool
isFull() = 0;
virtual void
setMode(OperatingMode om) = 0;
setMode(OperatingMode om, char const* reason) = 0;
virtual bool
isBlocked() = 0;
virtual bool

View File

@@ -520,7 +520,7 @@ private:
// getMissingNodes helper functions
void
gmn_ProcessNodes(MissingNodes&, MissingNodes::StackEntry& node);
void
static void
gmn_ProcessDeferredReads(MissingNodes&);
// fetch from DB helper function

View File

@@ -37,7 +37,7 @@ public:
XRPL_ASSERT((flags & tapBATCH) == 0, "Batch apply flag should not be set");
}
ServiceRegistry& registry;
std::reference_wrapper<ServiceRegistry> registry;
STTx const& tx;
TER const preclaimResult;
XRPAmount const baseFee;
@@ -111,7 +111,7 @@ public:
checkInvariants(TER const result, XRPAmount const fee);
private:
TER
static TER
failInvariantCheck(TER const result);
template <std::size_t... Is>

View File

@@ -13,7 +13,7 @@ namespace xrpl {
struct PreflightContext
{
public:
ServiceRegistry& registry;
std::reference_wrapper<ServiceRegistry> registry;
STTx const& tx;
Rules const rules;
ApplyFlags flags;
@@ -56,7 +56,7 @@ public:
struct PreclaimContext
{
public:
ServiceRegistry& registry;
std::reference_wrapper<ServiceRegistry> registry;
ReadView const& view;
TER preflightResult;
ApplyFlags flags;

View File

@@ -48,7 +48,7 @@ private:
bool
isValidEntry(std::shared_ptr<SLE const> const& before, std::shared_ptr<SLE const> const& after);
STAmount
static STAmount
calculateBalanceChange(
std::shared_ptr<SLE const> const& before,
std::shared_ptr<SLE const> const& after,
@@ -63,7 +63,7 @@ private:
std::shared_ptr<SLE const>
findIssuer(AccountID const& issuerID, ReadView const& view);
bool
static bool
validateIssuerChanges(
std::shared_ptr<SLE const> const& issuer,
IssuerChanges const& changes,
@@ -71,7 +71,7 @@ private:
beast::Journal const& j,
bool enforce);
bool
static bool
validateFrozenState(
BalanceChange const& change,
bool high,

View File

@@ -7,6 +7,7 @@
#include <xrpl/protocol/TER.h>
#include <xrpl/tx/invariants/AMMInvariant.h>
#include <xrpl/tx/invariants/FreezeInvariant.h>
#include <xrpl/tx/invariants/LoanBrokerInvariant.h>
#include <xrpl/tx/invariants/LoanInvariant.h>
#include <xrpl/tx/invariants/MPTInvariant.h>
#include <xrpl/tx/invariants/NFTInvariant.h>
@@ -111,7 +112,7 @@ public:
void
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
bool
static bool
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
};

View File

@@ -0,0 +1,55 @@
#pragma once
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TER.h>
#include <map>
#include <vector>
namespace xrpl {
/**
* @brief Invariants: Loan brokers are internally consistent
*
* 1. If `LoanBroker.OwnerCount = 0` the `DirectoryNode` will have at most one
* node (the root), which will only hold entries for `RippleState` or
* `MPToken` objects.
*
*/
class ValidLoanBroker
{
// Not all of these elements will necessarily be populated. Remaining items
// will be looked up as needed.
struct BrokerInfo
{
SLE::const_pointer brokerBefore = nullptr;
// After is used for most of the checks, except
// those that check changed values.
SLE::const_pointer brokerAfter = nullptr;
};
// Collect all the LoanBrokers found directly or indirectly through
// pseudo-accounts. Key is the brokerID / index. It will be used to find the
// LoanBroker object if brokerBefore and brokerAfter are nullptr
std::map<uint256, BrokerInfo> brokers_;
// Collect all the modified trust lines. Their high and low accounts will be
// loaded to look for LoanBroker pseudo-accounts.
std::vector<SLE::const_pointer> lines_;
// Collect all the modified MPTokens. Their accounts will be loaded to look
// for LoanBroker pseudo-accounts.
std::vector<SLE::const_pointer> mpts_;
static bool
goodZeroDirectory(ReadView const& view, SLE::const_ref dir, beast::Journal const& j);
public:
void
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
bool
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
};
} // namespace xrpl

View File

@@ -1,57 +1,14 @@
#pragma once
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TER.h>
#include <map>
#include <vector>
namespace xrpl {
/**
* @brief Invariants: Loan brokers are internally consistent
*
* 1. If `LoanBroker.OwnerCount = 0` the `DirectoryNode` will have at most one
* node (the root), which will only hold entries for `RippleState` or
* `MPToken` objects.
*
*/
class ValidLoanBroker
{
// Not all of these elements will necessarily be populated. Remaining items
// will be looked up as needed.
struct BrokerInfo
{
SLE::const_pointer brokerBefore = nullptr;
// After is used for most of the checks, except
// those that check changed values.
SLE::const_pointer brokerAfter = nullptr;
};
// Collect all the LoanBrokers found directly or indirectly through
// pseudo-accounts. Key is the brokerID / index. It will be used to find the
// LoanBroker object if brokerBefore and brokerAfter are nullptr
std::map<uint256, BrokerInfo> brokers_;
// Collect all the modified trust lines. Their high and low accounts will be
// loaded to look for LoanBroker pseudo-accounts.
std::vector<SLE::const_pointer> lines_;
// Collect all the modified MPTokens. Their accounts will be loaded to look
// for LoanBroker pseudo-accounts.
std::vector<SLE::const_pointer> mpts_;
bool
goodZeroDirectory(ReadView const& view, SLE::const_ref dir, beast::Journal const& j) const;
public:
void
visitEntry(bool, std::shared_ptr<SLE const> const&, std::shared_ptr<SLE const> const&);
bool
finalize(STTx const&, TER const, XRPAmount const, ReadView const&, beast::Journal const&);
};
/**
* @brief Invariants: Loans are internally consistent
*

View File

@@ -1,6 +1,6 @@
#pragma once
#include <xrpl/basics/Log.h>
#include <xrpl/core/ServiceRegistry.h>
#include <xrpl/ledger/PaymentSandbox.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/TER.h>
@@ -92,7 +92,7 @@ public:
STPathSet const& spsPaths,
std::optional<uint256> const& domainID,
Logs& l,
ServiceRegistry& registry,
Input const* const pInputs = nullptr);
// The view we are currently working on

View File

@@ -203,7 +203,7 @@ getAMMOfferStartWithTakerGets(
// Try to reduce the offer size to improve the quality.
// The quality might still not match the targetQuality for a tiny offer.
if (auto const amounts = getAmounts(*nTakerGets); Quality{amounts} < targetQuality)
if (auto amounts = getAmounts(*nTakerGets); Quality{amounts} < targetQuality)
return getAmounts(detail::reduceOffer(amounts.out));
else
return amounts;
@@ -270,7 +270,7 @@ getAMMOfferStartWithTakerPays(
// Try to reduce the offer size to improve the quality.
// The quality might still not match the targetQuality for a tiny offer.
if (auto const amounts = getAmounts(*nTakerPays); Quality{amounts} < targetQuality)
if (auto amounts = getAmounts(*nTakerPays); Quality{amounts} < targetQuality)
return getAmounts(detail::reduceOffer(amounts.in));
else
return amounts;
@@ -335,8 +335,7 @@ changeSpotPriceQuality(
}
auto const takerPays = toAmount<TIn>(getIssue(pool.in), nTakerPays, Number::upward);
// should not fail
if (auto const amounts =
TAmounts<TIn, TOut>{takerPays, swapAssetIn(pool, takerPays, tfee)};
if (auto amounts = TAmounts<TIn, TOut>{takerPays, swapAssetIn(pool, takerPays, tfee)};
Quality{amounts} < quality &&
!withinRelativeDistance(Quality{amounts}, quality, Number(1, -7)))
{
@@ -362,7 +361,7 @@ changeSpotPriceQuality(
// Generate the offer starting with XRP side. Return seated offer amounts
// if the offer can be generated, otherwise nullopt.
auto const amounts = [&]() {
auto amounts = [&]() {
if (isXRP(getIssue(pool.out)))
return getAMMOfferStartWithTakerGets(pool, quality, tfee);
return getAMMOfferStartWithTakerPays(pool, quality, tfee);

View File

@@ -45,7 +45,7 @@ getFileContents(
return {};
}
std::string const result{
std::string result{
std::istreambuf_iterator<char>{fileStream}, std::istreambuf_iterator<char>{}};
if (fileStream.bad())

View File

@@ -981,7 +981,7 @@ root(Number f, unsigned d)
auto ex = [e = e, di = di]() // Euclidean remainder of e/d
{
int k = (e >= 0 ? e : e - (di - 1)) / di;
int k2 = e - k * di;
int k2 = e - (k * di);
if (k2 == 0)
return 0;
return di - k2;
@@ -998,7 +998,7 @@ root(Number f, unsigned d)
}
// Quadratic least squares curve fit of f^(1/d) in the range [0, 1]
auto const D = ((6 * di + 11) * di + 6) * di + 1;
auto const D = (((6 * di + 11) * di + 6) * di) + 1;
auto const a0 = 3 * di * ((2 * di - 3) * di + 1);
auto const a1 = 24 * di * (2 * di - 1);
auto const a2 = -30 * (di - 1) * di;

View File

@@ -169,7 +169,7 @@ public:
XRPL_ASSERT(m_stopped == true, "xrpl::ResolverAsioImpl::start : stopped");
XRPL_ASSERT(m_stop_called == false, "xrpl::ResolverAsioImpl::start : not stopping");
if (m_stopped.exchange(false) == true)
if (m_stopped.exchange(false))
{
{
std::lock_guard lk{m_mut};
@@ -182,7 +182,7 @@ public:
void
stop_async() override
{
if (m_stop_called.exchange(true) == false)
if (!m_stop_called.exchange(true))
{
boost::asio::dispatch(
m_io_context,
@@ -229,7 +229,7 @@ public:
{
XRPL_ASSERT(m_stop_called == true, "xrpl::ResolverAsioImpl::do_stop : stopping");
if (m_stopped.exchange(true) == false)
if (!m_stopped.exchange(true))
{
m_work.clear();
m_resolver.cancel();
@@ -271,7 +271,7 @@ public:
m_strand, std::bind(&ResolverAsioImpl::do_work, this, CompletionCounter(this))));
}
HostAndPort
static HostAndPort
parseName(std::string const& str)
{
// first attempt to parse as an endpoint (IP addr + port).
@@ -319,7 +319,7 @@ public:
void
do_work(CompletionCounter)
{
if (m_stop_called == true)
if (m_stop_called)
return;
// We don't have any work to do at this time
@@ -367,7 +367,7 @@ public:
{
XRPL_ASSERT(!names.empty(), "xrpl::ResolverAsioImpl::do_resolve : names non-empty");
if (m_stop_called == false)
if (!m_stop_called)
{
m_work.emplace_back(names, handler);

View File

@@ -24,7 +24,7 @@ sqlBlobLiteral(Blob const& blob)
{
std::string j;
j.reserve(blob.size() * 2 + 3);
j.reserve((blob.size() * 2) + 3);
j.push_back('X');
j.push_back('\'');
boost::algorithm::hex(blob.begin(), blob.end(), std::back_inserter(j));

View File

@@ -107,7 +107,7 @@ encode(void* dest, void const* src, std::size_t len)
char const* in = static_cast<char const*>(src);
auto const tab = base64::get_alphabet();
for (auto n = len / 3; n--;)
for (auto n = len / 3; n != 0u; --n)
{
*out++ = tab[(in[0] & 0xfc) >> 2];
*out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
@@ -162,7 +162,7 @@ decode(void* dest, char const* src, std::size_t len)
auto const inverse = base64::get_inverse();
while (len-- && *in != '=')
while (((len--) != 0u) && *in != '=')
{
auto const v = inverse[*in];
if (v == -1)
@@ -181,7 +181,7 @@ decode(void* dest, char const* src, std::size_t len)
}
}
if (i)
if (i != 0)
{
c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4);
c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);

View File

@@ -253,7 +253,7 @@ initAuthenticated(
// VFALCO Replace fopen() with RAII
FILE* f = fopen(chain_file.c_str(), "r");
if (!f)
if (f == nullptr)
{
LogicError(
"Problem opening SSL chain file" +

View File

@@ -352,7 +352,7 @@ public:
}
}
void
static void
log(std::vector<boost::asio::const_buffer> const& buffers)
{
(void)buffers;

View File

@@ -10,7 +10,7 @@ bool
is_private(AddressV6 const& addr)
{
return (
(addr.to_bytes()[0] & 0xfd) || // TODO fc00::/8 too ?
((addr.to_bytes()[0] & 0xfd) != 0) || // TODO fc00::/8 too ?
(addr.is_v4_mapped() &&
is_private(boost::asio::ip::make_address_v4(boost::asio::ip::v4_mapped, addr))));
}

View File

@@ -57,7 +57,7 @@ Endpoint::to_string() const
if (port() != 0 && address().is_v6())
s += '[';
s += address().to_string();
if (port())
if (port() != 0u)
{
if (address().is_v6())
s += ']';
@@ -111,7 +111,7 @@ operator>>(std::istream& is, Endpoint& endpoint)
// so we continue to honor that here by assuming we are at the end
// of the address portion if we hit a space (or the separator
// we were expecting to see)
if (isspace(static_cast<unsigned char>(i)) || (readTo && i == readTo))
if ((isspace(static_cast<unsigned char>(i)) != 0) || ((readTo != 0) && i == readTo))
break;
if ((i == '.') || (i >= '0' && i <= ':') || (i >= 'a' && i <= 'f') ||
@@ -121,13 +121,13 @@ operator>>(std::istream& is, Endpoint& endpoint)
// don't exceed a reasonable length...
if (addrStr.size() == INET6_ADDRSTRLEN ||
(readTo && readTo == ':' && addrStr.size() > 15))
((readTo != 0) && readTo == ':' && addrStr.size() > 15))
{
is.setstate(std::ios_base::failbit);
return is;
}
if (!readTo && (i == '.' || i == ':'))
if ((readTo == 0) && (i == '.' || i == ':'))
{
// if we see a dot first, must be IPv4
// otherwise must be non-bracketed IPv6
@@ -145,7 +145,7 @@ operator>>(std::istream& is, Endpoint& endpoint)
if (readTo == ']' && is.rdbuf()->in_avail() > 0)
{
is.get(i);
if (!(isspace(static_cast<unsigned char>(i)) || i == ':'))
if ((isspace(static_cast<unsigned char>(i)) == 0) && i != ':')
{
is.unget();
is.setstate(std::ios_base::failbit);

View File

@@ -84,8 +84,7 @@ JobQueue::addRefCountedJob(JobType type, std::string const& name, JobFunction co
JobType const type(job.getType());
XRPL_ASSERT(type != jtINVALID, "xrpl::JobQueue::addRefCountedJob : has valid job type");
XRPL_ASSERT(
m_jobSet.find(job) != m_jobSet.end(), "xrpl::JobQueue::addRefCountedJob : job found");
XRPL_ASSERT(m_jobSet.contains(job), "xrpl::JobQueue::addRefCountedJob : job found");
perfLog_.jobQueue(type);
JobTypeData& data(getJobTypeData(type));

View File

@@ -141,7 +141,7 @@ LoadMonitor::isOver()
update();
if (mLatencyEvents == 0)
return 0;
return false;
return isOverTarget(
mLatencyMSAvg / (mLatencyEvents * 4), mLatencyMSPeak / (mLatencyEvents * 4));

View File

@@ -47,7 +47,7 @@ Workers::setNumberOfThreads(int numberOfThreads)
if (m_numberOfThreads == numberOfThreads)
return;
if (perfLog_)
if (perfLog_ != nullptr)
perfLog_->resizeJobs(numberOfThreads);
if (numberOfThreads > m_numberOfThreads)

View File

@@ -210,8 +210,8 @@ RFC1751::extract(char const* s, int start, int length)
int const shiftR = 24 - (length + (start % 8));
cl = s[start / 8]; // get components
cc = (shiftR < 16) ? s[start / 8 + 1] : 0;
cr = (shiftR < 8) ? s[start / 8 + 2] : 0;
cc = (shiftR < 16) ? s[(start / 8) + 1] : 0;
cr = (shiftR < 8) ? s[(start / 8) + 2] : 0;
x = ((long)(cl << 8 | cc) << 8 | cr); // Put bits together
x = x >> shiftR; // Right justify number
@@ -265,13 +265,13 @@ RFC1751::insert(char* s, int x, int start, int length)
if (shift + length > 16)
{
s[start / 8] |= cl;
s[start / 8 + 1] |= cc;
s[start / 8 + 2] |= cr;
s[(start / 8) + 1] |= cc;
s[(start / 8) + 2] |= cr;
}
else if (shift + length > 8)
{
s[start / 8] |= cc;
s[start / 8 + 1] |= cr;
s[(start / 8) + 1] |= cr;
}
else
{
@@ -284,7 +284,7 @@ RFC1751::standard(std::string& strWord)
{
for (auto& letter : strWord)
{
if (islower(static_cast<unsigned char>(letter)))
if (islower(static_cast<unsigned char>(letter)) != 0)
{
letter = toupper(static_cast<unsigned char>(letter));
}
@@ -312,10 +312,10 @@ RFC1751::wsrch(std::string const& strWord, int iMin, int iMax)
while (iResult < 0 && iMin != iMax)
{
// Have a range to search.
int iMid = iMin + (iMax - iMin) / 2;
int iMid = iMin + ((iMax - iMin) / 2);
int iDir = strWord.compare(s_dictionary[iMid]);
if (!iDir)
if (iDir == 0)
{
iResult = iMid; // Found it.
}

View File

@@ -152,7 +152,7 @@ public:
#ifndef NDEBUG
// Make sure we haven't already seen this tag.
auto& tags = stack_.top().tags;
check(tags.find(tag) == tags.end(), "Already seen tag " + tag);
check(!tags.contains(tag), "Already seen tag " + tag);
tags.insert(tag);
#endif

View File

@@ -296,7 +296,7 @@ Reader::match(Location pattern, int patternLength)
int index = patternLength;
while (index--)
while ((index--) != 0)
{
if (current_[index] != pattern[index])
return false;
@@ -362,7 +362,7 @@ Reader::readNumber()
while (current_ != end_)
{
if (!std::isdigit(static_cast<unsigned char>(*current_)))
if (std::isdigit(static_cast<unsigned char>(*current_)) == 0)
{
auto ret =
std::find(std::begin(extended_tokens), std::end(extended_tokens), *current_);
@@ -913,7 +913,7 @@ Reader::getFormattedErrorMessages() const
formattedMessage += "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
formattedMessage += " " + error.message_ + "\n";
if (error.extra_)
if (error.extra_ != nullptr)
formattedMessage += "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
}

View File

@@ -40,10 +40,10 @@ public:
// return 0;
if (length == unknown)
length = value ? (unsigned int)strlen(value) : 0;
length = (value != nullptr) ? (unsigned int)strlen(value) : 0;
char* newString = static_cast<char*>(malloc(length + 1));
if (value)
if (value != nullptr)
memcpy(newString, value, length);
newString[length] = 0;
return newString;
@@ -52,7 +52,7 @@ public:
void
releaseStringValue(char* value) override
{
if (value)
if (value != nullptr)
free(value);
}
};
@@ -108,14 +108,14 @@ Value::CZString::CZString(CZString const& other)
Value::CZString::~CZString()
{
if (cstr_ && index_ == duplicate)
if ((cstr_ != nullptr) && index_ == duplicate)
valueAllocator()->releaseMemberName(const_cast<char*>(cstr_));
}
bool
Value::CZString::operator<(CZString const& other) const
{
if (cstr_ && other.cstr_)
if ((cstr_ != nullptr) && (other.cstr_ != nullptr))
return strcmp(cstr_, other.cstr_) < 0;
return index_ < other.index_;
@@ -124,7 +124,7 @@ Value::CZString::operator<(CZString const& other) const
bool
Value::CZString::operator==(CZString const& other) const
{
if (cstr_ && other.cstr_)
if ((cstr_ != nullptr) && (other.cstr_ != nullptr))
return strcmp(cstr_, other.cstr_) == 0;
return index_ == other.index_;
@@ -251,7 +251,7 @@ Value::Value(Value const& other) : type_(other.type_)
break;
case stringValue:
if (other.value_.string_)
if (other.value_.string_ != nullptr)
{
value_.string_ = valueAllocator()->duplicateStringValue(other.value_.string_);
allocated_ = true;
@@ -294,7 +294,7 @@ Value::~Value()
case arrayValue:
case objectValue:
if (value_.map_)
if (value_.map_ != nullptr)
delete value_.map_;
break;
@@ -392,11 +392,11 @@ operator<(Value const& x, Value const& y)
return x.value_.real_ < y.value_.real_;
case booleanValue:
return x.value_.bool_ < y.value_.bool_;
return static_cast<int>(x.value_.bool_) < static_cast<int>(y.value_.bool_);
case stringValue:
return (x.value_.string_ == 0 && y.value_.string_) ||
(y.value_.string_ && x.value_.string_ &&
return (x.value_.string_ == 0 && (y.value_.string_ != nullptr)) ||
((y.value_.string_ != nullptr) && (x.value_.string_ != nullptr) &&
strcmp(x.value_.string_, y.value_.string_) < 0);
case arrayValue:
@@ -413,7 +413,7 @@ operator<(Value const& x, Value const& y)
// LCOV_EXCL_STOP
}
return 0; // unreachable
return false; // unreachable
}
bool
@@ -422,9 +422,9 @@ operator==(Value const& x, Value const& y)
if (x.type_ != y.type_)
{
if (x.type_ == intValue && y.type_ == uintValue)
return !integerCmp(x.value_.int_, y.value_.uint_);
return integerCmp(x.value_.int_, y.value_.uint_) == 0;
if (x.type_ == uintValue && y.type_ == intValue)
return !integerCmp(y.value_.int_, x.value_.uint_);
return integerCmp(y.value_.int_, x.value_.uint_) == 0;
return false;
}
@@ -447,8 +447,8 @@ operator==(Value const& x, Value const& y)
case stringValue:
return x.value_.string_ == y.value_.string_ ||
(y.value_.string_ && x.value_.string_ &&
!strcmp(x.value_.string_, y.value_.string_));
((y.value_.string_ != nullptr) && (x.value_.string_ != nullptr) &&
(strcmp(x.value_.string_, y.value_.string_) == 0));
case arrayValue:
case objectValue:
@@ -461,7 +461,7 @@ operator==(Value const& x, Value const& y)
// LCOV_EXCL_STOP
}
return 0; // unreachable
return false; // unreachable
}
char const*
@@ -480,7 +480,7 @@ Value::asString() const
return "";
case stringValue:
return value_.string_ ? value_.string_ : "";
return (value_.string_ != nullptr) ? value_.string_ : "";
case booleanValue:
return value_.bool_ ? "true" : "false";
@@ -525,7 +525,7 @@ Value::asInt() const
case realValue:
JSON_ASSERT_MESSAGE(
value_.real_ >= minInt && value_.real_ <= maxInt,
(value_.real_ >= minInt && value_.real_ <= maxInt),
"Real out of signed integer range");
return Int(value_.real_);
@@ -533,7 +533,7 @@ Value::asInt() const
return value_.bool_ ? 1 : 0;
case stringValue: {
char const* const str{value_.string_ ? value_.string_ : ""};
char const* const str{(value_.string_ != nullptr) ? value_.string_ : ""};
return beast::lexicalCastThrow<int>(str);
}
@@ -584,7 +584,7 @@ Value::asAbsUInt() const
return value_.bool_ ? 1 : 0;
case stringValue: {
char const* const str{value_.string_ ? value_.string_ : ""};
char const* const str{(value_.string_ != nullptr) ? value_.string_ : ""};
auto const temp = beast::lexicalCastThrow<std::int64_t>(str);
if (temp < 0)
{
@@ -626,14 +626,15 @@ Value::asUInt() const
case realValue:
JSON_ASSERT_MESSAGE(
value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range");
(value_.real_ >= 0 && value_.real_ <= maxUInt),
"Real out of unsigned integer range");
return UInt(value_.real_);
case booleanValue:
return value_.bool_ ? 1 : 0;
case stringValue: {
char const* const str{value_.string_ ? value_.string_ : ""};
char const* const str{(value_.string_ != nullptr) ? value_.string_ : ""};
return beast::lexicalCastThrow<unsigned int>(str);
}
@@ -703,7 +704,7 @@ Value::asBool() const
return value_.bool_;
case stringValue:
return value_.string_ && value_.string_[0] != 0;
return (value_.string_ != nullptr) && value_.string_[0] != 0;
case arrayValue:
case objectValue:
@@ -745,13 +746,13 @@ Value::isConvertibleTo(ValueType other) const
other == realValue || other == stringValue || other == booleanValue;
case booleanValue:
return (other == nullValue && value_.bool_ == false) || other == intValue ||
return (other == nullValue && !value_.bool_) || other == intValue ||
other == uintValue || other == realValue || other == stringValue ||
other == booleanValue;
case stringValue:
return other == stringValue ||
(other == nullValue && (!value_.string_ || value_.string_[0] == 0));
(other == nullValue && ((value_.string_ == nullptr) || value_.string_[0] == 0));
case arrayValue:
return other == arrayValue || (other == nullValue && value_.map_->empty());
@@ -813,10 +814,10 @@ operator bool() const
if (isString())
{
auto s = asCString();
return s && s[0];
return (s != nullptr) && (s[0] != 0);
}
return !(isArray() || isObject()) || size();
return !(isArray() || isObject()) || (size() != 0u);
}
void
@@ -1139,7 +1140,7 @@ Value::begin() const
{
case arrayValue:
case objectValue:
if (value_.map_)
if (value_.map_ != nullptr)
return const_iterator(value_.map_->begin());
break;
@@ -1157,7 +1158,7 @@ Value::end() const
{
case arrayValue:
case objectValue:
if (value_.map_)
if (value_.map_ != nullptr)
return const_iterator(value_.map_->end());
break;
@@ -1175,7 +1176,7 @@ Value::begin()
{
case arrayValue:
case objectValue:
if (value_.map_)
if (value_.map_ != nullptr)
return iterator(value_.map_->begin());
break;
default:
@@ -1192,7 +1193,7 @@ Value::end()
{
case arrayValue:
case objectValue:
if (value_.map_)
if (value_.map_ != nullptr)
return iterator(value_.map_->end());
break;
default:

View File

@@ -89,7 +89,7 @@ ValueIteratorBase::key() const
{
Value::CZString const czString = (*current_).first;
if (czString.c_str())
if (czString.c_str() != nullptr)
{
if (czString.isStaticString())
return Value(StaticString(czString.c_str()));
@@ -105,7 +105,7 @@ ValueIteratorBase::index() const
{
Value::CZString const czString = (*current_).first;
if (!czString.c_str())
if (czString.c_str() == nullptr)
return czString.index();
return Value::UInt(-1);
@@ -115,7 +115,7 @@ char const*
ValueIteratorBase::memberName() const
{
char const* name = (*current_).first.c_str();
return name ? name : "";
return (name != nullptr) ? name : "";
}
// //////////////////////////////////////////////////////////////////

View File

@@ -23,7 +23,7 @@ isControlCharacter(char ch)
static bool
containsControlCharacter(char const* str)
{
while (*str)
while (*str != 0)
{
if (isControlCharacter(*(str++)))
return true;
@@ -106,7 +106,7 @@ valueToQuotedString(char const* value)
// We have to walk value and escape any special characters.
// Appending to std::string is not efficient, but this should be rare.
// (Note: forward slashes are *not* rare, but I am not escaping them.)
unsigned maxsize = strlen(value) * 2 + 3; // all-escaped+quotes+NULL
unsigned maxsize = (strlen(value) * 2) + 3; // all-escaped+quotes+NULL
std::string result;
result.reserve(maxsize); // to avoid lots of mallocs
result += "\"";
@@ -416,7 +416,7 @@ StyledWriter::isMultilineArray(Value const& value)
{
childValues_.reserve(size);
addChildValues_ = true;
int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
int lineLength = 4 + ((size - 1) * 2); // '[ ' + ', '*n + ' ]'
for (int index = 0; index < size; ++index)
{
@@ -651,7 +651,7 @@ StyledStreamWriter::isMultilineArray(Value const& value)
{
childValues_.reserve(size);
addChildValues_ = true;
int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
int lineLength = 4 + ((size - 1) * 2); // '[ ' + ', '*n + ' ]'
for (int index = 0; index < size; ++index)
{

View File

@@ -275,9 +275,7 @@ ApplyStateTable::exists(ReadView const& base, Keylet const& k) const
case Action::modify:
break;
}
if (!k.check(*sle))
return false;
return true;
return k.check(*sle);
}
auto

View File

@@ -36,7 +36,7 @@ findPreviousPage(ApplyView& view, Keylet const& directory, SLE::ref start)
auto node = start;
if (page)
if (page != 0u)
{
node = view.peek(keylet::page(directory, page));
if (!node)

View File

@@ -1,4 +1,4 @@
#include <xrpld/app/misc/CanonicalTXSet.h>
#include <xrpl/ledger/CanonicalTXSet.h>
namespace xrpl {

View File

@@ -1,19 +1,9 @@
#include <xrpld/app/ledger/InboundLedgers.h>
#include <xrpld/app/ledger/Ledger.h>
#include <xrpld/app/ledger/LedgerToJson.h>
#include <xrpld/app/ledger/PendingSaves.h>
#include <xrpld/app/main/Application.h>
#include <xrpld/consensus/LedgerTiming.h>
#include <xrpld/core/Config.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/core/HashRouter.h>
#include <xrpl/core/JobQueue.h>
#include <xrpl/json/to_string.h>
#include <xrpl/nodestore/Database.h>
#include <xrpl/nodestore/detail/DatabaseNodeImp.h>
#include <xrpl/ledger/Ledger.h>
#include <xrpl/ledger/LedgerTiming.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/HashPrefix.h>
#include <xrpl/protocol/Indexes.h>
@@ -21,7 +11,6 @@
#include <xrpl/protocol/SecretKey.h>
#include <xrpl/protocol/digest.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/rdb/RelationalDatabase.h>
#include <utility>
#include <vector>
@@ -30,23 +19,6 @@ namespace xrpl {
create_genesis_t const create_genesis{};
uint256
calculateLedgerHash(LedgerHeader const& info)
{
// VFALCO This has to match addRaw in View.h.
return sha512Half(
HashPrefix::ledgerMaster,
std::uint32_t(info.seq),
std::uint64_t(info.drops.drops()),
info.parentHash,
info.txHash,
info.accountHash,
std::uint32_t(info.parentCloseTime.time_since_epoch().count()),
std::uint32_t(info.closeTime.time_since_epoch().count()),
std::uint8_t(info.closeTimeResolution.count()),
std::uint8_t(info.closeFlags));
}
//------------------------------------------------------------------------------
class Ledger::sles_iter_impl : public sles_type::iter_base
@@ -108,8 +80,7 @@ public:
txs_iter_impl(txs_iter_impl const&) = default;
txs_iter_impl(bool metadata, SHAMap::const_iterator iter)
: metadata_(metadata), iter_(std::move(iter))
txs_iter_impl(bool metadata, SHAMap::const_iterator iter) : metadata_(metadata), iter_(iter)
{
}
@@ -138,8 +109,8 @@ public:
{
auto const& item = *iter_;
if (metadata_)
return deserializeTxPlusMeta(item);
return {deserializeTx(item), nullptr};
return Ledger::deserializeTxPlusMeta(item);
return {Ledger::deserializeTx(item), nullptr};
}
};
@@ -147,13 +118,15 @@ public:
Ledger::Ledger(
create_genesis_t,
Config const& config,
Rules const& rules,
Fees const& fees,
std::vector<uint256> const& amendments,
Family& family)
: mImmutable(false)
, txMap_(SHAMapType::TRANSACTION, family)
, stateMap_(SHAMapType::STATE, family)
, rules_{config.features}
, fees_(fees)
, rules_(rules)
, j_(beast::Journal(beast::Journal::getNullSink()))
{
header_.seq = 1;
@@ -182,19 +155,19 @@ Ledger::Ledger(
// Whether featureXRPFees is supported will depend on startup options.
if (std::find(amendments.begin(), amendments.end(), featureXRPFees) != amendments.end())
{
sle->at(sfBaseFeeDrops) = config.FEES.reference_fee;
sle->at(sfReserveBaseDrops) = config.FEES.account_reserve;
sle->at(sfReserveIncrementDrops) = config.FEES.owner_reserve;
sle->at(sfBaseFeeDrops) = fees.base;
sle->at(sfReserveBaseDrops) = fees.reserve;
sle->at(sfReserveIncrementDrops) = fees.increment;
}
else
{
if (auto const f = config.FEES.reference_fee.dropsAs<std::uint64_t>())
if (auto const f = fees.base.dropsAs<std::uint64_t>())
sle->at(sfBaseFee) = *f;
if (auto const f = config.FEES.account_reserve.dropsAs<std::uint32_t>())
if (auto const f = fees.reserve.dropsAs<std::uint32_t>())
sle->at(sfReserveBase) = *f;
if (auto const f = config.FEES.owner_reserve.dropsAs<std::uint32_t>())
if (auto const f = fees.increment.dropsAs<std::uint32_t>())
sle->at(sfReserveIncrement) = *f;
sle->at(sfReferenceFeeUnits) = Config::FEE_UNITS_DEPRECATED;
sle->at(sfReferenceFeeUnits) = FEE_UNITS_DEPRECATED;
}
rawInsert(sle);
}
@@ -207,13 +180,15 @@ Ledger::Ledger(
LedgerHeader const& info,
bool& loaded,
bool acquire,
Config const& config,
Rules const& rules,
Fees const& fees,
Family& family,
beast::Journal j)
: mImmutable(true)
, txMap_(SHAMapType::TRANSACTION, info.txHash, family)
, stateMap_(SHAMapType::STATE, info.accountHash, family)
, rules_(config.features)
, fees_(fees)
, rules_(rules)
, header_(info)
, j_(j)
{
@@ -235,7 +210,6 @@ Ledger::Ledger(
txMap_.setImmutable();
stateMap_.setImmutable();
defaultFees(config);
if (!setup())
loaded = false;
@@ -275,11 +249,11 @@ Ledger::Ledger(Ledger const& prevLedger, NetClock::time_point closeTime)
}
}
Ledger::Ledger(LedgerHeader const& info, Config const& config, Family& family)
Ledger::Ledger(LedgerHeader const& info, Rules const& rules, Family& family)
: mImmutable(true)
, txMap_(SHAMapType::TRANSACTION, info.txHash, family)
, stateMap_(SHAMapType::STATE, info.accountHash, family)
, rules_{config.features}
, rules_(rules)
, header_(info)
, j_(beast::Journal(beast::Journal::getNullSink()))
{
@@ -289,18 +263,19 @@ Ledger::Ledger(LedgerHeader const& info, Config const& config, Family& family)
Ledger::Ledger(
std::uint32_t ledgerSeq,
NetClock::time_point closeTime,
Config const& config,
Rules const& rules,
Fees const& fees,
Family& family)
: mImmutable(false)
, txMap_(SHAMapType::TRANSACTION, family)
, stateMap_(SHAMapType::STATE, family)
, rules_{config.features}
, fees_(fees)
, rules_(rules)
, j_(beast::Journal(beast::Journal::getNullSink()))
{
header_.seq = ledgerSeq;
header_.closeTime = closeTime;
header_.closeTimeResolution = ledgerDefaultTimeResolution;
defaultFees(config);
setup();
}
@@ -350,14 +325,14 @@ Ledger::addSLE(SLE const& sle)
//------------------------------------------------------------------------------
std::shared_ptr<STTx const>
deserializeTx(SHAMapItem const& item)
Ledger::deserializeTx(SHAMapItem const& item)
{
SerialIter sit(item.slice());
return std::make_shared<STTx const>(sit);
}
std::pair<std::shared_ptr<STTx const>, std::shared_ptr<STObject const>>
deserializeTxPlusMeta(SHAMapItem const& item)
Ledger::deserializeTxPlusMeta(SHAMapItem const& item)
{
std::pair<std::shared_ptr<STTx const>, std::shared_ptr<STObject const>> result;
SerialIter sit(item.slice());
@@ -636,20 +611,6 @@ Ledger::setup()
return ret;
}
void
Ledger::defaultFees(Config const& config)
{
XRPL_ASSERT(
fees_.base == 0 && fees_.reserve == 0 && fees_.increment == 0,
"xrpl::Ledger::defaultFees : zero fees");
if (fees_.base == 0)
fees_.base = config.FEES.reference_fee;
if (fees_.reserve == 0)
fees_.reserve = config.FEES.account_reserve;
if (fees_.increment == 0)
fees_.increment = config.FEES.owner_reserve;
}
std::shared_ptr<SLE>
Ledger::peek(Keylet const& k) const
{
@@ -732,7 +693,7 @@ Ledger::updateNegativeUNL()
if (sle->isFieldPresent(sfDisabledValidators))
{
auto const& oldNUnl = sle->getFieldArray(sfDisabledValidators);
for (auto v : oldNUnl)
for (auto const& v : oldNUnl)
{
if (hasToReEnable && v.isFieldPresent(sfPublicKey) &&
v.getFieldVL(sfPublicKey) == sle->getFieldVL(sfValidatorToReEnable))
@@ -816,27 +777,17 @@ Ledger::walkLedger(beast::Journal j, bool parallel) const
}
bool
Ledger::assertSensible(beast::Journal ledgerJ) const
Ledger::isSensible() const
{
if (header_.hash.isNonZero() && header_.accountHash.isNonZero() &&
(header_.accountHash == stateMap_.getHash().as_uint256()) &&
(header_.txHash == txMap_.getHash().as_uint256()))
{
return true;
}
// LCOV_EXCL_START
Json::Value j = getJson({*this, {}});
j[jss::accountTreeHash] = to_string(header_.accountHash);
j[jss::transTreeHash] = to_string(header_.txHash);
JLOG(ledgerJ.fatal()) << "ledger is not sensible" << j;
UNREACHABLE("xrpl::Ledger::assertSensible : ledger is not sensible");
return false;
// LCOV_EXCL_STOP
if (header_.hash.isZero())
return false;
if (header_.accountHash.isZero())
return false;
if (header_.accountHash != stateMap_.getHash().as_uint256())
return false;
if (header_.txHash != txMap_.getHash().as_uint256())
return false;
return true;
}
// update the skip list with the information from our previous ledger
@@ -925,76 +876,6 @@ Ledger::isVotingLedger() const
return ::xrpl::isVotingLedger(header_.seq + 1);
}
static bool
saveValidatedLedger(Application& app, std::shared_ptr<Ledger const> const& ledger, bool current)
{
auto j = app.journal("Ledger");
auto seq = ledger->header().seq;
if (!app.pendingSaves().startWork(seq))
{
// The save was completed synchronously
JLOG(j.debug()) << "Save aborted";
return true;
}
auto& db = app.getRelationalDatabase();
auto const res = db.saveValidatedLedger(ledger, current);
// Clients can now trust the database for
// information about this ledger sequence.
app.pendingSaves().finishWork(seq);
return res;
}
/** Save, or arrange to save, a fully-validated ledger
Returns false on error
*/
bool
pendSaveValidated(
Application& app,
std::shared_ptr<Ledger const> const& ledger,
bool isSynchronous,
bool isCurrent)
{
if (!app.getHashRouter().setFlags(ledger->header().hash, HashRouterFlags::SAVED))
{
// We have tried to save this ledger recently
auto stream = app.journal("Ledger").debug();
JLOG(stream) << "Double pend save for " << ledger->header().seq;
if (!isSynchronous || !app.pendingSaves().pending(ledger->header().seq))
{
// Either we don't need it to be finished
// or it is finished
return true;
}
}
XRPL_ASSERT(ledger->isImmutable(), "xrpl::pendSaveValidated : immutable ledger");
if (!app.pendingSaves().shouldWork(ledger->header().seq, isSynchronous))
{
auto stream = app.journal("Ledger").debug();
JLOG(stream) << "Pend save with seq in pending saves " << ledger->header().seq;
return true;
}
// See if we can use the JobQueue.
if (!isSynchronous &&
app.getJobQueue().addJob(
isCurrent ? jtPUBLEDGER : jtPUBOLDLEDGER,
std::to_string(ledger->seq()),
[&app, ledger, isCurrent]() { saveValidatedLedger(app, ledger, isCurrent); }))
{
return true;
}
// The JobQueue won't do the Job. Do the save synchronously.
return saveValidatedLedger(app, ledger, isCurrent);
}
void
Ledger::unshare() const
{
@@ -1008,84 +889,5 @@ Ledger::invariants() const
stateMap_.invariants();
txMap_.invariants();
}
//------------------------------------------------------------------------------
/*
* Make ledger using info loaded from database.
*
* @param LedgerHeader: Ledger information.
* @param app: Link to the Application.
* @param acquire: Acquire the ledger if not found locally.
* @return Shared pointer to the ledger.
*/
std::shared_ptr<Ledger>
loadLedgerHelper(LedgerHeader const& info, Application& app, bool acquire)
{
bool loaded = false;
auto ledger = std::make_shared<Ledger>(
info, loaded, acquire, app.config(), app.getNodeFamily(), app.journal("Ledger"));
if (!loaded)
ledger.reset();
return ledger;
}
static void
finishLoadByIndexOrHash(
std::shared_ptr<Ledger> const& ledger,
Config const& config,
beast::Journal j)
{
if (!ledger)
return;
XRPL_ASSERT(
ledger->header().seq < XRP_LEDGER_EARLIEST_FEES || ledger->read(keylet::fees()),
"xrpl::finishLoadByIndexOrHash : valid ledger fees");
ledger->setImmutable();
JLOG(j.trace()) << "Loaded ledger: " << to_string(ledger->header().hash);
ledger->setFull();
}
std::tuple<std::shared_ptr<Ledger>, std::uint32_t, uint256>
getLatestLedger(Application& app)
{
std::optional<LedgerHeader> const info = app.getRelationalDatabase().getNewestLedgerInfo();
if (!info)
return {std::shared_ptr<Ledger>(), {}, {}};
return {loadLedgerHelper(*info, app, true), info->seq, info->hash};
}
std::shared_ptr<Ledger>
loadByIndex(std::uint32_t ledgerIndex, Application& app, bool acquire)
{
if (std::optional<LedgerHeader> info =
app.getRelationalDatabase().getLedgerInfoByIndex(ledgerIndex))
{
std::shared_ptr<Ledger> ledger = loadLedgerHelper(*info, app, acquire);
finishLoadByIndexOrHash(ledger, app.config(), app.journal("Ledger"));
return ledger;
}
return {};
}
std::shared_ptr<Ledger>
loadByHash(uint256 const& ledgerHash, Application& app, bool acquire)
{
if (std::optional<LedgerHeader> info =
app.getRelationalDatabase().getLedgerInfoByHash(ledgerHash))
{
std::shared_ptr<Ledger> ledger = loadLedgerHelper(*info, app, acquire);
finishLoadByIndexOrHash(ledger, app.config(), app.journal("Ledger"));
XRPL_ASSERT(
!ledger || ledger->header().hash == ledgerHash,
"xrpl::loadByHash : ledger hash match if loaded");
return ledger;
}
return {};
}
} // namespace xrpl

View File

@@ -164,7 +164,7 @@ PaymentSandbox::balanceHook(
auto delta = amount.zeroed();
auto lastBal = amount;
auto minBal = amount;
for (auto curSB = this; curSB; curSB = curSB->ps_)
for (auto curSB = this; curSB != nullptr; curSB = curSB->ps_)
{
if (auto adj = curSB->tab_.adjustments(account, issuer, currency))
{
@@ -198,7 +198,7 @@ std::uint32_t
PaymentSandbox::ownerCountHook(AccountID const& account, std::uint32_t count) const
{
std::uint32_t result = count;
for (auto curSB = this; curSB; curSB = curSB->ps_)
for (auto curSB = this; curSB != nullptr; curSB = curSB->ps_)
{
if (auto adj = curSB->tab_.ownerCount(account))
result = std::max(result, *adj);

View File

@@ -433,8 +433,7 @@ doWithdraw(
j) < amount)
{
// LCOV_EXCL_START
JLOG(j.error()) << "LoanBrokerCoverWithdraw: negative balance of "
"broker cover assets.";
JLOG(j.error()) << "doWithdraw: negative balance of broker cover assets.";
return tefINTERNAL;
// LCOV_EXCL_STOP
}

View File

@@ -78,7 +78,7 @@ deleteSLE(ApplyView& view, std::shared_ptr<SLE> const& sleCredential, beast::Jou
auto const issuer = sleCredential->getAccountID(sfIssuer);
auto const subject = sleCredential->getAccountID(sfSubject);
bool const accepted = sleCredential->getFlags() & lsfAccepted;
bool const accepted = (sleCredential->getFlags() & lsfAccepted) != 0u;
auto err = delSLE(issuer, sfIssuerNode, !accepted || (subject == issuer));
if (!isTesSuccess(err))
@@ -147,7 +147,7 @@ valid(STTx const& tx, ReadView const& view, AccountID const& src, beast::Journal
return tecBAD_CREDENTIALS;
}
if (!(sleCred->getFlags() & lsfAccepted))
if ((sleCred->getFlags() & lsfAccepted) == 0u)
{
JLOG(j.trace()) << "Credential isn't accepted. Cred: " << h;
return tecBAD_CREDENTIALS;
@@ -188,7 +188,7 @@ validDomain(ReadView const& view, uint256 domainID, AccountID const& subject)
foundExpired = true;
continue;
}
if (sleCredential->getFlags() & lsfAccepted)
if ((sleCredential->getFlags() & lsfAccepted) != 0u)
{
return tesSUCCESS;
}
@@ -309,7 +309,7 @@ verifyValidDomain(ApplyView& view, AccountID const& account, uint256 domainID, b
if (!sleCredential)
continue; // expired, i.e. deleted in credentials::removeExpired
if (sleCredential->getFlags() & lsfAccepted)
if ((sleCredential->getFlags() & lsfAccepted) != 0u)
return tesSUCCESS;
}
@@ -336,7 +336,7 @@ verifyDepositPreauth(
if (credentialsPresent && credentials::removeExpired(view, tx.getFieldV256(sfCredentialIDs), j))
return tecEXPIRED;
if (sleDst && (sleDst->getFlags() & lsfDepositAuth))
if (sleDst && ((sleDst->getFlags() & lsfDepositAuth) != 0u))
{
if (src != dst)
{

View File

@@ -69,7 +69,7 @@ forEachItem(
for (auto const& key : sle->getFieldV256(sfIndexes))
f(view.read(keylet::child(key)));
auto const next = sle->getFieldU64(sfIndexNext);
if (!next)
if (next == 0u)
return;
pos = keylet::page(root, next);
}

View File

@@ -1,6 +1,7 @@
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
//
#include <xrpl/basics/Log.h>
#include <xrpl/ledger/View.h>
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
#include <xrpl/ledger/helpers/CredentialHelpers.h>
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
@@ -12,21 +13,6 @@
namespace xrpl {
// Forward declarations for functions that remain in View.h/cpp
bool
isVaultPseudoAccountFrozen(
ReadView const& view,
AccountID const& account,
MPTIssue const& mptShare,
int depth);
[[nodiscard]] TER
dirLink(
ApplyView& view,
AccountID const& owner,
std::shared_ptr<SLE>& object,
SF_UINT64 const& node = sfOwnerNode);
bool
isGlobalFrozen(ReadView const& view, MPTIssue const& mptIssue)
{
@@ -83,7 +69,7 @@ transferRate(ReadView const& view, MPTID const& issuanceID)
// which represents 50% of 1,000,000,000
if (auto const sle = view.read(keylet::mptIssuance(issuanceID));
sle && sle->isFieldPresent(sfTransferFee))
return Rate{1'000'000'000u + 10'000 * sle->getFieldU16(sfTransferFee)};
return Rate{1'000'000'000u + (10'000 * sle->getFieldU16(sfTransferFee))};
return parityRate;
}
@@ -149,7 +135,7 @@ authorizeMPToken(
// When a holder wants to unauthorize/delete a MPT, the ledger must
// - delete mptokenKey from owner directory
// - delete the MPToken
if (flags & tfMPTUnauthorize)
if ((flags & tfMPTUnauthorize) != 0)
{
auto const mptokenKey = keylet::mptoken(mptIssuanceID, account);
auto const sleMpt = view.peek(mptokenKey);
@@ -229,7 +215,7 @@ authorizeMPToken(
// Issuer wants to unauthorize the holder, unset lsfMPTAuthorized on
// their MPToken
if (flags & tfMPTUnauthorize)
if ((flags & tfMPTUnauthorize) != 0)
{
flagsOut &= ~lsfMPTAuthorized;
}
@@ -490,7 +476,7 @@ canTransfer(
if (!sleIssuance)
return tecOBJECT_NOT_FOUND;
if (!(sleIssuance->getFieldU32(sfFlags) & lsfMPTCanTransfer))
if (!sleIssuance->isFlag(lsfMPTCanTransfer))
{
if (from != (*sleIssuance)[sfIssuer] && to != (*sleIssuance)[sfIssuer])
return TER{tecNO_AUTH};

View File

@@ -224,10 +224,10 @@ trustCreate(
bSetHigh ? sfLowLimit : sfHighLimit,
STAmount(Issue{saBalance.getCurrency(), bSetDst ? uSrcAccountID : uDstAccountID}));
if (uQualityIn)
if (uQualityIn != 0u)
sleRippleState->setFieldU32(bSetHigh ? sfHighQualityIn : sfLowQualityIn, uQualityIn);
if (uQualityOut)
if (uQualityOut != 0u)
sleRippleState->setFieldU32(bSetHigh ? sfHighQualityOut : sfLowQualityOut, uQualityOut);
std::uint32_t uFlags = bSetHigh ? lsfHighReserve : lsfLowReserve;
@@ -327,16 +327,16 @@ updateTrustLine(
// Sender balance was positive.
&& after <= beast::zero
// Sender is zero or negative.
&& (flags & (!bSenderHigh ? lsfLowReserve : lsfHighReserve))
&& ((flags & (!bSenderHigh ? lsfLowReserve : lsfHighReserve)) != 0u)
// Sender reserve is set.
&& static_cast<bool>(flags & (!bSenderHigh ? lsfLowNoRipple : lsfHighNoRipple)) !=
static_cast<bool>(sle->getFlags() & lsfDefaultRipple) &&
!(flags & (!bSenderHigh ? lsfLowFreeze : lsfHighFreeze)) &&
((flags & (!bSenderHigh ? lsfLowFreeze : lsfHighFreeze)) == 0u) &&
!state->getFieldAmount(!bSenderHigh ? sfLowLimit : sfHighLimit)
// Sender trust limit is 0.
&& !state->getFieldU32(!bSenderHigh ? sfLowQualityIn : sfHighQualityIn)
&& (state->getFieldU32(!bSenderHigh ? sfLowQualityIn : sfHighQualityIn) == 0u)
// Sender quality in is 0.
&& !state->getFieldU32(!bSenderHigh ? sfLowQualityOut : sfHighQualityOut))
&& (state->getFieldU32(!bSenderHigh ? sfLowQualityOut : sfHighQualityOut) == 0u))
// Sender quality out is 0.
{
// VFALCO Where is the line being deleted?
@@ -348,7 +348,7 @@ updateTrustLine(
// Balance is zero, receiver reserve is clear.
if (!after // Balance is zero.
&& !(flags & (bSenderHigh ? lsfLowReserve : lsfHighReserve)))
&& ((flags & (bSenderHigh ? lsfLowReserve : lsfHighReserve)) == 0u))
return true;
}
return false;
@@ -539,11 +539,12 @@ requireAuth(ReadView const& view, Issue const& issue, AccountID const& account,
// If this is a weak or legacy check, or if the account has a line, fail if
// auth is required and not set on the line
if (auto const issuerAccount = view.read(keylet::account(issue.account));
issuerAccount && (*issuerAccount)[sfFlags] & lsfRequireAuth)
issuerAccount && (((*issuerAccount)[sfFlags] & lsfRequireAuth) != 0u))
{
if (trustLine)
{
return ((*trustLine)[sfFlags] & ((account > issue.account) ? lsfLowAuth : lsfHighAuth))
return (((*trustLine)[sfFlags] &
((account > issue.account) ? lsfLowAuth : lsfHighAuth)) != 0u)
? tesSUCCESS
: TER{tecNO_AUTH};
}
@@ -575,7 +576,7 @@ canTransfer(ReadView const& view, Issue const& issue, AccountID const& from, Acc
bool const issuerHigh = issuerId > account;
return line->isFlag(issuerHigh ? lsfHighNoRipple : lsfLowNoRipple);
}
return sleIssuer->isFlag(lsfDefaultRipple) == false;
return !sleIssuer->isFlag(lsfDefaultRipple);
};
// Fail if rippling disabled on both trust lines
@@ -748,7 +749,7 @@ deleteAMMTrustLine(
}
auto const uFlags = !ammLow ? lsfLowReserve : lsfHighReserve;
if (!(sleState->getFlags() & uFlags))
if ((sleState->getFlags() & uFlags) == 0u)
return tecINTERNAL; // LCOV_EXCL_LINE
adjustOwnerCount(view, !ammLow ? sleLow : sleHigh, -1, j);

View File

@@ -161,7 +161,7 @@ getLineIfUsable(
FreezeHandling zeroIfFrozen,
beast::Journal j)
{
auto const sle = view.read(keylet::line(account, issuer, currency));
auto sle = view.read(keylet::line(account, issuer, currency));
if (!sle)
{
@@ -570,17 +570,18 @@ rippleCreditIOU(
// Sender balance was positive.
&& saBalance <= beast::zero
// Sender is zero or negative.
&& (uFlags & (!bSenderHigh ? lsfLowReserve : lsfHighReserve))
&& ((uFlags & (!bSenderHigh ? lsfLowReserve : lsfHighReserve)) != 0u)
// Sender reserve is set.
&& static_cast<bool>(uFlags & (!bSenderHigh ? lsfLowNoRipple : lsfHighNoRipple)) !=
static_cast<bool>(
view.read(keylet::account(uSenderID))->getFlags() & lsfDefaultRipple) &&
!(uFlags & (!bSenderHigh ? lsfLowFreeze : lsfHighFreeze)) &&
((uFlags & (!bSenderHigh ? lsfLowFreeze : lsfHighFreeze)) == 0u) &&
!sleRippleState->getFieldAmount(!bSenderHigh ? sfLowLimit : sfHighLimit)
// Sender trust limit is 0.
&& !sleRippleState->getFieldU32(!bSenderHigh ? sfLowQualityIn : sfHighQualityIn)
&& (sleRippleState->getFieldU32(!bSenderHigh ? sfLowQualityIn : sfHighQualityIn) == 0u)
// Sender quality in is 0.
&& !sleRippleState->getFieldU32(!bSenderHigh ? sfLowQualityOut : sfHighQualityOut))
&&
(sleRippleState->getFieldU32(!bSenderHigh ? sfLowQualityOut : sfHighQualityOut) == 0u))
// Sender quality out is 0.
{
// Clear the reserve of the sender, possibly delete the line!
@@ -592,7 +593,7 @@ rippleCreditIOU(
// Balance is zero, receiver reserve is clear.
bDelete = !saBalance // Balance is zero.
&& !(uFlags & (bSenderHigh ? lsfLowReserve : lsfHighReserve));
&& ((uFlags & (bSenderHigh ? lsfLowReserve : lsfHighReserve)) == 0u);
// Receiver reserve is clear.
}

View File

@@ -92,7 +92,7 @@ sharesToAssetsWithdraw(
std::shared_ptr<SLE const> const& issuance,
STAmount const& shares)
{
XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsDeposit : non-negative shares");
XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsWithdraw : non-negative shares");
XRPL_ASSERT(
shares.asset() == vault->at(sfShareMPTID),
"xrpl::sharesToAssetsWithdraw : shares and vault match");

View File

@@ -59,6 +59,7 @@ public:
//--------------------------------------------------------------------------
void
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
makeGet(std::string const& strPath, boost::asio::streambuf& sb, std::string const& strHost)
{
std::ostream osRequest(&sb);

View File

@@ -55,7 +55,7 @@ ManagerImp::make_Backend(
missing_backend();
auto factory{find(type)};
if (!factory)
if (factory == nullptr)
{
missing_backend();
}

View File

@@ -213,7 +213,7 @@ public:
rocksdb::DB* db = nullptr;
m_options.create_if_missing = createIfMissing;
rocksdb::Status status = rocksdb::DB::Open(m_options, m_name, &db);
if (!status.ok() || !db)
if (!status.ok() || (db == nullptr))
{
Throw<std::runtime_error>(
std::string("Unable to open/create RocksDB: ") + status.ToString());

View File

@@ -113,7 +113,7 @@ encodeSoftwareVersion(std::string_view versionStr)
{
std::uint8_t x = 0;
for (auto id : v.preReleaseIdentifiers)
for (auto const& id : v.preReleaseIdentifiers)
{
auto parsePreRelease = [](std::string_view identifier,
std::string_view prefix,
@@ -140,7 +140,7 @@ encodeSoftwareVersion(std::string_view versionStr)
if (x == 0)
x = parsePreRelease(id, "b", 0x40, 0, 63);
if (x & 0xC0)
if ((x & 0xC0) != 0)
{
c |= static_cast<std::uint64_t>(x) << 16;
break;

View File

@@ -205,9 +205,7 @@ make_error(error_code_i code, std::string const& message)
bool
contains_error(Json::Value const& json)
{
if (json.isObject() && json.isMember(jss::error))
return true;
return false;
return json.isObject() && json.isMember(jss::error);
}
int

View File

@@ -209,7 +209,7 @@ FeatureCollections::getRegisteredFeature(std::string const& name) const
XRPL_ASSERT(
readOnly.load(), "xrpl::FeatureCollections::getRegisteredFeature : startup completed");
Feature const* feature = getByName(name);
if (feature)
if (feature != nullptr)
return feature->feature;
return std::nullopt;
}
@@ -229,7 +229,7 @@ FeatureCollections::registerFeature(std::string const& name, Supported support,
support == Supported::yes || vote == VoteBehavior::DefaultNo,
"Invalid feature parameters. Must be supported to be up-voted.");
Feature const* i = getByName(name);
if (!i)
if (i == nullptr)
{
check(features.size() < detail::numFeatures, "More features defined than allocated.");
@@ -283,7 +283,7 @@ FeatureCollections::featureToBitsetIndex(uint256 const& f) const
readOnly.load(), "xrpl::FeatureCollections::featureToBitsetIndex : startup completed");
Feature const* feature = getByFeature(f);
if (!feature)
if (feature == nullptr)
LogicError("Invalid Feature ID");
return getIndex(*feature);
@@ -303,7 +303,7 @@ FeatureCollections::featureToName(uint256 const& f) const
{
XRPL_ASSERT(readOnly.load(), "xrpl::FeatureCollections::featureToName : startup completed");
Feature const* feature = getByFeature(f);
return feature ? feature->name : to_string(f);
return (feature != nullptr) ? feature->name : to_string(f);
}
FeatureCollections featureCollections;

View File

@@ -186,7 +186,7 @@ mulRatio(IOUAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundU
{
using namespace boost::multiprecision;
if (!den)
if (den == 0u)
Throw<std::runtime_error>("division by zero");
// A vector with the value 10^index for indexes from 0 to 29

View File

@@ -172,7 +172,7 @@ SOTemplate const*
InnerObjectFormats::findSOTemplateBySField(SField const& sField) const
{
auto itemPtr = findByType(sField.getCode());
if (itemPtr)
if (itemPtr != nullptr)
return &(itemPtr->getSOTemplate());
return nullptr;

View File

@@ -1,7 +1,9 @@
#include <xrpl/basics/Slice.h>
#include <xrpl/basics/chrono.h>
#include <xrpl/protocol/HashPrefix.h>
#include <xrpl/protocol/LedgerHeader.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/digest.h>
namespace xrpl {
@@ -51,4 +53,21 @@ deserializePrefixedHeader(Slice data, bool hasHash)
return deserializeHeader(data + 4, hasHash);
}
uint256
calculateLedgerHash(LedgerHeader const& info)
{
// VFALCO This has to match addRaw in View.h.
return sha512Half(
HashPrefix::ledgerMaster,
std::uint32_t(info.seq),
std::uint64_t(info.drops.drops()),
info.parentHash,
info.txHash,
info.accountHash,
std::uint32_t(info.parentCloseTime.time_since_epoch().count()),
std::uint32_t(info.closeTime.time_since_epoch().count()),
std::uint8_t(info.closeTimeResolution.count()),
std::uint8_t(info.closeFlags));
}
} // namespace xrpl

View File

@@ -24,7 +24,7 @@ canHaveNFTokenOfferID(
return false;
TxType const tt = serializedTx->getTxnType();
if (!(tt == ttNFTOKEN_MINT && serializedTx->isFieldPresent(sfAmount)) &&
if ((tt != ttNFTOKEN_MINT || !serializedTx->isFieldPresent(sfAmount)) &&
tt != ttNFTOKEN_CREATE_OFFER)
return false;

View File

@@ -176,13 +176,13 @@ Permission::isDelegable(std::uint32_t const& permissionValue, Rules const& rules
}
uint32_t
Permission::txToPermissionType(TxType const& type) const
Permission::txToPermissionType(TxType const& type)
{
return static_cast<uint32_t>(type) + 1;
}
TxType
Permission::permissionToTxType(uint32_t const& value) const
Permission::permissionToTxType(uint32_t const& value)
{
return static_cast<TxType>(value - 1);
}

View File

@@ -75,7 +75,7 @@ static std::string
sliceToHex(Slice const& slice)
{
std::string s;
if (slice[0] & 0x80)
if ((slice[0] & 0x80) != 0)
{
s.reserve(2 * (slice.size() + 2));
s = "0x00";

View File

@@ -84,7 +84,7 @@ bool
STAccount::isEquivalent(STBase const& t) const
{
auto const* const tPtr = dynamic_cast<STAccount const*>(&t);
return tPtr && (default_ == tPtr->default_) && (value_ == tPtr->value_);
return (tPtr != nullptr) && (default_ == tPtr->default_) && (value_ == tPtr->value_);
}
bool

View File

@@ -152,7 +152,7 @@ STAmount::STAmount(SerialIter& sit, SField const& name) : STBase(name)
value &= ~(1023ull << (64 - 10));
if (value)
if (value != 0u)
{
bool isNegative = (offset & 256) == 0;
offset = (offset & 255) - 97; // center the range
@@ -505,14 +505,11 @@ canAdd(STAmount const& a, STAmount const& b)
XRPAmount A = a.xrp();
XRPAmount B = b.xrp();
if ((B > XRPAmount{0} &&
return !(
(B > XRPAmount{0} &&
A > XRPAmount{std::numeric_limits<XRPAmount::value_type>::max()} - B) ||
(B < XRPAmount{0} &&
A < XRPAmount{std::numeric_limits<XRPAmount::value_type>::min()} - B))
{
return false;
}
return true;
A < XRPAmount{std::numeric_limits<XRPAmount::value_type>::min()} - B));
}
// IOU case (precision check)
@@ -530,15 +527,11 @@ canAdd(STAmount const& a, STAmount const& b)
{
MPTAmount A = a.mpt();
MPTAmount B = b.mpt();
if ((B > MPTAmount{0} &&
return !(
(B > MPTAmount{0} &&
A > MPTAmount{std::numeric_limits<MPTAmount::value_type>::max()} - B) ||
(B < MPTAmount{0} &&
A < MPTAmount{std::numeric_limits<MPTAmount::value_type>::min()} - B))
{
return false;
}
return true;
A < MPTAmount{std::numeric_limits<MPTAmount::value_type>::min()} - B));
}
// LCOV_EXCL_START
UNREACHABLE("STAmount::canAdd : unexpected STAmount type");
@@ -803,7 +796,7 @@ bool
STAmount::isEquivalent(STBase const& t) const
{
STAmount const* v = dynamic_cast<STAmount const*>(&t);
return v && (*v == *this);
return (v != nullptr) && (*v == *this);
}
bool

View File

@@ -53,7 +53,7 @@ bool
STBlob::isEquivalent(STBase const& t) const
{
STBlob const* v = dynamic_cast<STBlob const*>(&t);
return v && (value_ == v->value_);
return (v != nullptr) && (value_ == v->value_);
}
bool

View File

@@ -56,7 +56,7 @@ bool
STCurrency::isEquivalent(STBase const& t) const
{
STCurrency const* v = dynamic_cast<STCurrency const*>(&t);
return v && (*v == *this);
return (v != nullptr) && (*v == *this);
}
bool

View File

@@ -110,7 +110,7 @@ bool
STIssue::isEquivalent(STBase const& t) const
{
STIssue const* v = dynamic_cast<STIssue const*>(&t);
return v && (*v == *this);
return (v != nullptr) && (*v == *this);
}
bool

View File

@@ -136,7 +136,7 @@ STLedgerEntry::isThreadedType(Rules const& rules) const
// Exclude PrevTxnID/PrevTxnLgrSeq if the fixPreviousTxnID amendment is not
// enabled and the ledger object type is in the above set
bool const excludePrevTxnID = !rules.enabled(fixPreviousTxnID) &&
std::count(newPreviousTxnIDTypes.cbegin(), newPreviousTxnIDTypes.cend(), type_);
(std::count(newPreviousTxnIDTypes.cbegin(), newPreviousTxnIDTypes.cend(), type_) != 0);
return !excludePrevTxnID && getFieldIndex(sfPreviousTxnID) != -1;
}

View File

@@ -204,7 +204,7 @@ void
STObject::applyTemplateFromSField(SField const& sField)
{
SOTemplate const* elements = InnerObjectFormats::getInstance().findSOTemplateBySField(sField);
if (elements)
if (elements != nullptr)
applyTemplate(*elements); // May throw
}
@@ -276,7 +276,7 @@ STObject::hasMatchingEntry(STBase const& t) const
{
STBase const* o = peekAtPField(t.getFName());
if (!o)
if (o == nullptr)
return false;
return t == *o;
@@ -343,7 +343,7 @@ STObject::isEquivalent(STBase const& t) const
{
STObject const* v = dynamic_cast<STObject const*>(&t);
if (!v)
if (v == nullptr)
return false;
if (mType != nullptr && v->mType == mType)
@@ -480,7 +480,7 @@ STObject::setFlag(std::uint32_t f)
{
STUInt32* t = dynamic_cast<STUInt32*>(getPField(sfFlags, true));
if (!t)
if (t == nullptr)
return false;
t->setValue(t->value() | f);
@@ -492,7 +492,7 @@ STObject::clearFlag(std::uint32_t f)
{
STUInt32* t = dynamic_cast<STUInt32*>(getPField(sfFlags));
if (!t)
if (t == nullptr)
return false;
t->setValue(t->value() & ~f);
@@ -510,7 +510,7 @@ STObject::getFlags(void) const
{
STUInt32 const* t = dynamic_cast<STUInt32 const*>(peekAtPField(sfFlags));
if (!t)
if (t == nullptr)
return 0;
return t->value();
@@ -574,7 +574,7 @@ STObject::delField(int index)
SOEStyle
STObject::getStyle(SField const& field) const
{
return mType ? mType->style(field) : soeINVALID;
return (mType != nullptr) ? mType->style(field) : soeINVALID;
}
unsigned char
@@ -877,10 +877,7 @@ STObject::operator==(STObject const& obj) const
++fields;
}
if (fields != matches)
return false;
return true;
return fields == matches;
}
void
@@ -917,7 +914,8 @@ STObject::getSortedFields(STObject const& objToSort, WhichFields whichFields)
for (detail::STVar const& elem : objToSort.v_)
{
STBase const& base = elem.get();
if ((base.getSType() != STI_NOTPRESENT) && base.getFName().shouldInclude(whichFields))
if ((base.getSType() != STI_NOTPRESENT) &&
base.getFName().shouldInclude(static_cast<bool>(whichFields)))
{
sf.push_back(&base);
}

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