Update Tari's Difficulty Algorithm

I’m sure everyone is well aware of the large hashrate swings resulting in certain lanes dominating block production periodically or others getting drowned out entirely. This is causing block times to temporarily exceed the 2min target - often approaching 3min or more and sometimes resulting in chain reorgs many blocks deep.

I was thinking about proposing a modified DGW/MultiShield implementation, but I saw @blackwolfsa 's issue here about adding a consecutive block penalty to Tari’s current LWMA implementation. This seems like a much simpler/more elegant solution to me, and I’m of the belief that smaller architectural changes are typically better when it comes to consensus.

What are everyone’s thoughts on implementing this or something else like Digibyte’s MultiShield?

@blackwolfsa is there any reason that you decided not to go ahead with this proposal?

3 Likes

Its still in proposal stage. Changing the PoW is something that needs to be approached with caution and enough time.

But the lanes should not effect each other. But target difficulty changes is inherant to the design of pow and an a side effect of mining. Miners will swap to and from a chain if its more or less profitable to do so. That will just impact that chain, but should not impact the other chains. See my explanation on the other post about pow.

My proposal is about reorgs which we dont see atm.

2 Likes

Sorry, I didn’t mean to imply that hashrate on one lane is directly impacting block times on another - I am saying that the slow adjustment of the LWMA paired with the violent hashrate swings (in both directions) are resulting in overall block times exceeding the 2min target.

This is part of the problem, right now the ability to mine many blocks in quick succession is resulting in pools gaming the network to exploit small windows profitability on a particular lane, after which they usually switch off/abandon the network. You can see others observing this behavior in the hashrate concentration thread. This is causing a “hangover” effect with these hyper-fast blocks in the LWMA difficulty calculation window. Your solution somewhat remedies this by preventing these hyper-fast blocks in the first place.

I understand you initially proposed this to solve reorgs, but I believe it would indirectly solve some of this blocktime variance issue as well.

You also mentioned “tuning some of the parameters to make it adjust quicker” in your issue, which is the most appealing part of your proposal. If we could just shrink the window from 90 to 45, for example, that would be a much simpler fix compared to implementing something entirely new like DGW/MultiShield or an EMA. Maybe I misunderstood and you only meant tuning the target_time parameter and not block_window?

Also, we do see reorgs every day as far as I know. Just glancing at the network as I write this I can see a 3 block reorg from 27893-27895 with 4 blocks mined in rapid succession ~1min. It’s not a massive reorg, but it is an issue - and if bridge limits are removed like many in this community are asking for this could become significant unless confirmation requirements are raised (which has UX tradeoffs).

2 Likes

Bridge safety limits are an entirely different conversation, and I am of the opinion to keep it on the safe side. Most crypto hacks and attacks that steal money are targeted at a bridge.

But the LMWA jumps relatively quickly. But if you make the block window too small, it jumps too erratically. Having block times that are not exactly 2 mins are fine. A good example of this is Bitcoin, it only adjusts the difficulty every 2 weeks. Now I know they have much, much higher hash rates, so it’s difficult for it to swing.

Block target time is only there for an estimate for the pow and so you give the network time to sync new blocks. As long as the avg block time is roughly 2 mins, its fine.

With Mythos and other AI amlified security work, I agree it’s a good time to keep the bridge limits on the safe side for now.

I have published a tip about this: feat: adds tip004 pow changes by SWvheerden · Pull Request #174 · tari-project/rfcs · GitHub

1 Like

I would love to be able to mine and hodl XTM again. But I cant because of the hashrate swings. Even though I dont sell the XTM I mine, I cant in good conscience mine it as a charity, which is what it is right now. A new difficulty targeting algo would definitely help build that loyal miner base I think we want.

2 Likes

I think its good to be honest about this, PoW swings are going to be a thing for smaller pow chains like Tari, nothing we do can stop this. We can try and optimise how its handled, but it will happen, its part of the economics of PoW.

A clever Rx Pool will be able to mitigate the algo changes very easily as the hardware required to mine RxT vs RxM is exactly the same. Sha3 vs C29 vs Rx{T/M} is different, in that it is ASIC/FPGA vs GPU vs CPU.

1 Like

While I’d love to see the wild RxT and C29 swings gone, I’m not sure an incremental penalty, exponential or not, is the answer - wouldn’t that just make gaming the swings more predictable?

It’s easy to redirect hashpower, so now instead of booming for 4-5 hours, while the current algorithm slowly catches up, one could push for 2-3-4 quick blocks, and then redirect elsewhere, since no-one is going to find more blocks in that lane anytime soon. And, depending on how the penalty peters out, it could also be quite predictable when a given POW lane is ripe for the next push.

I could very well be missing something but couldn’t a simple penalty on consecutive blocks in a lane make for even wilder swings and maybe even fewer blocks found by the regular, non-switching miners?

the “penalty” only applies till a nother block is mined by any other alogrthim. All you are doing is making it harder to mine consecutive blocks. Its not going to increase the mining difficulty, any more than the current lmwa does.

Per our discussion from yesterday’s Tari Show.
I am going to push to code for this, but I added debug code to the node to print out the stats from the difficulty calculations.

But on the last 1000 blocks we have the following:
Avg block time: 124
RandomXMonero: 17,041 blocks
Sha3: 17,031 blocks
Cuckaroo: 16,257 blocks
RandomXTari: 16,186 blocks

These stats show that the difficulty adjustment is doing its job

I am digging more into the seeing if we can adjust quicker and the effects of that

EDIT: cant seem to upload an image, but image shows all 4 algo’s with their avg solve times, and its all around 8 minutes.

Solve times for each algo, C29 and RxT have high fluctuations with pools jumping on and off.

I can’t post my previous simulations here either. I’m working on a workaround.

The sweet spot for the block window seems to be around 45 - perhaps even a little bit lower. But not <=30. If we’re only going to do one update in the near-term, the block window should certainly be decreased from the current 90.

Like you said in the show, this isn’t going to prevent the issue entirely, but it will mitigate it significantly, and updating LWMA is a much simpler change compared to multishield or implementing DGW for each separate lane. That is the primary appeal here - it’s minor enough to be a “quick” and non-contentious hardfork while still providing some necessary relief.

I want to put the multishield DGW thing to bed.

In terms of DGW its a simple moving avg, we use a Linear moving avg. I would argue the LWMA is better than a moving avg since the LWMA weights the most recent blocks more than a simple avg. This gives a better response in terms of Diffculty up or down.

Multishield uses a moving average with a geometric mean.
They have a Moving avg for each algo, and then they calculate the geometric mean between all.

Tari uses the LWMA and we skip the nth sqrt of the geometric mean.

So for example :
s_pow, c_pow, rm_pow, rt_pow being the pow for each algo
Multishield total Pow would be: 4^sqrt( (s_pow )(c_pow)(rm_pow)(rt_pow) )

Tari total Pow would be: (s_pow )(c_pow)(rm_pow)(rt_pow)

So we just skip the sqrt step as this is a floating operation which means the value is different on each cpu type, as well as not being a precice number. The downside is where the Multishield value would fit in a u128, we need a u512 to store this, so its a larger number.

Then another difference is the Multishield feeds in the current timestamp difference into the DAA, where we only feed in the actual mined blocks, so our algo has a 1 block delay. Making this real-time adds a whole range of complications which I dont think is worth it.

So where does this come to, There is big differance between Tari’s DAA and Multishield/DGW. Changing it wont make any differance

I agree with you. I want to put this entire issue to bed. I dislike that I feel like I’m repeating myself over and over and potentially coming across as confrontational/argumentative when I’m just trying to fix a very clear issue with the network. But I feel that I have to keep doing it because I see obvious potential for Tari to improve here and I’m sick of watching us bleed some of our most valuable community members/supporters because miners appear to be treated as an afterthought.

Calling DGW “a simple moving average” is a bit of an oversimplification and slightly inaccurate. DGW was specifically created to improve upon SMAs, and has a dynamically adjusted block window, time-based dampening, and real-time difficulty adjustments.
LWMA with a consecutive block penalty and reduced block window should perform similarly to DGW on the way up when handling these hashrate spikes, but will be much slower to adjust on the way down since difficulty isn’t retargeted on LWMA until after the most recent block is mined. We don’t have the “gravity well” signature to DGW that brings difficulty down immediately after a large miner leaves the network.

This real-time adjustment is the key feature both of these algorithms share and is likely what we would need to fix the blocktime variance entirely.

There are pros and cons to this as well, of course, with the largest con being complexity. You are absolutely correct there - they would both be massive changes going beyond just the core software. The pro is, block times would almost always be right on target. I’m not suggesting we attempt this right now, or ideally ever. My hope is that reducing the block window paired with this consecutive block penalty will be enough, but we’ve both acknowledged it may only mitigate the issue and not fix it entirely.

FWIW, Meowcoin has a similar PoW implementation to Tari with multiple lanes + merge-mining and I’ve just learned they use a block window of 45 for their LWMA.

1 Like

Yeah, I am not trying to come across as confrontational/argumentative. Everything we do here has some pros and cons, and its up to us to find the best route. I hope to be able to publish some results soon of a few simulations I am running, and we can compare if its worth the tradeoffs.

1 Like

Here is my simulation results

TLDR

45 vs 90 block window, 45 response twice as fast, but has double the difficulty variance

## Difficulty variance with a % change on the solve time

**

Variance Rate 0.1**

### Variance Rate 0.2

Block Window Mean Avg Min Max % Mean % Avg % Min % Max
30 100567221 100606923 93621172 108338610 0.56722164 0.60691833 -6.3788295 8.338606
45 100641155 100652757 94847753 106614700 0.64115524 0.6527543 -5.1522493 6.614709
60 100523816 100526996 94485835 105380965 0.52381754 0.5269885 -5.5141687 5.3809643
80 100550608 100557026 96357879 105233207 0.55060387 0.55702925 -3.642118 5.2332044
90 100300070 100328873 96345624 104363222 0.30007362 0.3288746 -3.6543787 4.363227
110 100305686 100263832 96158393 104444062 0.30568838 0.263834 -3.8416088 4.4440627
150 100768785 100735141 98096177 103426807 0.7687807 0.73513985 -1.903826 3.4268022

### Variance Rate 0.3

Block Window Mean Avg Min Max % Mean % Avg % Min % Max
30 100436085 100485559 90224472 113243841 0.43609142 0.48556328 -9.775525 13.243842
45 100510048 100733470 92501516 111853647 0.51004887 0.7334709 -7.498479 11.853647
60 100558380 100582733 93056434 108749250 0.55838823 0.58273077 -6.9435654 8.749247
80 100287258 100324447 94554579 107443519 0.28725863 0.32445192 -5.445427 7.4435234
90 100428100 100433031 94765091 106699037 0.42809248 0.43302774 -5.234909 6.6990376
110 100714302 100676726 94848951 107139830 0.71430206 0.6767273 -5.1510453 7.1398377
150 100553130 100598151 96612161 105845588 0.5531311 0.59815645 -3.3878386 5.8455825

### Variance Rate 0.4

Block Window Mean Avg Min Max % Mean % Avg % Min % Max
30 100434094 100525228 86547598 116245969 0.43410063 0.5252361 -13.452398 16.245974
45 100298417 100504001 88655422 113313641 0.2984166 0.50400496 -11.344576 13.313639
60 100467818 100510962 90984173 111024219 0.46781301 0.51095486 -9.015822 11.024213
80 100527214 100497276 89104795 109705274 0.527215 0.49728155 -10.89521 9.705269
90 100517069 100581347 91998849 108809535 0.5170703 0.58134794 -8.001155 8.80953
110 100839961 100818642 94169156 107889333 0.8399606 0.81864595 -5.830848 7.8893304
150 100805460 100914997 94835484 107805951 0.8054614 0.9150028 -5.16451 7.8059554

### Variance Rate 0.5

Block Window Mean Avg Min Max % Mean % Avg % Min % Max
30 100786064 100828423 81105319 121498171 0.78606606 0.8284211 -18.894678 21.498167
45 100802245 100913821 87577069 115853912 0.80224276 0.91382265 -12.422925 15.853918
60 100621099 100730295 89320492 114684533 0.6210923 0.73029995 -10.679502 14.684534
80 100875099 100738969 88757934 111991633 0.87509155 0.73896646 -11.242062 11.991632
90 100771657 100865549 90266664 110963286 0.77165365 0.8655548 -9.733337 10.963285
110 100660486 100685297 91478576 112655976 0.660491 0.68529844 -8.521425 12.655973
150 100538432 100540505 92047719 110307009 0.5384326 0.54050684 -7.952279 10.307002

### Variance Rate 0.7

Block Window Mean Avg Min Max % Mean % Avg % Min % Max
30 100561020 100741044 78067344 128011776 0.56102276 0.7410407 -21.932655 28.011776
45 100393119 100624371 79748368 127322708 0.39311647 0.6243706 -20.251633 27.32271
60 100284333 100497485 85449788 121584176 0.284338 0.4974842 -14.550209 21.584177
80 100744913 100678110 86565601 114896063 0.744915 0.6781101 -13.434399 14.896059
90 100887707 100858626 86614204 114523477 0.8877039 0.85862875 -13.385791 14.523482
110 100975576 101112352 87999287 114526543 0.97557306 1.1123538 -12.00071 14.5265465
150 100042808 100051678 91345420 111055387 0.042808056 0.051677227 -8.654576 11.055386

### Variance Rate 1

Block Window Mean Avg Min Max % Mean % Avg % Min % Max
30 100039710 100823670 69744741 155950053 0.039708614 0.8236766 -30.255259 55.950047
45 100415085 101018270 74998645 140026638 0.41508675 1.0182738 -25.001352 40.02664
60 100843872 100914876 75098380 130794636 0.84387064 0.9148836 -24.901617 30.794643
80 100120217 100191426 81103546 125893646 0.12021065 0.19142628 -18.896454 25.893652
90 101310017 101558415 83775582 130482293 1.3100147 1.5584111 -16.224415 30.482292
110 100339904 100416970 85426253 119702089 0.33990145 0.41697025 -14.573747 19.70209
150 99611308 99836756 86315574 115687012 -0.38868785 -0.1632452 -13.684422 15.687013

Hash change

How many blocks it takes for the difficulty to go to 95% of the desired difficulty after the hash rate changes

### Hash Rate 0.9 (reduce)

Block Window Blocks
30 13
45 19
60 25
80 33
90 37
110 45
150 62

### Hash Rate 0.8 (reduce)

Block Window Blocks
30 25
45 37
60 49
80 65
90 73
110 89
150 121

### Hash Rate 0.7 (reduce)

Block Window Blocks
30 31
45 47
60 62
80 83
90 93
110 114
150 155

### Hash Rate 0.6 (reduce)

Block Window Blocks
30 36
45 55
60 73
80 97
90 109
110 133
150 182

## Hash Rate 0.5 (reduce)

Block Window Blocks
30 42
45 63
60 83
80 111
90 125
110 153
150 208

### Hash Rate 0.4 (reduce)

Block Window Blocks
30 47
45 70
60 94
80 125
90 140
110 171
150 233

### Hash Rate 0.3 (reduce)

Block Window Blocks
30 51
45 77
60 102
80 136
90 153
110 187
150 255

### Hash Rate 1.1 (increase)

Block Window Blocks
30 9
45 14
60 18
80 24
90 27
110 33
150 44

### Hash Rate 1.3 (increase)

Block Window Blocks
30 24
45 35
60 47
80 62
90 69
110 85
150 115

### Hash Rate 1.5 (increase)

Block Window Blocks
30 30
45 44
60 59
80 79
90 89
110 108
150 148

### Hash Rate 1.7 (increase)

Block Window Blocks
30 34
45 52
60 68
80 91
90 102
110 124
150 170

### Hash Rate 2 (increase)

Block Window Blocks
30 38
45 57
60 76
80 101
90 114
110 139
150 189

### Hash Rate 2.1 (increase)

Block Window Blocks
30 39
45 59
60 78
80 104
90 117
110 142
150 194

### Hash Rate 5 (increase)

Block Window Blocks
30 49
45 73
60 97
80 129
90 145
110 177
150 241

If the issue is clear as day, keeping it going will put Tari’s credibility at risk.

So, are we going to let it be? Or we going to implement measures?

We are going to fix it. It seems like the timeline has even been moved up based on feedback here and in the Tari Show.

Family has been staying with me for the holiday weekend so I’m running a bit behind, but I’d still like to post my simulations too. All I have of the originals are screenshots so I’m still in the process of redoing these in a more auditable format.

Hi y’all! I know some of you were attempting to upload attachments as part of the data you were sharing. This should work now-- for new attachments.

If you already uploaded an attachment before, it will think it already has it/the hash for it. Rather than trying to spelunk into the DB too much, I’ll ask you to just modify whatever file you were going to upload slightly so it has a different hash before trying to upload that one again.

1 Like