Skip to content

refactor: Start making ledger helpers type-safe, beginning with AccountRoot#6620

Open
mvadari wants to merge 46 commits intodevelopfrom
mvadari/rearch/account
Open

refactor: Start making ledger helpers type-safe, beginning with AccountRoot#6620
mvadari wants to merge 46 commits intodevelopfrom
mvadari/rearch/account

Conversation

@mvadari
Copy link
Copy Markdown
Collaborator

@mvadari mvadari commented Mar 23, 2026

High Level Overview of Change

This PR marks the beginning of a process to make SLEs and SLE helpers more type-safe. The original proposal is here. The general idea is each ledger entry will have a read-only and a write-access version of the class. Getter functions will be on the read-only version, and modifier functions will be on the writable version.

This PR begins with implementing base read and write classes, and also implements and migrates AccountRoot to the type-safe architecture. To keep PRs small and easy to review, ~each ledger entry will have its own implementation/migration PR.

There is no functionality change in this PR, only pure refactoring.

Note for reviewers: I recommend enabling "Hide whitespace" when looking at the diff for this PR in the Github UI.

Context of Change

There is a README added as a part of this PR

API Impact

N/A

Test Plan

Tests were not modified at all, and still pass.

@mvadari mvadari requested review from Tapanito, a1q123456, godexsoft and ximinez and removed request for Tapanito and a1q123456 March 23, 2026 16:28
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 23, 2026

Codecov Report

❌ Patch coverage is 97.05357% with 33 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.6%. Comparing base (56c9d1d) to head (ea3ca12).

Files with missing lines Patch % Lines
.../libxrpl/tx/transactors/lending/LendingHelpers.cpp 66.7% 8 Missing ⚠️
include/xrpl/ledger/helpers/AccountRootHelpers.h 65.0% 7 Missing ⚠️
include/xrpl/ledger/helpers/SLEBase.h 91.8% 5 Missing ⚠️
src/xrpld/rpc/handlers/account/AccountInfo.cpp 68.8% 5 Missing ⚠️
include/xrpl/ledger/helpers/EscrowHelpers.h 83.3% 2 Missing ⚠️
src/libxrpl/ledger/helpers/RippleStateHelpers.cpp 95.3% 2 Missing ⚠️
src/libxrpl/ledger/helpers/TokenHelpers.cpp 97.3% 1 Missing ⚠️
...c/libxrpl/tx/transactors/account/AccountDelete.cpp 95.5% 1 Missing ⚠️
src/libxrpl/tx/transactors/account/AccountSet.cpp 96.6% 1 Missing ⚠️
src/libxrpl/tx/transactors/dex/AMMClawback.cpp 87.5% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##           develop   #6620     +/-   ##
=========================================
- Coverage     81.6%   81.6%   -0.0%     
=========================================
  Files         1010    1011      +1     
  Lines        75982   76090    +108     
  Branches      7633    7640      +7     
=========================================
+ Hits         61983   62071     +88     
- Misses       13999   14019     +20     
Files with missing lines Coverage Δ
include/xrpl/ledger/View.h 100.0% <ø> (ø)
include/xrpl/ledger/helpers/RippleStateHelpers.h 100.0% <ø> (ø)
include/xrpl/tx/Transactor.h 100.0% <ø> (ø)
include/xrpl/tx/paths/detail/StepChecks.h 100.0% <100.0%> (ø)
...clude/xrpl/tx/transactors/lending/LendingHelpers.h 95.2% <ø> (ø)
src/libxrpl/ledger/View.cpp 96.6% <100.0%> (ø)
src/libxrpl/ledger/helpers/AMMHelpers.cpp 95.3% <100.0%> (ø)
src/libxrpl/ledger/helpers/AccountRootHelpers.cpp 96.0% <100.0%> (+0.9%) ⬆️
src/libxrpl/ledger/helpers/CredentialHelpers.cpp 97.6% <100.0%> (ø)
src/libxrpl/ledger/helpers/MPTokenHelpers.cpp 96.1% <100.0%> (ø)
... and 88 more

... and 3 files with indirect coverage changes

Impacted file tree graph

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mvadari
Copy link
Copy Markdown
Collaborator Author

mvadari commented Mar 23, 2026

/ai-review

* Inherits from AccountRoot to reuse read-only methods,
* and adds write capabilities.
*/
class WritableAccountRoot : public AccountRoot, public WritableSLE
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this multi-inheritance is a good practice.

AccountRoot is a ReadOnlySLE, so we're effectively doing

class WritableAccouontRoot : public ReadOnlySLE, public WritableSLE
{};

Because both WritableSLE and ReadOnlySLE hold a shared_ptr, each WritableAccountRoot will hold two shared_ptr instances.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@a1q123456 how do you propose to address this? Note, having a single class responsible for both reading and writing is not an option, as it invites making mistakes.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please take a look at the latest version - I think I've resolved this issue while still separating read and write considerations.

Comment thread include/xrpl/ledger/helpers/SLEBase.h Outdated
* Derived classes should provide domain-specific accessors that hide
* implementation details of the underlying ledger entry format.
*/
class WritableSLE
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think WritableSLE provides functionalities interacting with the ledger itself, like removing, inserting, updating, etc, which doesn't fully align with the name WritableSLE.

I suggest making it a template class and we use the CRTP pattern.

template <typename T>
class SLEEditor : T
{};

This approach provides 2 benefits:

  1. The name SLEEditor aligns better with what the class is doing
  2. We don't have to use multiple inheritance at all. If you want to get the sle pointer, you get it from the base class

Comment thread include/xrpl/ledger/helpers/SLEBase.h Outdated
@github-actions

This comment was marked as resolved.

@github-actions

This comment was marked as resolved.

@github-actions

This comment was marked as resolved.

@github-actions

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor

@xrplf-ai-reviewer xrplf-ai-reviewer bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues.

Review by Claude Opus 4.6 · Prompt: V14

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 103 out of 103 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 102 to 107
if (!ctx.view.rules().enabled(featureMPTokensV2))
{
// If AllowTrustLineClawback is not set or NoFreeze is set, return no
// permission
if (((issuerFlagsIn & lsfAllowTrustLineClawback) == 0u) ||
((issuerFlagsIn & lsfNoFreeze) != 0u))
if (!acctIssuer->isFlag(lsfAllowTrustLineClawback) || !acctIssuer->isFlag(lsfNoFreeze))
return tesSUCCESS;
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In preclaim, the lsfNoFreeze check appears inverted vs the prior logic and the comment directly above it. The old code early-returned when NoFreeze is set; the refactor now early-returns when NoFreeze is not set (!acctIssuer->isFlag(lsfNoFreeze)), which changes clawback permission behavior. Update the condition to preserve the original (NoFreeze != 0u) semantics (and align with the comment).

Copilot uses AI. Check for mistakes.
Comment on lines 25 to 30
* @details
* Populates the provided JSON value with the description of the specified
* ledger entry. If the entry is an account root and contains an email hash,
* adds a 'urlgravatar' field with the corresponding Gravatar URL.
* If the entry is not an account root, sets the 'Invalid' field to true.
*/
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docblock for injectSLE still says: "If the entry is not an account root, sets the 'Invalid' field to true." After changing the signature to RAccountRoot const&, the function can no longer be called with a non-account-root entry and it no longer sets jss::Invalid. Please update the comment (or reintroduce equivalent handling if you still need to represent invalid/non-account-root entries).

Copilot uses AI. Check for mistakes.
Comment on lines +21 to +24
**`SLEBase<ReadView>`** (aliased as `ReadOnlySLE`) holds a `std::shared_ptr<SLE const>` and a `ReadView const&`. Write-only members are excluded at compile time.

**`SLEBase<ApplyView>`** (aliased as `WritableSLE`) holds a mutable `std::shared_ptr<SLE>`, an `ApplyView&`, and a `Keylet`. It exposes `insert()`, `update()`, `erase()`, and `newSLE()` to keep the SLE and its view in sync automatically.

Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

README states SLEBase<ReadView>/SLEBase<ApplyView> are aliased as ReadOnlySLE/WritableSLE, and the file table repeats this, but those aliases are not actually declared in SLEBase.h (only mentioned in comments). Either add the aliases (e.g., using ReadOnlySLE = SLEBase<ReadView>; using WritableSLE = SLEBase<ApplyView>;) or adjust the README to match the implementation.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@xrplf-ai-reviewer xrplf-ai-reviewer bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues.

Review by Claude Opus 4.6 · Prompt: V14

@mvadari
Copy link
Copy Markdown
Collaborator Author

mvadari commented Apr 9, 2026

@a1q123456 after this PR is merged I plan on tinkering with how we can add in the autogen classes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants