Skip to content

[CRE] confidential relay: wait for late execution handler before failing relay callback - #23284

Open
prashantkumar1982 wants to merge 2 commits into
developfrom
fix/cre-confidential-relay-handler-wait
Open

[CRE] confidential relay: wait for late execution handler before failing relay callback#23284
prashantkumar1982 wants to merge 2 commits into
developfrom
fix/cre-confidential-relay-handler-wait

Conversation

@prashantkumar1982

@prashantkumar1982 prashantkumar1982 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Motivation

Nodes were intermittently failing the enclave's confidential-relay callbacks with
execution handler for workflow <id> execution <id> not found, sometimes often
enough that the gateway relay handler timed out without quorum and the whole
confidential execution failed.

Root cause is a start-edge race, not an early removal:

  • A confidential workflow runs once on the enclave for the DON, and the
    enclave only needs a relay quorum (F+1..2F+1) to proceed.
  • The gateway fans each enclave relay callback out to every workflow-DON
    member (fanOutToNodes ranges over donConfig.Members), not just the nodes
    currently executing.
  • On each node the execution handler is registered by AddExecution inside
    ConfidentialModule.Execute, which runs well after the engine's
    Workflow execution starting log.

So a node that is slightly behind (still scheduling the trigger, briefly blocked
on the per-workflow execution-concurrency limiter, etc.) can receive the relay
callback before it has started its own copy of the execution and registered a
handler. It then fails the callback instantly, dropping its signature. Confirmed
in the field: erroring nodes had no Workflow execution starting log for the
execution the gateway was asking about.

What this changes

Make the node-side relay handler tolerant of a not-yet-registered execution:

  • ExecutionHandlers.GetExecutionWithWait(ctx, workflowID, execID) — on a miss it
    registers a waiter and blocks until AddExecution registers the handler or
    ctx is done. The check-then-register happens under a single lock hold that
    AddExecution also takes, so there is no lost-wakeup window. Backed by a
    mutex-guarded map + waiter registry (replacing the bare sync.Map); the zero
    value is still ready to use.
  • handleSecretsGet / handleCapabilityExecute call it with a bounded deadline
    (defaultGetExecutionWait = 5s, well under the gateway's 30s relay request
    timeout so the node still answers in time to be counted), and — importantly —
    only after attestation and Workflow-DON authorization pass, so an
    unverified callback cannot make a node park a waiter. A callback for an
    execution this node never runs still fails promptly once the bound elapses.

…ing relay callback

The enclave runs one DON-shared confidential execution and only needs a
relay quorum to proceed, so the gateway's relay callback (fanned out to
every workflow-DON member) can reach a node before that node has started
its own copy of the execution and registered the execution handler. The
node then failed the callback with "execution handler not found",
dropping its signature and, when enough nodes raced, pushing the relay
below quorum.

Add ExecutionHandlers.GetExecutionWithWait: on a miss it registers a
lost-wakeup-safe waiter and blocks until the handler appears or the
caller's context is done. The relay handler calls it with a bounded (5s)
deadline, well under the gateway's relay request timeout, and only after
attestation and Workflow-DON authorization pass so an unverified callback
cannot park a waiter.

This addresses the start-edge race; the end-edge (early RemoveExecution
on execution timeout) and pathological never-starts (concurrency
saturation, stale-event drops) are separate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@prashantkumar1982
prashantkumar1982 requested review from a team as code owners July 30, 2026 21:24
@github-actions

Copy link
Copy Markdown
Contributor

👋 prashantkumar1982, thanks for creating this pull request!

To help reviewers, please consider creating future PRs as drafts first. This allows you to self-review and make any final changes before notifying the team.

Once you're ready, you can mark it as "Ready for review" to request feedback. Thanks!

@github-actions

Copy link
Copy Markdown
Contributor

✅ No conflicts with other open PRs targeting develop

Satisfy golangci paralleltest, which flagged the new test functions. Also
capture start before setting the deadline in the timeout test so the
elapsed lower-bound assertion cannot flake.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@trunk-io

trunk-io Bot commented Jul 30, 2026

Copy link
Copy Markdown

Static BadgeStatic BadgeStatic Badge

View Full Report ↗︎Docs

@cl-sonarqube-production

Copy link
Copy Markdown

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