Skip to content

fix(provenance): stamp last_tx/last_eos_account on objective and action writes - #71

Merged
lucca65 merged 1 commit into
masterfrom
fix/last-tx-provenance
Aug 29, 2026
Merged

fix(provenance): stamp last_tx/last_eos_account on objective and action writes#71
lucca65 merged 1 commit into
masterfrom
fix/last-tx-provenance

Conversation

@lucca65

@lucca65 lucca65 commented Aug 29, 2026

Copy link
Copy Markdown
Member

Paired with cambiatus/backend#434, which adds the two columns. Deploy the backend first — until the columns exist these keys would be rejected on write.

The bug

created_tx / created_eos_account are written once, on the create, and this updater deliberately never rewrites them on an edit — the create-path replay guard keys on created_tx, so rewriting it would make a later replay re-run the create and duplicate the row. That behaviour is unchanged here and should stay.

The side effect landed on the backend. DbListener announces an indexed write on user_tx:<created_eos_account> carrying created_tx, and TxSignerLive confirms only on an exact hash match. For an edit that means:

  • the announcement goes to the original creator's topic — not the member who signed the edit;
  • it carries the original creation hash — which can never equal the edit's hash.

So editing an action someone else created could never confirm. The signer's tracker stalled at 30s even though the chain write had landed. Closing a 2021 MUDA action as a present-day admin hit this every single time, which is how the objective-completion flow could leave an objective reopened while its actions were already closed on chain.

The change

last_tx / last_eos_account carry the writer of the current row version, alongside the untouched create provenance. The replay guard still keys on created_tx and is unaffected.

Stamped on both paths — on a create they simply equal the created_* pair, which keeps the backend's fallback (last_* || created_*) a no-op for new creates and correct for every row written before this ships.

10 lines, one file, both updaters.

Testing

  • node --check passes
  • npx standard src/updaters/community.js reports the same 18 pre-existing findings before and after this diff (none on the added lines)

This repo has no test suite (yarn test exits 1), so the behavioural verification lives on the backend side: test/cambiatus/db_listener_test.exs covers both an edit confirming to its actual signer under the edit's hash, and the fallback to created_* when last_* is null or blank.

🤖 Generated with Claude Code

…on writes

`created_tx` / `created_eos_account` are written once, on the create, and this
updater deliberately never rewrites them on an edit — the create-path replay
guard keys on `created_tx`, so rewriting it would make a later replay re-run the
create and duplicate the row. That stays exactly as it was.

The side effect was on the backend: its DbListener announces an indexed write on
`user_tx:<created_eos_account>` carrying `created_tx`, and TxSignerLive confirms
only on an exact hash match. For an EDIT that meant the announcement went to the
original creator under the original creation hash, so the member who actually
signed the edit could never see their transaction confirm — the tracker stalled
at 30s even though the chain write had landed. Closing a 2021 action as a
different admin hit this every time.

`last_tx` / `last_eos_account` carry the writer of the current row version
alongside the untouched create provenance, so the replay guard is unaffected and
the backend can confirm to whoever signed. Stamped on both paths: on a create
they simply equal the created_* pair.

Needs the backend migration adding the two nullable columns
(cambiatus/backend#434). Deploy the backend first — until the columns exist these
keys would be rejected on write.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@lucca65
lucca65 merged commit 0f88575 into master Aug 29, 2026
2 checks passed
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.

1 participant