Per-handler idempotency review + TaskResult.Output engine extension

Open
#174 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
30/100
Issue type
Feature
Clarity
Needs clarification
Activity status
Quiet
Tech stack
go, sqlite
Domain
api, backend, databases

Research direction

Start with PR #175 and gov_vote.go to understand the existing crash-rehydration and idempotency guarantees. Review SQLite marker handling around BroadcastSync and QueryTx, then examine TaskResult and the /tasks/{id} contract; this issue is complete only when a future non-idempotent handler or second sign-tx consumer makes the deferred design concrete.

Written by the indexing model from the issue text.

Description

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

  • PR #175 (gov-vote handler)
  • Cross-review session 2026-05-12
Dominant language
Go
Stars
1
Forks
3
Avg merge
2h 56m
Merged PRs (30d)
14

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from sei-protocol/seictl

All issues in sei-protocol/seictl

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.