Skip to content

Add payment session callback for runner calls - #81

Merged
j0sh merged 3 commits into
mainfrom
ja/payment-callback
Oct 21, 2026
Merged

j0sh merged 3 commits into
mainfrom
ja/payment-callback

Conversation

@j0sh

@j0sh j0sh commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator

Support sync and async on_payment_session callbacks in call_runner and expose LivePaymentSession.manifest_id for payment attribution. Invoke the callback for each new session.

Validate segCreds when parsing signer responses and remove redundant caller checks. Cover callback ordering, failures, and cancellation.

Support sync and async on_payment_session callbacks in call_runner and
expose LivePaymentSession.manifest_id for payment attribution. Invoke the
callback for each new session.

Validate segCreds when parsing signer responses and remove redundant
caller checks. Cover callback ordering, failures, and cancellation.
@j0sh
j0sh requested review from rickstaa and a balanced review from Copilot and removed request for Copilot October 20, 2026 03:23

@eliteprox eliteprox left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still reviewing the error handling and payment status reporting, but here is one nit

Comment thread src/livepeer_gateway/live_runner.py Outdated
eliteprox
eliteprox previously approved these changes Oct 21, 2026

@eliteprox eliteprox left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall changes lgtm and test fine. Added one more suggestion to call_runner.

For context, we're using the on_payment_session callback with manifest_id in builder-core to confirm if payment was sent for the job.

Comment thread src/livepeer_gateway/live_runner.py Outdated
Copilot AI balanced review requested due to automatic review settings October 21, 2026 23:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

Static review identified no blocking issues in callback handling or signer validation, and the added tests cover the key failure paths; tests were not executed.

No open issues 🎉

What changed in this PR

Adds payment-session notifications to runner calls, allowing callers to attribute payments using the session’s manifest ID.

Changes:

  • Supports synchronous and asynchronous callbacks for each new payment session, before dispatching the paid request.
  • Exposes LivePaymentSession.manifest_id and centralizes segCreds validation in signer-response parsing.
  • Adds tests for callback ordering, failures, cancellation, and manifest attribution.
File Description
tests/​test_live_runner.py Tests callback sequencing, error propagation, and cancellation.
tests/​test_live_payment_session.py Verifies the exposed manifest ID.
src/​livepeer_gateway/​remote_signer.py Adds the manifest property and validates segment credentials centrally.
src/​livepeer_gateway/​live_runner.py Implements payment-session callbacks and removes redundant validation.
src/​livepeer_gateway/​__init__.py Exports the callback type.
CHANGELOG.md Documents the new callback and manifest property.

Review effort: Balanced

Comment thread src/livepeer_gateway/live_runner.py Outdated
if on_payment_session is not None:
result = on_payment_session(payment_session)
if inspect.isawaitable(result):
await result

@eliteprox eliteprox Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once await payment_session.get_payment() returns on line 851, the remote signer has already persisted the ticket and debited the caller's allocation, but call_runner only surfaces that payment_session through on_payment_session. This makes it hard to match job attempts that recorded cost by successfully signing, but failing on job start attempt, leading to regression in billing accuracy.

Would you be open to accumulating each signed payment_session into a list immediately after get_payment() succeeds (before awaiting on_payment_session) and attaching payment_sessions: tuple[LivePaymentSession, ...] = () (or manifest_ids: tuple[str, ...] = ()) to LiveRunnerCallResult, LiveRunnerCallStream, and LivepeerGatewayError? That way consumers recording a job attempt can read every signed manifest_id and whether payment was sent (bool(payment_sessions)) directly from the returned result or caught error, while keeping on_payment_session for callers that want to persist pre-dispatch state (more context in NE-Build-Track/livepeer-builder-core#33 (comment)). This way we're not relying on a callback hook for the manifest_id.

  • On LiveRunnerCallResult (lines 161–173) and LiveRunnerCallStream (lines 176–196), payment_session is cleared to None when payment_type == "fixed" (line 892 and line 939), and when multiple 402 challenges are signed across retries (as in test_reports_each_successful_session_before_dispatch), only the last payment_session and session_id are retained on the return value.
  • When the paid runner request subsequently raises a non-402 LivepeerHTTPError (line 944), fails JSON decoding (lines 923–930), or exhausts challenge retries (line 951), the raised LivepeerGatewayError carries none of the sessions signed during the attempt.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What regression in billing accuracy?

Is there a reason this needs to be built into the API? Can accomplish the same with

payment_sessions = []
await call_runner(
    ...,
    on_payment_session=payment_sessions.append,
)

Copilot AI balanced review requested due to automatic review settings October 21, 2026 23:14

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

Static review found no blocking issues in callback handling, signer validation, or the accompanying tests; tests were not executed.

No open issues 🎉

Review effort: Balanced

@j0sh
j0sh merged commit 76a1a1c into main Oct 21, 2026
6 checks passed
@j0sh
j0sh deleted the ja/payment-callback branch October 21, 2026 23:24
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.

3 participants