Skip to content

fix(tsp): say why an inbound frame was not claimed as a reply - #136

Merged
stormer78 merged 1 commit into
mainfrom
fix/tsp-claim-diagnostics
Aug 29, 2026
Merged

fix(tsp): say why an inbound frame was not claimed as a reply#136
stormer78 merged 1 commit into
mainfrom
fix/tsp-claim-diagnostics

Conversation

@stormer78

Copy link
Copy Markdown
Contributor

Silence was the bug I could actually prove

The claim predicate from #134 returned false for every failure mode without recording any of them. On a shared socket that is right in principle — a frame from another peer is not this request's problem — but it made the one case that is a problem indistinguishable from silence.

When the VTA's own reply gets declined, the request waits out its full timeout and reports timed out awaiting reply frame, with no record that a frame arrived at all, let alone why it was rejected. Four completely different faults — unpack failure, unexpected sender, unparseable payload, a threadId that doesn't thread — all present identically, and each needs a different fix.

That is a regression in diagnosability against the code this replaced, which threw a typed error naming the sender mismatch or the parse failure. The predicate is the only thing in the path that knows; if it doesn't report, by construction nothing downstream can.

What changed

It records the reason for the most recent decline and attaches it to the error the caller sees when the wait ends:

tsp: timed out awaiting reply frame — last inbound frame declined:
threadId "urn:uuid:…" != request id "urn:uuid:…" (reply type "…", reply id "…")

The threadId case names both values plus the reply's own type and id, because a mismatch is only actionable if you can see what it was compared against.

The frame is still declined in exactly the same cases. Only the silence is removed — the predicate logic is unchanged, byte for byte.

Field note

This was written to diagnose a live failure: vault entries would not load over TSP after a fresh enrolment, with nothing in the logs but a 30s timeout. The wallet worked with preferTsp off, which narrowed it to the TSP path but no further.

On the build with these diagnostics, TSP works — so the predicate is not inherently broken, and the earlier failure looks transient. The leading explanation is the pre-0.7.0 backlog of never-acked TSP frames draining on first connect after the upgrade; see the follow-up note in the linked discussion about serial inbound processing starving an in-flight reply. That hypothesis is unproven precisely because there was no decline line to read at the time — which is the argument for this change.

463 core tests pass; build clean.

The claim predicate added with the TSP inbound work returned `false` for every
failure mode without recording any of them. On a shared socket that is right in
principle — a frame from another peer is not this request's problem — but it
made the one case that *is* a problem indistinguishable from silence: when the
VTA's reply is declined, the request waits out its full timeout and reports
`timed out awaiting reply frame`, with no record anywhere that a frame arrived
at all, let alone why it was rejected.

That is a regression in diagnosability against the code it replaced, which
threw a typed error naming the sender mismatch or the parse failure. The
predicate is the only thing in the path that knows; if it does not report, by
construction nothing downstream can.

It now records the reason for the most recent decline — unpack failure, sender
mismatch, unparseable payload, or a `threadId` that does not thread to this
request (naming both values, plus the reply's own type and id) — and attaches it
to the error the caller sees when the wait ends. The frame is still declined in
exactly the same cases; only the silence is removed.

Signed-off-by: Glenn Gore <glenn.g@affinidi.com>
@stormer78
stormer78 merged commit 988f5df into main Aug 29, 2026
3 checks passed
@stormer78
stormer78 deleted the fix/tsp-claim-diagnostics branch August 29, 2026 13:20
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