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/9] 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/9] 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/9] 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/9] 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/9] 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/9] 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/9] 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/9] 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. From 1c264feb0c958a33f3f761829e11ab7b6cd69d83 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Wed, 19 Aug 2026 14:00:22 +0200 Subject: [PATCH 9/9] updates --- ...MT-0004_MinoTari_PoW_Difficulty_changes.md | 293 ++++++++++++------ 1 file changed, 193 insertions(+), 100 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 a5acf8a6..545e9442 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-07-28 | +| Last Modified | 2026-08-19 | | Authors | SW van Heerden | | Status | Accepted | | Type | Architecture | @@ -111,47 +111,67 @@ 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 +inherent to a rule keyed on the previous block's algorithm. + +Because RxM and RxT are both RandomX variants mined by the same +hardware, that exemption covers RandomX capacity by construction: a +miner with CPU hash rate can alternate the two variants at no cost. This +is a deliberate choice, discussed under *Penalty scope* below, and it +means the mechanism binds Sha3x and C29 in practice. + +### Penalty scope + +The backoff is keyed on the **PoW algorithm** of the preceding blocks. +All four algorithms --- RxM, RxT, Sha3x and C29 --- are treated +independently. A run is a sequence of consecutive blocks of the *same* +algorithm, and a block of any other algorithm resets the modifier. + +An earlier draft of this RFC grouped RxM and RxT into a single RandomX +penalty class, on the grounds that both are mined by the same hardware +and a RandomX farm could otherwise alternate them to bypass the +mechanism. That grouping is not adopted, for two reasons. + +First, it is not neutral between algorithms. All four algorithms are +configured with the same base target time, and each algorithm's LWMA +pins that algorithm to its own target time independently of hash rate, +so in steady state each wins roughly one quarter of blocks. A combined +RandomX class would therefore hold roughly half of all blocks and pay a +far larger expected penalty than Sha3x --- about 1.47x against about +1.15x in simulation. The mechanism would tax the CPU-mined algorithms +hardest while the Sha3x concentration it was written to deter paid +least. + +Second, the grouping is the dominant contributor to the block time +inflation described below. It raises the mean block interval by roughly +8%, against roughly 2% with the algorithms kept separate. + +The cost of keeping them separate is that a miner with RandomX capacity +can alternate RxM and RxT and pay no penalty at all, including when +building a private chain. This is accepted: it is the same exemption +already granted to any miner holding capacity in two algorithms, and the +threat model above names single-algorithm Sha3x concentration as the +target. + +Penalty scope affects 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 penalty class: +by the same algorithm: -- 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. +- If a block is mined with algorithm A and the previous block was also + mined with algorithm A, the target time for A is doubled. - The doubling compounds for each further consecutive block of the - same class. -- If a block of a different class is mined, the target time for class - A resets to its base consensus value. + same algorithm. +- If a block of any other algorithm is mined, the target time for 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 +number of consecutive blocks of the same algorithm ending at and including the block being mined --- the modifier is: ```text @@ -169,33 +189,35 @@ m = min( 2^(r - 1), 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 +only resets when a block of a *different* algorithm is mined. If an +algorithm is ever the sole active miner --- for example if the other 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. +target, a chain mined by a single algorithm settles at roughly 4.3 hours +per block and resumes normal operation as soon as any other algorithm +mines. A chain left with only RandomX miners does not reach this state, +because RxM and RxT reset each other. The cap is reached after 5 doublings, i.e. on the **sixth** consecutive -block of a class. +block of an algorithm. ### 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: +Model each block's algorithm as independent, with `p` the share of +blocks won by algorithm 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: +The expected modifier paid by a block of algorithm A is therefore: ```text E[m] = sum over k of (1 - p) * p^k * 2^k @@ -206,7 +228,7 @@ 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 +above a two-thirds share, and a factor of 3 would penalize an algorithm 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. @@ -218,53 +240,108 @@ five or more preceding blocks pays a flat 32: 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 | +| Block share `p` | `E[m]` uncapped | `E[m]` capped at 32 | +|----------------------|-----------------|---------------------| +| 0.25 (four algos) | 1.50 | 1.48 | +| 1/3 (three algos) | 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 +above, and it pays for that by blunting the sharp majority threshold: an +algorithm 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. +#### Why these figures are an upper bound + +The independent-arrival model above is what fixes the backoff factor at +two, but it overstates the penalty actually paid, and by a wide margin. +It ignores the feedback the mechanism itself creates: while an algorithm +holds the tip it is throttled by `m` and the other three are not, so it +is markedly less likely to extend its own run than `p` suggests. + +Simulating the race between algorithms through to the LWMA fixed point, +at four live algorithms with equal base target times: + +| Run length `r` | P(extend) modelled | P(extend) simulated | +|----------------|--------------------|---------------------| +| 1 | 0.25 | 0.13 | +| 2 | 0.25 | 0.07 | +| 3 | 0.25 | 0.04 | +| 4 | 0.25 | 0.03 | + +Long runs are therefore far rarer than `p^k`, and long runs are exactly +what the `2^k` weight multiplies. The realised expected modifier is +correspondingly lower: + +| Live algorithms | `E[m]` modelled | `E[m]` simulated | +|-----------------|-----------------|------------------| +| 4 | 1.48 | 1.16 | +| 3 | 1.87 | 1.23 | + +Note also that `p` is a share of *blocks won*, not of hash rate, and the +two are only loosely coupled here. Because each algorithm's LWMA pins it +to its own target time, steady-state block share is set by the +configured target times and is insensitive to hash rate: a Sha3x hash +rate boom raises Sha3x difficulty rather than its block share. Shares +materially above 1/4 arise from algorithms losing their miners +altogether, not from one algorithm out-hashing the others. The rows at +`p >= 0.4` above are therefore about attack and abandonment scenarios, +not about ordinary operation. ### 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. +LWMA has no feedback path that fully corrects for the penalty. It +converges to the point where the *normalized* mean solve time equals the +base target time `T`, while wall-clock intervals remain longer than +that. Block production is therefore slower than the configured target. + +A first-order estimate treats the modifier and the solve time as +independent, giving `E[solve_time] = E[m] * T`. That overstates the +effect substantially, for three reasons: + +- Runs are suppressed by the penalty itself, so `E[m]` is much smaller + than the independent model predicts. See *Why these figures are an + upper bound* above. +- The chain does not stall while an algorithm is penalized. Only the + algorithm holding the tip is throttled; the other three continue at + full rate, so total block production dips rather than scaling down + by `m`. +- The normalization does not fully blind the LWMA. Tari keeps one LWMA + per algorithm, so a solve time is the gap between consecutive blocks + of *that* algorithm and spans blocks of other algorithms. Penalties + in force during the gap stretch it, but only the modifier of the + block that closes the gap is divided out. The residual stretch is + visible to the LWMA, which lowers difficulty in response and + partially compensates. + +Simulating the race through to the LWMA fixed point at the mainnet +configuration --- four algorithms with equal base target times --- gives +the following inflation of the mean chain block interval: + +| Configuration | Inflation | +|---------------------------------------|---------------| +| Four algorithms live | 1.7% | +| Three algorithms live (one abandoned) | 3.5% | +| Single algorithm live | 32x (the cap) | + +At under 2% the effect does not warrant reducing the base target times +to compensate, and doing so would misconfigure the chain if the number +of live algorithms later changed. For comparison, grouping RxM and RxT +into one penalty class raises the four-algorithm figure to 8.4% and the +three-algorithm figure to 19.6%, which is the second reason that +grouping is not adopted. + +The inflation that does remain is a consequence of normalizing solve +times rather than letting the LWMA absorb the penalty. The alternative +--- omitting the normalization --- holds block time exactly constant but +lets the LWMA cancel the penalty in steady state, leaving it effective +only transiently. ### Difficulty calculation @@ -371,44 +448,48 @@ Assume the base target time for Sha3x is **8 minutes**. becomes **32 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**. +- If a block of any other algorithm 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. +An RxM block followed by an RxT block is a run of one in each algorithm, +so neither block is penalized. Switching between the two RandomX +variants resets the modifier, and a miner with RandomX capacity can +alternate them indefinitely without ever paying a penalty. ## Consequences 1 ### Positive - Significantly increases the cost of selfish mining. A private chain - of depth 6 built by a single penalty class costs 63 units of work + of depth 6 built by a single algorithm 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. -- 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. +- Treating every algorithm independently keeps the mechanism neutral + between them: all four carry the same steady-state block share and + the same expected modifier, so no algorithm is taxed more than + another for mining honestly. +- The cost to honest mining is small --- about 1.16x on average with + four algorithms live --- while remaining progressive in + concentration. ### 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 +- Inflates the mean block interval by roughly 2% with four algorithms + live, rising as algorithms are abandoned. See *Effect on mean block + time*. +- The 32x cap blunts the majority threshold: an algorithm 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. -- 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. +- Does not prevent a miner holding capacity in two or more algorithms + from alternating between them to avoid the penalty entirely. Because + RxM and RxT run on the same hardware, this exempts RandomX capacity + in full, including when building a private chain. +- If a single algorithm is left as the only active miner, the chain + runs at up to 32x the base target time until another algorithm mines + a block. - Penalizes a single-algorithm miner for a run that occurs by chance, not only for one produced deliberately. @@ -453,3 +534,15 @@ window should be reduced to 45 blocks. ### 2026-06-11 * Document Created. + +### 2026-08-19 + +* RxM and RxT are no longer grouped into a shared RandomX penalty class; + every algorithm is its own penalty scope. +* Corrected the *Effect on mean block time* analysis. The previous + figure of 87% came from the independent-arrival model, which ignores + that the penalty suppresses the runs it taxes, that unpenalized + algorithms keep mining at full rate, and that the per-algorithm LWMA + is only partially blinded by the normalization. Simulated inflation is + 1.7% with four algorithms live, and the base target times no longer + need to be reduced to compensate.