Skip to content
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

Correct validator rewards #119

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft

Conversation

burdges
Copy link

@burdges burdges commented Sep 16, 2024

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

@burdges
Copy link
Author

burdges commented Sep 18, 2024

Implementation stages:

  1. Approvals:
    a. Extract used approvals from machine elves gadget
    b. Send the message
    c. On-chain median computation
    d. Fix rewards, including replacing existing backing rewards
  2. Availability:
    a. Extract sent and recieved chunks information, add to used approvals record
    b. Add to used approvals message
    c. Off-chain rewards & stiffed computation
    d. Tit-for-tat record storage
    e. Tit-for-tat punishments
    f. On-chain rewards computation

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.
Copy link
Contributor

@alindima alindima Sep 23, 2024

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

Copy link
Author

@burdges burdges Sep 23, 2024

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.
Copy link
Contributor

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 ?

Copy link
Author

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.

approval_usages_medians.push(v[num_validators/2]);
}
```
Assuming more than 50% honersty, these median tell us how many approval votes form each validator
Copy link
Contributor

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 ?

Copy link
Author

@burdges burdges Sep 23, 2024

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.

@alexggh
Copy link
Contributor

alexggh commented Sep 23, 2024

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:

  1. Freeload by not gossiping their assignments and approvals and get their rewards.
  2. Gossip the assignments, but don't show up with the vote, in that case finality is lagging.
  3. Gossip the assignments and blindly vote, we already have disputes for this, so I don't think rewards helps here.

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:

  1. Were all the relaychain blocks produced in their slot then reward MAX_REWARDS_PER_ERA to everyone, otherwise decrease the pot of rewards that get split between validators.
  2. Where parachains slots occupied every relay chain blocks, then reward MAX_REWARDS_PER_ERA to everyone, otherwise decrease the pot.
  3. Is finality in parameters then rewards MAX_REWARDS_PER_ERA to everyone, otherwise decrease the pot. Note! This is probably not a simple thing to do :D.
  4. Is everyone in your backing group getting all of their statements on chain, you get MAX_REWARDS_PER_ERA, are some missing, everyone in the backing group gets less rewards.

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 ?

@burdges
Copy link
Author

burdges commented Sep 23, 2024

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..

Were all the relaychain blocks produced in their slot then reward MAX_REWARDS_PER_ERA to everyone, otherwise decrease the pot of rewards that get split between validators.

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.

Where parachains slots occupied every relay chain blocks, then reward MAX_REWARDS_PER_ERA to everyone, otherwise decrease the pot.

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?

Is finality in parameters then rewards MAX_REWARDS_PER_ERA to everyone, otherwise decrease the pot. Note! This is probably not a simple thing to do :D.

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.

Is everyone in your backing group getting all of their statements on chain, you get MAX_REWARDS_PER_ERA, are some missing, everyone in the backing group gets less rewards.

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.

@alexggh
Copy link
Contributor

alexggh commented Sep 24, 2024

Is finality in parameters then rewards MAX_REWARDS_PER_ERA to everyone, otherwise decrease the pot. Note! This is probably not a simple thing to do :D.

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.

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.

Is everyone in your backing group getting all of their statements on chain, you get MAX_REWARDS_PER_ERA, are some missing, everyone in the backing group gets less rewards.

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.

No, all backed statements are put on chain and validators get rewarded accordingly.

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

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.

@burdges
Copy link
Author

burdges commented Sep 24, 2024

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.

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.

We could collect and publish latancy statistics for validators, but not do rewards based upon them.

unfortunately it doesn't help if specific validators and nominators don't care about their rewards

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.

I guess this RFC and this paritytech/polkadot-sdk#5674, would get us far away.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants