Skip to content

feat: Add an invariant to ensure object deletion also deletes its pseudo-account#7445

Open
Tapanito wants to merge 8 commits into
developfrom
tapanito/pseudo-invariants
Open

feat: Add an invariant to ensure object deletion also deletes its pseudo-account#7445
Tapanito wants to merge 8 commits into
developfrom
tapanito/pseudo-invariants

Conversation

@Tapanito

@Tapanito Tapanito commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

Overview

Ensures that when a ledger object with an associated pseudo-account (AMM, Vault, LoanBroker) is deleted, its pseudo-account is also deleted.

High Level Overview of Change

The ObjectHasPseudoAccount invariant checks: object deleted → pseudo-account deleted.

Together with the existing AccountRootsDeletedClean invariant (which checks the reverse: pseudo-account deleted → object deleted), these two invariants guarantee that an object and its pseudo-account are always deleted as a pair.

Context of Change

Previously, the only invariant enforcement was one-directional: AccountRootsDeletedClean ensured that deleting a pseudo-account also deleted the linked object (via getPseudoAccountFields()). The reverse direction — deleting the object must also delete the pseudo-account — was only enforced by convention in transactor code.

This PR closes the gap by adding the complementary check.

API Impact

  • Public API: New feature (new methods and/or new fields)
  • Public API: Breaking change (in general, breaking changes should only impact the next api_version)
  • libxrpl change (any change that may affect libxrpl or dependents of libxrpl)
  • Peer protocol change (must be backward compatible or bump the peer protocol version)

@Tapanito Tapanito requested review from a1q123456 and gregtatcam June 10, 2026 13:22

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

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.

Gave this a review

Two correctness issues: implicit fallthrough drops sle_ on match, and the single-pointer field silently ignores all but the last matching object per transaction — see inline comments.


Review by ReviewBot 🤖

Review by Claude Sonnet 4.6 · Prompt: V15

Comment thread src/libxrpl/tx/invariants/InvariantCheck.cpp Outdated
Comment thread include/xrpl/tx/invariants/InvariantCheck.h Outdated
@codecov

codecov Bot commented Jun 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.93939% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.0%. Comparing base (45ddc1d) to head (0eca5a7).

Files with missing lines Patch % Lines
src/libxrpl/tx/invariants/InvariantCheck.cpp 93.9% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##           develop   #7445   +/-   ##
=======================================
  Coverage     82.0%   82.0%           
=======================================
  Files         1009    1009           
  Lines        76782   76815   +33     
  Branches      8939    8938    -1     
=======================================
+ Hits         62975   63007   +32     
- Misses       13798   13799    +1     
  Partials         9       9           
Files with missing lines Coverage Δ
include/xrpl/tx/invariants/InvariantCheck.h 100.0% <ø> (ø)
src/libxrpl/tx/invariants/InvariantCheck.cpp 95.3% <93.9%> (-0.1%) ⬇️

... 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.

Comment thread src/libxrpl/tx/invariants/InvariantCheck.cpp Outdated
Comment thread src/libxrpl/tx/invariants/InvariantCheck.cpp Outdated
@Tapanito Tapanito requested a review from a1q123456 June 10, 2026 15:17

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

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.

No issues.

Review by Claude Sonnet 4.6 · Prompt: V15

@a1q123456 a1q123456 left a comment

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.

lgtm

@gregtatcam gregtatcam 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.

LGTM

@github-actions

Copy link
Copy Markdown

This PR has conflicts, please resolve them in order for the PR to be reviewed.

@github-actions

Copy link
Copy Markdown

All conflicts have been resolved. Assigned reviewers can now start or resume their review.

@Tapanito Tapanito added Ready to merge *PR author* thinks it's ready to merge. Has passed code review. Perf sign-off may still be required. PR: has conflicts and removed PR: has conflicts labels Jun 11, 2026

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

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.

Clean implementation. Ship it!

Review by Claude Sonnet 4.6 · Prompt: V15

Copilot AI left a comment

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.

Pull request overview

This PR introduces a new transaction invariant intended to ensure certain ledger object types (AMM, Vault, LoanBroker) always reference a valid on-ledger pseudo-account, and extends unit tests to cover the new invariant behavior.

Changes:

  • Add a new ObjectHasPseudoAccount invariant that checks sfAccount is present and the referenced account root exists (behind fixCleanup3_3_0).
  • Update invariant wiring (InvariantChecks tuple) to include the new check.
  • Adjust invariant unit tests by setting sfAccount where needed and adding dedicated coverage for missing/nonexistent pseudo-accounts.

Reviewed changes

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

File Description
src/test/app/Invariants_test.cpp Updates Vault test setup to include sfAccount and adds a new invariant test for pseudo-account presence/existence.
src/libxrpl/tx/invariants/InvariantCheck.cpp Implements the ObjectHasPseudoAccount invariant logic and logging.
include/xrpl/tx/invariants/InvariantCheck.h Declares the new invariant and adds it to the public InvariantChecks tuple.

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

Comment thread src/libxrpl/tx/invariants/InvariantCheck.cpp
Comment thread src/libxrpl/tx/invariants/InvariantCheck.cpp Outdated
Comment thread src/libxrpl/tx/invariants/InvariantCheck.cpp Outdated
Comment thread include/xrpl/tx/invariants/InvariantCheck.h
Comment thread include/xrpl/tx/invariants/InvariantCheck.h
@Tapanito Tapanito changed the title feat: Add an invariant to ensure a pseudo-account exists feat: Add an invariant to ensure object deletion also deletes its pseudo-account Jun 12, 2026

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

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.

No issues.

Review by Claude Sonnet 4.6 · Prompt: V15

Change ObjectHasPseudoAccount from checking "object exists →
pseudo-account exists" to "object deleted → pseudo-account deleted".

Together with AccountRootsDeletedClean (which enforces the reverse:
pseudo-account deleted → object deleted), this pair of invariants
guarantees that an object and its pseudo-account are always deleted
as a unit.
@Tapanito Tapanito force-pushed the tapanito/pseudo-invariants branch from 93dfbb5 to 0a8b12c Compare June 12, 2026 10:38
@Tapanito Tapanito requested a review from gregtatcam June 12, 2026 10:39
@Tapanito Tapanito requested a review from a1q123456 June 12, 2026 10:39

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

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.

No issues.

Review by Claude Sonnet 4.6 · Prompt: V15

@Tapanito

Copy link
Copy Markdown
Collaborator Author

@gregtatcam , @a1q123456 the Clanker gave me a way to improve this PR. Instead of enforcing that an object pseudo-account always exist, I changed to to enforce that if an object is deleted, so is it's pseudo-account. We already have an invariant that enforces the inverse (deleted pseudo, dangling object). Together, they ensure that there's always a pseudo-account and an object.

Could you please re-review the PR? 🙏

XRPAmount{},
STTx{ttPAYMENT, [](STObject&) {}},
{tecINVARIANT_FAILED, tecINVARIANT_FAILED},
{tecINVARIANT_FAILED, tefINVARIANT_FAILED},

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.

Note for reviewers, ValidVault::finalize:290 returns true when !isTesSuccess(ret), so it only fires on the first pass. On the second pass (with tecINVARIANT_FAILED as input), ValidVault passes, but now ObjectHasPseudoAccount also fires because it doesn't gate on the result. This causes tefINVARIANT_FAILED on the second pass.

@Tapanito Tapanito removed the Ready to merge *PR author* thinks it's ready to merge. Has passed code review. Perf sign-off may still be required. label Jun 12, 2026

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

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.

LGTM

Review by Claude Sonnet 4.6 · Prompt: V15

@gregtatcam gregtatcam 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.

LGTM

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

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.

No issues.

Review by Claude Sonnet 4.6 · Prompt: V15

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.

4 participants