-
Notifications
You must be signed in to change notification settings - Fork 71
Correct validator rewards #119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Implementation stages:
Alone, approvals rewards suffices to incentivise validator hardware upgrades. Availability rewards just disincentivise nodes from shirking availability duties. We'll want availability rewards eventually, and they help paritytech/polkadot-sdk#5334 (comment), but if we delay doing it, then maybe 2a and 2b would be worth doing early, just to save ourselves on upgrade work later. |
|
|
||
| As approval checkers could easily perform useless checks, we shall reward availability providers for the availability chunks they provide that resulted in useful approval checks. We enforce honesty using a tit-for-tat mechanism because chunk transfers are inherently subjective. | ||
|
|
||
| An approval checker reconstructs the full parachain block by downloading distinct $f+1$ chunks from other validators, where at most $f$ validators are byzantine, out of the $n \ge 3 f + 1$ total validators. In downloading chunks, validators prefer the $f+1$ systemic chunks over the non-systemic chunks, and prefer fetching from validators who already voted valid, like backing checkers. It follows some validators should recieve credit for more than one chunk per candidate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In practice, we almost always first try to recover the full plaintext PoV from one of the validators in the backing group. We fallback to systematic chunks and regular chunks if this fails OR if the PoV size is larger than 1 Mib.
Would the validators in the backing group be rewarded as if they had provided all of the chunks (which they did)? Or are we going to ignore these
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's actually what this says. Fetching from backers is one of the two ways to fetch the systemic chunks. Systemic chunks is just means the original parablock. It's fine if this is rephrased to better match the terminology elsewhere though.
Would the validators in the backing group be rewarded as if they had provided all of the chunks (which they did)? Or are we going to ignore these
Yes, backers are rewarded for every chunk they give out to approval checkers (assuming the guy who gets the chunk credits them). This is why backers are only paid like 80% of what approval checkers are paid, instead of something higher like 98% or whatever.
Backers are not rewarded for the chunks they give out in availability distribution though.
|
|
||
| As approval checkers could easily perform useless checks, we shall reward availability providers for the availability chunks they provide that resulted in useful approval checks. We enforce honesty using a tit-for-tat mechanism because chunk transfers are inherently subjective. | ||
|
|
||
| An approval checker reconstructs the full parachain block by downloading distinct $f+1$ chunks from other validators, where at most $f$ validators are byzantine, out of the $n \ge 3 f + 1$ total validators. In downloading chunks, validators prefer the $f+1$ systemic chunks over the non-systemic chunks, and prefer fetching from validators who already voted valid, like backing checkers. It follows some validators should recieve credit for more than one chunk per candidate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would reword worked for other mechanism of fetching the PoV, e.g: entirely fetching it from one backer ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above, fetching from backers is one of the two ways to fetch the systemic chunks. We reward backers like the availability providing nodes in that case.
In principle if backer A provides like 330 systemic chunks, and then we need the other 4 or so chunks from the other backer and someone else, then backer A gets credited for 330, while the others get credited for what they provided. Afaik it shouldn't matter if backer A gave us less than the full block, since they'd presumably provide it as chunks.
I suppose backers might not provide as chunks, but instead provide the parablock as a flat file, since chunks incur the overhead of the merkle proofs. If this is better then that's fine, we can still pay the backer for f+1 chunks here. I'm not sure this is better though.
text/0000-rewards.md
Outdated
| approval_usages_medians.push(v[num_validators/2]); | ||
| } | ||
| ``` | ||
| Assuming more than 50% honersty, these median tell us how many approval votes form each validator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this create like an incentive for 50% + 1 validators to band together an lie about their stats and get all of the rewards ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you can completely corrupt the rewards if you can break the 50% honesty threshold, but you can likely do worse things then.
At least this off-chain gadget creates clear on-chain statements from everyone about what they saw, so if some validators feel themselves cheated, then they could raise those issues in governence.
I designed the elves approval gadget to be runnable on-chain, so that's an option too, even running it on a parachain, but this creates a different problem, in that people would censor how data reaches the on-chain gadget. It seems to me this on-chain censorship attack is much worse in practice, because chains are pretty easy to censor.
In essense, an on-chain elves run would really be fought out in the memepool, among block producers, among backers placing the parachain on-chain, etc, which all sounds much more opaque and harder to diagnose than simply obtaining everyone's opinons and doing this median computation.
As an aside, we could replace the median used here by like a 3/5ths percentile computation or something, but this permits biases form the other side.
|
I was looking over the RFC, and I found myself wondering if we explored other ideas in the past. In the current form I think what are we gaining from implementing this RFC is to disincentivize validators from skipping any approval-work, so the problem that would solve is that in the current state validators can:
Since we already have the 2/3 honest nodes assumption baked into various places of the protocols I think the rewards does not help with the security here, it helps with disincentivizing freeloading and that could become a problem if enough honest nodes are freeloading, but it does not help with malicious nodes, since they do not care about the rewards. Hence what if we have a reward mechanism based on the network as a whole achieving some SLAs on properties that polkadot users find useful. I imagine something where you can have a max pot of rewards MAX_REWARDS_PER_ERA and then you have some on-chain logic like:
This way we create incentives for validators to cooperate rather than freeload and also we create incentives for validators to care about the quality of the network as a whole. Another benefit is that it would include un-seen work, that is as important as approving parachain blocks, like gossiping. Any idea if we explored this path in the past ? |
Not really. I do like the collaborative rewards idea. We should probably shave off some rewards from both this and relay chain block production for collaborative rewards, provided we come up with nice designs for collaborative rewards, that're not too painful to code. We'd still have a tragedy of the commons problem though, so not sure it changes much here aside from adding a future work category. In practice, some validator operators pay minimal attention, and many nominators pay no attention, so the there is an innocent-ish tragedy of the commons already occuring. My immediate reason for pushing this now is because you've already started pushing for upgraded validator specs, and further upgrades sound likely in another year or so, but I'd expect the tragedy of the commons problem reoccurs even if it disapears now. That's also why the immediate push does not necessarily require the availability rewards. I suspect collecting the availability rewards data would help us anyways though. Also, if we start sending the availability rewards data too, then we'll save one message type upgrade. As for specifics..
We already pay for relay chain blocks. If we've specific timing problems, then lets discuss those, but I doubt timing needs rewards. We do know collaborative timing protocols, mostly by Cardano, but one variant by Handan (w3f), which afaik use median votes too. According to the wiki, we already pay something for relay chain uncles, aka acknoledging forks, which makes longest chain somewhat more collaborative. Alistair pushed for this way back, so this should already be running.
This could fail for a lot of different reasons, not sure how good a measure this is. You can maybe keep a running tally of statistics for the claim queue though?
I'm not sure what you're saying here, but we descided not to reward for finality. It's really easy to shirk your duty in grandpa, aka tragedy of the commons, but it's also really easy to make bad things happen by rewarding it too much.
We only put the first two on chain though, right? Or maybe we put them all on eventually? I doubt this impacts much honestly. We do not want rewards to focus too much upon backing anyways. |
I was suggested that if the finality lag is bellow a certain threshold(3-4) to reward people, but I see your point we create incentives for everyone to blindly approve which is not good by any mean.
No, all backed statements are put on chain and validators get rewarded accordingly.
Yeah, I get it that this RFC would help with that, unfortunately it doesn't help if specific validators and nominators don't care about their rewards, but I guess this RFC and this paritytech/polkadot-sdk#5674, would get us far away. |
|
It's unclear how the claim queue could inform rewards, but.. If you want backer speed rewarded, then you could decrease backing rewards slightly if the parablock takes more than one relay chain block between appearing backed on-chain and being included. That's imperfect, but fairly easy and nothing really dangerous there.
We could collect and publish latancy statistics for validators, but not do rewards based upon them.
It's more they might not even notice, but this gives us a serious talking point. Also, our curret rewards are simply dangerous becuase they pay backers.
We'd still have all validators recieving all rewards types, because they'll manage approval votes sometimes. At least 1kv could start removing ones who no-show much though. Actually one weakeness: If a validator runs 24.5 seconds late, then they'd no-show lots but still beat their no-show replacements. In principle, we could tally no-shows seperately for another median vote. I've not suggested doing this because if they no-show lots then likely they're just overloaded and the replacement wins lots, but it's maybe still interesting to collect the data. We'd then have the option to add a small penalty in the future. |
Afaik there is no reason not to do this, so long as some noshows are excused, and the perccentile is 2/3 instead of median.
|
Added noshow collection and accounting to the rewards RFC in 3976449 |
text/0000-rewards.md
Outdated
| After the epoch is finalized, we share the first two lines of its `ApprovalTally`. | ||
| ``` | ||
| /// Our subjective record of what we used from some other validator on the finalized chain | ||
| pub struct ApprovalTallyMessageLine { | ||
| /// Approvals by this validator which our approvals gadget used in marking candidates approved. | ||
| approval_usages: u32, | ||
| /// How many times we think this validator no-showed, even only briefly. | ||
| noshows: u32 | ||
| /// Availability chunks we downloaded from this validator for our approval checks we used. | ||
| used_downloads: u32, | ||
| } | ||
|
|
||
| /// Our subjective record of what we used from all other validators on the finalized chain | ||
| pub struct ApprovalsTallyMessage(Vec<ApprovalTallyMessageLine>); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming these are put on chain, I am still of the opinion it's too much data.
First, with 1000 validators and assuming Vec capacity is aligned to a power of 2, this would be 12 * 1024 * 1024 = 12MB worth of records. Apart from overweight/overlimit blocks my concern is that we might hit allocation limits, esp. considering that things like .sort() might allocate as well (twice the amount).
We could perhaps change the types of approval_usages and no_shows to u16 (e.g. 2400 blocks per session and 10 approvals per blocks should fit into 64k), but still I'd favor paritytech/polkadot-sdk#1811 (comment) or any other protocol that only requires
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also I don't see a mention of these messages being signed with some key, but I assume this is the case?
What we could do is store only a small window of ApprovalTallyMessageLine messages in each block and a bitfield of validators for which we have already processed a message line. These way we could compute an approximation to the medians using some streaming algorithm. While allowing only a small batch of messages being submitted per block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes ApprovalsTallyMessage should be singed. Yes, we could run this entirely off-chain like I describe in paritytech/polkadot-sdk#1811 (comment) which incurs a failure mode. We could run this on a (true) system parachain too:
We've a parachain whose state is an MMR on the relay chain. All validatoes make a parablock for their ApprovalsTallyMessage so then their JAM-like accumulate function pushes the block hash into the MMR, well even an MMR maybe unecessary here. After this, all validators claims their rewards by making a second block that proves their rewards by proving their median(s) from the MMR. If a validator missed a block in this parachaun, then they cannot prove or claim their rewards, but the rewards chain itself has no real state, so it can always make progress.
The trade off is: One validator cannot claim their rewards because they missed something vs every validator cannot claim their rewards because more than half missed different things. We could've system parachain infrastructure that runs roughly the O(n^2) on-chain protocol too.
All of these work fine, under our Byzantine assumptions, but the parachain ones exploit the Byzantine assumptions more heavily: After we see everyone's votes then we might find it easier to corrupt 50% of validators.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've pushed changes that address the concensus component. I think a rewards parachain looks simplest because the governance fallback for theoff-core scheme could trigger way more than we'd like.
Around PVM overrunsWe've this minor issues that PVM metering doesn't capture wall clock time or actual CPU time, because issues like CPU cache misses have a hugh impact there. Yet PVM metering remains enormously useful because the PVM meter stops the parachain having indefinite overruns, and stops the parachain doing useful work during the overrun, but griefing attacks remain possible. We designed the original pre-PVM overrun scheme to address overruns in which parachains do useful work, but without the userful work component bad backers become much less likely. Proposal:
Imho we do not need this rewards system point initially, because simply making backers drop blocks that overrun likely suffices, but we know how to add it later if griefing by backers becomes a concern, or if we discover an exploit for free compute. |
Co-authored-by: Diego <[email protected]>
Co-authored-by: Diego <[email protected]>
Co-authored-by: Diego <[email protected]>
Co-authored-by: Diego <[email protected]>
|
@burdges What are the next steps to get this PR ready for review? Are there any missing details or anything else we should address? I’d like to start working on the implementation with my team |
| pub struct ApprovalsTallyMessage(Vec<ApprovalTallyMessageLine>); | ||
| ``` | ||
|
|
||
| Actual `ApprovalsTallyMessage`s sent over the wire must be signed of course, likely by the grandpa ed25519 key. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi! I have some questions about this message exchanging step.
- Regarding the messages, they should be shared using grid topology? Using an existent protocol or a new one?
- Will exist some timeout to receive some amount X of messages from other validators? What happens if we don't receive the messages in time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also the signed message should be very specific about which epoch it is about.
|
|
||
| Arguably after JAM, we should migrate critical functions to non/sub-parachain aka JAM services without mutable state, so this covers validator elections, DKGs, and rewards. Yet, non/sub-parachains cannot eliminate all censorship risks, so the near term benefits seem questionable. | ||
|
|
||
| #### Off-core |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still the off-chain steps provided here: paritytech/polkadot-sdk#1811 (comment) valid for this RFC? If so I think mentioning them in the RFC could make it more explicit.
It was never in too bad a shape, maybe you guys add what you think it needs to be more explicit, and I'll comment on those changes? I sent this PR from my personal github, not w3f, specifically so that fellows could edit the PR, but we can always change where the PR comes from if that's preferable.
AssetHub migration should kinda obsoleted some details here, so probably the JAM-ish flavor takes precedence. I guess in this one there isn't much difference, but some other upcoming W3F research RFC do wind up a little different for JAM.
As I say somewhere here, the order of implementation matters: The tit-for-tat game for availability rewards touches more subsystems in bad ways, but also seems like a low priority. Also conversely, all validators merely collecting their local data, and sending the messages,represents a huge step forward, even before we do rewards based upon it, because it means we can see who cannot talk to who and start to discuss the networking realisties. We'd really love to have even the collection part by the time the next spammening happens. The collection part does touch some pretty delicate susystems, like approvals. I think @alexggh was the last person to touch that code. |
Co-authored-by: Eclésio Junior <[email protected]>
Another mistake someone noticed
| We no longer require this data during disputes. | ||
| <!-- You could optionally track a `downloaded_one: Option<AuthorityBitField>` too, for the nodes from whome we douwnloaded only one chunk, but this seems like premature optimization --> | ||
|
|
||
| After we approve a relay chain block, then we collect all its `CandidateRewards` into an `ApprovalsTally`, with one `ApprovalTallyLine` for each validator. In this, we compute `approval_usages` from the final run of the approvals loop, plus `0.8` for each backer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@burdges since the candidate reward is per candidate, and approvals tally is per validator, when you say:
we compute
approval_usagesfrom the final run of the approvals loop, plus0.8for each backer.
here we should consider each backer of all candidates rewards?
Example:
candidates_rewards =
[
{backers: [...; 3]},
{backers: [...; 3]},
]
// approvals usage for a given relay block X
approvals_usage = {
validatorA: 5, // counted 5 candidate approvals
validatorB: 3, // counted 3 candidate approvals
}
given the example, when computing the approval_usages + 0.8 for each backer we should consider the 6 backers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I placed 0.8 here simply so that backers get paid less than approval checkers, but 0.9 or 0.95 sound fine too. It likely that 1 works because backers spend more than approval checkers.
I've now forgotten if I even considered the number of backers here. We could count only the ones the RC sees. A priori, we're maybe better off if we count them if we think they participate in availability, but I've not yet thought throught how that interacts with the tit-for-tat game.
alexggh
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some comments and my general thoughts, before we do any significant implementation effort. I think the first step would be to tidy this RFC to be clear what is actionable and implementable for the first version and what would be deferred for later.
| /// Our subjective record of out availability transfers for this candidate. | ||
| CandidateRewards { | ||
| /// Anyone who backed this parablock | ||
| backers: [AuthorityId; NumBackers], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This data is still already on chain, I wonder if we need it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not necessarily on the chain where we collect this data, not necessarily AH or RC. Yes, we're a validator so we do have this data ourselves, but maybe eiaser if we track this all together?
It's overall tracked within this system so that backers have no advantages over approval cehckers.
|
|
||
| ### Messages | ||
|
|
||
| After the epoch is finalized, we share the first three field of each `ApprovalTallyLine` in its `ApprovalTally`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to check the on-chain logic, does this mean that we can't compute the rewards at the block an epoch is finalized and we need a delay ?
What does we share means ? Do you envision a distribution algorithm to bring this Tallies to the block author, or will each validator append this when it is their turn to author blocks ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, rewards are ultiamtely computed using on-chain medians, so nobody can compute them locally, until enough votes come in.
| - Any existing rewards for on-chain validity statements would only cover backers, so those rewards must be removed. | ||
|
|
||
| We add roughly these proportions of total rewards covering parachain work: | ||
| - 70-75% - approval and backing validity checks, with the backing rewards being required to be less than approval rewards. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? I mean in total yes, because there is less backing work than approval work. But per candidate, I think it should even be more, because they are facing the higher risk and also more work (availability distribution) + potentially having validated spam candidates/forks, which never made it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm afraid someone might sabotage the back pressure, by making their node drop approval checks first when overworked. An approval checks should therefore always gross more than a backing check, even if the operator ignores the risks, which folks often do.
|
|
||
| ### Backing | ||
|
|
||
| Polkadot's efficency creates subtle liveness concerns: Anytime one node cannot perform one of its approval checks then Polkadot loses in expectation 3.25 approval checks, or 0.10833 parablocks. This makes back pressure essential. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we have other means to get back pressure. E.g. we do want finality proofs on chain, so we can have a back-off again once finality starts lagging.
But even without, I don't think it needs to be less: If rewards are equal, then I would already expect operators to not change the implementation, as there are no gains to be made.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll never find as fast acting a form of back pressure as simply doing less work when you're overworked.
We allow finality to lag much more than elves does, so on-chain finality proofs cannot always signal elves lag within any reasonable timeframe. We've some pretty sharp spikes soo, so even the several block delay for finality proofs sounds much too long.
If rewards are equal, then I would already expect operators to not change the implementation, as there are no gains to be made.
Yes, rewards being equal sounds mostly fine. I'm slightly worried backers get extra money under the table, but not sure anything could be done really.
I'm alightly worried people only recognize the backing role for various psychological reaosns, so backers earning even 1% less provides an extra defense against idiots who change stuff they do not understand. "I made a patch to increase rewards by prioiritize the all important backing task. Oh shit my rewards went down."
| pub struct ApprovalsTallyMessage(Vec<ApprovalTallyMessageLine>); | ||
| ``` | ||
|
|
||
| Actual `ApprovalsTallyMessage`s sent over the wire must be signed of course, likely by the grandpa ed25519 key. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also the signed message should be very specific about which epoch it is about.
|
|
||
| All validators could collect `ApprovalsTallyMessage`s and independently compute rewards off-core. At that point, all validators have opinions about all other validators rewards, but even among honest validators these opinions could differ if some lack some `ApprovalsTallyMessage`s. | ||
|
|
||
| We'd have the same in-core computation problem if we perform statistics like medians upon these opinions. We could however take an optimistic approach where each validator computes medians like above, but then shares their hash of the final rewards list. If 2/3rds voted for the same hash, then we distribute rewards as above. If not, then we distribute no rewards until governance selects the correct hash. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, not sure yet how we ensure this won't happen all the time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We simply do the median computaiton in-core then? That's simplest anyways.
text/0000-rewards.md
Outdated
|
|
||
| In polkadot, all validators run an approval assignment loop for each candidate, in which the validator listens to other approval checkers assignments and approval statements/votes, with which it marks checkers no-show or done, and marks candidates approved. Also, this loop determines and announces validators' own approval checker assignments. | ||
|
|
||
| Any validator should always conclude whatever approval checks it begins, but our approval assignment loop ignore some approval checks, either because they were announced too soon or because an earlier no-show delivered its approval vote before the final approval. We say a validator $u$ *uses* an approval vote by a validator $v$ on a candidate $c$ if the approval assignments loop by $u$ counted the vote by $v$ towards approving the candidate $c$. We should not rewards votes announced too soon, so we unavoidably omit rewards for some honest no-show replacements too. We expect the 80% discount for backing covers these losses, so approval checks remain more profitable than backing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this is the big reason to discount the backing checks slightly.
If desired, you can compute backing checks outside the RC too. Alice might've shitty internet and build some block X saying Bob backed X, but everyone else thinks Carol backed X, so then erveryone votes Carol and Bob doesn't get paid even though his backing appears on-chain.
Assuming 2/3rd hoenst this is biased towards the guys with better internet, while the RC method is biased towards the current block producer's opinion. It's possible the RC scheme is better in the sense that you do better by having a better connection to everyone. I donno here.
|
We do not alter the ELVES gadget in this proposal, merely instrument it, so.. If Alice no-shows, Bob & Carol cover for Alice, but then Alice checks before Bob & Carol, then Alice gets paid, but Bob and Carol do not get paid. We could alter the ELVES gadget to finish all the no-show covering checks, but not treat them as additional no-shows once approved. I'll expand upon that example: Alice gets her vote in, so she is getting some reward, and the candidate and RC block are approved. We keep the ELVES gadget running though because Bob and Carol started checking. Bob gets his vote in, so he is getting paid too. Carol comes in slow, and would've no-showed herself, so we do not pay her, but also the block is alraedy apporoved so this has not real impact upon anything but rewards. This would add complexity to the ELVES gadget and make it consume memory and CPU tiem for longer, so not necessarily worthwhile. I'm unsure how "politeness" works in this case: Bob and Carol have the right to send their votes, so nodes should gossip those votes, even though we think the block is already aporoved, becuase some node might not see the block as approved. This doesn't need to be addressed in this RFC or in an initial implementation, but I wanted to emnetion it since people are payng attention now. :) |
| /// Our subjective record of what we used from all other validators on the finalized chain | ||
| pub struct ApprovalsTallyMessage(Vec<ApprovalTallyMessageLine>); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given comment: https://github.com/polkadot-fellows/RFCs/pull/119/files#r2221892201
| /// Our subjective record of what we used from all other validators on the finalized chain | |
| pub struct ApprovalsTallyMessage(Vec<ApprovalTallyMessageLine>); | |
| /// Our subjective record of what we used from all other validators on the finalized chain | |
| pub struct ApprovalsTallyMessage((u64, Vec<ApprovalTallyMessageLine>)); |
A draft RFC for paritytech/polkadot-sdk#1811
Rendered
At a high level the points:
Relay chain block production matters, and should be paid reasonably, and better than any one parachain, but afaik 10% or 15% or 20% matters little.
This protocol requires only one new message type, but incurs some internal overhead in data collection, especially for the availability parts.
Approval checker rewards must be computed by an off-chain median protocol, because althoug hte machine elves gadget could run on-chain, doing so creates something biased and gives wrong results.
Approval checker statement must be paid strictly better than backing statements. I propose backers being paid only 80% of what approval checkers get paid, which winds up being 87% after other details.
Backers should never be paid unless the approval checkers get paid. Also neither should be paid unless the inclusion block gets finalized. This means there is not much point in computing the backers rewards on-chain, just add them in the new off-chain system for approval checkers rewards.
Availability re-distribution should also be paid by an off-chain protocol, but it's nastier than the approval checker one. We could postpone this in an initial implementation, or do the data collection and messaging, but omit the tit-for-tat strategy. Yet long-term validators do incur some bandwidth costs from availability redistribution so this avoids a nasty tragedy of the commons.
Availability distribution cannot really be paid fairly, so backers reduced rewards must cover this bandwidth cost.
In both those, we're seemingly paying more for compute than bandwidth, dispite bandwidth being more expensive than compute. This is not really avoidable, so really we're merging bandwdith and compute rewards, but providing some extra bandwidth rewards in one niche case.
Non-laziness hashes ideas are split off into https://github.com/burdges/Polkadot-RFCs/blob/nonlaziness/text/0000-nonlaziness.md