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

Control validator security budget #3702

Closed
bedeho opened this issue May 3, 2022 · 11 comments
Closed

Control validator security budget #3702

bedeho opened this issue May 3, 2022 · 11 comments
Assignees
Labels

Comments

@bedeho
Copy link
Member

bedeho commented May 3, 2022

Background

Right now (Olympia), it is not feasible for the council to set the total $JOY reward devoted to validators over a given period of time, this not only negatively affects the testnet incentives, but it also

Proposal

Introduce ability for this to be controlled directly. Add support in proposal #3626

┆Issue is synchronized with this Asana task by Unito

@traumschule
Copy link
Contributor

The council should be able to set max_inflation and ideal_stake with low grace period (similar to max validator count).

@kdembler kdembler added the next-runtime-upgrade Next runtime upgrade label Jan 20, 2024
@mochet
Copy link

mochet commented Jan 20, 2024

For some context on urgency with this GH issue, this forum post shares a % look into how much we are currently paying validators/nominators, it is a significant amount: https://pioneerapp.xyz/#/forum/thread/809

@kdembler
Copy link
Member

Needs estimation of the effort

@kdembler
Copy link
Member

To give a status update: we've considered including this functionality in Nara but decided not to.

The validator rewards are controlled by a curve defined in the runtime code:

pallet_staking_reward_curve::build! {
const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
min_inflation: 0_007_500,
max_inflation: 0_030_000,
ideal_stake: 0_500_000,
falloff: 0_050_000,
max_piece_count: 40,
test_precision: 0_005_000,
);
}

Our initial idea was to add a proposal that can adjust the parameters to construct the curve as seen above. However, Mokhtar has pointed out that the process of compiling the curve - using the parameters to calculate set of curve points - is currently done during runtime build and may be too heave of a calculation to actually do at runtime with a proposal.

So an alternative idea is to have the curve itself be a mutable storage value and have a proposal that changes the curve directly (not its parameters). That means we would compute the curve off-chain and only submit the result of that calculation as a proposal.

This however requires some basic tooling - we need to be able to construct the curve given a set of parameters but also to somehow verify a proposed curve. We need to research how the curve is stored and what the inputs to a proposal would look like

@ignazio-bovo ignazio-bovo self-assigned this Feb 26, 2024
@ignazio-bovo
Copy link
Contributor

We want the same curve structure just the ability to change parameters, right? @bedeho @kdembler

@kdembler
Copy link
Member

@ignazio-bovo I think yes, but what exactly do you mean by the curve structure?

@ignazio-bovo
Copy link
Contributor

ignazio-bovo commented Feb 27, 2024

The math formula being used.
I have figured out a way to do it in a clean way, ETA: ??days (depending on what do we want to change)
EDIT:
The way substrate construct the curve is by using a macro, for which the curve is quantised into around 1,000,000 intervals (via while loop with a lot of iterations)
The curve lifetime is also marked as static, which means that the full array of quantised points is stored in the actual "static" section of the binary file.
I am convinced that if we do want also to be able to change the ideal staking rate, then we need to come up with our own curve implementation and I am not sure we want this

@kdembler
Copy link
Member

So Mokhtar's point from his initial research was that we don't want to compute the curve during runtime, so if we want to update it dynamically, we would replace the full curve (1,000,000 points) via a proposal, not specific parameters. Are you thinking about the same thing or have a different approach in mind?

@ignazio-bovo
Copy link
Contributor

ignazio-bovo commented Feb 28, 2024

I think that if we do want to replace the curve in its entirety we have to come up with our own implementation for this basically
#3702 (comment)
And not relying on the PiecewiseLinear struct provided by substrate
Otherwise if we just want to reduce the amount the validators are receiving we simply scale the result from era_payout

@ignazio-bovo
Copy link
Contributor

ignazio-bovo commented Feb 28, 2024

Premise:
On the runtime we are using the following https://github.com/ignazio-bovo/joystream/blob/1e092cc0d55bf710a68d9787ad7e00d3a93131c4/runtime/src/lib.rs#L528 to compute the era payout.
The era payout is defined as

	/// Returns the amount to be paid to stakers in this era, as well as whatever else should be
	/// paid out ("the rest").

The following function internally uses this quantisation for the actual formula to be computed:

pub struct PiecewiseLinear<'a> {
	/// Array of points. Must be in order from the lowest abscissas to the highest.
	pub points: &'a [(Perbill, Perbill)],  // points (x,y) for the function 
	/// The maximum value that can be returned.
	pub maximum: Perbill,
}

On a call with @kdembler we discussed the following 3 approaches, which might satisfy various objectives. We just need to be clear on the objectives and the methodologies:

  • scale the output of era_payout: this will allow us just to reduce / increase the values of the amount of JOY destined as validator rewards, without touching anything else.This is very simple and low risk.
    To be explicit the payout for stakers will change from era_payout to const_less_than_1 * era_payout.
    We allow this constant to be updated via proposal.
    The following below 2 alternatives are in case we also want to be able to modify the ideal_staking_rate via proposal
  • Provide a proposal where we actually specify all the points used internally by the PiecewiseLinear (which will be entirely stored on chain). The number of points to be specified is however very high (approx 1,000,000) and needs to be precomputed offchain. However using this approach we are re using the implementation for computing the payout provided by Substrate
  • provide a custom implementation of the era_payout that computes the payouts for validators in the desired scale. This implementation will be based on runtime parameters that can be changed via a proposal. I want to remark that this implementation will probably look like a math formula like we did for the AMM, for which a result can be computed in costant time. This is different from the previous approach in the sense that here we have to write our own implementation instead of relying on the PiecewiseLinear construct.

In any case in all of the three approached we should just modify the EraPayout type trait in the pallet_staking::Config which specifies the implementation of the era_payout. If we stick to that, there is no need to fork substrate pallets

@kdembler
Copy link
Member

kdembler commented Mar 1, 2024

We discussed that the simplest approach of introducing some mutable multiplier applied on top of curve calculation should be good enough for our usecase. The only open question at this point is whether we should introduce some min/max value validation in runtime

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

No branches or pull requests

6 participants