Skip to content

Per-handler idempotency review + TaskResult.Output engine extension #174

@bdchatham

Description

@bdchatham

Two follow-ups surfaced during the Coral cross-review of PR #175 (gov-vote handler).

1. Per-handler idempotency review template

PR #175 documents in `gov_vote.go` that the engine's crash-rehydration path is safe specifically because MsgVote is chain-idempotent (last-write-wins on `(proposalID, voter)`). Future sign-tx handlers — MsgSend, MsgWithdrawDelegatorReward, MsgDelegate, etc. — do NOT have chain-side idempotency. Copying the gov-vote pattern blindly would double-spend on crash-after-broadcast.

Action when the next non-idempotent sign-tx handler ships:

  • Persist a "broadcast-attempted, txHash=H" marker to SQLite before calling `BroadcastSync`
  • On rehydration, `QueryTx(H)` first — if found, treat handler as completed; only re-broadcast if the chain has no record
  • Add a per-handler doc comment matching the gov-vote template stating which idempotency guarantee applies

When to do this: when the next sign-tx handler (likely gov-submit-proposal #163-C or a staking task) is proposed — not as a speculative refactor. The pre-broadcast marker has its own failure window (between hash compute and the SQLite write) so it deserves real design.

2. `TaskResult.Output` engine extension

`TaskResult` currently exposes only `Status`/`Error`/timestamps. Sign-tx handlers' structured output (`txHash`, `height`, `sequence`, `inclusionStatus`, etc.) is logged but not returned via the engine's task-result surface. Operators must grep the sidecar logs or chain by memo (`taskID=`) for tx outcome.

Acceptable for MVP because:

  • The chain is the genuine source of truth
  • The memo carries the task UUID for forensic correlation
  • Adding `Output any` is a one-way door: storage schema change, `/tasks/{id}` JSON contract change, every other handler suddenly nullable-output

When to do this: when a second sign-tx handler ships and the demand for structured output is concrete (not speculative). At that point design the `Output` shape against two real consumers rather than over-engineering for one.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions