Skip to content

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

Merged
bthomee merged 17 commits into
developfrom
tapanito/pseudo-invariants
Jul 1, 2026
Merged

feat: Add an invariant to ensure object deletion also deletes its pseudo-account#7445
bthomee merged 17 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

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.3%. Comparing base (ecf7f80) to head (3c7d214).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##           develop   #7445   +/-   ##
=======================================
  Coverage     82.3%   82.3%           
=======================================
  Files         1024    1024           
  Lines        78397   78423   +26     
  Branches      8973    8973           
=======================================
+ Hits         64514   64545   +31     
+ Misses       13874   13869    -5     
  Partials         9       9           
Files with missing lines Coverage Δ
include/xrpl/tx/invariants/InvariantCheck.h 100.0% <ø> (ø)
src/libxrpl/tx/invariants/InvariantCheck.cpp 95.9% <100.0%> (+0.5%) ⬆️

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

@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

gregtatcam
gregtatcam previously approved these changes Jun 25, 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

@ximinez ximinez self-requested a review June 26, 2026 14:56
@github-actions

Copy link
Copy Markdown

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

ximinez
ximinez previously approved these changes Jun 30, 2026

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

Updates look good. You've got conflicts to resolve, though.

@Tapanito Tapanito dismissed stale reviews from ximinez and gregtatcam via ad6e6e9 June 30, 2026 07:42
@github-actions

Copy link
Copy Markdown

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

@Tapanito Tapanito requested review from a1q123456 and ximinez June 30, 2026 07:43

@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

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

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

Comment thread src/libxrpl/tx/invariants/InvariantCheck.cpp
Comment thread src/test/app/Invariants_test.cpp
@Tapanito Tapanito added the Ready to merge *PR author* thinks it's ready to merge. Has passed code review. Perf sign-off may still be required. label Jul 1, 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

Comment on lines +1092 to +1096
// LCOV_EXCL_START
UNREACHABLE(
"xrpl::ObjectHasPseudoAccount::visitEntry : deleted ledger entry missing before state");
return;
// LCOV_EXCL_STOP

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.

For a follow-up PR, it makes sense to add a new UNREACHABLE_IF macro, just like the XRPL_ASSERT_IF that was added previously.

@bthomee bthomee added this pull request to the merge queue Jul 1, 2026
Merged via the queue into develop with commit ea13be8 Jul 1, 2026
49 checks passed
@bthomee bthomee deleted the tapanito/pseudo-invariants branch July 1, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Ready to merge *PR author* thinks it's ready to merge. Has passed code review. Perf sign-off may still be required.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants