Repository navigation
payments: keep the state a skipped cycle hands back - #78
Closed
chrishobcroft wants to merge 1 commit into
Closed
chrishobcroft wants to merge 1 commit into
chrishobcroft wants to merge 1 commit into
Conversation
A 482 from the remote signer is a completed cycle, not a failed one: a signer with livepeer/go-livepeer#4077 fixed debits the service consumed since its last update and returns new state alongside the error. Dropping it means resending the same balance every cycle, minting nothing, and being released by the orchestrator once the opening credit runs out. Read the state off the 482 body when it is present and store it. Signers that answer with a bare error are unaffected: the caller keeps what it had.
There was a problem hiding this comment.
🟢 Approval recommended
State propagation is consistent, legacy behavior is preserved, and focused regression tests cover the change.
0 open findings
What changed in this PR
Preserves signer state returned with skipped payment cycles, preventing live payment sessions from repeatedly sending stale balances.
Changes:
- Carries optional state through HTTP 482 exceptions in both HTTP helpers.
- Saves skipped-cycle state while preserving compatibility with older signers.
- Adds parsing and session-state regression tests.
| File | Description |
|---|---|
| tests/test_live_payment_session.py | Tests state parsing, retention, and legacy behavior. |
| src/livepeer_gateway/remote_signer.py | Saves returned state before re-raising a skipped cycle. |
| src/livepeer_gateway/http.py | Extracts state from HTTP 482 response bodies. |
| src/livepeer_gateway/errors.py | Adds optional state to SkipPaymentCycle. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Collaborator
|
Since livepeer/go-livepeer#4107 is closed, I'm going to close this one too. The state does not change on a skip, and the next request accounts for the elapsed time since the last successful payment. It's not necessary to retain anything here. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Client half of livepeer/go-livepeer#4107 (fixes livepeer/go-livepeer#4077).
The remote signer is stateless: the balance and its clock travel with the client. When a payment cycle is skipped, the signer answers HTTP 482. With livepeer/go-livepeer#4107 that 482 also carries the advanced, re-signed state. Today
LivePaymentSessiondrops it, so it resends the same balance every cycle, never mints again, and the orchestrator releases the session once its opening credit runs out.Change
SkipPaymentCyclegains an optionalstate.http.pyreadsstatefrom the 482 body when there is one (both the async and sync helpers).LivePaymentSession._payment_requeststores that state before re-raising.Against a signer without livepeer/go-livepeer#4107 the 482 body has no state, so nothing changes: the session keeps what it had.
Tests
New
TestSkippedCycleStateintests/test_live_payment_session.py: parsing the 482 body, a session that keeps the state from a skip and sends it on the next request, and one that keeps its old state when a skip carries none. The state-keeping test fails without the change toremote_signer.py.Full suite: 216 passed. The 2 failures in
test_stats_pull.pyand 2 teardown errors intest_live_runner.pyhappen identically onmainwithout this change.