livepeer / livepeer/research

PM ticket params

Open
#29 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
No language data
Stars
7
Forks
1
PR merge metrics
No merged PRs in 30d

Description

## Definitions

`txGas` = The transaction gas cost for redeeming a winning ticket. If it is possible for the gas cost to vary due to state dependent operations in the contract, the average gas cost can be multiplied by a constant factor so that this value is always greater than or equal to the actual gas cost.

`gasPrice` = The current gas price required for timely transaction confirmation. In practice, B and O might receive different values depending on how they are fetching the gas price (i.e. using the ETHGasStation API or querying an ETH node using the `eth_gasPrice` JSON-RPC call). Furthermore, the actual gas price used will depend on how fast the transaction needs to be confirmed. One way to synchronize the gas price view for B and O is to allow B to query O for the current gas price. B can cache the current gas price and refresh it regularly by querying O. Thus, both B and O use whatever gas price O currently requires.

`txCost` = The ETH transaction cost for redeeming a winning ticket.

`price` = The ETH price for a unit of work corresponding to a set of transcoding options that a ticket is supposed to pay for.

`reserve` = The value B guarantees the set of all Os on the network.

`numOrchestrators` = The current number of orchestrators on the network. There is a cap on the number of orchestrators.

`float` = The value B guarantees an individual O from its reserve.

`guaranteedTickets` = The number of winning tickets that O wishes to be guaranteed by `float`. Generally, this value should be > 1 because if it is 1 then as soon as O receives a winning ticket, it will have to stop accepting additional tickets since any subsequent winning tickets will not be guaranteed by `float`. Increasing this value reduces `faceValue`, increases `txOverhead` and increases `winProb`. The default value can be 2.

`faceValue` = The ETH payout from a winning ticket.

`winProb` = The probability of a ticket winning.

`minAvgHoursPerWin` = The minimum hours of continuous ticket creation that a winning ticket will on average be created after.

`txOverhead` = The % of the ticket `faceValue` that `txCost` represents assuming `faceValue` will always be set so that B pays for the transaction cost incurred by O.

### Generating Ticket Params

`genTicketParams()` can be used to compute the required parameters for a ticket based on a particular gas price.

1. `txCost = txGas * gasPrice`
2. `float = reserve / numOrchestrators`
3. `faceValue = float / guaranteedTickets` (using `guaranteedTickets = 2` by default)
4. Check if `faceValue` is sufficient to cover the transcoding price and transaction cost
i. If `faceValue < price + txCost`, abort
5. `winProb = price / (faceValue - txCost)`
6. Check if `winProb` results, on average, in <= 1 winning ticket every `minAvgHoursPerWin` hours
i. `avgHoursPerWin = secPerTicket / (3600 * winProb)`
ii. If `avgHoursPerWin < minAvgHoursPerWin`, abort
5. Return `faceValue`, `winProb`

Step 3 is an early check that ensures that the `faceValue` derived from a B's `float` will actually be able to cover the price of transcoding as well as the transaction cost given a reasonable `winProb`. When `faceValue < price + txCost`, then `winProb > 1` which is clearly not reasonable within the system.

Step 4 sets `winProb` so that given a `faceValue` derived from `float`, B is always paying for the transaction cost that O will incur when redeeming a winning ticket. As a result, `faceValue * winProb = expValue > price`. The difference `expValue - price` reflects the per ticket overhead and the cumulative percentage overhead is reflected by `txOverhead = txCost / faceValue`.

Step 5 creates a ceiling on the number of transactions O could have to submit on-chain during a period of time. While the ticket parameters can always be adjusted to ensure that winning ticket redemption is profitable for O, reducing the number of transactions submitted on-chain during a period of time helps avoid congesting the ETH network and also reduces the frequency of blockchain interactions for O. Note that the inclusion of this step can actually obviate the need for the check in step 3 - for example, if `minAvgHoursPerWin = 1`, then it is clear that `winProb < 1`.

### B <-> O Flow

1. B periodically refreshes its cached list of Os along with their price menus and required gas prices
3. B executes `genTicketParams()` to get `faceValue` and `winProb`
4. B sends a ticket with `faceValue` and `winProb` to O along with the gas price it used
5. If the gas price sent by B is less than O's current required gas price (perhaps there is some buffer), O returns an error message with its current required gas price (TODO: Describe behavior when O can still hold onto the received ticket)
6. O executes `genTicketParams()` and compares the `faceValue` and `winProb` of the ticket sent by B with the returned values. If the values do not match (they should if the same gas price is used), O returns an error message
7. O accepts the ticket

### Observations

Since B can regularly refresh the gas price required by O, it can always re-compute ticket parameters to reflect gas price changes on the network. Thus, O does not need to require ticket parameters that price in the risk of future gas price spikes on the network.

B can set its `reserve` freely with a few caveats:

- O has an absolute minimum float: `minFloat = (price + txCost) * guaranteedTickets`. If B's `reserve` results in a `float` that is less than `minFloat`, then O will not work with B
- O will also not work with B if B's `float` results in a `winProb` that corresponds to `avgHoursPerWin < minAvgHoursPerWin`
- Lower `reserve` -> lower `float` -> lower `faceValue` -> higher `overhead`
- Higher `reserve` -> higher `float` -> higher `faceValue` -> lower `overhead`
- As a result of the previous two points, B's with a smaller `reserve` will effectively pay more for transcoding

Questions:

- As `reserve` increases, `overhead` decreases and `winProb` decreases. Is there a point at which that we should consider increasing `guaranteedTickets` to increase `overhead` and increase `winProb`? For example, certain configurations might result in a `winProb` that corresponds to a winning ticket every couple of days

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the Definitions, Generating Ticket Params, and B ↔ O Flow sections, then trace genTicketParams() and the listed constraints. Done means resolving the guaranteedTickets, overhead, and winProb question and documenting the resulting ticket-parameter behavior, including the TODO about tickets O can retain.

Written by the indexing model from the issue text.

Assessment

Tech stack
blockchain
Domain
blockchain
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.