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

Inflation: tune default parameter values to obtain desired behavior #1130

Closed
Tracked by #2006
brentstone opened this issue Feb 7, 2023 · 10 comments · Fixed by #1992
Closed
Tracked by #2006

Inflation: tune default parameter values to obtain desired behavior #1130

brentstone opened this issue Feb 7, 2023 · 10 comments · Fixed by #1992
Assignees
Labels

Comments

@brentstone
Copy link
Collaborator

Once the inflation+rewards (and possibly slashing) is implemented, we need to properly tune the default parameters to obtain the desired behavior. At the moment, reasonable but somewhat arbitrary values are in the codebase as placeholders.

@brentstone brentstone added the PoS label Feb 7, 2023
@cwgoes
Copy link
Contributor

cwgoes commented May 19, 2023

By "default parameter values", do you mean the starting values (for e.g. proof-of-stake inflation rewards), which will then be adjusted by the controller?

@cwgoes
Copy link
Contributor

cwgoes commented May 23, 2023

Probably the starting values will all just be zero, except the proportionality constant, which we should initially pick so that it can sweep the range in a month.

@cwgoes
Copy link
Contributor

cwgoes commented Oct 26, 2023

@brentstone to make a quick writeup which we will then review

@brentstone
Copy link
Collaborator Author

brentstone commented Oct 26, 2023

The first three parameters to tune are the block proposer reward r_p, the minimum block proposer reward c_p and the block vote/sign reward r_s. See here for how these work.

In summary though, the fraction of a block's PoS rewards that go to the block proposer solely for proposing the block is r_p * (f-2/3) + c_p, where f is the fraction of the consensus stake that signed the block. The fraction of the block rewards that go to all validators who signed the block (further doled out as a proportion of a signer's stake) is simply r_s.

Currently, we have r_p = 0.125, c_p = 0.01, and r_s = 0.1. This means that 10% of block rewards go to the set of all signers. Anywhere from 1% to 5.17% is allocated to the block proposer just for proposing the block. The remaining 84.83% - 89% goes to the set of all consensus validators just for being in the consensus set. As an example, a block proposer (who presumably also signs the block) with 10% of the consensus stake and who includes votes from 80% of the consensus stake would themselves earn 12.65% of the block rewards with the current configuration.

Another consideration in choosing r_p and r_s is how to ensure that a block proposer is always incentivized to include votes in the block (i.e., as opposed to just satisfying the minimum 2/3 and relying on having a large stake to collect larger rewards for signing and being a consensus member). There was once an old github discussion from @cwgoes, but I can't find it, but nevertheless I think I can recall and summarize:

Consider the derivative of a block proposer's total rewards (this expression is in here) w.r.t the signing fraction f:

dR_prop / df = r_p * (1 - x) - r_s * x / f^2

where x is the block proposer's stake as a fraction of the total consensus stake. Consider an extreme case where the block proposer has x = 1/3 and f = 2/3. The block proposer is incentivized with larger rewards R_prop if it waits to include more signatures for a larger f if r_p > 9/8 r_s. This initial choice of values satisfies this with some wiggle room. Obeying this relation for r_p and r_s maintains the incentive for all values of f larger than 2/3 and values of x smaller than 1/3 as well.

So what are the thoughts on the current distribution?

Side note: we should also prob make c_p a governance-configurable parameter, as it is currently just hard-coded in the impl.

@brentstone
Copy link
Collaborator Author

The next two parameters to tune for PoS are the PD controller gain factors kD and kP. See https://specs.namada.net/economics/inflation-system#detailed-inflation-calculation-model for how they work. The current values for both are 0.1. I'm not sure what the targeted behavior is though, and there are lots of factors to consider when trying to analyze this, but let's consider some examples. I'm going to assume that we start at basically a 0% rate. The controller determines the new inflation based on the previous inflation, and at the end of the first epoch in a network, the last inflation is 0, hence my assumption.

We know the target staked ratio is 2/3, the total tokens at genesis is 10^9 NAM (10^15 namnam), and we expect 365 epochs per year. Let's consider some random cases with the current gain values:

  • 10% of tokens initially staked and no additional staking each epoch:

    • after the first epoch, the inflation rate is 0.5%, it is 5% by epoch 9, and it maxes out by epoch 18.
  • 10% of tokens staked, growing by 3% each epoch until a ratio of 1:

    • the rate starts at 0.5%, grows to 5% at epoch 12, maxes out at 6.2% at epoch 21 when the locked ratio hits 2/3, then starts decreasing slowly. By epoch 50, the rate is down 1.5%
  • 40% of tokens initially staked with no additional staking:

    • rate starts at 0.2%, grows to 5% by epoch 19, maxes out at epoch epoch 38
  • 40% of tokens staked, growing by 3% each epoch until a ratio of 1:

    • rate starts at 0.2%, grows to 1.6% at epoch 10 (hitting target ratio), falls down to 0% at epoch 21, then stays at 0
  • 40% initially staked, with a 3% change each epoch. However, now the locked ratio increases by 3% until it hits 80%, at which point it then starts to decrease by 3% until hitting 40% again, then it will start increasing again by 3% and so on so forth:

    • the rate fluctuates but its scale gradually grows over time (because it spends more epochs below 67% locked rate than above). The trends and inflection points are:
      • rate starts at 0.2%
      • grows to 1.6% at epoch 10
      • falls to 0.8% at epoch 21
      • grows to 3.2% at epoch 39
      • falls to 2.4% at epoch 47
      • grows to 4.8% at epoch 65
      • falls to 4% at epoch 75
      • grows to 6.5% at epoch 95 (stopped looking after epoch 100)

Overall, I think the current values are at worst pretty close to what we would want in good behavior. Let me know your thoughts

@cwgoes
Copy link
Contributor

cwgoes commented Oct 30, 2023

So what are the thoughts on the current distribution?

I think these parameters are fine for the initial launch sequence, we can always tweak them via governance later if something merits it.

I'm not sure what the targeted behavior is though, and there are lots of factors to consider when trying to analyze this, but let's consider some examples.

For the PD controller parameters, typically one would tune these by selecting a timerange in which you want the controller to be able to sweep the entire input parameter range (in this case, the inflation paid to stakers). I'd say that we want to be able to sweep the parameter range in a month - this should give us an equation to solve for kD and kP. Let me know if this makes sense.

@brentstone
Copy link
Collaborator Author

For the PD controller parameters, typically one would tune these by selecting a timerange in which you want the controller to be able to sweep the entire input parameter range (in this case, the inflation paid to stakers). I'd say that we want to be able to sweep the parameter range in a month - this should give us an equation to solve for kD and kP. Let me know if this makes sense.

By sweep, do you mean a full cycle of rising and falling with the range of 0 -> max_reward_rate? Regardless, I think it is more complicated than solving a simple equation because the dynamics of how the locked ratio changes and what its values are will affect this sweeping time significantly too. If this one-month sweeping is how we want to determine kD and kP, I think we should define some way that the locked ratio changes in a test (i.e. like some of my earlier examples) and tune the params to such that the rate sweeps in one month. Something like:

  • Initial locked ratio is X and once the reward rate hits max_reward_rate, set the locked ratio to 1 and see how long the reward rate takes to fall back to 0
  • Initial locked ratio is X and increases by Y until the locked ratio hits 1, how long does the reward rate take to get back down to 0? Does it ever hit max_reward_rate?

@cwgoes
Copy link
Contributor

cwgoes commented Oct 31, 2023

For parameter picking we can say that the rate of change is constant; this should give us an equation to pick kP and kD.

@brentstone
Copy link
Collaborator Author

Ok what are thoughts on this: start with a 10% locked ratio that increases by 4% each epoch until it hits 100% and then remains there. With kP = 0.25 and kD = 0.25, the full range of the rate is swept in 31 days. It hits the maximum rate in epoch 10, stays there for 6 epochs until the locked ratio exceeds 2/3, then falls down to 0 by epoch 31.

@cwgoes
Copy link
Contributor

cwgoes commented Oct 31, 2023

Ok what are thoughts on this: start with a 10% locked ratio that increases by 4% each epoch until it hits 100% and then remains there. With kP = 0.25 and kD = 0.25, the full range of the rate is swept in 31 days. It hits the maximum rate in epoch 10, stays there for 6 epochs until the locked ratio exceeds 2/3, then falls down to 0 by epoch 31.

Thanks; I think this is fine for defaults.

@brentstone brentstone mentioned this issue Nov 8, 2023
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants