Skip to content
Open
Show file tree
Hide file tree
Changes from 82 commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
659f455
add WrappedSLEBase
mvadari Mar 16, 2026
4157e36
First cut of WrappedAccountRoot
mvadari Mar 16, 2026
a8987cf
fix all the build issues
mvadari Mar 17, 2026
e0f487b
fix more build issues
mvadari Mar 17, 2026
43caa7d
fix remaining build issues
mvadari Mar 17, 2026
e6369c0
minor improvements
mvadari Mar 17, 2026
b5562cc
split up read only and write
mvadari Mar 17, 2026
1cc7424
Add insert/update/erase to WritableSLE
mvadari Mar 18, 2026
1ccd84e
clean up comments
mvadari Mar 18, 2026
c24432f
change . to ->
mvadari Mar 21, 2026
add3d7e
fix more AccountRoot stuff
mvadari Mar 21, 2026
0ffb3e2
fix long tail issues
mvadari Mar 21, 2026
7900fa9
more fixes
mvadari Mar 22, 2026
56c173a
fix account_
mvadari Mar 22, 2026
a423813
fix issues
mvadari Mar 23, 2026
f41c02d
WrappedSLEBase -> SLEBase
mvadari Mar 23, 2026
9b42e17
add readme
mvadari Mar 23, 2026
638477c
fix pre-commit issues
mvadari Mar 23, 2026
deaa23f
cleanup
mvadari Mar 23, 2026
e9c4ed6
establish architecture for creating a new object
mvadari Mar 23, 2026
5b0b1ff
refactor: Replace SLE helper inheritance with view-parameterized temp…
mvadari Mar 24, 2026
c0895c6
fix pre-commit issues
mvadari Mar 24, 2026
dcdc5e1
fix clang-tidy
mvadari Mar 24, 2026
819d3fc
Merge branch 'develop' into mvadari/rearch/account
mvadari Apr 2, 2026
e928781
move Journal to constructor
mvadari Apr 2, 2026
ffd96e3
remove old isPseudoAccount helper
mvadari Apr 2, 2026
fa77338
cleanup
mvadari Apr 2, 2026
5096811
minor cleanups
mvadari Apr 2, 2026
b3829e5
update readme
mvadari Apr 2, 2026
27e9d0d
Merge branch 'develop' into mvadari/rearch/account
mvadari Apr 2, 2026
e2238b1
fix merge issues
mvadari Apr 2, 2026
b0ca6ad
Merge branch 'develop' of https://github.com/XRPLF/rippled into mvada…
mvadari Apr 3, 2026
97629e7
fix clang-tidy issues
mvadari Apr 3, 2026
737d128
fix build issues
mvadari Apr 3, 2026
03863d9
fix clang-tidy issues
mvadari Apr 3, 2026
945b4f7
roll back unrelated changes
mvadari Apr 3, 2026
8269964
fix clang-tidy issues
mvadari Apr 3, 2026
2d64509
Merge branch 'develop' into mvadari/rearch/account
mvadari Apr 7, 2026
9c9281e
Merge branch 'develop' into mvadari/rearch/account
mvadari Apr 8, 2026
683ff84
respond to copilot comments
mvadari Apr 8, 2026
b99a766
respond to human comments
mvadari Apr 8, 2026
be9913f
Merge branch 'develop' into mvadari/rearch/account
mvadari Apr 8, 2026
d616aff
fix tests (typos)
mvadari Apr 9, 2026
c00491b
fix one last typo bug
mvadari Apr 9, 2026
7b27096
Merge branch 'develop' into mvadari/rearch/account
mvadari Apr 9, 2026
ea3ca12
fix clang-tidy
mvadari Apr 9, 2026
3d9eba7
Merge branch 'develop' into mvadari/rearch/account
mvadari Apr 21, 2026
0de37c2
respond to comments
mvadari Apr 21, 2026
dc2430e
fix clang-tidy issues
mvadari Apr 21, 2026
fabf328
fix build (smh clang-tidy)
mvadari Apr 21, 2026
fb37cc2
oops
mvadari Apr 21, 2026
5dbbd9b
is_writable -> isWritable
mvadari Apr 22, 2026
d10bb71
Merge branch 'develop' into mvadari/rearch/account
mvadari Apr 22, 2026
d7b6c8e
Update include/xrpl/ledger/helpers/SLEBase.h
mvadari Apr 22, 2026
3d2e078
fix clang-tidy
mvadari Apr 22, 2026
700cd6a
Merge branch 'develop' into mvadari/rearch/account
mvadari May 4, 2026
cedebd5
fix tests
mvadari May 4, 2026
ffaf510
fix clang-tidy issues
mvadari May 4, 2026
bcd2639
Merge branch 'develop' into mvadari/rearch/account
mvadari May 14, 2026
6cb5842
fix build
mvadari May 14, 2026
7661483
fix clang-tidy issues
mvadari May 14, 2026
554c0ba
fix tests
mvadari May 14, 2026
144835c
fix clang-tidy
mvadari May 14, 2026
1306d35
Merge branch 'develop' into mvadari/rearch/account
mvadari May 15, 2026
9b1406a
Merge branch 'develop' of https://github.com/XRPLF/rippled into mvada…
mvadari May 15, 2026
8c80a6a
Merge branch 'develop' into mvadari/rearch/account
mvadari May 15, 2026
b557403
fix clang-tidy issues
mvadari May 15, 2026
d38f457
clean up (roll back AI weirdness)
mvadari May 15, 2026
fb76e29
fix clang-tidy issues
mvadari May 15, 2026
0ac76df
Update src/xrpld/rpc/detail/PathRequest.cpp
mvadari May 15, 2026
07b3d2d
Merge branch 'develop' of https://github.com/XRPLF/rippled into mvada…
mvadari May 18, 2026
12d8221
Merge branch 'develop' of https://github.com/XRPLF/rippled into mvada…
mvadari May 18, 2026
7add8b3
fix clang-tidy
mvadari May 18, 2026
e5555c5
Merge branch 'develop' of https://github.com/XRPLF/rippled into mvada…
mvadari May 20, 2026
19d1b24
Merge branch 'develop' of https://github.com/XRPLF/rippled into mvada…
mvadari May 27, 2026
1ac402f
fix build
mvadari May 27, 2026
c14fdd7
fix clang-tidy issues
mvadari May 27, 2026
07f3954
fix bug
mvadari May 28, 2026
1015e7c
Merge branch 'develop' into mvadari/rearch/account
mvadari Jun 8, 2026
45a4585
Merge branch 'develop' into mvadari/rearch/account
mvadari Jun 8, 2026
b1f4e61
Merge branch 'develop' into mvadari/rearch/account
mvadari Jun 8, 2026
77120e7
fix clang-tidy issues
mvadari Jun 8, 2026
f4cb0b8
fix build
mvadari Jun 8, 2026
805d12d
fix clang-tidy issues
mvadari Jun 8, 2026
3a5eb97
Merge branch 'develop' of https://github.com/XRPLF/rippled into mvada…
mvadari Jun 11, 2026
7098e49
fix clang-tidy issues
mvadari Jun 11, 2026
052bb02
roll back unrelated clang-tidy changes
mvadari Jun 11, 2026
f91fbc9
clang-tidy broke my build -.-
mvadari Jun 11, 2026
095a588
fix clang-tidy issues
mvadari Jun 11, 2026
a0d2d17
fix merge issues
mvadari Jun 11, 2026
6c7a8ed
Merge branch 'develop' into mvadari/rearch/account
mvadari Jun 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion include/xrpl/ledger/View.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@

namespace xrpl {

// Forward declarations for SLE wrappers
template <typename ViewT>
class AccountRoot;
using RAccountRoot = AccountRoot<ReadView>;

Comment thread
mvadari marked this conversation as resolved.
enum class SkipEntry : bool { No = false, Yes };

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -156,7 +161,7 @@ canWithdraw(
ReadView const& view,
AccountID const& from,
AccountID const& to,
SLE::const_ref toSle,
RAccountRoot const& toWrapped,
STAmount const& amount,
bool hasDestinationTag);

Expand Down
209 changes: 150 additions & 59 deletions include/xrpl/ledger/helpers/AccountRootHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

#include <xrpl/basics/Expected.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/ledger/helpers/SLEBase.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Rate.h>
#include <xrpl/protocol/STLedgerEntry.h>
Expand All @@ -14,42 +16,160 @@

namespace xrpl {

/** Check if the issuer has the global freeze flag set.
@param issuer The account to check
@return true if the account has global freeze set
*/
[[nodiscard]] bool
isGlobalFrozen(ReadView const& view, AccountID const& issuer);

// Calculate liquid XRP balance for an account.
// This function may be used to calculate the amount of XRP that
// the holder is able to freely spend. It subtracts reserve requirements.
//
// ownerCountAdj adjusts the owner count in case the caller calculates
// before ledger entries are added or removed. Positive to add, negative
// to subtract.
//
// @param ownerCountAdj positive to add to count, negative to reduce count.
[[nodiscard]] XRPAmount
xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, beast::Journal j);

/** Adjust the owner count up or down. */
void
adjustOwnerCount(ApplyView& view, SLE::ref sle, std::int32_t amount, beast::Journal j);

/** Returns IOU issuer transfer fee as Rate. Rate specifies
* the fee as fractions of 1 billion. For example, 1% transfer rate
* is represented as 1,010,000,000.
* @param issuer The IOU issuer
/**
* View-parameterized wrapper for AccountRoot ledger entries.
*
* AccountRoot<ReadView> — read-only access to account data
* AccountRoot<ApplyView> — read-write access, with insert/update/erase
* and domain-specific write methods
*/
[[nodiscard]] Rate
transferRate(ReadView const& view, AccountID const& issuer);
template <typename ViewT>
Comment thread
Tapanito marked this conversation as resolved.
class AccountRoot : public SLEBase<ViewT>
Comment thread
Tapanito marked this conversation as resolved.
Comment thread
Tapanito marked this conversation as resolved.
{
static constexpr bool kIsWritable = SLEBase<ViewT>::kIsWritable;

AccountID const id_;

public:
/** Constructor for read-only context */
AccountRoot(
AccountID const& id,
ReadView const& view,
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
requires(!kIsWritable)
: SLEBase<ViewT>(view.read(keylet::account(id)), view, j), id_(id)
{
}

/** Constructor for writable context */
AccountRoot(
AccountID const& id,
ApplyView& view,
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
requires kIsWritable
: SLEBase<ViewT>(keylet::account(id), view, j), id_(id)
{
}

/** Converting constructor: writable → read-only. */
template <WritableView OtherViewT>
AccountRoot(AccountRoot<OtherViewT> const& other)
requires(!kIsWritable)
: SLEBase<ViewT>(other), id_(other.id())
{
}

/** Create an AccountRoot backed by a brand-new SLE.
*/
[[nodiscard]] static AccountRoot
makeNew(

Check warning on line 65 in include/xrpl/ledger/helpers/AccountRootHelpers.h

View check run for this annotation

Codecov / codecov/patch

include/xrpl/ledger/helpers/AccountRootHelpers.h#L65

Added line #L65 was not covered by tests
AccountID const& id,
ApplyView& view,
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
requires kIsWritable
{
return AccountRoot(id, view, j, std::make_shared<SLE>(keylet::account(id)));
}

[[nodiscard]] AccountID const&
id() const
{
return id_;
}

// --- Read-only domain methods (available on both specializations) ---

/** Check if the issuer has the global freeze flag set.
@return true if the account has global freeze set
*/
[[nodiscard]] bool
isGlobalFrozen() const;

/** Returns IOU issuer transfer fee as Rate. Rate specifies
* the fee as fractions of 1 billion. For example, 1% transfer rate
* is represented as 1,010,000,000.
*/
[[nodiscard]] Rate
transferRate() const;

// Calculate liquid XRP balance for an account.
// This function may be used to calculate the amount of XRP that
// the holder is able to freely spend. It subtracts reserve requirements.
//
// ownerCountAdj adjusts the owner count in case the caller calculates
// before ledger entries are added or removed. Positive to add, negative
// to subtract.
//
// @param ownerCountAdj positive to add to count, negative to reduce count.
[[nodiscard]] XRPAmount
xrpLiquid(std::int32_t ownerCountAdj) const;

/** Checks the destination and tag.

- Checks that the SLE is not null.
- If the SLE requires a destination tag, checks that there is a tag.
*/
[[nodiscard]] TER
checkDestinationAndTag(bool hasDestinationTag) const;

/** Returns true if and only if sleAcct is a pseudo-account or specific
pseudo-accounts in pseudoFieldFilter.

Returns false if sleAcct is:
- NOT a pseudo-account OR
- NOT a ltACCOUNT_ROOT OR
- null pointer
*/
[[nodiscard]] bool
isPseudoAccount(std::set<SField const*> const& pseudoFieldFilter = {}) const;

[[nodiscard]] bool
operator==(AccountRoot const& other) const

Check warning on line 127 in include/xrpl/ledger/helpers/AccountRootHelpers.h

View check run for this annotation

Codecov / codecov/patch

include/xrpl/ledger/helpers/AccountRootHelpers.h#L127

Added line #L127 was not covered by tests
{
return id_ == other.id_;

Check warning on line 129 in include/xrpl/ledger/helpers/AccountRootHelpers.h

View check run for this annotation

Codecov / codecov/patch

include/xrpl/ledger/helpers/AccountRootHelpers.h#L129

Added line #L129 was not covered by tests
}

[[nodiscard]] bool
operator==(AccountID const& other) const
{
return id_ == other;
}

// --- Write-only domain methods (compile-time gated) ---

/** Adjust the owner count up or down. */
void
adjustOwnerCount(std::int32_t amount)
requires kIsWritable;

private:
// Private constructor only used by `makeNew`
AccountRoot(AccountID const& id, ApplyView& view, beast::Journal j, std::shared_ptr<SLE> sle)

Check warning on line 147 in include/xrpl/ledger/helpers/AccountRootHelpers.h

View check run for this annotation

Codecov / codecov/patch

include/xrpl/ledger/helpers/AccountRootHelpers.h#L147

Added line #L147 was not covered by tests
requires kIsWritable
: SLEBase<ViewT>(std::move(sle), view, j), id_(id)
{
this->insert();
}
};

// CTAD deduction guide — bare AccountRoot(id, view) always deduces read-only.
// For writable access, use WAccountRoot(id, applyView) explicitly.
Comment on lines +157 to +158
AccountRoot(AccountID const&, ReadView const&) -> AccountRoot<ReadView>;
AccountRoot(AccountID const&, ReadView const&, beast::Journal) -> AccountRoot<ReadView>;

// Backward-compatible aliases
using RAccountRoot = AccountRoot<ReadView>;
using WAccountRoot = AccountRoot<ApplyView>;

Comment thread
mvadari marked this conversation as resolved.
// Explicit instantiation declarations (definitions in .cpp)
extern template class AccountRoot<ReadView>;
extern template class AccountRoot<ApplyView>;

/** Generate a pseudo-account address from a pseudo owner key.
@param pseudoOwnerKey The key to generate the address from
@return The generated account ID
*/
AccountID
[[nodiscard]] AccountID
pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey);

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 a good rule of thumb would be that anything that takes a ReadView should be const? What do you think?

At the same time, since AccountRoot already has a view member, this argument is redundant.

Suggested change
[[nodiscard]] AccountID
pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey) const;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, that's the rule of thumb I've been using as well.


/** Returns the list of fields that define an ACCOUNT_ROOT as a pseudo-account
Expand All @@ -62,27 +182,6 @@
[[nodiscard]] std::vector<SField const*> const&
getPseudoAccountFields();

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.

Suggested change
getPseudoAccountFields() const;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

/Users/mvadari/Documents/rippled-all/rippled/.build/modules/xrpl.libxrpl.ledger/xrpl/ledger/helpers/AccountRootHelpers.h:185:26: error: non-member function cannot have 'const' qualifier
  185 | getPseudoAccountFields() const;


/** Returns true if and only if sleAcct is a pseudo-account or specific
pseudo-accounts in pseudoFieldFilter.

Returns false if sleAcct is:
- NOT a pseudo-account OR
- NOT a ltACCOUNT_ROOT OR
- null pointer
*/
[[nodiscard]] bool
isPseudoAccount(SLE::const_pointer sleAcct, std::set<SField const*> const& pseudoFieldFilter = {});

/** Convenience overload that reads the account from the view. */
[[nodiscard]] inline bool
isPseudoAccount(
ReadView const& view,
AccountID const& accountId,
std::set<SField const*> const& pseudoFieldFilter = {})
{
return isPseudoAccount(view.read(keylet::account(accountId)), pseudoFieldFilter);
}

/**
* Create pseudo-account, storing pseudoOwnerKey into ownerField.
*
Expand All @@ -94,12 +193,4 @@
[[nodiscard]] Expected<SLE::pointer, TER>
createPseudoAccount(ApplyView& view, uint256 const& pseudoOwnerKey, SField const& ownerField);

/** Checks the destination and tag.

- Checks that the SLE is not null.
- If the SLE requires a destination tag, checks that there is a tag.
*/
[[nodiscard]] TER
checkDestinationAndTag(SLE::const_ref toSle, bool hasDestinationTag);

} // namespace xrpl
4 changes: 2 additions & 2 deletions include/xrpl/ledger/helpers/CredentialHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/STArray.h>
#include <xrpl/protocol/STTx.h>
Expand Down Expand Up @@ -69,8 +70,7 @@ verifyDepositPreauth(
STTx const& tx,
ApplyView& view,
AccountID const& src,
AccountID const& dst,
SLE::const_ref sleDst,
RAccountRoot const& dst,
beast::Journal j);

} // namespace xrpl
Loading