PM Ticket Expiration
See original GitHub issueWhy do we want ticket expiration?
- Minimize double spending by B
- By design B cannot know for any given ticket if it’s a winning ticket until O reveals its
recipientRand
value, which happens upon redemption on-chain. With no bound on when O redeems tickets, B can easily hand out winning tickets of a value greater than B’s deposit and accidentally double spend. - B can decide to maliciously double spend on many Os, and until enough Os redeem enough winning tickets to trigger double spend detection, B’s additional utility keep growing. Ticket expiration is a way to curb B’s additional utility for such behavior.
- By design B cannot know for any given ticket if it’s a winning ticket until O reveals its
- Delegators being squeezed by O and B colluding: without expirations O can hold on to many tickets to accrue a significant chunk of revenue, then update their fee sharing params on-chain, and only once those changes take effect redeem all the tickets. Expiration can not only curb this behavior, but further ensure that the right delegators are rewarded for the work (if we agree that the right delegators to reward are those that delegated onto O at the round when the ticket was created).
(for more background on some of these issues see https://github.com/livepeer/prob-pay/issues/5 and https://github.com/livepeer/prob-pay/issues/6).
Assuming we’ve established that we want to have an expiration mechanism, moving on to its design.
Ticket expiration design
- Expiration must rely on a verifiable data point that is infeasible to know ahead of time, otherwise colluding Bs and Os can easily issue future-dated tickets.
- The best source of such data in our case seems to be Ethereum block hashes.
- This problem becomes more challenging since currently in Ethereum we can only query for the block hash of the last 256 blocks.
Initial solution approach:
- The foundation for our workaround is to rely on smart contract storage for block hashes lookup.
- To have that we need some mechanism for storing block hashes regularly.
- The most cost-effective solution we have now is to leverage the existing round initialization mechanism.
- At every round initialization we would store a mapping from round number to the previous blockhash.
- Bs can query this mapping to get the latest values, and include them in each PM ticket.
- Both O and TicketBroker can reference that same map for their ticket validation process:
- Do the round number and round hash in the ticket match what’s stored on-chain?
- Are we still within the ticket expiration period?
Round-based expirations challenges
Rounds are currently about 24-hours long. This granularity presents us with a few challenges:
- If we set the expiration period to be one round, we open the protocol to edge cases of tickets expiring very quickly if B gets the latest block hash just before a new round is initialized (worst case could be one block).
- From this we deduce that the expiration period should be at least 2 rounds.
- However, a 2-round expiration means that the worst case for exposing double spending becomes 48 hours, and that’s suboptimal as well.
- A potential mitigation could be shortening rounds from 24 hours to 12 hours, but that would come at the expense of not giving delegators reasonable time to learn of any delegation params changes (fee share, etc.) - which is an intention currently baked into the protocol.
As mentioned, the ideal solution would be to rely on block hashes, and there are EIPs that present such a possibility, but we have no certainty on if and when they will be included in a mainnet Ethereum version.
What is the best compromise for now?
Issue Analytics
- State:
- Created 5 years ago
- Comments:7 (4 by maintainers)
Top Results From Across the Web
Disneyland Ticket Expiration Dates - The Happiest Blog on Earth
Do Disneyland tickets expire? Yes, tickets do have an expiration date listed ...
Read more >New Ticket Expiration Deadlines & Usage | FAQ
Here are the details: 1-day – The ticket expires on the selected start date.2-day – The ticket expires 4 days after the selected...
Read more >Required Elements in a Ticket - NYC.gov
The box for “Missing” or Expired” must be checked on the ticket. · If the ticket is for an expired inspection, the expiration...
Read more >Walt Disney World Ticket and Pass Advice Tips & Tricks
Any current-issue standard Disney World ticket expires after every admission on the ticket has been used, or on the listed expiration date, ...
Read more >How to escalate a support ticket - PM PrepCast Forum
How to escalate a support ticket I am having an urgent ticket with wrong expiration date of the exam and no helpful reply...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Here is an update on the current proposed roadmap for this feature based on this thread and an offline discussion between @eladmallel and I:
We prefer not to use the approach of storing block hashes on winning ticket redemption because:
We prefer not to directly rely on block numbers i.e. attach a block hash and a block number to a ticket and the Broker checks if the block hash is valid for the block number and use a maximum ticket validity period of 256 blocks which is around 1 hour given ~15 second block times (since contracts cannot look up block hashes past
currentBlock - 256
) because:We propose the use of round initialization to store block hashes that can be used to prove the existence of a block at the time of ticket creation. The workflow for B would be as follows:
currentBlockHash
for the current initialized round. Note: If the current round is not initialized, B will query the RoundsManager for the block hash of the last initialized round - this behavior is to ensure that B is never blocked from streaming if we are in a transitionary period during which the current round is not initialized yet.currentBlockHash
andcurrentRound
.currentBlockHash
is indeed the block hash forcurrentRound
by querying the RoundsManager.currentBlockHash
is indeed the block hash forcurrentRound
by querying the RoundsManager. The ticket pay out can then be sent to O’s fee pool forcurrentRound
(which results in fees directed to delegators that delegated to O at the time of ticket creation).The upsides of this approach are:
The downsides of this approach are:
Our conclusion is that while using round initialization to store block hashes might not be the most ideal solution, it still beats out the other available solutions at the moment.
If anyone has any additional thoughts/concerns we please continue the discussion here!
If there are no additional thoughts/concerns, we can proceed with the following plan:
Thanks for taking the time to dissect alternatives so thoroughly. Is round initialization anticipated to be used for anything other than storing the block hash?
If the block hash is the only reason for round initialization, then it might be nice to continue exploring other avenues to avoid round initialization. Performing global round initialization to accommodate an incidental effect of the payment mechanism feels heavy.
One possible approach is to set the block hash during the first
reward
call.