Skip to content

Observe LendingProtocolV1_1: principal-only accounting and closed-ended vaults - #91

Merged
manasip-prog merged 5 commits into
mainfrom
manasip/lending-v1_1-accounting
Sep 8, 2026
Merged

manasip-prog merged 5 commits into
mainfrom
manasip/lending-v1_1-accounting

Conversation

@manasip-prog

@manasip-prog manasip-prog commented Aug 26, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Adds workload coverage and observability for LendingProtocolV1_1 (XLS-65/66).

Principal-only accounting

  • Tracks Vault AssetsTotal, AssetsAvailable, and LossUnrealized, plus LoanBroker DebtTotal, in workload::result balance changes.
  • Adds the changed field name to each balance-change row.
  • Reports vault_le_version for results touching a Vault so legacy accrual-basis and V1.1 principal-only vaults remain distinguishable.

Closed-ended vaults

  • Exercises VaultKind, SubscriptionDate, and RedemptionDate on VaultCreate.
  • Exercises optional MemoData on VaultDelete.
  • Tracks vault phase metadata and keeps valid deposit/withdraw paths phase-aware.
  • Adds malformed, expired, invalid-kind, and invalid-memo vectors.

Compatibility

The current xrpl-py main revision does not yet include the V1.1 model fields from xrpl-py PR #1034. lending_v1_1_compat.py temporarily registers the matching codec fields and extends VaultCreate/VaultDelete.

Genesis

Genesis amendment discovery includes both Supported::Yes and Supported::No, matching the workload image's force-enable behavior, while excluding obsolete amendments.

Validation

  • check-imports
  • check-endpoints
  • check-fuzz-coverage
  • check-modifier-coverage
  • check-assembler-roundtrip
  • Ruff lint and format
  • basedpyright on touched Python files
  • focused phase-boundary and amendment-parser checks

Full-project mypy still reports two pre-existing no-any-return errors outside this PR's changes.

RXT-832

@manasip-prog
manasip-prog marked this pull request as ready for review September 2, 2026 17:49
manasip-prog added a commit that referenced this pull request Sep 8, 2026
Two build fixes that already exist on the unmerged #91 branch but not on
`main`. Both are needed for any xrpld ref newer than
`staging/3.3.x-private`, and neither has anything to do with the lending
work they are currently attached to.

**1. `XRPLD_NO_PATCH_NIX_BINARY=1` on the fuzzer's conan install.**
rippled's `cmake/PatchNixBinary.cmake` resolves the loader via
`${CMAKE_SOURCE_DIR}/bin/default-loader-path.sh`, which is absent in
conan's build folder (the recipe's `exports_sources` has no `bin/`), and
`COMMAND_ERROR_IS_FATAL` aborts configure. Observed against `3.4.0-rc2`
on ripple/rippled-antithesis [run
34240477121](https://github.com/ripple/rippled-antithesis/actions/runs/34240477121):

```
CMake Error at cmake/PatchNixBinary.cmake:36 (execute_process)
-- Configuring incomplete, errors occurred!
xrpl/develop: ERROR: Error in build() method, line 185
```

Nothing is lost: that step builds libxrpl (`xrpld=False`), a static
archive with no `PT_INTERP`, and the shipped binaries are patchelf'd
explicitly. Scoped to this step so the xrpld build itself keeps rippled
CI's behaviour.

**2. Rewrite the fuzzer's pre-rename symbols.** XRPLF/rippled#7933 moved
`beast::IP` → `beast::ip` and `xrpl::BuildInfo` → `xrpl::build_info`;
rippled-fuzzer still uses the old spelling. The rewrite is gated on the
cloned xrpld actually carrying the new names, so pre-rename refs build
unchanged.

Both were authored on `manasip/lending-v1_1-accounting` (commits
`8416b05`, `46e55ea`) and are lifted here verbatim so the release-line
move does not depend on that PR landing.

Does not address amendment activation for new Supported::No features —
`generate_genesis.py` still needs the change that remains in #91.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Track the four Vault/LoanBroker fields the amendment moves (AssetsTotal,
AssetsAvailable, LossUnrealized, DebtTotal) and stamp Vault.LEVersion on any
result touching a Vault node, since LEVersion -- not amendment activation --
gates which accounting model a Vault follows and both coexist post-activation.
…-65)

LendingProtocolV1_1 adds VaultKind/SubscriptionDate/RedemptionDate to
VaultCreate and an optional MemoData deletion reason to VaultDelete. The
pinned xrpl-py has neither the model fields nor the codec definitions, so
lending_v1_1_compat registers the field headers into the live binarycodec
maps and subclasses both models. Length and range checks stay server-side
so faulty handlers can still build the out-of-range cases.

The amendment is latched off metadata, not config: a validated Vault's
LEVersion is 1 only once LendingProtocolV1_1 is active, so the V1.1 fields
join only after one has been seen. Pre-amendment they are temDISABLED, which
never validates and would starve the failure bucket.

VaultCreate now mints a minority of closed-ended vaults, so open-ended ones
keep the phase-free deposit/withdraw valid paths stocked. Vault tracks the
kind and both dates from the created node, and deposit/withdraw pick a vault
whose current phase permits the transaction. Faulty vectors cover the
sub-kMinInvestmentPeriod gap, already-expired dates, an out-of-enum
VaultKind, and for VaultDelete an empty and an over-256-byte MemoData
(validDataLength rejects both).

Genesis was activating only Supported::Yes amendments, but Dockerfile.xrpld
rewrites Supported::No to Yes before building, so LendingProtocolV1_1 was
known to the binary yet inactive in the ledger. Genesis now includes those
too, skipping VoteBehavior::Obsolete (enabling one amendment-blocks the
node). Also scopes XRPLD_NO_PATCH_NIX_BINARY to the fuzzer's conan install,
whose build folder lacks the loader script rippled's PatchNixBinary.cmake
expects.

RXT-832
Every XLS-65 path is gated on lending_v1_1_compat.enabled(), which latches off
a validated Vault's LEVersion. If that never flips -- amendment inactive, or a
genesis regression -- the whole feature goes dark while VaultCreate's
success/failure dims stay satisfied off the open-ended vectors, so a run would
report green having exercised none of it.

Five sometimes buckets off tx_result's validated stream: lending_v1_1_active
(the latch itself), vault_closed_ended_created (created node carries a nonzero
VaultKind), vault_deposit_phase_blocked (tecEXPIRED) and
vault_withdraw_phase_blocked (tecTOO_SOON) for the two phase gates, and
vault_delete_reason_used (validated MemoData). All must_hit=False, matching
conf_mpt_version_monotonic: they only fire against an xrpld with
LendingProtocolV1_1 active, so a run without it must not starve.

_fire_sometimes takes must_hit so the fire site can match its catalog entry.

RXT-832
@manasip-prog
manasip-prog force-pushed the manasip/lending-v1_1-accounting branch from 46e55ea to aca0cbb Compare September 8, 2026 17:54

@lmaisons lmaisons left a comment

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.

This mostly looks OK. My main concern is the seeming blanket activation of Supported::No amendments - Normally I would expect the code guarded as such to be underdetermined. I'm willing to merge this for now given it's a blocker, but please create an item to figure out a better strategy for making sure we're not shooting our feet off in the future.

@manasip-prog
manasip-prog merged commit 2b6b170 into main Sep 8, 2026
1 check passed
@manasip-prog
manasip-prog deleted the manasip/lending-v1_1-accounting branch September 8, 2026 19:01
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.

2 participants