Commit f117b44
authored
ai/live: Remote signer implementation for tickets (#3822)
This PR completes the remote signing feature, allowing gateways to retrieve PM tickets for Live AI (live-video-to-video) without requiring any on-chain connectivity or possession of an Ethereum signing key. See the design background for additional motivation and design detail around remote signers. Refer to doc/remote-signer.md for instructions on how to enable this feature.
Retrieving tickets is mostly done via implementing the LivePaymentSender interface with a new implementation: `remotePaymentSender` in `live_payment.go`. The LivePaymentSender implementations (signer or non-signer) is also initialized earlier in the process, before an orchestrator is requested, and stored in the LiveParams struct. This is so the gateway can send an upfront payment to the orchestrator using remote signers. Processing remote payment signing requests happens in the `remote_signer.go` file.
When a job first starts, the gateway sends an upfront payment to the orchestrator encoded in the initial request header. To support this, the API for the `remotePaymentSender` also offers a standalone `RequestPayment` method to retrieve signed tickets without sending them. The non-remote signer does not have a clean, singular method to retrieve tickets; at some point we may codify this behind a proper interface and clean up this bit, but that can come later to avoid introducing additional concepts to an already involved PR.
### Remote Signing Protocol
Refer to the design document for context behind the design of the protocol. Here is some more detail on that:
* There are 2 bits of state: the remote signer's state, and the orchestrator's state (OrchestratorInfo ticket parameters). The remote signing protocol is stateless, and each call to sign tickets returns an updated state. The gateway is responsible for retaining both bits of state in between calls, and re-sending the state to the remote signer.
* The remote signer's state is itself signed to prevent tampering. The OrchestratorInfo data is already signed.
* There is a loose requirement for the gateway to store the payment response since it contains updated OrchestratorInfo data. However, this is not strictly necessary; the existing OrchestratorInfo can be reused until its parameters expire.
* If expired OrchestratorInfo parameters are sent to the signer, the signer will respond with an internal status code of 480 ("HTTPStatusRefreshSession") indicating the client should retrieve a fresh set of parameters using an GetOrchestratorInfo RPC request. This comes at the cost of an additional set of requests to the O and the signer, but the impact should be negligible given that Live AI payments are asynchronous and there is typically a bit of a buffer before the gateway depletes its balance with the O.
```mermaid
sequenceDiagram
participant O as Orchestrator
participant G as Gateway
participant S as Signer
%% Initial session setup
G->>S: getOrchInfoSig()
S-->>G: gatewaySig
G->>O: getOrchInfo(gatewaySig)
O-->>G: ticketParams₀
%% First signing call (no prior signer state)
Note over S: state is null → create fresh signer state
G->>S: signTicket(state=null, ticketParams₀)
S-->>G: signedTicket₀, signerState₀
G->>O: pay(signedTicket₀)
O-->>G: ticketParams₁
G->>S: signTicket(signerState₀, ticketParams₁)
S-->>G: signedTicket₁, signerState₁
%% Subsequent calls (k = 1..N)
loop For each k = 1..N
Note over S: NB: ticketParamsₖ reusable between<br>calls as long as it is valid but not<br>signedTicketₖ or signerStateₖ
G->>S: signTicket(signerStateₖ₋₁, ticketParamsₖ)
S-->>G: signedTicketₖ, signerStateₖ
G->>O: pay(signedTicketₖ)
O-->>G: ticketParamsₖ₊₁
end
```
### PM Changes
All the changes here are used only by the remote signer, so the impact on the existing code is minimal.
The `Sender` interface adds two new methods: a StartSessionWithNonce constructor, and a `Nonce` accessor. The nonce is a (mostly internal) PM construct that allows for multiple tickets to be generated using the same set of PM parameters. For ordinary signers, the `Sender` persists for the duration of the session, so the nonce would stay internal and be incremented as necessary. However, since remote signers are stateless, the nonce needs to be extracted and set with each signing call, and that is what we do here.
The `Balance` struct has a new `Reserve()` method added to zero out the current balance. This addition makes the `Balance` more closely mirror the API of the nested `AddressBalances()` list. (Otherwise I would have chosen a better name than "Reserve" to zero out a balance.)
Note that the `Balances` object itself hides quite a bit of nested global accouting that we don't strictly need here, and it would be much neater to not have to use these in favor of strictly request-local accounting. However, this would make the rest of the implementation more complex, since the `BroadcastSession` works on the global `Balances` and most of the payment helper functions themselves take a `BroadcastSession` ... so here we go.
There is also a small change in starter.go to initialize more PM and Ethereum scaffolding (watchers etc) when the node starts up in remote signer mode.1 parent 778c2e1 commit f117b44
13 files changed
Lines changed: 1744 additions & 33 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1092 | 1092 | | |
1093 | 1093 | | |
1094 | 1094 | | |
1095 | | - | |
| 1095 | + | |
1096 | 1096 | | |
1097 | 1097 | | |
1098 | 1098 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
34 | 39 | | |
35 | 40 | | |
36 | 41 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
92 | 109 | | |
93 | 110 | | |
94 | 111 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
25 | 28 | | |
26 | 29 | | |
27 | 30 | | |
| |||
33 | 36 | | |
34 | 37 | | |
35 | 38 | | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
36 | 42 | | |
37 | 43 | | |
38 | 44 | | |
| |||
75 | 81 | | |
76 | 82 | | |
77 | 83 | | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
78 | 95 | | |
79 | 96 | | |
80 | 97 | | |
| |||
85 | 102 | | |
86 | 103 | | |
87 | 104 | | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
88 | 113 | | |
89 | 114 | | |
90 | 115 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
511 | 511 | | |
512 | 512 | | |
513 | 513 | | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
514 | 519 | | |
515 | 520 | | |
516 | 521 | | |
| |||
545 | 550 | | |
546 | 551 | | |
547 | 552 | | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
83 | 83 | | |
84 | 84 | | |
85 | 85 | | |
86 | | - | |
| 86 | + | |
87 | 87 | | |
88 | 88 | | |
89 | 89 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
695 | 695 | | |
696 | 696 | | |
697 | 697 | | |
698 | | - | |
| 698 | + | |
699 | 699 | | |
700 | 700 | | |
701 | 701 | | |
| |||
761 | 761 | | |
762 | 762 | | |
763 | 763 | | |
764 | | - | |
| 764 | + | |
| 765 | + | |
765 | 766 | | |
766 | 767 | | |
767 | 768 | | |
| |||
778 | 779 | | |
779 | 780 | | |
780 | 781 | | |
| 782 | + | |
781 | 783 | | |
| 784 | + | |
782 | 785 | | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
783 | 791 | | |
784 | 792 | | |
785 | 793 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
104 | 104 | | |
105 | 105 | | |
106 | 106 | | |
| 107 | + | |
107 | 108 | | |
108 | 109 | | |
109 | 110 | | |
| |||
1051 | 1052 | | |
1052 | 1053 | | |
1053 | 1054 | | |
1054 | | - | |
1055 | | - | |
1056 | | - | |
1057 | | - | |
| 1055 | + | |
| 1056 | + | |
| 1057 | + | |
| 1058 | + | |
| 1059 | + | |
| 1060 | + | |
| 1061 | + | |
| 1062 | + | |
| 1063 | + | |
| 1064 | + | |
| 1065 | + | |
| 1066 | + | |
| 1067 | + | |
| 1068 | + | |
| 1069 | + | |
| 1070 | + | |
| 1071 | + | |
| 1072 | + | |
| 1073 | + | |
1058 | 1074 | | |
1059 | | - | |
1060 | | - | |
1061 | | - | |
1062 | | - | |
| 1075 | + | |
| 1076 | + | |
| 1077 | + | |
| 1078 | + | |
| 1079 | + | |
| 1080 | + | |
| 1081 | + | |
| 1082 | + | |
| 1083 | + | |
| 1084 | + | |
| 1085 | + | |
| 1086 | + | |
| 1087 | + | |
| 1088 | + | |
| 1089 | + | |
1063 | 1090 | | |
1064 | | - | |
| 1091 | + | |
1065 | 1092 | | |
1066 | | - | |
| 1093 | + | |
| 1094 | + | |
| 1095 | + | |
1067 | 1096 | | |
1068 | 1097 | | |
1069 | 1098 | | |
1070 | 1099 | | |
1071 | 1100 | | |
1072 | 1101 | | |
1073 | | - | |
1074 | 1102 | | |
1075 | | - | |
1076 | 1103 | | |
1077 | 1104 | | |
1078 | 1105 | | |
| |||
1669 | 1696 | | |
1670 | 1697 | | |
1671 | 1698 | | |
| 1699 | + | |
| 1700 | + | |
| 1701 | + | |
| 1702 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
243 | 243 | | |
244 | 244 | | |
245 | 245 | | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
246 | 250 | | |
247 | 251 | | |
248 | 252 | | |
| |||
269 | 273 | | |
270 | 274 | | |
271 | 275 | | |
| 276 | + | |
272 | 277 | | |
273 | 278 | | |
274 | 279 | | |
| |||
281 | 286 | | |
282 | 287 | | |
283 | 288 | | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
284 | 293 | | |
285 | 294 | | |
286 | 295 | | |
| |||
450 | 459 | | |
451 | 460 | | |
452 | 461 | | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
453 | 466 | | |
454 | 467 | | |
455 | 468 | | |
| |||
0 commit comments