From 24f91b131fafb6425a28497397eed5b02c5519db Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Thu, 11 Jun 2026 12:26:07 +0200 Subject: [PATCH 1/8] adds tip004 pow changes --- ...MT-0004_MinoTari_PoW_Difficulty_changes.md | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 Process/MinoTari/TIP-Proc-MT-0004_MinoTari_PoW_Difficulty_changes.md diff --git a/Process/MinoTari/TIP-Proc-MT-0004_MinoTari_PoW_Difficulty_changes.md b/Process/MinoTari/TIP-Proc-MT-0004_MinoTari_PoW_Difficulty_changes.md new file mode 100644 index 00000000..33688594 --- /dev/null +++ b/Process/MinoTari/TIP-Proc-MT-0004_MinoTari_PoW_Difficulty_changes.md @@ -0,0 +1,157 @@ +# P-TIP-PROC-MT-0004: MinoTari PoW difficulty changes + +| TIP | [P-TIP-PROC-MT-0004](#/Process/MinoTari/TIP-Proc-MT-0004_MinoTari_PoW_Difficulty_changes.md) | +|-----------------|---------------------------------------------------------------------------| +| Title | MinoTari PoW difficulty changes | +| Last Modified | 2026-05-17 | +| Authors | SW van Heerden | +| Status | Proposed | +| Type | Process | +| Created | 2026-06-11 | +| References | Based on the Open edX community's [OEP] process. Forum discussion thread. | + +## Overview + +Tari Core currently uses a geometric-mean-style comparison to determine +the best chain tip across multiple Proof-of-Work (PoW) algorithms. + +The geometric mean is a measure of central tendency calculated by +multiplying a set of values together and then taking the n-th root +(where n is the number of values). Unlike the arithmetic mean, the +geometric mean is well suited to comparing values that span multiple +orders of magnitude. + +Tari does not compute the full geometric mean. Specifically, the final +n-th root step is omitted to avoid floating-point operations. Since the +protocol only needs to compare two values (rather than compute the exact +geometric mean), the root operation is unnecessary --- multiplying the +accumulated difficulties is sufficient for ordering purposes. + +Tari currently supports four PoW algorithms: + +- Rx +- RxT +- Sha3x +- C29 + +To compare two competing chain tips, Tari calculates: + + Rx * RxT * Sha3x * C29 + +The chain with the larger product is considered to have more accumulated +PoW. + +### Example + +Assume the total accumulated difficulties for the four algorithms are: + + Rx, RxT, Sha3x, C29 + +Now consider two competing new blocks: + +- One mined on Rx with difficulty `x` +- One mined on Sha3x with difficulty `y` + +We compare: + + (Rx + x) * RxT * Sha3x * C29 + Rx * RxT * (Sha3x + y) * C29 + +After cancelling common terms, this comparison reduces to evaluating: + + x / Rx vs y / Sha3x + +Whichever ratio is larger represents the larger relative increase in +accumulated PoW. + +### Problem + +This approach works under balanced hash rate conditions. However, if one +algorithm (e.g., Sha3x) experiences a significant hash rate increase --- +for example due to ASIC hardware becoming dominant relative to GPU +mining --- its relative contribution can dominate the comparison. + +As accumulated difficulty grows, terms such as `x / Rx` converge toward +zero unless `x` scales proportionally with `Rx`. If one algorithm's +difficulty grows much faster than the others, its blocks will +consistently produce larger relative increases. + +This creates a situation where one algorithm can disproportionately +reorg blocks mined by other algorithms. That outcome undermines the +original design goal of including multiple PoW algorithms for +decentralization and hardware diversity. + + +## Proposed Change + +Tari currently calculates target difficulty using LWMA (Linearly +Weighted Moving Average) over the last 90 blocks. The LWMA uses: + +- Target block time +- Header timestamps +- Historical target difficulties + +to compute the next target difficulty. + + +Introduce an exponential backoff mechanism for consecutive blocks mined +by the same PoW algorithm: + +- If a block is mined using algorithm A, and the previous block was + also mined using algorithm A, then the target time for algorithm A + is doubled. +- This doubling continues for each consecutive block of the same + algorithm. +- If a block of a different algorithm is mined, the target time for + algorithm A resets to its base consensus value. + +### Example + +Assume the base target time for Sha3x is **8 minutes**. + +- If the previous block was Sha3x → the next Sha3x target time becomes + **16 minutes**. +- If another Sha3x block is mined consecutively → target time becomes + **32 minutes**. +- If a different algorithm mines a block → Sha3x target time resets to + **8 minutes**. + +This mechanism: + +- Does not alter the underlying hash rate. +- Does not directly manipulate accumulated difficulty. +- Makes selfish mining exponentially more expensive for any single + algorithm attempting to dominate. +- Encourages natural interleaving of algorithms. +- +## Consequences + +### Positive + +- Significantly increases the cost of selfish mining. +- Reduces the ability of a single algorithm to reorg multiple blocks. +- Preserves the multi-algorithm decentralization objective. + +### Negative + +- Requires a hard fork. +- Changes block-time dynamics under certain hash rate distributions. +- May introduce more short-term variance in block intervals. + +### Neutral + +- Does not change the geometric-mean comparison logic directly. +- Does not modify the LWMA formula itself --- only its target-time + input. + +## References + +- https://github.com/zawy12/difficulty-algorithms/issues/3#issuecomment-442129791 +- https://github.com/zcash/zcash/issues/4021 + + +## Change History + +### 2026-06-11 + +* Document Created. From 8ee8843a582178752f57cc0e5af8791cbb96f969 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Tue, 23 Jun 2026 11:31:00 +0200 Subject: [PATCH 2/8] code reviews --- .../MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Process/MinoTari/TIP-Proc-MT-0004_MinoTari_PoW_Difficulty_changes.md => src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md (100%) diff --git a/Process/MinoTari/TIP-Proc-MT-0004_MinoTari_PoW_Difficulty_changes.md b/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md similarity index 100% rename from Process/MinoTari/TIP-Proc-MT-0004_MinoTari_PoW_Difficulty_changes.md rename to src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md From d9bcdb5da44487e828038a6c401f32d1895607e3 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Thu, 23 Jul 2026 15:20:06 +0200 Subject: [PATCH 3/8] change to accepted --- .../TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md | 10 +++++----- src/SUMMARY.md | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md b/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md index 33688594..feca0b23 100644 --- a/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md +++ b/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md @@ -1,14 +1,14 @@ -# P-TIP-PROC-MT-0004: MinoTari PoW difficulty changes +# A-TIP-RFC-MT-0004: MinoTari PoW difficulty changes -| TIP | [P-TIP-PROC-MT-0004](#/Process/MinoTari/TIP-Proc-MT-0004_MinoTari_PoW_Difficulty_changes.md) | +| TIP | [A-TIP-RFC-MT-0004](#/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md) | |-----------------|---------------------------------------------------------------------------| -| Title | MinoTari PoW difficulty changes | +| Title | MinoTari PoW difficulty changes | | Last Modified | 2026-05-17 | | Authors | SW van Heerden | -| Status | Proposed | +| Status | Accepted | | Type | Process | | Created | 2026-06-11 | -| References | Based on the Open edX community's [OEP] process. Forum discussion thread. | +| References | | ## Overview diff --git a/src/SUMMARY.md b/src/SUMMARY.md index ee06e9cd..bfe46049 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -7,6 +7,7 @@ - [TIP-PROC-3: Community Forums](TIP-0003_community_forums.md) - [TIP-RFC-O-8003: Tari Use Cases](RFC-8003_TariUseCases.md) - [Accepted](accepted.md) + - [TIP-RFC-MT-0004: MinoTari PoW difficulty changes](RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md) - [TIP-RFC-MT-0241: XMR Atomic swap](RFC-0241_AtomicSwapXMR.md) - [Implemented](implemented.md) - [TIP-PROC-2: The Tari Community Charter](TIP-0002_tari_community_charter.md) From d48424d45fd74f9af03869d7e412995435bc2470 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Fri, 24 Jul 2026 08:42:04 +0200 Subject: [PATCH 4/8] review --- ...MT-0004_MinoTari_PoW_Difficulty_changes.md | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md b/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md index feca0b23..a39dc677 100644 --- a/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md +++ b/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md @@ -3,10 +3,10 @@ | TIP | [A-TIP-RFC-MT-0004](#/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md) | |-----------------|---------------------------------------------------------------------------| | Title | MinoTari PoW difficulty changes | -| Last Modified | 2026-05-17 | +| Last Modified | 2026-06-24 | | Authors | SW van Heerden | | Status | Accepted | -| Type | Process | +| Type | Architecture | | Created | 2026-06-11 | | References | | @@ -123,8 +123,8 @@ This mechanism: - Makes selfish mining exponentially more expensive for any single algorithm attempting to dominate. - Encourages natural interleaving of algorithms. -- -## Consequences + +## Consequences 1 ### Positive @@ -144,6 +144,20 @@ This mechanism: - Does not modify the LWMA formula itself --- only its target-time input. +## Proposed Change 2 + +Tari currently uses a block window of 90 for the LWMA. While this provides stability to the mining power, it takes a few blocks to respond to hash rate changes. If exchanges jump on and off, this can lead to large hash rate differences that come with large changes in the solvetime. Having the LWMA respond quicker to these will be helpful. This should be changed to a 45-block window, given the large target time per block that we have. + +## Consequences 2 + +### Positive + +- Faster response on blocks with an increase or decrease in hash power + +### Negative + +- Can cause some oscillation in the difficulty + ## References - https://github.com/zawy12/difficulty-algorithms/issues/3#issuecomment-442129791 From 9af2936d1436dbafa8407fb909aca559d0095cb0 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Fri, 24 Jul 2026 09:25:37 +0200 Subject: [PATCH 5/8] fix --- ...-MT-0004_MinoTari_PoW_Difficulty_changes.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md b/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md index a39dc677..d606f7e1 100644 --- a/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md +++ b/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md @@ -36,7 +36,9 @@ Tari currently supports four PoW algorithms: To compare two competing chain tips, Tari calculates: - Rx * RxT * Sha3x * C29 +```text +Rx * RxT * Sha3x * C29 +``` The chain with the larger product is considered to have more accumulated PoW. @@ -45,7 +47,9 @@ PoW. Assume the total accumulated difficulties for the four algorithms are: - Rx, RxT, Sha3x, C29 +```text +Rx, RxT, Sha3x, C29 +``` Now consider two competing new blocks: @@ -54,12 +58,16 @@ Now consider two competing new blocks: We compare: - (Rx + x) * RxT * Sha3x * C29 - Rx * RxT * (Sha3x + y) * C29 +```text +(Rx + x) * RxT * Sha3x * C29 +Rx * RxT * (Sha3x + y) * C29 +``` After cancelling common terms, this comparison reduces to evaluating: - x / Rx vs y / Sha3x +```text +x / Rx vs y / Sha3x +``` Whichever ratio is larger represents the larger relative increase in accumulated PoW. From 0e3f156f34916a632db6b1139d589dac1adfac28 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Tue, 28 Jul 2026 16:04:33 +0200 Subject: [PATCH 6/8] some edits --- ...MT-0004_MinoTari_PoW_Difficulty_changes.md | 140 ++++++++++++------ 1 file changed, 94 insertions(+), 46 deletions(-) diff --git a/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md b/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md index d606f7e1..f5aa20d3 100644 --- a/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md +++ b/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md @@ -3,7 +3,7 @@ | TIP | [A-TIP-RFC-MT-0004](#/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md) | |-----------------|---------------------------------------------------------------------------| | Title | MinoTari PoW difficulty changes | -| Last Modified | 2026-06-24 | +| Last Modified | 2026-07-28 | | Authors | SW van Heerden | | Status | Accepted | | Type | Architecture | @@ -21,15 +21,15 @@ multiplying a set of values together and then taking the n-th root geometric mean is well suited to comparing values that span multiple orders of magnitude. -Tari does not compute the full geometric mean. Specifically, the final -n-th root step is omitted to avoid floating-point operations. Since the -protocol only needs to compare two values (rather than compute the exact -geometric mean), the root operation is unnecessary --- multiplying the -accumulated difficulties is sufficient for ordering purposes. +Tari does not compute the full geometric mean: the final n-th root step +is omitted to avoid floating-point operations. Because the protocol only +needs to order two values rather than compute an exact mean, the root is +unnecessary --- multiplying the accumulated difficulties preserves the +same ordering. Tari currently supports four PoW algorithms: -- Rx +- RxM - RxT - Sha3x - C29 @@ -37,7 +37,7 @@ Tari currently supports four PoW algorithms: To compare two competing chain tips, Tari calculates: ```text -Rx * RxT * Sha3x * C29 +RxM * RxT * Sha3x * C29 ``` The chain with the larger product is considered to have more accumulated @@ -48,25 +48,25 @@ PoW. Assume the total accumulated difficulties for the four algorithms are: ```text -Rx, RxT, Sha3x, C29 +RxM, RxT, Sha3x, C29 ``` Now consider two competing new blocks: -- One mined on Rx with difficulty `x` +- One mined on RxM with difficulty `x` - One mined on Sha3x with difficulty `y` We compare: ```text -(Rx + x) * RxT * Sha3x * C29 -Rx * RxT * (Sha3x + y) * C29 +(RxM + x) * RxT * Sha3x * C29 +RxM * RxT * (Sha3x + y) * C29 ``` After cancelling common terms, this comparison reduces to evaluating: ```text -x / Rx vs y / Sha3x +x / RxM vs y / Sha3x ``` Whichever ratio is larger represents the larger relative increase in @@ -74,25 +74,24 @@ accumulated PoW. ### Problem -This approach works under balanced hash rate conditions. However, if one -algorithm (e.g., Sha3x) experiences a significant hash rate increase --- -for example due to ASIC hardware becoming dominant relative to GPU -mining --- its relative contribution can dominate the comparison. +This approach works while hash rate is balanced across the algorithms. +If one algorithm (for example Sha3x) sees a large hash rate increase --- +say because ASIC hardware becomes dominant relative to GPU mining --- its +relative contribution can dominate the comparison. -As accumulated difficulty grows, terms such as `x / Rx` converge toward -zero unless `x` scales proportionally with `Rx`. If one algorithm's -difficulty grows much faster than the others, its blocks will -consistently produce larger relative increases. +As accumulated difficulty grows, terms such as `x / RxM` converge toward +zero unless `x` scales proportionally with `RxM`. If one algorithm's +difficulty grows much faster than the others, its blocks consistently +produce larger relative increases. -This creates a situation where one algorithm can disproportionately -reorg blocks mined by other algorithms. That outcome undermines the -original design goal of including multiple PoW algorithms for -decentralization and hardware diversity. +One algorithm can therefore reorg blocks mined by the other algorithms +disproportionately often, which undermines the original design goal of +using multiple PoW algorithms for decentralization and hardware +diversity. +## Proposed Change 1 -## Proposed Change - -Tari currently calculates target difficulty using LWMA (Linearly +Tari currently calculates target difficulty using an LWMA (Linearly Weighted Moving Average) over the last 90 blocks. The LWMA uses: - Target block time @@ -101,28 +100,60 @@ Weighted Moving Average) over the last 90 blocks. The LWMA uses: to compute the next target difficulty. - -Introduce an exponential backoff mechanism for consecutive blocks mined +This RFC introduces an exponential backoff for consecutive blocks mined by the same PoW algorithm: -- If a block is mined using algorithm A, and the previous block was - also mined using algorithm A, then the target time for algorithm A - is doubled. -- This doubling continues for each consecutive block of the same - algorithm. +- If a block is mined using algorithm A and the previous block was + also mined using algorithm A, the target time for algorithm A is + doubled. +- The doubling compounds for each further consecutive block of the + same algorithm. - If a block of a different algorithm is mined, the target time for algorithm A resets to its base consensus value. -### Example +The current difficulty calculation is: -Assume the base target time for Sha3x is **8 minutes**. +```text +next_target_difficulty = ave_difficulty * k / weighted_times -- If the previous block was Sha3x → the next Sha3x target time becomes - **16 minutes**. -- If another Sha3x block is mined consecutively → target time becomes - **32 minutes**. -- If a different algorithm mines a block → Sha3x target time resets to - **8 minutes**. +where k = block_window * (block_window + 1) * target_time / 2 +``` + +Because the penalty enters the formula only through `target_time`, it +can be expressed as a single multiplier: + +```text +adjusted_next_target_difficulty = next_target_difficulty * m + +where m = the penalty modifier +``` + +The `adjusted_next_target_difficulty` is used only as the target +difficulty that the mined block must meet. It is not counted when +calculating the total accumulated PoW of the chain --- the unadjusted +difficulty is used there. + +The modifier applied to each block in the window must also be fed back +into the next difficulty calculation. The weighted times are currently +the sum over the window of: + +```text +weighted_times = sum( solve_time[i] * (i + 1) ) + +where i = index of the block within the window +``` + +Each solve time is normalized by the modifier that was in force for that +block, so that a block mined against an inflated target is not read as a +drop in hash rate: + +```text +weighted_times = sum( solve_time[i] / m[i] * (i + 1) ) + +where +i = index of the block within the window +m[i] = modifier applied to block i +``` This mechanism: @@ -132,6 +163,17 @@ This mechanism: algorithm attempting to dominate. - Encourages natural interleaving of algorithms. +### Example + +Assume the base target time for Sha3x is **8 minutes**. + +- If the previous block was Sha3x, the next Sha3x target time becomes + **16 minutes**. +- If another Sha3x block is mined consecutively, the target time + becomes **32 minutes**. +- If a different algorithm mines a block, the Sha3x target time resets + to **8 minutes**. + ## Consequences 1 ### Positive @@ -145,6 +187,7 @@ This mechanism: - Requires a hard fork. - Changes block-time dynamics under certain hash rate distributions. - May introduce more short-term variance in block intervals. +- Does not prevent pools from switching between RxT and RxM. ### Neutral @@ -154,17 +197,22 @@ This mechanism: ## Proposed Change 2 -Tari currently uses a block window of 90 for the LWMA. While this provides stability to the mining power, it takes a few blocks to respond to hash rate changes. If exchanges jump on and off, this can lead to large hash rate differences that come with large changes in the solvetime. Having the LWMA respond quicker to these will be helpful. This should be changed to a 45-block window, given the large target time per block that we have. +Tari currently uses a block window of 90 blocks for the LWMA. This gives +a stable difficulty, but it takes several blocks to respond to a change +in hash rate. When large miners switch on and off, the resulting hash +rate swings produce correspondingly large swings in solve time, so a +faster response is desirable. Given Tari's long target block time, the +window should be reduced to 45 blocks. ## Consequences 2 ### Positive -- Faster response on blocks with an increase or decrease in hash power +- Responds faster to an increase or decrease in hash power. ### Negative -- Can cause some oscillation in the difficulty +- Can cause more oscillation in the difficulty. ## References From 6c0730fa78263558044897c44a6aef518cc95888 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Tue, 28 Jul 2026 16:12:13 +0200 Subject: [PATCH 7/8] more edits --- ...MT-0004_MinoTari_PoW_Difficulty_changes.md | 161 ++++++++++++++++-- 1 file changed, 148 insertions(+), 13 deletions(-) diff --git a/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md b/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md index f5aa20d3..4d99f133 100644 --- a/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md +++ b/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md @@ -100,16 +100,88 @@ Weighted Moving Average) over the last 90 blocks. The LWMA uses: to compute the next target difficulty. +### Threat model + +The mechanism proposed here targets a miner whose hash power is +concentrated in a **single** PoW algorithm and who therefore has to mine +consecutive blocks with that one algorithm in order to build a competing +chain. The canonical case is Sha3x ASIC capacity growing until it can +routinely out-pace the GPU and CPU algorithms. + +It does not defend against a miner who controls capacity in two or more +algorithms and can alternate between them. Such a miner never produces a +same-algorithm run and never incurs a penalty. This limitation is +inherent to a rule keyed on the previous block's algorithm, and is the +reason for the penalty classes defined below. + +### Penalty classes + +RxM and RxT are both RandomX variants and are mined by the same +hardware, so a miner can move between them at no cost. Treating them as +distinct algorithms for backoff purposes would leave the mechanism open +to trivial bypass: a RandomX farm alternating RxM and RxT would build an +unbroken chain with no penalty at all, while a Sha3x miner --- the party +this RFC is aimed at --- would pay in full. + +Algorithms are therefore grouped into **penalty classes** for the +purposes of the backoff rule: + +| Penalty class | Algorithms | +|---------------|-------------| +| RandomX | RxM, RxT | +| Sha3x | Sha3x | +| C29 | C29 | + +Penalty classes affect only the backoff rule. Accumulated difficulty is +still tracked per algorithm, and the chain comparison in the Overview is +unchanged. + +### The backoff rule + This RFC introduces an exponential backoff for consecutive blocks mined -by the same PoW algorithm: +by the same penalty class: -- If a block is mined using algorithm A and the previous block was - also mined using algorithm A, the target time for algorithm A is - doubled. +- If a block is mined in class A and the previous block was also mined + in class A, the target time for class A is doubled. - The doubling compounds for each further consecutive block of the - same algorithm. -- If a block of a different algorithm is mined, the target time for - algorithm A resets to its base consensus value. + same class. +- If a block of a different class is mined, the target time for class + A resets to its base consensus value. + +### Cap + +The doubling is capped at **32x**. Writing `r` for the run length --- the +number of consecutive blocks of the same penalty class ending at and +including the block being mined --- the modifier is: + +```text +m = min( 2^(r - 1), 32 ) +``` + +| Run length `r` | Modifier `m` | +|----------------|--------------| +| 1 | 1 | +| 2 | 2 | +| 3 | 4 | +| 4 | 8 | +| 5 | 16 | +| 6 | 32 | +| 7 or more | 32 | + +The cap is a liveness requirement, not a tuning choice. The modifier +only resets when a block of a *different* penalty class is mined. If a +class is ever the sole active miner --- for example if the GPU and CPU +algorithms lose their miners after a fork --- there is nothing to reset +it, and an uncapped modifier would double indefinitely until the chain +stopped producing blocks, with no recovery path short of another fork. +The cap bounds that failure to a 32x slowdown: at an 8 minute base +target, a chain mined by a single class settles at roughly 4.3 hours per +block and resumes normal operation as soon as any other class mines. + +The cap is reached after 5 doublings, i.e. on the **sixth** consecutive +block of a class. + +### Difficulty calculation The current difficulty calculation is: @@ -155,6 +227,47 @@ i = index of the block within the window m[i] = modifier applied to block i ``` +#### Order of normalization and clamping + +The existing LWMA clamps each solve time before use, to bound the +influence of manipulated timestamps. The normalization above interacts +with that clamp, and the order is consensus-critical. + +Normalization is applied **first**, and the clamp is then applied to the +normalized value against the **unchanged** base bounds: + +```text +solve_time[i] = clamp( raw_solve_time[i] / m[i], min_bound, max_bound ) +``` + +Clamping the raw solve time against the base bounds and dividing +afterwards is incorrect. A block legitimately mined against a 32x target +takes roughly 32x longer, so the base upper bound would truncate a real +solve time and the subsequent division would yield a spuriously small +value, driving a false difficulty spike. Because `m[i]` is always +positive, clamping the normalized value against the base bounds is +exactly equivalent to clamping the raw value against bounds scaled by +`m[i]`, which is the intended behaviour. + +#### Integer arithmetic + +`solve_time[i] / m[i]` must not be evaluated as an integer division per +term: with `m = 32` a 15 second solve time truncates to zero, and the +error accumulates across every block in the window. Because every +modifier is a power of two dividing the 32x cap, the sum can be kept in +exact integer arithmetic by scaling every term by the cap: + +```text +weighted_times = sum( raw_solve_time[i] * (i + 1) * (M_MAX / m[i]) ) +k = block_window * (block_window + 1) * target_time * M_MAX / 2 + +where M_MAX = 32 +``` + +`M_MAX / m[i]` is an exact integer for every permitted modifier, and +scaling both `k` and `weighted_times` by the same factor leaves +`next_target_difficulty` unchanged. + This mechanism: - Does not alter the underlying hash rate. @@ -171,29 +284,51 @@ Assume the base target time for Sha3x is **8 minutes**. **16 minutes**. - If another Sha3x block is mined consecutively, the target time becomes **32 minutes**. -- If a different algorithm mines a block, the Sha3x target time resets - to **8 minutes**. +- After six consecutive Sha3x blocks the target time reaches **4 hours + 16 minutes** (32x) and stops growing. +- If a block of a different penalty class is mined, the Sha3x target + time resets to **8 minutes**. + +An RxM block followed by an RxT block is a run of two within the RandomX +class, so the second block is mined at a 16 minute target. Switching +between the two RandomX variants does not reset the modifier. ## Consequences 1 ### Positive -- Significantly increases the cost of selfish mining. +- Significantly increases the cost of selfish mining. A private chain + of depth 6 built by a single penalty class costs 63 units of work + against 6 for an honest chain of the same depth. - Reduces the ability of a single algorithm to reorg multiple blocks. - Preserves the multi-algorithm decentralization objective. +- Grouping RxM and RxT into one penalty class closes the cheapest + bypass, since both are mined by the same hardware. ### Negative - Requires a hard fork. - Changes block-time dynamics under certain hash rate distributions. - May introduce more short-term variance in block intervals. -- Does not prevent pools from switching between RxT and RxM. +- Does not prevent a miner holding capacity in two or more penalty + classes from alternating between them to avoid the penalty + entirely. +- If a single penalty class is left as the only active miner, the + chain runs at up to 32x the base target time until another class + mines a block. +- Penalizes a single-algorithm miner for a run that occurs by chance, + not only for one produced deliberately. ### Neutral - Does not change the geometric-mean comparison logic directly. -- Does not modify the LWMA formula itself --- only its target-time - input. +- Modifies the LWMA only through its target-time input and the + corresponding normalization of solve times; the shape of the moving + average is unchanged. +- Requires no new header fields. The modifier for any block is derived + from the PoW algorithms of the preceding blocks, so validators can + recompute it from headers alone --- noting that this requires up to + 5 headers of lookback beyond the start of the LWMA window. ## Proposed Change 2 From 90f131e0f0a2b1c80bda6ee1b4b1f5b7c459415b Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Tue, 28 Jul 2026 16:23:05 +0200 Subject: [PATCH 8/8] more edits --- ...MT-0004_MinoTari_PoW_Difficulty_changes.md | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md b/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md index 4d99f133..a5acf8a6 100644 --- a/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md +++ b/src/RFC/MinoTari/TIP-RFC-MT-0004_MinoTari_PoW_Difficulty_changes.md @@ -181,6 +181,91 @@ block and resumes normal operation as soon as any other class mines. The cap is reached after 5 doublings, i.e. on the **sixth** consecutive block of a class. +### Expected cost, and why the factor is two + +The doubling factor is not arbitrary. It places the point at which the +mechanism becomes prohibitive exactly at the majority threshold. + +Model each block's penalty class as independent, with `p` the share of +blocks won by class A. For a block mined by A, let `j` be the number of +immediately preceding consecutive A blocks, so that `m = 2^j`. The `j` +preceding blocks are A and the one before them is not, giving: + +```text +P(j = k) = p^k * (1 - p) +``` + +The expected modifier paid by a block of class A is therefore: + +```text +E[m] = sum over k of (1 - p) * p^k * 2^k + = (1 - p) / (1 - 2p) for p < 1/2 +``` + +The series converges only while `2p < 1`. Below 50% block share the +expected penalty is finite and mild; as share approaches 50% it grows +without bound. More generally, a backoff factor of `b` places the +divergence at `p = 1/b`: a factor of 1.5 would only become prohibitive +above a two-thirds share, and a factor of 3 would penalize a class +holding only a third of blocks. **A factor of two is the choice that +puts the pole at the majority threshold**, which is the threshold the +protocol already treats as the security boundary. + +With the 32x cap the expectation is finite everywhere, since a run of +five or more preceding blocks pays a flat 32: + +```text +E[m] = (1 - p) * (1 - (2p)^5) / (1 - 2p) + 32 * p^5 +``` + +| Block share `p` | `E[m]` uncapped | `E[m]` capped at 32 | +|-----------------|-----------------|---------------------| +| 1/3 (balanced) | 2.00 | 1.87 | +| 0.40 | 3.00 | 2.34 | +| 0.45 | 5.50 | 2.84 | +| 0.50 | diverges | 3.50 | +| 0.60 | diverges | 5.47 | +| 0.75 | diverges | 10.89 | + +The cap is a deliberate trade. It buys the liveness guarantee described +above, and it pays for that by blunting the sharp majority threshold: a +class at 50% share pays 3.5x rather than an unbounded amount. The +mechanism therefore taxes concentration progressively rather than +imposing a hard ceiling on it. + +Two caveats apply to these figures. The model assumes each block's class +is drawn independently with a fixed `p`, which ignores the behavioural +feedback the mechanism is designed to create --- miners who interleave +deliberately pay less than the table shows, and `E[m]` tends to 1 under +perfect round-robin mining. And `p` is a share of *blocks won*, not of +hash rate; because the penalty itself suppresses a concentrated class's +block share, the hash rate corresponding to a given `p` is higher than +`p` alone suggests. + +### Effect on mean block time + +The expectation above has a direct consequence for block pacing that the +base target times must account for. + +Because solve times are normalized by `m` before entering the LWMA, the +LWMA converges to the point where the *normalized* mean solve time +equals the base target time `T`. Actual solve times are `m` times the +normalized ones, so the mean interval between blocks of a class is: + +```text +E[solve_time] = E[m] * T +``` + +At three balanced penalty classes this inflates the mean block interval +by roughly 87% for as long as classes arrive independently. The base +target times must be reduced accordingly if the emission schedule is to +be preserved, and the correct divisor depends on how far real miner +behaviour sits between independent arrival and deliberate interleaving. +This is a consequence of normalizing solve times rather than letting the +LWMA absorb the penalty; the alternative --- omitting the normalization +--- holds block time constant but lets the LWMA cancel most of the +penalty in steady state, leaving it effective only transiently. + ### Difficulty calculation The current difficulty calculation is: @@ -304,12 +389,20 @@ between the two RandomX variants does not reset the modifier. - Preserves the multi-algorithm decentralization objective. - Grouping RxM and RxT into one penalty class closes the cheapest bypass, since both are mined by the same hardware. +- The cost is progressive in concentration rather than flat: a class + at balanced share pays about 1.9x on average, one at 60% share pays + about 5.5x. ### Negative - Requires a hard fork. - Changes block-time dynamics under certain hash rate distributions. - May introduce more short-term variance in block intervals. +- Inflates the mean block interval by a factor of `E[m]` unless the + base target times are reduced to compensate. See *Effect on mean + block time*. +- The 32x cap blunts the majority threshold: a class at 50% block + share pays 3.5x on average rather than an unbounded amount. - Does not prevent a miner holding capacity in two or more penalty classes from alternating between them to avoid the penalty entirely.