I want to implement this, so does anyone have a formula for dynamic block durations instead of a fixed target of 10 minutes?
Essentially, you would have to change the difficulty every block, or define the difficulty in terms of passed time. AFAIR The Kimoto Gravity Well does both: How does the Kimoto Gravity Well regulate difficulty?– Murch ♦Mar 20, 2015 at 10:06
@Murch I already use Kimoto Gravity Well, but it changes the difficulty but not the blockduration?– MaestroMar 20, 2015 at 12:22
Sorry, it's been a year since I read about KGW. If I recall correctly, there was some altcoin that accepted blocks at a receding difficulty the more time had passed, I thought it was KGW that did that, but alas I seem to misremember. Also, now that I think about it, that might come with some unique attack vectors to replace the chain leaf by mining a higher difficulty block redated to an earlier time.– Murch ♦Mar 20, 2015 at 12:33
1How do you want the block duration to change? That's the hard part. After that, the formula is essentially the same, one of the input parameters (the target block time), just changes.– morsecoderMar 20, 2015 at 16:07
1@NickODell No? Suppose you have a chain that almost receives no transactions for 10 years, but it must be ready for 1 month of high-traffic. If you make the block-duration shorter to be prepared, then you have 10 years of empty blocks to store. If the duration was dynamic, you could have blocks which span 1 month (only 120 for 10 years), and then switch to 1 minute when needed.– MaestroMar 24, 2015 at 13:00
Block duration is only controlled by difficulty (although indirectly) and network hashrate, so you'd want to increase difficulty when there are very few transactions in the last X blocks, and vice versa, decrease difficulty when blocks become too full, but also decrease difficulty when there is a low hashrate, and increase difficulty when there is a high hashrate.
At the same time, you'd need to incentivize mining, so you might want to have a reward relative to target time, instead of constant per block, as otherwise miners could spam the network in order to increase revenue.
Let's say, we are aiming to adjust from looking at the last 100 blocks for blocks that are 50% full.
findNewBlockTime(): newTimeTarget = (avBlockInterval100)*(0.5/averageFullness); //shorter interval with many transactions, longer with less setReward(): newReward = newTimeTarget*totalIntervalReward/rewardInterval; //rewardInterval could be four years like Bitcoin, or some other interval, with four years totalIntervalReward would be 11.5M coins for first interval calculateDifficulty(): newDifficulty = sumDiffLast100/last100BlocksTime*newTimeTarget;
You might be interested in what I wrote about the subject here. You can make a protocol change where miners are given a choice of their block's "weight", and their decision can then be used to set the global frequency parameters.