Skip to content

test(ledger): a soft-dropped ledger reads as absent from exists() - #1739

Closed
aaj3f wants to merge 2 commits into
mainfrom
fix/ledger-exists-retracted-test
Closed

test(ledger): a soft-dropped ledger reads as absent from exists()#1739
aaj3f wants to merge 2 commits into
mainfrom
fix/ledger-exists-retracted-test

Conversation

@aaj3f

@aaj3f aaj3f commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

main's test job has been red since #1716 merged, on a single assertion.

43d758610 made ledger_exists treat a retracted record as not-found on the query path — matching LedgerState::load, so that a dropped ledger can neither load nor serve queries. it_ledger_lifecycle::ledger_exists_on_file_storage:219 still encoded the older contract, that exists answers "is there a record" rather than "is it live":

assert!(
    fluree.ledger_exists("x:main").await.unwrap(),
    "exists() reports the record, which a soft drop keeps",
);

This flips the assertion and rewrites the comment to say why both halves are true at once: the record genuinely survives on a tombstoning nameservice so admin tooling can read the retracted flag, and exists answers false because it's a query-path question. It cites the commit, so the next reader gets the reasoning rather than re-deriving it.

Nothing else in the test changes — the create/commit/unknown-name/malformed-id assertions above it are untouched, and they're the reason the test exists.

Worth knowing this is currently inherited by every open PR whose CI has run since 01:35, since CI merges main into each head. It's the only failure in those runs.

I've written this as the smaller of the two readings — that the test was stale and the change was intended. If the older contract was the right one and exists should keep reporting retracted records, then this should be closed and 43d758610 revisited instead; that's a call for @bplatz rather than me.

One related note: this settles a sub-question of #1670, which is still open and carries the wider delete-semantics decision — init-reclaims versus reject, whether an un-retract path exists, and branch-scoped hard purge. Worth recording there that the exists half is now decided, so whoever picks up the rest doesn't re-derive it and the two don't drift apart, which is what that issue is about in the first place.

43d7586 made ledger_exists treat a retracted record as not-found on the
query path, matching LedgerState::load: a dropped ledger must not load or
serve queries, so it must not report as existing either. The assertion
here still encoded the older contract -- exists() as "is there a record"
-- and has been red on main since that merge.

Updates the assertion and the comment to state the current contract and
why the record still exists on a tombstoning nameservice while exists()
answers false.

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

Approving — merge this quickly, it's unblocking every open PR's CI (I hit it independently on #1727, #1730 and #1736).

Your reading is the right one, and there's a piece of evidence for it that also corrects 43d758610's own message. That commit says "Backends that hide the record outright (file, DynamoDB, memory) never showed this." The file backend does not hide itretract flips status to "retracted" and keeps the file (only purge removes it), and lookup returns the retracted record unfiltered. That's exactly why a file-storage test went red.

Which means the bug #1716 fixed — a dropped ledger still loading and serving queries — was live on the default embedded/CLI backend too, not just raft. So the test was pinning the buggy contract on the very backend where the bug was real. The new assertion is also consistent with list_branches, which already filtered retracted before any of this.

One thing worth adding to #1670, since you're right that it's the place for it — the concrete symptom rather than the abstract question. exists and create now contradict each other after a soft drop, on both backends:

call answer
ledger_exists("x:main") false
create_ledger("x:main") LedgerAlreadyExists
  • raft: retract_ledger inserts into state.retracted but doesn't remove the branch from ledger.branches, and create_ledger rejects on branches.contains(&branch).
  • file: init uses storage.insert (create-if-absent) and the retracted file is still there.

So a user is told the ledger doesn't exist and simultaneously can't create it — reachable from the CLI, not only raft. Live on main today either way, so it's no reason to hold this.

Also: writing this up as the smaller of two readings and naming the call as someone else's was the right way to handle a test that contradicts a deliberate change.

// tombstoning nameservice so admin tooling can read the retracted
// flag, but `exists` is a query-path question: a dropped ledger must
// not load or serve queries, so it must not report as existing
// either. See 43d758610.

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.

Nit: a bare SHA is awkward to chase from a code comment — worth adding "(#1716)" alongside so the next reader gets the discussion, not just the diff.

@aaj3f

aaj3f commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

Closing as superseded — 6b4c211d4 (landed with #1717) fixed this on main directly, and better: same assertion flip, a sharper comment tying the answer to the query-path rationale, plus the follow-on assertion that the record survives the soft drop, which is the half this PR didn't pin and is exactly what distinguishes soft from hard. Main's test job is green again as of b892ac9f9.

Thanks for the review regardless — the file-backend correction ("the file backend does not hide the record; retract flips status and keeps the file") is the piece that explains why a file-storage test was the one that went red, and it's a correction to 43d758610's own commit message worth having on the record. The exists/create contradiction table is captured on #1670 so the design note inherits it.

@aaj3f aaj3f closed this Aug 28, 2026
@aaj3f
aaj3f deleted the fix/ledger-exists-retracted-test branch August 28, 2026 15:00
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