[RFC-0011] PoS inflation adjustment

While peerchemist is correct that the aim is not to become deflationary, the txn fees are not included directly in the calculation of adjustment (just like pow rewards are not directly included), so it is still entirely possible that some time in the future the txn fees overtakes the pos rewards.

This proposal was discussed recently in a team meeting. We will attempt to simplify implementation and will continue to discuss it.

I did some coding to create a simulation. While doing this, I realized some of the math of the rfc isn’t quite right, but the spirit is still the same, as is all the discussion we’ve had on it. The simulation makes a whole bunch of assumptions, such as no PoW component and the same order of minters every year, but I think it is something that is worth playing with. Attached are some images representing the case of the ‘seasonal minter’ that people have been worried about. As you can see, it should pose no issue because the adjustment is an average over a year. Indeed, the ‘opportunistic minter’ would need to wait for an opportunistic year, rather than a season, and at that point they are missing out on quite a bit of compounded interest. I’m happy to answer questions about this simulation, it can be slow when run with >100 blocks and has a lot of assumptions embedded into it, but it shows some interesting details that I think are important to play with.

inflation.py (2.6 KB)
adjustment.pdf (24.6 KB)
outputs.pdf (35.1 KB)
newtotal.pdf (24.9 KB)

I’ll continue to play with it and maybe make some of it more pretty with time, but this is the general gyst.

2 Likes

Here is an updated version of the simulation. I have added in a tag for seasonal minting, as well as an inflation rate for PoW mining that is assumed to not participate in minting. I have made a number of changes, but the most important here is one that will most likely wind up changing the way rfc11 is written/coded. I believe the best way to implement this is to calculate the adjustment based on what the PoS reward would have been had rfc11 not been implemented, i.e. 1%. The most obvious result of this is that the first year behaves differently than subsequent years (as the adjustment has not boosted the PoS holdings yet).

The long-term result of this simulation (when run over 100s of years) is for the adjustment to match the PoW reward. For example, if PoW=0.02, then the adjustment will trend towards 2.5, corresponding to 50% participation. This is because that is the participation at which the increase of the supply due to PoW cancels out with the adjusted inflation of PoS. This is not quite realistic, as in reality the PoW is not a % inflation, but rather a fixed rate. I may try adjust this to better represent reality in the future, but it is of course impossible to fully simulate the entire network.

The other potential upgrade I might want to do, other than trying to put a legend or something on the graphs, is to add in the concept of ‘coindays’. This would be a very difficult upgrade, and I’m not sure I will be able to ever truly simulate coindays as they should be simulated.

inflation.py (2.9 KB)
adjustment.pdf (11.6 KB)
newtotal.pdf (10.6 KB)
outputs.pdf (12.4 KB)

In these images, blue is year 1, orange year 2, green year 3, red year 4, purple year 5. The ‘newtotal’ graph includes a brown curve because it has year 0 added in, which shifts all the years by 1. Plotted are the settings as they are uploaded here. I think this shows a pretty powerful case which is quite close to the current network stats: 20.5% participation, 3% PoW inflation.

2 Likes

I look forward to studying the simulations. This proposal seems certain to ensure that 1% inflation is maintained.

The next question, therefore, is whether it also keeps up the minting rate, and hence blockchain security?

It seems to me that the main risk is from “yoyo-ing” - that is, a low minting rate leads to 5% inflation, which leads to people rushing to mint, which means the inflation falls back to 1%. Do those new minters them lose interest and leave - which in turn repeats the process?

You are describing the ‘seasonal minter’. The solution to this concern is two fold. The first step is to understand that the adjustment is a yearly average. That means that it doesnt matter if people are minting more in the winter and less in the fall, the result is essentially an average of the whole year. So you get the same amount whether you mint in the winter or the fall. You can play with this concept by turning on the ‘seasonal’ trigger in the simulation.

This means the way to game the system in this ‘yo-yo’ type procedure is to game it year-to-year. So you would withhold your coindays for a full year hoping that next year the participation is less than this year. The solution here is to impose a new type of restriction that hasn’t been brought up before but that I have been discussing with some of the devs. Essentially, we would impose a maximum coinday reward. In the current code, if you held your coins for 10 years and then mint, you would receive about 10% reward. I would make it so that after 365 days you stop accruing additional reward. This would entirely defeat any attempt to game the system year-to-year, because if you mint now and again in a year you would get the same reward next year plus you would get this year’s reward.

With these considerations, I do not believe a ‘yo-yo’ effect is possible given rational actors.

The way you phrase your concern sounds like less of an attack and more of an economic concern. So we imagine individuals who simply would not mint at 1% (i.e. are not current minters) but would at 5%. So first off, we are assuming that rfc11 increases security over the current protocol. Next, we assume that there are a number of these people, all with different % thresholds that they would mint at. The result is something akin to a Dutch auction, where the system will locate the average threshold % and operate there. Any oscillatory behavior comes in by assuming that the threshold to turn on a minter is different than the threshold to turn off, i.e. at 5% a minter becomes interested and is still interested when it lowers to 4%, but decides to turn off the minter at 3%. This is possible, and would create oscillations, but it is vital to understand that a) these oscillations would by definition be above the current mint/security difficulty, and b) that the oscillations are averaged throughout a year, so they are slow and likely have a complex relationship with actual market interest in the coin.

Yes, that’s how I saw it. Part of the overall solution can include Peercoin’s own education to coinholders; so rather than saying minters can “get up to 5% per annum”, we should say: minting is 1%, with a possibility of more for maintaining security, i.e. Peercoin’s selling point should be the security guarantee, rather than the 5%.

Right, but it should also be noted that % gains on a coin that is going up in value is very different from % gains on a coin going down in value. It is entirely possible this form of market-driven oscillation already exists, and we simply aren’t able to distinguish it. In that case, rfc11 could potentially act as a damper for market-driven oscillations by offering higher reward when interest wanes and lower reward when it rises.

I have heavily modified the RFC, and am doing a few re-reads before I commit back to the Peercoin branch. Biggest changes include using nAnnualStake instead of nAnnualPoSRewards, which frames the whole implementation a bit differently, and addition of the 1-year limitation on coinage.

3 Likes

RFC pushed, also I updated the simulation to have a more realistic PoW, namely a constant PoW block reward rather than a % of supply (though you initialize using % of supply still because then it’s not dependent on the specific parameters used). You can see that PoS becomes dominant after ~80 years, even without any reduction in PoW reward (i.e. InflationAdjustment trends toward 1). This is realistic because the PoS supply grows as a % while the PoW reward grows as a constant number.

The following simulation uses the same values as last time, but runs it for 80 years. I only use 20 blocks per year to cut down on simulation time.

inflation.py (3.0 KB)
adjustment.pdf (41.2 KB)
newtotal.pdf (40.1 KB)
outputs.pdf (45.2 KB)

3 Likes

As have been discussed already, RFC11 means that there will be additional load on the nodes.
History of the past ~50k blocks has to be parsed in order to validate the PoS reward properly with RFC11. This can be done in RAM, so that node scans 50k blocks during the startup or by indexing the needed data in the database. Scanning during startup will increase the start time and maybe cause some discomfort to users.

Implementation in the block database will increase size of each block on disk by ~3kb, which means extra 1.5 GB to store the blockchain.

I thought the idea was to do it in RAM since you are going through the blocks anyway, it’s just one or two extra numbers to keep a running tally of. How much discomfort are we talking about?

Won’t be able to tell before we implement it and run out tests. I guess a 2-3min tax on the app load time (on the Raspberry Pi) is acceptable.

You are talking about calculating nAnnualStake, but is calculation of nMoneySupply not a similar problem? How was the calculation of nMoneySupply done for getinfo before v0.8?

in 0.7 total money supply and block mint amount was written in every block on disk, which took up extra space, but made output of these two values very easy and fast.

for annual stake we can’t just store the amount as a number, because we won’t be able to expire old stake records.

there are at least three options to keep tabs on stake amounts, simplest is to scan last 55k odd blocks and fill structure of 366 stake amounts for last 365 days +today. at 0000 gmt we would rotate today to yesterday, etc, zeroing the latest day on record and starting to fill it up again with stake values. this solution requires extra work to be done at the start of the daemon before pos rewards can be validated. it will be slow, as we need to parse transactions of all pos blocks.

simplest way to speed it up would be to store this structure as part of block record, meaning every block will contain a year worth of records of daily stake state. it would be about 4k for every block if done head on.

more difficult solution would be to have an extra db for stake records that need to be kept in sync with block state.

Perhaps each block could contain the running total for that day, the total for the previous 364 days, and a reference to which block was >365 days ago. I might not have the logic quite right, but the idea is to avoid the large repetitive structure and replace it with a bulk total that you can add the recent to and subtract the old from. It would of course take a year before every block contained the data needed to be quick referenced a year later.

Also, just to be clear the ram solution would only need to parse each coinstake transaction, not every transaction in all the blocks, right?

Oh, and would the RAM solution affect just the initial sync, just restarts of the client, or both? Can we save the structure to the local harddrive on shutdown?

I’d like to seriously propose a decrease of maximum adjustment to 4 from 5. This would mean the most reward for participation under 25% and would reduce attack vectors based on compounding interest. The downside is that we would have to use ‘up to 4%’ in the messaging instead of ‘up to 5%’. The reason I propose this change is that I underestimated the current participation in the chain, and we are likely closer to 25% than 20% currently.

1 Like

I’m not sure if I understand the problem with max adjustment being 5 or even 10 for that matter. if only 1 in 10 coins are minting like we have on testnet what is the issue with increased coefficient? don’t we want to increase minter participation when it’s low? in the end it’s still only 1 percent of money supply per annum.

i would rather set it to 10 and be ready to provide incentives when bull is back and everyone thinks to move coins to exchange.

The issue is that attacks like stake grind and N@S can be exacerbated by compounding interest. If someone builds a private chain (N@S) with a greatly reduced minter participation but a similar PoS difficulty (stake grind) then they could wind up taking advantage of significant compounding interest on a series of large stakes just before they release and reorg the main chain to their private chain. The attack is complex, but the minimum stake at which it becomes profitable can be seen as roughly the % at which max adjustment takes over. So for max of 10, this attack could be profitable at 10% total coin ownership. For max 5, it takes 20% coin ownership. At max 4, 25%.

It is important to make the distinction between ‘total coin ownership’ and what would be required for a ‘51%’ attack, because they are very different. Currently, the 10% total coin ownership would have upwards of 40% mint majority and would likely be able to carry out double spends and the like with some chance of success (due to the <25% mint participation). So even 10x would not be absolutely abhorrent, if we assume a certain level of decentralization. However, at the same time, the richest addresses in Peercoin have 6% coin supply each, so it’s not completely out of the question to imagine someone with 10% total coin ownership.

1 Like