Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Priority: P1 — ambiguous-outcome class at the TollGate layer. Independent of gonuts fixes.

Open
#498 2 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
30/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active
Tech stack
go
Domain
backend, payments

Research direction

Start with src/merchant/merchant.go:506-538 to trace the Receive timeout and normal session-grant path; then review the proposed payment-saga state names for Rust parity. The issue calls for a durable pending-payment store, late-completion handling, and startup and periodic reconciliation, so first map those existing entry points before choosing an implementation. Done means the late-success and restart-reconciliation acceptance tests pass and /usage reflects a granted session.

Written by the indexing model from the issue text.

Description

Priority: P1 — ambiguous-outcome class at the TollGate layer. Independent of gonuts fixes.

Problem

PurchaseSession wraps Receive in a 30s timeout, but the goroutine keeps running. When Receive completes after the timeout response was sent: funds land in the operator wallet, no session is granted, no record exists, and the customer was told "timed out, try again" — so they pay again. Duplicate value consumed for one session; every timeout has this tail risk.

Why it matters

Timeouts are routine (mobile-network mints). The current code converts each one into a potential silent confiscation with a lying error message. Same family as #403 but via the timeout path, and invisible in logs beyond a Receive-completed line nobody correlates.

Current behavior (source refs)

  • src/merchant/merchant.go:506-538 — goroutine + select timeout; on timeout the notice returns immediately, goroutine abandoned.
  • src/merchant/merchant.go:519-529 — late result (success or error) is logged and dropped.
  • No pending-payment record anywhere (sessions are created only post-timeout-window).

Desired invariant

No Receive outcome is discarded: a late success is reconciled into a granted session (or refund) durably; a late failure clears the pending record; the customer-visible timeout message states that the payment may still complete and how to check (GET /usage).

Proposed scope

  1. Durable pending-payment record keyed by token Ys hash, written before launching Receive (this is also the idempotency key — coordinate with the payment-saga design for Rust parity, Rust issues #5/#6).
  2. Late-completion handler: on late success → same grant path as normal completion (session + gate + record COMPLETE); on late failure → record FAILED.
  3. Startup + periodic reconciliation: records in RECEIVE state older than timeout → query mint proof state (NUT-07) → resolve.
  4. Timeout notice copy updated to reflect "may complete; check usage" (wire-compatible text change only).

Areas / files

src/merchant/merchant.go, new small store (JSONL or bbolt sub-bucket; flash-aware), startup reconciliation in merchant init.

Acceptance criteria

  • Fault test: Receive completes at t=35s, timeout returned at t=30s → session granted at t=35s, /usage reflects it, record COMPLETE.
  • Kill between receive-start and completion → restart reconciliation resolves by mint state.

Required tests

  • Unit: late-completion grant path; reconciliation decision table.
  • Integration (cloud-lab): slow-mint proxy lane.

Failure-injection tests

  • Proxy delays swap response 35s (payment completes late).
  • Proxy drops response entirely; mint did consume inputs (mint-side state says spent) → reconciliation grants session.

Compatibility

Notice text change only.

Dependencies

Conceptually pairs with the Rust payment-saga issue (Amperstrand/tollgate-module-basic-rust#5) — implement to the same state names for test parity.

Out of scope

  • Refund issuance on late success + unreachable client (session grant suffices; refund policy lives in #403's resolution).
Dominant language
Go
Stars
12
Forks
14
Avg merge
1d 5h
Merged PRs (30d)
246

Getting set up

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 OpenTollGate/tollgate-module-basic-go

All issues in OpenTollGate/tollgate-module-basic-go

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.