Open kianenigma opened 2 years ago
Marking it as unconfirmed for now to allow discussion around the design.
cc @niklasad1 your input will be useful.
Another cool idea here would be to use pre-image pallet for image submission.
I added a few comments and ideas on how to proceed with this task here https://hackmd.io/zE1goNRmSsa8q_LCjHD5Kg?view.
Overview
The current signed phase of the election-provider-multi-phase pallet has a major flaw: There is a single transaction (
submit
), quite heavy, that submits both the solution score and the payload of a signed solution.This is a lot of burden on the chain, and a lot of tx-fee for miners, even if they are honest.
For example, in polkadot, the tx-fee for this call is around 10DOTs and the deposit is around 50DOTs.
To partially fix this, we introduced paritytech/substrate#11002, so that a number of honest miners get their transaction fee back, even if they are not the winner, as long as they are not found to be dishonest.
This is still not totally ux-friendly, and also lacks ideal security.
The ideal solution is to split the solution submission into two phases:
Details
A new phase is added, called` is added.
Commitment
. A new transaction is added,fn commit(origin, score)
. It should work somewhat similar to the current signed phase. scores are kept sorted, and the weakest one will get ejected. So, a new typetype
MaxCommitments: GetCommitting will reserve a large deposit, similar to the current deposit.
Then, there is a new phase called
Reveal(..)
. The duration of this phase istype RevealDuration * MaxCommitments
. In essence, this means that for every commitment, we will allocate a maximum ofRevealDuration
block for the signer to reveal their payload.For example, we could have 12 commitments, and with allowing 10 blocks per reveal, we need a total of 12 minutes to revel.
Note that this is intentionally designed this way to alleviate any race condition among miners. Each miner will get its own allocated blocks to submit, and there should be no races.
A
Reval
phase is actuallyRevel(submitter, left_blocks)
. The first argument is the committer that is allowed to submit. The second is the number of blocks they have left. For example, in the previous example, we will haveReveal(Alice, 10) -> Reveal(Alice, 9) -> Reveal(Alice, 8) ..
.During the reveal phase, the
submitter
can submit a solution payload. This is verified on the fly, and has a similar logic as the current submission’s verification: If good, everything is refunded + reward is given, if bad, everything is slashed.If a committer fails to submit, i.e. we reach
Reveal(_, 0)
, and we receive nothing, this is also considered as a misbehavior and the committer will lose their deposit.Upon verifying the first solution, if it is valid, then we are done, and there is no point in verifying anything and anyone else. This is mainly because we must have verified the BEST solution that we has been claimed. Recall that bids are kept sorted.
All in all, this approach is one way to go about this, but I am not sure if it is the best. This approach is optimizing the scenario for miners, making sure they each have their own dedicated slot to submit freely, avoiding race conditions. On the other hand, the downside the current one is that the duration of the reveal phase cannot be too long, ergo the number of commitments cannot also be too big.