Skip to content

call_runner doesn't report the signer sessions it opens #74

Open

Description

@mikezupper

A caller of call_runner can't tell which signer sessions a call opened. That matters because the remote signer charges when it signs a payment, not when the runner delivers. A gateway that bills its users, or reconciles against Clearinghouse Batteries, has to link each charge to a call, including calls that failed after the payment was signed. The signer records each charge under the session's AuthID, but call_runner keeps its sessions private.

Proposed change

eliteprox#5 adds two things:

  • call_runner(..., on_payment_session=callback) calls callback(session) for each session the signer signs, before the paid request is sent.
  • LivePaymentSession.auth_id returns that session's AuthID. It reads go-livepeer's State key and livepeer/node's state key.

Callers that don't pass the callback see no change. The PR adds 17 tests, covering repeated 402s, a runner failure after payment, a refused session and a cancelled call.

It replaces #71, which was closed so the change could target the fork's releases/m2. That branch matches main, and GitHub reports no conflicts. Could it come back here as a PR against main?

Known limit

RunnerSelectionCursor still fails over after a signed payment, so one job can pay twice. #70 tracks that.

Why we need it

The Network Engineering SPE build track matches each job attempt to Batteries usage by auth_id. Until this is released, the build track pins the fork.

Activity

  1. j0sh commented on Oct 14, 2026

    @j0sh
    Collaborator

    The signer state is opaque and I'm not sure if we really want to turn that into a public compatibility requirement. Also, the AuthID might not always be there and I don't think it would be guaranteed to identify a specific session.

    Would the ManifestID work in the callback? That is known to the SDK and would identify the orchestrator session and you can query it in the clearinghouse.

  2. eliteprox commented on Oct 14, 2026

    @eliteprox
    Collaborator

    The signer state is opaque and I'm not sure if we really want to turn that into a public compatibility requirement. Also, the AuthID might not always be there and I don't think it would be guaranteed to identify a specific session.

    Would the ManifestID work in the callback? That is known to the SDK and would identify the orchestrator session and you can query it in the clearinghouse.

    Agreed on not decoding the signer state. AuthID only identifies a session because Clearinghouse Batteries makes it one; the signer doesn't promise that.

    ManifestID works. Builder core attributes cost per job on (allocation_id, payment_session_id) (services/costs.py in livepeer-builder-core), and that key stays. The callback reports each signed session's manifest_id, and cost sync resolves it to the payment_session_id on the matching Batteries usage rows. In our runs against public orchestrators the two mapped one-to-one.

    I'll update eliteprox#5 to replace auth_id and the state decoding with LivePaymentSession.manifest_id from the 402 challenge, then open it here against main.

    One question: the orchestrator chooses the manifest, and the signer can't verify Auth.SessionID. Is a fresh ManifestID per challenge an orchestrator guarantee, or a livepeer/node implementation detail? Either way, we can hold any manifest that maps to more than one Batteries session as uncertain (for per-job attribution, per allocation_id attribution remains unaffected). If it isn't guaranteed, we may want to consider having Batteries record our own per-attempt reference from a signer request header.

  3. eliteprox commented on Oct 14, 2026

    @eliteprox
    Collaborator

    Opened #77 against main. call_runner(..., on_payment_session=callback) reports each signed session, and LivePaymentSession.manifest_id is the manifest from the 402 challenge. The signer state is not decoded.

    The question from the previous comment is still open: is a fresh ManifestID per challenge an orchestrator guarantee, or a livepeer/node implementation detail? Builder core will hold any manifest that maps to more than one Batteries payment session as uncertain, so per-job attribution stays honest either way. Per-allocation attribution does not depend on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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