From 51683268140ab28674bf04c4075a36bf5ea00308 Mon Sep 17 00:00:00 2001 From: danieljperry Date: Mon, 19 May 2025 21:22:33 +0800 Subject: [PATCH 01/24] Add CHIP for fork timelines and assign 49, Draft --- CHIPs/chip-0049.md | 172 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 CHIPs/chip-0049.md diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md new file mode 100644 index 00000000..d4e8dea8 --- /dev/null +++ b/CHIPs/chip-0049.md @@ -0,0 +1,172 @@ +CHIP Number | 0049 +:------------|:---- +Title | Proof Format Fork Timelines +Description | Provide all necessary timelines for the hard fork to support the new proof format +Author | [Arvid Norberg](https://github.com/arvidn) +Editor | [Dan Perry](https://github.com/danieljperry) +Comments-URI | [CHIPs repo, PR #161](https://github.com/Chia-Network/chips/pull/161) +Status | Draft +Category | Standards Track +Sub-Category | Core +Created | 2025-05-19 +Requires | [0048](https://github.com/Chia-Network/chips/pull/160) + +## Abstract +[CHIP-48](https://github.com/Chia-Network/chips/pull/160), which introduces the new proof format, requires a hard fork of the Chia blockchain. This document describes how the new proof of space will be integrated with the blockchain as well as how original plots will be phased out, gradually. In anticipation of advancing technology, we plan to make adjustments to the plot ID filter, proof fragment scan filter, and minimum plot difficulty. This CHIP also proposes a few other hard-fork changes, unrelated to the new proof format. + +## Motivation +### New proof format +The current proof format was released in July 2020, during the Chia blockchain’s beta phase. Five years later, the format remains secure. However, two broad issues exist, one of which remains hypothetical, and the other of which is in production today. + +The hypothetical issue is plot grinding. This is where a farmer creates an entire plot and submits a proof within around 28 seconds. Plot grinding is described in detail in [CHIP-12](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0012.md). + +The other issue is plot "compression," where bits are dropped during a plot's creation, and added back in while farming. The result is a farm that squeezes more proofs into the same space. Plot compression is described in detail in a [blog post](https://www.chia.net/2023/01/21/plot-compression-is-here/). + +Neither of these issues is an attack on the network itself, but in both cases, they make time-space tradeoffs, which cause the plots’ Proof of Space to begin to resemble Proof of Work (PoW). As a consequence, the network is consuming more energy than what was originally intended. + +In the first half of 2024, we made the decision to sunset the existing proof format in favor of a new one that will be significantly more resilient to bit dropping and other time-space tradeoffs. Farmers will need to replace their existing plots with new ones, so we have built this format with minimizing future disruptions in mind. + +We will future-proof the new format by introducing two new parameters with periodic modifications: the plot ID filter, and the plot difficulty. + +### Keccak256 +The hard fork gives us the opportunity to promote the keccak256 CLVM operator from [CHIP-36](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0036.md) to be allowed outside the `softfork` guard. This makes it easier to use. + +### Conditions +Currently, only `CREATE_COIN`, the `AGG_SIG_*`-family and `SOFTFORK` conditions have a cost. All other conditions are free and could therefore risk being a DoS vector. The full node currently limits the number of announce-family conditions, per coin spend, to 1024 (See [CHIP-25](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0025.md#clvm-cost)). Conditions in this family are expensive because they require memory allocation during validation. +With [Vaults](https://www.chia.net/2025/01/31/chia-vaults-a-secure-and-flexible-way-to-manage-your-digital-assets/), each coin spend requires a message to be sent from the vault to the coin. This makes the 1024 limit at risk of being hit by legitimate uses. + +This CHIP proposes replacing the hard upper limit of some conditions with a cost applied to all conditions beyond a certain number in a given coin spend. + +## Backwards Compatibility +This CHIP proposes a hard fork to upgrade the proof format. Hard forks relax rules. Blocks that are invalid by the existing rules will be considered valid by the new rules (and sometimes vice versa). This is why every node must update for a hard fork to be accepted. If this CHIP is accepted, then there will be a window of at least six months prior to its activation for all full nodes, farmers, and harvesters to be upgraded. + +Even though the original plot format will be disabled by this CHIP, it will remain valid until the end of a phase-out period, which starts at hard fork activation. + +## Specification +The specification for each of this CHIP’s features will be listed individually. + +### Fork activation +We will release Chia version 3.0.0 in the fourth quarter of 2025. This upgrade will implement the hard fork. The fork will activate in the block immediately following the first *transaction* block, with a later signage point, at or above height 8’800’000. This is expected to happen around 2026-06-01. +A signage point may have multiple blocks. If the block immediately following the transaction block at the activation height happens to be on the same signage point, it will also be pre-activation. The hard fork activates with the next signage point. + +Starting with the block in which the hard fork is activated, the new proof-of-space will be accepted. + +This hard fork is different from previous forks in that it affects the validity of proofs of space. When farming a block, the harvester does not know (exactly) at what height its proof may be infused. However, it *can* know what the most recent transaction block was. + +### Phase-out period +During the phase-out period, original proofs of space will become increasingly unlikely to win a block. The probability of winning a block will be scaled down, linearly, starting at the activation block, to reach 0 probability after 256 days (technically, 4608 x 256 blocks). + +In order for a plot to win a block, it first needs to pass the plot filter. The proof’s quality then needs to yield a low enough required iterations, lower than the signage point interval iterations. The required iterations count is part of the block’s infusion point calculation: + +```infusion_iterations = (signage_point_iterations + 3 * signage_point_interval_iterations + required_iterations) % sub-slot_iterations``` + +A higher required iteration count means the proof is less likely to be valid. + +The phase-out counter (`i`) starts at 0 at the hard fork activation. Every 4608 blocks, it’s incremented by 1. When computing `required_iterations` for original proofs of space, we add `signage_point_interval_iterations * i // 256` to required iterations. + +Just like the hard fork activation, each increment of `i` happens immediately following the first transaction block whose height is 8’800’000 + i * 4608 or above. + +Once `i` reaches 256, we end up adding `signage_point_interval_iterations` (or more) to the required iterations, so no original proof will ever be valid. This ends the phase-out period and effectively disables the original proof-of-space. + +| For blocks whose previous TX block is at or above | i | win probability factor | +| :------- | :—- | :---- | +| 8800000 | 0 | 1.000 | +| 8804608 | 1 | 0.996 | +| 8809216 | 2 | 0.992 | +| 8813824 | 3 | 0.988 | +| … | … | … | +| 9970432 | 254 | 0.008 | +| 9975040 | 255 | 0.004 | +| 9979648 | 256 | 0.000 | + + +### Protocol +A `FullNode` object contains a `ProofOfSpace` which has these fields: +``` +size: u8, +proof: Bytes, +``` +The `size` is not allowed to be less than 32 or greater than 50. After the hard fork, the most significant bit in the `size` field indicates whether the proof is the original proof-of-space (0) or the new proof-of-space (1). The remaining 7 bits then indicate the k-size of the plot that produced the proof. + +Valid k-sizes in the new proof-of-space are 28, 30 and 32. +The `proof`s are either v1 or v2 proof-of-space, depending on the most significant bit in the `size` field. + +### Plot ID filter adjustments +This is a similar concept to the plot filter for the existing proof format. CHIP-48 provides the technical details of this filter. If required, we can push the dates of these adjustments further into the future with a soft fork. + +The current proposal is to start the plot ID filter at 32 and cut it in half every two years until it reaches 1. The block heights of the filter adjustments are shown in the table in the next section. + +### Proof fragment scan filter adjustments +Only certain proof fragments will pass the proof fragment scan filter. The current proposal is to start the proof fragment scan filter at 32 (1/32 proof fragments will pass it) and cut it in half every two years until it reaches 1. + +The following table shows when both the plot ID filter, and the proof fragment scan filter will initially be set to adjust, as well as their values after the adjustments. This table is identical for both of the filters. + +| Block height | Month/Year (app.) | ID and fragment filters | +|:------------ | :---------------- | :---------------------- | +| 8’800’000 | May 2026 | 32 | +| 12’163’840 | May 2028 | 16 | +| 15’527’680 | May 2030 | 8 | +| 18’891’520 | May 2032 | 4 | +| 22’255’360 | May 2034 | 2 | +| 25’619’200 | May 2036 | 1 | + +It is difficult to predict advancements in technology, so these filters are intentionally set to be rather aggressive in their scheduled adjustments. If we feel that we can delay one or both of the filters, then this can be done in a future soft fork. + +### Plot difficulty adjustments +As detailed in CHIP-48, every plot will include a “difficulty” parameter, which will adjust how much time is required to create Table 3, _ceteris paribus_. If a given plot's difficulty is `n`, then creating Table 3 will require `2^n` times longer than the minimum amount of time. (Harvesting time is unaffected by the plot’s difficulty.) At a given block height, the network will only accept plots that meet the current minimum difficulty threshold, which will increase over time, as detailed below. + +By increasing the minimum threshold, the network will continue to be resistant to rental attacks for the foreseeable future. If required, we can push the dates of these adjustments further into the future with a soft fork. + +Another aspect of the difficulty parameter is that it will give each plot a _de facto_ expiration date. Farmers who want to get set up as quickly as possible can create plots with the current minimum difficulty, with the tradeoff being that their plots will expire the next time the threshold is increased. Farmers who expect to keep their farms running for many years can create plots with a higher difficulty level. This will increase the time required to plot their farms, but it will also mean that they won’t need to replot for a longer period of time. + +One thing to note is that a given farm can contain plots with various difficulty levels. Some farmers may choose a strategy of plotting their entire farm at the minimum current difficulty, and then gradually replacing their plots with higher-difficulty plots over time. The difficulty level doesn’t affect the size of plots. + +The current proposal is to start the difficulty at `2`, adjust it to `4` after two years, and increase it by one every two years thereafter. The difficulty parameter will be an 8-bit integer, so the maximum difficulty will be `255`, which will be reached at least 506 years after the hard fork’s activation. + +The reason to skip difficulty `3` is because this parameter only affects one table, so the plot times don’t exactly double with each increment. In addition, only the first three tables are used for grinding attacks, so their resistance is affected by a higher relative amount as the difficulty is adjusted upward. Finally, the initial difficulty is always applied to every table aside from Table 3. The following table demonstrates this effect for the first several difficulty levels: + +| Difficulty | Table 1 | Table 2 | Table 3 | Table 4 | Table 5 | Plot time | Grinding resistance | +| :--------- | :------ | :------ | :------ | :------ | :------ | :--------- | :------------------ | +| 2 | 4 | 4 | 4 | 4 | 4 | 20 | 12 | +| 4 | 4 | 4 | 16 | 4 | 4 | 32 (1.6x) | 24 (2x) | +| 5 | 4 | 4 | 32 | 4 | 4 | 48 (1.5x) | 40 (1.67x) | +| 6 | 4 | 4 | 64 | 4 | 4 | 80 (1.67x) | 72 (1.8x) | +| 7 | 4 | 4 | 128 | 4 | 4 | 144 (1.8x) | 136 (1.89x) | + +The difficulty adjustments will continue until the difficulty reaches 255. The plot time and grinding resistance will both approach 2x the previous level as the difficulty increases. + +The following table shows the block height and approximate month and year when the minimum plot difficulty will be adjusted. + +| Block height | Month/Year (app.) | Min. difficulty | +| :----------- | :---------------- | :-------------- | +| 8’800’000 | May 2026 | 2 | +| 12’160’000 | May 2028 | 4 | +| 15’530’000 | May 2030 | 5 | +| 18’890’000 | May 2032 | 6 | +| 22’250’000 | May 2034 | 7 | +| 25’620’000 | May 2036 | 8 | + +These adjustments will continue until the minimum difficulty level reaches 255. As with the plot ID filter and the proof fragment scan filter, we can delay these adjustments with a future soft fork. + +### keccak256 +The `keccak256` operator was previously added via soft fork, and is therefore only available under the `softfork` operator. Its usage (both inside and outside the `softfork` guard) is described in [the Specification section of CHIP-36](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0036.md#specification). After block 8,800,000, the `keccak256` operator will become part of the core CLVM, so it will be usable by calling it directly. It will also continue to be usable from inside the `softfork` guard. + +### Condition cost +After the hard fork activates, the limit of 1024 announcement conditions per spend will be removed. + +Instead, for each CoinSpend; Except for the first 100 conditions (which will not incur an additional cost) conditions will have a cost of 500. This is in addition to any existing cost for the condition. This cost applies to all conditions, including unknown conditions, `SOFTFORK`, `CREATE_COIN` and `AGG_SIG_*` conditions. + +## Test Cases +We will add any needed test cases prior to this CHIP’s completion. + +## Reference Implementation +We will include links to the reference implementation prior to this CHIP’s completion. + +## Security +The majority of the security work for the new proof format can be found in CHIP-48. That said, CNI will also perform an internal audit of the code updates involved with this CHIP. + +## Additional Assets +None + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 5ff939e8e4084c51afb3bda4e94654ae28b08dba Mon Sep 17 00:00:00 2001 From: danieljperry Date: Mon, 19 May 2025 21:35:43 +0800 Subject: [PATCH 02/24] Fix formatting --- CHIPs/chip-0049.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index d4e8dea8..53aed90a 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -1,15 +1,15 @@ CHIP Number | 0049 :------------|:---- -Title | Proof Format Fork Timelines +Title | Proof Format Fork Timelines Description | Provide all necessary timelines for the hard fork to support the new proof format -Author | [Arvid Norberg](https://github.com/arvidn) +Author | [Arvid Norberg](https://github.com/arvidn) Editor | [Dan Perry](https://github.com/danieljperry) Comments-URI | [CHIPs repo, PR #161](https://github.com/Chia-Network/chips/pull/161) -Status | Draft -Category | Standards Track +Status | Draft +Category | Standards Track Sub-Category | Core Created | 2025-05-19 -Requires | [0048](https://github.com/Chia-Network/chips/pull/160) +Requires | [0048](https://github.com/Chia-Network/chips/pull/160) ## Abstract [CHIP-48](https://github.com/Chia-Network/chips/pull/160), which introduces the new proof format, requires a hard fork of the Chia blockchain. This document describes how the new proof of space will be integrated with the blockchain as well as how original plots will be phased out, gradually. In anticipation of advancing technology, we plan to make adjustments to the plot ID filter, proof fragment scan filter, and minimum plot difficulty. This CHIP also proposes a few other hard-fork changes, unrelated to the new proof format. @@ -68,16 +68,16 @@ Just like the hard fork activation, each increment of `i` happens immediately fo Once `i` reaches 256, we end up adding `signage_point_interval_iterations` (or more) to the required iterations, so no original proof will ever be valid. This ends the phase-out period and effectively disables the original proof-of-space. -| For blocks whose previous TX block is at or above | i | win probability factor | -| :------- | :—- | :---- | -| 8800000 | 0 | 1.000 | -| 8804608 | 1 | 0.996 | -| 8809216 | 2 | 0.992 | -| 8813824 | 3 | 0.988 | -| … | … | … | -| 9970432 | 254 | 0.008 | -| 9975040 | 255 | 0.004 | -| 9979648 | 256 | 0.000 | +| Blocks w/prev. TX block >= | i | Win prob. factor | +|:-------------------------- | :-- | :--------------- | +| 8800000 | 0 | 1.000 | +| 8804608 | 1 | 0.996 | +| 8809216 | 2 | 0.992 | +| 8813824 | 3 | 0.988 | +| … | … | … | +| 9970432 | 254 | 0.008 | +| 9975040 | 255 | 0.004 | +| 9979648 | 256 | 0.000 | ### Protocol From 71133daecb3ed2663b0c0180931b6967a8c7fd4a Mon Sep 17 00:00:00 2001 From: danieljperry Date: Mon, 15 Sep 2025 11:13:10 +0800 Subject: [PATCH 03/24] Update Plot Difficulty to Plot Strength --- CHIPs/chip-0049.md | 52 +++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index 53aed90a..c99a2894 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -12,7 +12,7 @@ Created | 2025-05-19 Requires | [0048](https://github.com/Chia-Network/chips/pull/160) ## Abstract -[CHIP-48](https://github.com/Chia-Network/chips/pull/160), which introduces the new proof format, requires a hard fork of the Chia blockchain. This document describes how the new proof of space will be integrated with the blockchain as well as how original plots will be phased out, gradually. In anticipation of advancing technology, we plan to make adjustments to the plot ID filter, proof fragment scan filter, and minimum plot difficulty. This CHIP also proposes a few other hard-fork changes, unrelated to the new proof format. +[CHIP-48](https://github.com/Chia-Network/chips/pull/160), which introduces the new proof format, requires a hard fork of the Chia blockchain. This document describes how the new proof of space will be integrated with the blockchain as well as how original plots will be phased out, gradually. In anticipation of advancing technology, we plan to make adjustments to the plot ID filter, proof fragment scan filter, and minimum plot strength. This CHIP also proposes a few other hard-fork changes, unrelated to the new proof format. ## Motivation ### New proof format @@ -26,7 +26,7 @@ Neither of these issues is an attack on the network itself, but in both cases, t In the first half of 2024, we made the decision to sunset the existing proof format in favor of a new one that will be significantly more resilient to bit dropping and other time-space tradeoffs. Farmers will need to replace their existing plots with new ones, so we have built this format with minimizing future disruptions in mind. -We will future-proof the new format by introducing two new parameters with periodic modifications: the plot ID filter, and the plot difficulty. +We will future-proof the new format by introducing two new parameters with periodic modifications: the plot ID filter, and the plot strength. ### Keccak256 The hard fork gives us the opportunity to promote the keccak256 CLVM operator from [CHIP-36](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0036.md) to be allowed outside the `softfork` guard. This makes it easier to use. @@ -112,41 +112,41 @@ The following table shows when both the plot ID filter, and the proof fragment s It is difficult to predict advancements in technology, so these filters are intentionally set to be rather aggressive in their scheduled adjustments. If we feel that we can delay one or both of the filters, then this can be done in a future soft fork. -### Plot difficulty adjustments -As detailed in CHIP-48, every plot will include a “difficulty” parameter, which will adjust how much time is required to create Table 3, _ceteris paribus_. If a given plot's difficulty is `n`, then creating Table 3 will require `2^n` times longer than the minimum amount of time. (Harvesting time is unaffected by the plot’s difficulty.) At a given block height, the network will only accept plots that meet the current minimum difficulty threshold, which will increase over time, as detailed below. +### Plot strength adjustments +As detailed in CHIP-48, every plot will include a “strength” parameter, which will adjust how much time is required to create Table 3, _ceteris paribus_. If a given plot's strength is `n`, then creating Table 3 will require `2^n` times longer than the minimum amount of time. (Harvesting time is unaffected by the plot’s strength.) At a given block height, the network will only accept plots that meet the current minimum strength threshold, which will increase over time, as detailed below. By increasing the minimum threshold, the network will continue to be resistant to rental attacks for the foreseeable future. If required, we can push the dates of these adjustments further into the future with a soft fork. -Another aspect of the difficulty parameter is that it will give each plot a _de facto_ expiration date. Farmers who want to get set up as quickly as possible can create plots with the current minimum difficulty, with the tradeoff being that their plots will expire the next time the threshold is increased. Farmers who expect to keep their farms running for many years can create plots with a higher difficulty level. This will increase the time required to plot their farms, but it will also mean that they won’t need to replot for a longer period of time. +Another aspect of the strength parameter is that it will give each plot a _de facto_ expiration date. Farmers who want to get set up as quickly as possible can create plots with the current minimum strength, with the tradeoff being that their plots will expire the next time the threshold is increased. Farmers who expect to keep their farms running for many years can create plots with a higher strength level. This will increase the time required to plot their farms, but it will also mean that they won’t need to replot for a longer period of time. -One thing to note is that a given farm can contain plots with various difficulty levels. Some farmers may choose a strategy of plotting their entire farm at the minimum current difficulty, and then gradually replacing their plots with higher-difficulty plots over time. The difficulty level doesn’t affect the size of plots. +One thing to note is that a given farm can contain plots with various strength levels. Some farmers may choose a strategy of plotting their entire farm at the minimum current strength, and then gradually replacing their plots with higher-strength plots over time. The strength level doesn’t affect the size of plots. -The current proposal is to start the difficulty at `2`, adjust it to `4` after two years, and increase it by one every two years thereafter. The difficulty parameter will be an 8-bit integer, so the maximum difficulty will be `255`, which will be reached at least 506 years after the hard fork’s activation. +The current proposal is to start the minimum strength at `2`, adjust it to `4` after two years, and increase it by one every two years thereafter. The strength parameter will be an 8-bit unsigned integer, so the maximum strength will be `255`, which will be reached at least 506 years after the hard fork’s activation. -The reason to skip difficulty `3` is because this parameter only affects one table, so the plot times don’t exactly double with each increment. In addition, only the first three tables are used for grinding attacks, so their resistance is affected by a higher relative amount as the difficulty is adjusted upward. Finally, the initial difficulty is always applied to every table aside from Table 3. The following table demonstrates this effect for the first several difficulty levels: +The reason to skip strength `3` is because this parameter only affects one table, so the plot times don’t exactly double with each increment. In addition, only the first three tables are used for grinding attacks, so their resistance is affected by a higher relative amount as the strength is adjusted upward. Finally, the initial strength is always applied to every table aside from Table 3. The following table demonstrates this effect for the first several strength levels: -| Difficulty | Table 1 | Table 2 | Table 3 | Table 4 | Table 5 | Plot time | Grinding resistance | -| :--------- | :------ | :------ | :------ | :------ | :------ | :--------- | :------------------ | -| 2 | 4 | 4 | 4 | 4 | 4 | 20 | 12 | -| 4 | 4 | 4 | 16 | 4 | 4 | 32 (1.6x) | 24 (2x) | -| 5 | 4 | 4 | 32 | 4 | 4 | 48 (1.5x) | 40 (1.67x) | -| 6 | 4 | 4 | 64 | 4 | 4 | 80 (1.67x) | 72 (1.8x) | -| 7 | 4 | 4 | 128 | 4 | 4 | 144 (1.8x) | 136 (1.89x) | +| Strength | Table 1 | Table 2 | Table 3 | Table 4 | Table 5 | Plot time | Grinding resistance | +| :------- | :------ | :------ | :------ | :------ | :------ | :--------- | :------------------ | +| 2 | 4 | 4 | 4 | 4 | 4 | 20 | 12 | +| 4 | 4 | 4 | 16 | 4 | 4 | 32 (1.6x) | 24 (2x) | +| 5 | 4 | 4 | 32 | 4 | 4 | 48 (1.5x) | 40 (1.67x) | +| 6 | 4 | 4 | 64 | 4 | 4 | 80 (1.67x) | 72 (1.8x) | +| 7 | 4 | 4 | 128 | 4 | 4 | 144 (1.8x) | 136 (1.89x) | -The difficulty adjustments will continue until the difficulty reaches 255. The plot time and grinding resistance will both approach 2x the previous level as the difficulty increases. +The strength adjustments will continue until the strength reaches 255. The plot time and grinding resistance will both approach 2x the previous level as the strength increases. -The following table shows the block height and approximate month and year when the minimum plot difficulty will be adjusted. +The following table shows the block height and approximate month and year when the minimum plot strength will be adjusted. -| Block height | Month/Year (app.) | Min. difficulty | -| :----------- | :---------------- | :-------------- | -| 8’800’000 | May 2026 | 2 | -| 12’160’000 | May 2028 | 4 | -| 15’530’000 | May 2030 | 5 | -| 18’890’000 | May 2032 | 6 | -| 22’250’000 | May 2034 | 7 | -| 25’620’000 | May 2036 | 8 | +| Block height | Month/Year (app.) | Min. strength | +| :----------- | :---------------- | :------------ | +| 8’800’000 | May 2026 | 2 | +| 12’160’000 | May 2028 | 4 | +| 15’530’000 | May 2030 | 5 | +| 18’890’000 | May 2032 | 6 | +| 22’250’000 | May 2034 | 7 | +| 25’620’000 | May 2036 | 8 | -These adjustments will continue until the minimum difficulty level reaches 255. As with the plot ID filter and the proof fragment scan filter, we can delay these adjustments with a future soft fork. +These adjustments will continue until the minimum strength level reaches 255. As with the plot ID filter and the proof fragment scan filter, we can delay these adjustments with a future soft fork. ### keccak256 The `keccak256` operator was previously added via soft fork, and is therefore only available under the `softfork` operator. Its usage (both inside and outside the `softfork` guard) is described in [the Specification section of CHIP-36](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0036.md#specification). After block 8,800,000, the `keccak256` operator will become part of the core CLVM, so it will be usable by calling it directly. It will also continue to be usable from inside the `softfork` guard. From 8d7ab9e42aa710628071d52430a95eae671c9ef9 Mon Sep 17 00:00:00 2001 From: danieljperry Date: Thu, 25 Sep 2025 15:48:06 +0800 Subject: [PATCH 04/24] Update minimum plot strength strategy to use manual increases instead of automated --- CHIPs/chip-0049.md | 43 +++++++++---------------------------------- 1 file changed, 9 insertions(+), 34 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index c99a2894..4faf6197 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -12,7 +12,7 @@ Created | 2025-05-19 Requires | [0048](https://github.com/Chia-Network/chips/pull/160) ## Abstract -[CHIP-48](https://github.com/Chia-Network/chips/pull/160), which introduces the new proof format, requires a hard fork of the Chia blockchain. This document describes how the new proof of space will be integrated with the blockchain as well as how original plots will be phased out, gradually. In anticipation of advancing technology, we plan to make adjustments to the plot ID filter, proof fragment scan filter, and minimum plot strength. This CHIP also proposes a few other hard-fork changes, unrelated to the new proof format. +[CHIP-48](https://github.com/Chia-Network/chips/pull/160), which introduces the new proof format, requires a hard fork of the Chia blockchain. This document describes how the new proof of space will be integrated with the blockchain as well as how original plots will be phased out, gradually. In anticipation of advancing technology, we plan to make automated adjustments to the plot ID filter and the proof fragment scan filter. We will adjust the minimum plot strength manually when needed. This CHIP also proposes a few other hard-fork changes, unrelated to the new proof format. ## Motivation ### New proof format @@ -26,7 +26,7 @@ Neither of these issues is an attack on the network itself, but in both cases, t In the first half of 2024, we made the decision to sunset the existing proof format in favor of a new one that will be significantly more resilient to bit dropping and other time-space tradeoffs. Farmers will need to replace their existing plots with new ones, so we have built this format with minimizing future disruptions in mind. -We will future-proof the new format by introducing two new parameters with periodic modifications: the plot ID filter, and the plot strength. +We will future-proof the new format by introducing a new parameter with periodic modifications for the plot ID filter and the proof fragment scan filter. ### Keccak256 The hard fork gives us the opportunity to promote the keccak256 CLVM operator from [CHIP-36](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0036.md) to be allowed outside the `softfork` guard. This makes it easier to use. @@ -46,7 +46,7 @@ Even though the original plot format will be disabled by this CHIP, it will rema The specification for each of this CHIP’s features will be listed individually. ### Fork activation -We will release Chia version 3.0.0 in the fourth quarter of 2025. This upgrade will implement the hard fork. The fork will activate in the block immediately following the first *transaction* block, with a later signage point, at or above height 8’800’000. This is expected to happen around 2026-06-01. +We will release Chia version 3.0.0, which will implement the hard fork. The fork will activate in the block immediately following the first *transaction* block, with a later signage point, at or above height 8’800’000. This is expected to happen around 2026-06-01. A signage point may have multiple blocks. If the block immediately following the transaction block at the activation height happens to be on the same signage point, it will also be pre-activation. The hard fork activates with the next signage point. Starting with the block in which the hard fork is activated, the new proof-of-space will be accepted. @@ -113,40 +113,15 @@ The following table shows when both the plot ID filter, and the proof fragment s It is difficult to predict advancements in technology, so these filters are intentionally set to be rather aggressive in their scheduled adjustments. If we feel that we can delay one or both of the filters, then this can be done in a future soft fork. ### Plot strength adjustments -As detailed in CHIP-48, every plot will include a “strength” parameter, which will adjust how much time is required to create Table 3, _ceteris paribus_. If a given plot's strength is `n`, then creating Table 3 will require `2^n` times longer than the minimum amount of time. (Harvesting time is unaffected by the plot’s strength.) At a given block height, the network will only accept plots that meet the current minimum strength threshold, which will increase over time, as detailed below. +As detailed in CHIP-48, every plot will include a “strength” parameter, which will adjust how much time is required to create Table 3, _ceteris paribus_. If a given plot's strength is `n`, then creating Table 3 will require `2^n` times longer than the minimum amount of time. (Harvesting time is unaffected by the plot’s strength.) At a given block height, the network will only accept plots that meet the current minimum strength threshold. The strength parameter will be an 8-bit unsigned integer, so the maximum strength will be `255`. -By increasing the minimum threshold, the network will continue to be resistant to rental attacks for the foreseeable future. If required, we can push the dates of these adjustments further into the future with a soft fork. +The current proposal is to start the minimum strength at `2`, and to adjust it upward as needed. Adjusting the minimum strength will require a soft fork. Each increase in the minimum strength will require some portion of the netspace to be replotted in order to continue farming. Therefore, the plan will be to propose a lengthy lead time before any increases in the minimum strength take effect. -Another aspect of the strength parameter is that it will give each plot a _de facto_ expiration date. Farmers who want to get set up as quickly as possible can create plots with the current minimum strength, with the tradeoff being that their plots will expire the next time the threshold is increased. Farmers who expect to keep their farms running for many years can create plots with a higher strength level. This will increase the time required to plot their farms, but it will also mean that they won’t need to replot for a longer period of time. +For example, if we proposed to increase the minimum strength from `2` to `5`, then all plots with strength `2`, `3`, or `4` would no longer be able to farm after the increase went into effect. We therefore would provide a lengthy warning (perhaps six or twelve months) for the fork to activate. -One thing to note is that a given farm can contain plots with various strength levels. Some farmers may choose a strategy of plotting their entire farm at the minimum current strength, and then gradually replacing their plots with higher-strength plots over time. The strength level doesn’t affect the size of plots. +In order to decrease the number of expected replots, some farmers might initially choose to plot to a high strength. In order to keep up with advances in technology, we might need to increase the minimum strength every two years (though keep in mind that this is a rough estimate). If a farmer estimated that the lifespan of their farm's HDDs would be eight years, then they might consider initially plotting to four levels above the current minimum strength. That way, by the time of the next expected replot, their HDDs would have already exceeded their expected lifespan. -The current proposal is to start the minimum strength at `2`, adjust it to `4` after two years, and increase it by one every two years thereafter. The strength parameter will be an 8-bit unsigned integer, so the maximum strength will be `255`, which will be reached at least 506 years after the hard fork’s activation. - -The reason to skip strength `3` is because this parameter only affects one table, so the plot times don’t exactly double with each increment. In addition, only the first three tables are used for grinding attacks, so their resistance is affected by a higher relative amount as the strength is adjusted upward. Finally, the initial strength is always applied to every table aside from Table 3. The following table demonstrates this effect for the first several strength levels: - -| Strength | Table 1 | Table 2 | Table 3 | Table 4 | Table 5 | Plot time | Grinding resistance | -| :------- | :------ | :------ | :------ | :------ | :------ | :--------- | :------------------ | -| 2 | 4 | 4 | 4 | 4 | 4 | 20 | 12 | -| 4 | 4 | 4 | 16 | 4 | 4 | 32 (1.6x) | 24 (2x) | -| 5 | 4 | 4 | 32 | 4 | 4 | 48 (1.5x) | 40 (1.67x) | -| 6 | 4 | 4 | 64 | 4 | 4 | 80 (1.67x) | 72 (1.8x) | -| 7 | 4 | 4 | 128 | 4 | 4 | 144 (1.8x) | 136 (1.89x) | - -The strength adjustments will continue until the strength reaches 255. The plot time and grinding resistance will both approach 2x the previous level as the strength increases. - -The following table shows the block height and approximate month and year when the minimum plot strength will be adjusted. - -| Block height | Month/Year (app.) | Min. strength | -| :----------- | :---------------- | :------------ | -| 8’800’000 | May 2026 | 2 | -| 12’160’000 | May 2028 | 4 | -| 15’530’000 | May 2030 | 5 | -| 18’890’000 | May 2032 | 6 | -| 22’250’000 | May 2034 | 7 | -| 25’620’000 | May 2036 | 8 | - -These adjustments will continue until the minimum strength level reaches 255. As with the plot ID filter and the proof fragment scan filter, we can delay these adjustments with a future soft fork. +One thing to note is that a given farm can contain plots with various strength levels. Some farmers may choose a strategy of plotting their entire farm at the minimum current strength, and then gradually replacing their plots with higher-strength plots over time. Plots of the same k-size will be approximately the same size, regardless of strength. ### keccak256 The `keccak256` operator was previously added via soft fork, and is therefore only available under the `softfork` operator. Its usage (both inside and outside the `softfork` guard) is described in [the Specification section of CHIP-36](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0036.md#specification). After block 8,800,000, the `keccak256` operator will become part of the core CLVM, so it will be usable by calling it directly. It will also continue to be usable from inside the `softfork` guard. @@ -154,7 +129,7 @@ The `keccak256` operator was previously added via soft fork, and is therefore on ### Condition cost After the hard fork activates, the limit of 1024 announcement conditions per spend will be removed. -Instead, for each CoinSpend; Except for the first 100 conditions (which will not incur an additional cost) conditions will have a cost of 500. This is in addition to any existing cost for the condition. This cost applies to all conditions, including unknown conditions, `SOFTFORK`, `CREATE_COIN` and `AGG_SIG_*` conditions. +Instead, for each CoinSpend, conditions will have a cost of 500, **except** for the first 100 conditions, which will not incur an additional cost. This is in addition to any existing cost for the condition. This cost applies to all conditions, including unknown conditions, `SOFTFORK`, `CREATE_COIN` and `AGG_SIG_*` conditions. ## Test Cases We will add any needed test cases prior to this CHIP’s completion. From 7e767e1daeecdf4cfa915fba1692633476e5e159 Mon Sep 17 00:00:00 2001 From: danieljperry Date: Wed, 1 Oct 2025 12:46:17 +0800 Subject: [PATCH 05/24] Add shatree operator to CHIP-49 --- CHIPs/chip-0049.md | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index 4faf6197..44da19a7 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -1,7 +1,7 @@ CHIP Number | 0049 :------------|:---- -Title | Proof Format Fork Timelines -Description | Provide all necessary timelines for the hard fork to support the new proof format +Title | 3.0 Fork Info +Description | Provide all info that will be included in the 3.0 fork Author | [Arvid Norberg](https://github.com/arvidn) Editor | [Dan Perry](https://github.com/danieljperry) Comments-URI | [CHIPs repo, PR #161](https://github.com/Chia-Network/chips/pull/161) @@ -28,9 +28,26 @@ In the first half of 2024, we made the decision to sunset the existing proof for We will future-proof the new format by introducing a new parameter with periodic modifications for the plot ID filter and the proof fragment scan filter. -### Keccak256 +### keccak256 The hard fork gives us the opportunity to promote the keccak256 CLVM operator from [CHIP-36](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0036.md) to be allowed outside the `softfork` guard. This makes it easier to use. +The usage and CLVM cost of this operator are provided in CHIP-36. + +### shatree +Many puzzles use the [sha256tree](https://github.com/Chia-Network/chia_puzzles/blob/0b46a6ebfc3b432d68edf9b91e6cef0ec13da2e7/puzzles/sha256tree.clib) library, which calculates the puzzle hash of a given puzzle program. This library is used so frequently, in fact, that it makes sense to include it as a native CLVM operator in the hard fork. Another advantage of including `shatree` in the CLVM is that it will be cheaper to call, both in terms of CPU compute and CLVM cost. + +#### Technical info about shatree + +Opcode: todo + +Argument: Exactly one valid CLVM tree + +Returns: The `sha256` puzzle hash (Merkle root) of the input tree + +Usage: (shatree (TREE)) + +CLVM Cost: todo + ### Conditions Currently, only `CREATE_COIN`, the `AGG_SIG_*`-family and `SOFTFORK` conditions have a cost. All other conditions are free and could therefore risk being a DoS vector. The full node currently limits the number of announce-family conditions, per coin spend, to 1024 (See [CHIP-25](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0025.md#clvm-cost)). Conditions in this family are expensive because they require memory allocation during validation. With [Vaults](https://www.chia.net/2025/01/31/chia-vaults-a-secure-and-flexible-way-to-manage-your-digital-assets/), each coin spend requires a message to be sent from the vault to the coin. This makes the 1024 limit at risk of being hit by legitimate uses. From 3a537d7db74daf5d7a32aca1a101074f7335377d Mon Sep 17 00:00:00 2001 From: danieljperry Date: Mon, 3 Nov 2025 12:11:48 +0800 Subject: [PATCH 06/24] Update name of shatree to sha256tree --- CHIPs/chip-0049.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index 44da19a7..adddea96 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -33,18 +33,18 @@ The hard fork gives us the opportunity to promote the keccak256 CLVM operator fr The usage and CLVM cost of this operator are provided in CHIP-36. -### shatree -Many puzzles use the [sha256tree](https://github.com/Chia-Network/chia_puzzles/blob/0b46a6ebfc3b432d68edf9b91e6cef0ec13da2e7/puzzles/sha256tree.clib) library, which calculates the puzzle hash of a given puzzle program. This library is used so frequently, in fact, that it makes sense to include it as a native CLVM operator in the hard fork. Another advantage of including `shatree` in the CLVM is that it will be cheaper to call, both in terms of CPU compute and CLVM cost. +### sha256tree +Many puzzles use the [sha256tree](https://github.com/Chia-Network/chia_puzzles/blob/0b46a6ebfc3b432d68edf9b91e6cef0ec13da2e7/puzzles/sha256tree.clib) library, which calculates the puzzle hash of a given puzzle program. This library is used so frequently, in fact, that it makes sense to include it as a native CLVM operator in the hard fork. Another advantage of including `sha256tree` in the CLVM is that it will be cheaper to call, both in terms of CPU compute and CLVM cost. -#### Technical info about shatree +#### Technical info about sha256tree -Opcode: todo +Opcode: 63 Argument: Exactly one valid CLVM tree Returns: The `sha256` puzzle hash (Merkle root) of the input tree -Usage: (shatree (TREE)) +Usage: (sha256tree (TREE)) CLVM Cost: todo From 388525e0b546a590268a3d2093902129d964d0a7 Mon Sep 17 00:00:00 2001 From: danieljperry Date: Fri, 19 Dec 2025 15:58:18 +0700 Subject: [PATCH 07/24] Update description of hard fork --- CHIPs/chip-0049.md | 288 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 219 insertions(+), 69 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index adddea96..073e71c7 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -12,50 +12,27 @@ Created | 2025-05-19 Requires | [0048](https://github.com/Chia-Network/chips/pull/160) ## Abstract -[CHIP-48](https://github.com/Chia-Network/chips/pull/160), which introduces the new proof format, requires a hard fork of the Chia blockchain. This document describes how the new proof of space will be integrated with the blockchain as well as how original plots will be phased out, gradually. In anticipation of advancing technology, we plan to make automated adjustments to the plot ID filter and the proof fragment scan filter. We will adjust the minimum plot strength manually when needed. This CHIP also proposes a few other hard-fork changes, unrelated to the new proof format. +[CHIP-48](https://github.com/Chia-Network/chips/pull/160), which introduces the new Proof of Space format (PoS v2), requires a hard fork of the Chia blockchain. This document describes how PoS v2 will be integrated with the blockchain, as well as how original plots will be phased out. This CHIP also proposes a few other hard-fork changes, unrelated to the new proof format. ## Motivation -### New proof format -The current proof format was released in July 2020, during the Chia blockchain’s beta phase. Five years later, the format remains secure. However, two broad issues exist, one of which remains hypothetical, and the other of which is in production today. +The current Proof of Space format (PoS v1) was released in July 2020, during the Chia blockchain’s beta phase. Five years later, the format remains secure. However, two broad issues exist, one of which remains hypothetical, and the other of which is in production today. The hypothetical issue is plot grinding. This is where a farmer creates an entire plot and submits a proof within around 28 seconds. Plot grinding is described in detail in [CHIP-12](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0012.md). The other issue is plot "compression," where bits are dropped during a plot's creation, and added back in while farming. The result is a farm that squeezes more proofs into the same space. Plot compression is described in detail in a [blog post](https://www.chia.net/2023/01/21/plot-compression-is-here/). -Neither of these issues is an attack on the network itself, but in both cases, they make time-space tradeoffs, which cause the plots’ Proof of Space to begin to resemble Proof of Work (PoW). As a consequence, the network is consuming more energy than what was originally intended. +Neither of these issues is an attack on the network itself, but in both cases, they make time-space tradeoffs, which cause the plots’ Proof of Space to begin to resemble Proof of Work (PoW). As a consequence, the network uses more compute than what was originally intended. In the first half of 2024, we made the decision to sunset the existing proof format in favor of a new one that will be significantly more resilient to bit dropping and other time-space tradeoffs. Farmers will need to replace their existing plots with new ones, so we have built this format with minimizing future disruptions in mind. -We will future-proof the new format by introducing a new parameter with periodic modifications for the plot ID filter and the proof fragment scan filter. +We will future-proof the new format with two independent mechanisms: +1. Automatically reducing the network's base filter (can be delayed with a soft fork) +2. Manually increasing the network's minimum plot strength (a soft fork) -### keccak256 -The hard fork gives us the opportunity to promote the keccak256 CLVM operator from [CHIP-36](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0036.md) to be allowed outside the `softfork` guard. This makes it easier to use. - -The usage and CLVM cost of this operator are provided in CHIP-36. - -### sha256tree -Many puzzles use the [sha256tree](https://github.com/Chia-Network/chia_puzzles/blob/0b46a6ebfc3b432d68edf9b91e6cef0ec13da2e7/puzzles/sha256tree.clib) library, which calculates the puzzle hash of a given puzzle program. This library is used so frequently, in fact, that it makes sense to include it as a native CLVM operator in the hard fork. Another advantage of including `sha256tree` in the CLVM is that it will be cheaper to call, both in terms of CPU compute and CLVM cost. - -#### Technical info about sha256tree - -Opcode: 63 - -Argument: Exactly one valid CLVM tree - -Returns: The `sha256` puzzle hash (Merkle root) of the input tree - -Usage: (sha256tree (TREE)) - -CLVM Cost: todo - -### Conditions -Currently, only `CREATE_COIN`, the `AGG_SIG_*`-family and `SOFTFORK` conditions have a cost. All other conditions are free and could therefore risk being a DoS vector. The full node currently limits the number of announce-family conditions, per coin spend, to 1024 (See [CHIP-25](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0025.md#clvm-cost)). Conditions in this family are expensive because they require memory allocation during validation. -With [Vaults](https://www.chia.net/2025/01/31/chia-vaults-a-secure-and-flexible-way-to-manage-your-digital-assets/), each coin spend requires a message to be sent from the vault to the coin. This makes the 1024 limit at risk of being hit by legitimate uses. - -This CHIP proposes replacing the hard upper limit of some conditions with a cost applied to all conditions beyond a certain number in a given coin spend. +Both of these adjustments are detailed in the [Specification](#specification) section. ## Backwards Compatibility -This CHIP proposes a hard fork to upgrade the proof format. Hard forks relax rules. Blocks that are invalid by the existing rules will be considered valid by the new rules (and sometimes vice versa). This is why every node must update for a hard fork to be accepted. If this CHIP is accepted, then there will be a window of at least six months prior to its activation for all full nodes, farmers, and harvesters to be upgraded. +This CHIP proposes a hard fork to upgrade the proof format. Hard forks relax rules. Blocks that are invalid by the existing rules will be considered valid by the new rules (and sometimes vice versa). This is why every node must update for a hard fork to be accepted. If this CHIP is accepted, then there will be a window of several months prior to its activation for all full nodes, farmers, and harvesters to be upgraded. Even though the original plot format will be disabled by this CHIP, it will remain valid until the end of a phase-out period, which starts at hard fork activation. @@ -63,27 +40,33 @@ Even though the original plot format will be disabled by this CHIP, it will rema The specification for each of this CHIP’s features will be listed individually. ### Fork activation -We will release Chia version 3.0.0, which will implement the hard fork. The fork will activate in the block immediately following the first *transaction* block, with a later signage point, at or above height 8’800’000. This is expected to happen around 2026-06-01. +We will release Chia version 3.0.0, which will implement the hard fork. The fork will activate in the block immediately following the first *transaction* block, with a later signage point, at or above height [todo]. This is expected to happen around [todo]. A signage point may have multiple blocks. If the block immediately following the transaction block at the activation height happens to be on the same signage point, it will also be pre-activation. The hard fork activates with the next signage point. -Starting with the block in which the hard fork is activated, the new proof-of-space will be accepted. +Starting with the block in which the hard fork is activated, the new Proof of Space will be accepted. -This hard fork is different from previous forks in that it affects the validity of proofs of space. When farming a block, the harvester does not know (exactly) at what height its proof may be infused. However, it *can* know what the most recent transaction block was. +This hard fork is different from previous forks in that it affects the validity of Proofs of Space. When farming a block, the harvester does not know (exactly) at what height its proof may be infused. However, it *can* know what the most recent transaction block was. ### Phase-out period -During the phase-out period, original proofs of space will become increasingly unlikely to win a block. The probability of winning a block will be scaled down, linearly, starting at the activation block, to reach 0 probability after 256 days (technically, 4608 x 256 blocks). +During the phase-out period, original Proofs of Space will become increasingly unlikely to win a block. The probability of winning a block will be scaled down, linearly, starting at the activation block, to reach 0 probability after 256 days (technically, 4608 x 256 blocks). -In order for a plot to win a block, it first needs to pass the plot filter. The proof’s quality then needs to yield a low enough required iterations, lower than the signage point interval iterations. The required iterations count is part of the block’s infusion point calculation: +In order for a plot to win a block, it first needs to pass the plot filter. The proof’s quality then needs to yield a low enough required iterations, lower than the signage point interval iterations. The required iterations count is part of the block’s infusion iterations calculation: ```infusion_iterations = (signage_point_iterations + 3 * signage_point_interval_iterations + required_iterations) % sub-slot_iterations``` A higher required iteration count means the proof is less likely to be valid. -The phase-out counter (`i`) starts at 0 at the hard fork activation. Every 4608 blocks, it’s incremented by 1. When computing `required_iterations` for original proofs of space, we add `signage_point_interval_iterations * i // 256` to required iterations. +The phase-out counter (`i`) starts at 0 at the hard fork activation. Every 4608 blocks, it’s incremented by 1. When computing `required_iterations` for original Proofs of Space, we add `signage_point_interval_iterations * (i // 256)` to required iterations, so the calculation becomes: + +```infusion_iterations = (signage_point_iterations + 3 * signage_point_interval_iterations * (i // 256) + required_iterations) % sub-slot_iterations``` + +[todo] (i // 256) might be wrong -Just like the hard fork activation, each increment of `i` happens immediately following the first transaction block whose height is 8’800’000 + i * 4608 or above. +Just like the hard fork activation, each increment of `i` happens immediately following the first transaction block whose height is [todo (activation height)] + i * 4608 or above. -Once `i` reaches 256, we end up adding `signage_point_interval_iterations` (or more) to the required iterations, so no original proof will ever be valid. This ends the phase-out period and effectively disables the original proof-of-space. +Once `i` reaches 256, we end up adding `signage_point_interval_iterations` (or more) to the required iterations, so no original proof will ever be valid. This ends the phase-out period and effectively disables the original Proof of Space. + +[todo update heights ni this table] | Blocks w/prev. TX block >= | i | Win prob. factor | |:-------------------------- | :-- | :--------------- | @@ -96,66 +79,233 @@ Once `i` reaches 256, we end up adding `signage_point_interval_iterations` (or m | 9975040 | 255 | 0.004 | | 9979648 | 256 | 0.000 | - ### Protocol A `FullNode` object contains a `ProofOfSpace` which has these fields: ``` size: u8, proof: Bytes, ``` -The `size` is not allowed to be less than 32 or greater than 50. After the hard fork, the most significant bit in the `size` field indicates whether the proof is the original proof-of-space (0) or the new proof-of-space (1). The remaining 7 bits then indicate the k-size of the plot that produced the proof. +The `size` is not allowed to be less than 32 or greater than 50. After the hard fork, the most significant bit in the `size` field indicates whether the proof is the original Proof of Space (0) or the new Proof of Space (1). + +The remaining 7 bits then indicate either: +* The k-size of the plot that produced the proof (original Proof of Space), or +* The strength of the plot that produced the proof (new Proof of Space) + +The only valid k-size in the new Proof of Space is 28 (mainnet/testnet) and 18 (testnet only). +The `proof`s are either v1 or v2 Proof of Space, depending on the most significant bit in the `size` field. + +### Filter and strength adjustments +We have two ways to future-proof the network against rental attacks, and plot grinding more generally: automatic reductions in the base filter, and manual increases in the network's minimum plot strength. Both of these will be detailed in this section. + +At every signage point, a certain number of plots are excluded from participating in the challenge. In the original Proof of Space protocol, this was known as the `plot filter`, and is described in [our documentation](https://docs.chia.net/chia-blockchain/consensus/chains/signage-and-infusion-points/). In Proof of Space v2, there are now two related filters to consider: the network's base filter, and an individual plot's ID filter. + +#### Base filter definition and plan +The base filter indicates the lowest filter allowed for all plots across the network. This filter will start `1024` and will automatically be adjusted downward every two years at pre-defined block heights, until it reaches `64`. It will remain at `64` thereafter. + +The reason to reduce the base filter over time is to decrease the leverage a rental attacker is able to gain. This topic is covered extensively in [CHIP-12](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0012.md). In summary, a rental attacker can opt to exclusively create plots that will pass the filter, so the amount of space they are able to spoof is multiplied by a given plot's ID filter ([described below](#plot-id-filter-definition)). As GPUs become faster, we can initially protect the network against rental attacks by proactively reducing the Plot ID filter. However, for technical reasons covered in CHIP-48, we won't reduce the filter to be lower than `64`. The next protection against rental attacks will come from increasing the minimum plot strength, which will be [covered later](#minimum-strength-plan). + +Cutting the base filter in half every two years will have two impacts for all farmers: higher disk usage, and longer plot stability. + +##### Disk usage +Each time the base filter is cut in half, the likelihood that a plot will pass it is doubled. The load on individual disks will therefore roughly double as well. + +HDDs can operate at 20% of capacity without significantly shortening their life expectancy. The filter will be cut in half four times over the course of eight years, so if a farmer expects their disks to last for eight years, then they should plot so that their disks initially run at 1% of capacity or lower. That way, their disks will never run at more than 16% of capacity, so they will remain viable for farming for their entire life expectancy. + +Read speeds of SSDs are much faster than those of HDDs, so farmers can safely plot their SSDs at the minimum strength without running into issues related to high disk usage. However, they should still plan according to the expected scheduling for minimum strength increases, which are [covered later](#minimum-strength-plan). + +##### Plot stability +By decreasing the base filter every two years for the first eight years of the new Proof of Space's existence, we expect to be able to keep the minimum strength at `0` for that time frame. This means that all plots created at the minimum strength are expected to be valid for at least eight years, pending unexpected advancements in technology. + +Starting around 2034, plot stability will come entirely from plotting to a higher strength than the minimum. + +#### Plot ID filter definition +Each plot will have its own `plot ID filter`, which determines the likelihood that it is eligible to participate in a challenge at a given signage point. The plot ID filter is calculated based on a given plot's strength. [CHIP-48](https://github.com/Chia-Network/chips/pull/160) provides the technical details. + +The formula to calculate a given plot's ID filter is: +`plot ID filter = base filter * (2^(plot strength - min strength))` + +For each level that a given plot's strength is higher than the network's base strength, the plot ID filter will be doubled. + +#### Plot strength definition +As detailed in CHIP-48, every plot will include a “strength” parameter, which will adjust how much time is required to create the plot, _ceteris paribus_. If a given plot's strength is `n`, then creating the plot will require `2^n` times longer than the minimum amount of time. (Harvesting time is unaffected by the plot’s strength.) At a given block height, the network will only accept plots that meet the current minimum strength threshold. + +By definition, `strength = 0` indicates the minimum compute required to create a plot, with no additional arbitrary computation. + +The maximum allowed strength will be [TODO]. This strength is capped arbitrarily, in order to prevent future attacks which may emerge from applying an extremely high strength to one or more plots. + +#### Minimum strength plan +The network's minimum strength will start at `0`, and will be adjusted upward as needed. Adjusting the minimum strength will require a soft fork. We won't plan to increase the minimum strength for the first eight years after the PoS2 fork activates, barring any unexpected advancements in technology. + +The minimum strength should only ever be increased with time. It can be increased by any integer, but typically we will only increase it by 1 in a given soft fork. Because any plots with the current minimum strength will need to be recreated when the minimum strength is increased, we plan provide a lengthy warning (perhaps six or twelve months) for a fork that increases the minimum strength to activate. + +In order to decrease the number of expected replots, some farmers might initially choose to plot to a high strength. In order to keep up with advancements in technology, we might need to increase the minimum strength every two years (though keep in mind that this is a rough estimate). + +One thing to note is that a given farm can contain plots with various strength levels. Some farmers may choose a strategy of plotting their entire farm at the minimum current strength, and then gradually replacing their plots with higher-strength plots over time. A plot's size is unaffected by its strength. + +#### Expected base filter and strength +To recap: + +The base filter will start at `1024` and will be cut in half every two years until it reaches `64`. These adjustments will happen automatically, and can be delayed with a soft fork. -Valid k-sizes in the new proof-of-space are 28, 30 and 32. -The `proof`s are either v1 or v2 proof-of-space, depending on the most significant bit in the `size` field. +The minimum strength will start at `0` and will be increased via a soft fork as needed. We won't plan to increase the minimum strength until at least 2036, though this is subject to change. -### Plot ID filter adjustments -This is a similar concept to the plot filter for the existing proof format. CHIP-48 provides the technical details of this filter. If required, we can push the dates of these adjustments further into the future with a soft fork. +The following table illustrates how we expect these adjustments to occur. The second column from the right shows the plot ID filter for a plot created at `strength = 3`, and the rightmost column shows how often that plot will pass the filter, on average. This plot will take eight times longer than the minimum to be created, and is expected to be valid into the 2040s. It will only become invalid when the minimum strength reaches `4`. -The current proposal is to start the plot ID filter at 32 and cut it in half every two years until it reaches 1. The block heights of the filter adjustments are shown in the table in the next section. +| Block height | Month/Year (app.) | Base Filter | Min Str | Filter at Str=3 | Pass Frequency | +| :----------- | :---------------- | :---------- | :------ | :-------------- | :------------- | +| TODO | July 2026 | 1024 | 0 | 8192 | 1 day | +| TODO | July 2028 | 512 | 0 | 4096 | 12 hours | +| TODO | July 2030 | 256 | 0 | 2048 | 6 hours | +| TODO | July 2032 | 128 | 0 | 1024 | 3 hours | +| TODO | July 2034 | 64 | 0 | 512 | 80 minutes | +| TBD | TBD | 64 | 1 | 256 | 40 minutes | +| TBD | TBD | 64 | 2 | 128 | 20 minutes | +| TBD | TBD | 64 | 3 | 64 | 10 minutes | +| TBD | TBD | 64 | 4 | Invalid | N/A | -### Proof fragment scan filter adjustments -Only certain proof fragments will pass the proof fragment scan filter. The current proposal is to start the proof fragment scan filter at 32 (1/32 proof fragments will pass it) and cut it in half every two years until it reaches 1. +### Plot groupings +In PoS v2, farmers are recommended to combine multiple plots into a single _group_. This will work by combining multiple plots together, as if they were the same plot. -The following table shows when both the plot ID filter, and the proof fragment scan filter will initially be set to adjust, as well as their values after the adjustments. This table is identical for both of the filters. +The length of a plot ID 256 bits (32 bytes). The first 240 bits are define the plot itself, and the final 16 bits represent that plot's slot in the group. Plots that are part of the same group will have IDs that begin with the same 240 bits. For example, if two plots are to be grouped together, their IDs might look like this (shown in base-16): -| Block height | Month/Year (app.) | ID and fragment filters | -|:------------ | :---------------- | :---------------------- | -| 8’800’000 | May 2026 | 32 | -| 12’163’840 | May 2028 | 16 | -| 15’527’680 | May 2030 | 8 | -| 18’891’520 | May 2032 | 4 | -| 22’255’360 | May 2034 | 2 | -| 25’619’200 | May 2036 | 1 | +1. [todo]0 +2. [todo]1 -It is difficult to predict advancements in technology, so these filters are intentionally set to be rather aggressive in their scheduled adjustments. If we feel that we can delay one or both of the filters, then this can be done in a future soft fork. +[todo] Add naming convention here, will it include k-size and creation date? Also, will it actually be 512 bit (64 hex chars)? +[todo] describe how memory is used and managed when combining plots, how much extra memory and compute are needed? -### Plot strength adjustments -As detailed in CHIP-48, every plot will include a “strength” parameter, which will adjust how much time is required to create Table 3, _ceteris paribus_. If a given plot's strength is `n`, then creating Table 3 will require `2^n` times longer than the minimum amount of time. (Harvesting time is unaffected by the plot’s strength.) At a given block height, the network will only accept plots that meet the current minimum strength threshold. The strength parameter will be an 8-bit unsigned integer, so the maximum strength will be `255`. +Because the final 16 bits are used to determine the slot in the group for each plot, the maximum number of plots that can be included in a group is 2**16 (65,536), or about 65 TB. -The current proposal is to start the minimum strength at `2`, and to adjust it upward as needed. Adjusting the minimum strength will require a soft fork. Each increase in the minimum strength will require some portion of the netspace to be replotted in order to continue farming. Therefore, the plan will be to propose a lengthy lead time before any increases in the minimum strength take effect. +Grouping multiple plots together is required beyond a few thousand plots on HDDs, and is recommended on SSDs as well. If plots are not grouped together, then multiple lookups will be needed at each signage point. -For example, if we proposed to increase the minimum strength from `2` to `5`, then all plots with strength `2`, `3`, or `4` would no longer be able to farm after the increase went into effect. We therefore would provide a lengthy warning (perhaps six or twelve months) for the fork to activate. +For example, a 20-TB HDD will hold around 20,000 plots. If the plot ID filter for these plots is 256, and the plots are not grouped, then an average of around 78 plots will pass each the filter at each signage point. This will require a large amount of lookups, which could affect the harvester's ability to respond on time. -In order to decrease the number of expected replots, some farmers might initially choose to plot to a high strength. In order to keep up with advances in technology, we might need to increase the minimum strength every two years (though keep in mind that this is a rough estimate). If a farmer estimated that the lifespan of their farm's HDDs would be eight years, then they might consider initially plotting to four levels above the current minimum strength. That way, by the time of the next expected replot, their HDDs would have already exceeded their expected lifespan. +However, grouping _too many_ plots together could also cause issues, though they would be minor in comparison. Due to the extra memory required to group plots together, creating a group with more than 128 plots is not generally recommended. In addition, because a plot group acts as a single plot, larger groups will also increase the volatility of block rewards being won. This volatility is only noticeable in the short term, though -- the long-term expected win rate will be unaffected by large group sizes. -One thing to note is that a given farm can contain plots with various strength levels. Some farmers may choose a strategy of plotting their entire farm at the minimum current strength, and then gradually replacing their plots with higher-strength plots over time. Plots of the same k-size will be approximately the same size, regardless of strength. +Keeping the above considerations in mind, the recommended group size is 128. This will yield plot groups of around 120 GB, which is roughly the same size as v1 plots. For plotters with lower RAM, grouping 64 plots together is also fine. + +However, there are exceptions to these recommendations For example, older HDDs with low capacities may not be profitable for some farmers due to ongoing electricity costs. However, these HDDs could be filled with plots that are grouped together so that the entire HDD consists of a single "plot". These HDDs could then be powered down until their plot is about to pass the filter, which would save on electricity. This is [described in detail](#powering-down-hdds) below. + +### Meta groupings +All plots in a standard plot group will pass the plot ID filter together. However, the plot groups themselves will occasionally also pass the filter together. By using _meta groupings_, one can guarantee that separate groups will never pass the filter together. This can be beneficial, for example, in order to reduce the chances that a disk becomes overloaded from excessive lookups. It also will somewhat help to smooth out rewards. + +[todo] other advantages? +[todo] are we still doing meta groupings? + +### Plot ID filter calculation +The formula to determine whether a given plot passes the plot ID filter will be modified for the new Proof of Space protocol. In this section, we'll start by describing this formula for PoS v1, along with its deficiencies. Next, we'll describe the new formula for PoS v2, along with its advantages. + +#### Old formula and deficiencies +In the original Proof of Space protocol, plots randomly pass (or don't pass) the filter at each signage point. This is determined by hashing the plot ID concatenated with the current challenge and signage point: + +`plot filter bits = sha256(plot ID + sub slot challenge + challenge chain signage point)` + +If `plot filter bits` begins with a certain number of zeroes, then the plot passes the filter. For example, if the plot filter is `256`, at each signage point, a plot will have will have a 1 in 256 chance of passing the filter (`plot filter bits` must begin with eight zeroes in this case). Because `plot filter bits` is calculated from a `sha256` hash, the plot has an equal chance of passing the filter at any given signage point. + +There is also no mechanism to prevent the plot from passing the filter at multiple consecutive signage points. By analogy, if I roll a die three times, the result might be `1` each time. This means that a plot will have a 1 in 65,536 (256 * 256) chance of passing two consecutive signage points, and a 1 in 16,777,216 (256 * 256 * 256) chance of passing three consecutive signage points. + +Plot grinders can generate a plot ID without creating the plot, so they can grind through millions of plot IDs per second. This means that at any given signage point, they can grind a plot ID that will pass it, as well as the next two signage points, giving them extra leverage. The details of plot grinding, and the leverage gained, are shown in [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). + +#### New formula +[todo] update this formula; currently it's for up to 10 minutes of lead time, but we'll change it to 40-120 seconds + +In order to prevent the extra grinding leverage described above, the Proof of Space v2 protocol will change the formula to determine whether a plot passes the filter. We'll start with some definitions: +* `challenge_value` -- the challenge from the beginning of a subslot. It should kick in several signage points after being calculated and last for one subslot (64 signage points) +* `challenge_height` -- the subslot's offset within the range it applies (must be an integer from `0` to `63`) +* `filter_bits` -- the strength of the plot group +* `plot_group_id` -- the hash of everything which defines the group +* `meta_group` -- used to make sure the load from different plot groups is spread out (must be an integer from `0` to `2**filter_bits`) + +These values apply the same to all specific plots within the group. Their only difference is an index. + +The following function uses the above values to determine whether a plot passes the filter at a given signage point: +```python +def passes_plot_id_filter(challenge_value, challenge_height, filter_bits, plot_group_id, meta_group): + mask = (1 << filter_bits) - 1 + multiplier = ((challenge_value >> filter_bits) | 1) & mask + current_value = ((challenge_value << 6) & mask) | challenge_height + return current_value == (plot_group_id ^ ((meta_group * multiplier) & 63)) & mask +``` + +The main two advantages of using this new formula is that it removes the potential extra leverage from plot grinding, and that it makes it possible to power down HDDs between times when they pass the filter. Both of these advantages are detailed below. + +#### No extra leverage when grinding +By using the new formula, we can guarantee that a plot group won't pass the plot ID filter more than once every four signage points. This means that the extra leverage the could previously be gained from grinding a plot's ID is no longer applicable. Plot grinders will be able to create plots on the fly, but it won't be possible to have a multiplier effect. The new formula will therefore accomplish the original goal of the defunct [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). + +#### Powering down HDDs +In addition, it will now be possible to predict between 4 to 20 signage points (~37 seconds to two minutes) in advance when a plot group will pass the filter. This will make it possible to power down a hard drive, and start it up in advance of the plot group passing the filter. A few guidelines should be followed in order to maximize the efficiency of this use case. + +##### Group many plots together +If a farmer's goal is to maximize the timing between wake-ups (as opposed to smoothing rewards), an HDD should ideally be filled with a single plot group. If a 20-TB HDD were filled with 4 plot groups of 5 TB, and the filter for those plots were 8192, then the HDD would need to be started and stopped four times daily, on average. But if the same HDD were filled with a single plot group of 20 TB and the same filter, then it would only need to be started and stopped once daily. + +##### Use smaller HDDs +HDDs use a similar amount of electricity, regardless of their capacity. In PoS v1, this made small HDDs economically unprofitable. In PoS v2, powering down these smaller disks will potentially make them profitable. However, the advantage of powering down an HDD is reduced as the HDD's capacity is increased. It may turn out that there is little advantage to powering down a modern, large-capacity HDD. It may actually be a disadvantage due to the increased compute needed to create a plot group for the large HDD, as well as due to the extra wear caused by repeatedly shutting down and starting up an HDD. + +##### Plot to a high strength +Per the above table, plot groups that were created at strength `3` will initially pass the filter once per day. After two years, this frequency will be reduced to 12 hours, and after four years, it will be reduced to 6 hours. Farmers may not be comfortable with starting and stopping their HDDs more than four times daily, so in order to take advantage of this use case for six years, they will need to plot to at least strength `3`, which requires 8x the compute of strength `0`. + +#### Determining when a plot group will pass +[todo] describe how to figure this out so that you have plenty of time to start your HDD +For example, if my plot will pass the filter at signage point 0, is this going to be determined from the previous subslot's challenge? +[answer] The ideas is that every 16th challenge point is used for the plot id filter and it applies to the challenge points 4-20 ahead of it ### keccak256 -The `keccak256` operator was previously added via soft fork, and is therefore only available under the `softfork` operator. Its usage (both inside and outside the `softfork` guard) is described in [the Specification section of CHIP-36](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0036.md#specification). After block 8,800,000, the `keccak256` operator will become part of the core CLVM, so it will be usable by calling it directly. It will also continue to be usable from inside the `softfork` guard. +The `keccak256` operator was previously added via soft fork, and is therefore only available under the `softfork` operator. Its usage (both inside and outside the `softfork` guard) is described in [the Specification section of CHIP-36](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0036.md#specification). + +The hard fork gives us the opportunity to promote `keccak256` to be allowed outside the `softfork` guard. This makes it easier to use. + +After block 8,800,000, the `keccak256` operator will become part of the core CLVM, so it will be usable by calling it directly. It will also continue to be usable from inside the `softfork` guard. + +### sha256tree +Many puzzles use the [sha256tree](https://github.com/Chia-Network/chia_puzzles/blob/0b46a6ebfc3b432d68edf9b91e6cef0ec13da2e7/puzzles/sha256tree.clib) library, which calculates the puzzle hash of a given puzzle program. This library is used so frequently, in fact, that it makes sense to include it as a native CLVM operator in the hard fork. Another advantage of including `sha256tree` in the CLVM is that it will be cheaper to call, both in terms of CPU compute and CLVM cost. + +#### Technical info about sha256tree +Opcode: 63 + +Argument: Exactly one valid CLVM tree + +Returns: The `sha256` puzzle hash (Merkle root) of the input tree + +Usage: (sha256tree (TREE)) + +CLVM Cost: [todo] + +### Conditions with cost +Currently, only `CREATE_COIN`, the `AGG_SIG_*`-family and `SOFTFORK` conditions have a cost. All other conditions are free and could therefore risk being a DoS vector. The full node currently limits the number of announce-family conditions per coin spend to 1024 (See [CHIP-25](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0025.md#clvm-cost)). Conditions in this family are expensive because they require memory allocation during validation. + +With [Vaults](https://www.chia.net/2025/01/31/chia-vaults-a-secure-and-flexible-way-to-manage-your-digital-assets/), each coin spend requires a message to be sent from the vault to the coin. This makes the 1024 limit at risk of being hit by legitimate uses. -### Condition cost After the hard fork activates, the limit of 1024 announcement conditions per spend will be removed. Instead, for each CoinSpend, conditions will have a cost of 500, **except** for the first 100 conditions, which will not incur an additional cost. This is in addition to any existing cost for the condition. This cost applies to all conditions, including unknown conditions, `SOFTFORK`, `CREATE_COIN` and `AGG_SIG_*` conditions. +### New Weight Proof Commitments +The 3.0 fork will include [new weight proof commitments](https://github.com/Chia-Network/chia-blockchain/pull/20340) that use Merkle Mountain Ranges for easier and faster validation. These include commitments to block headers, as well as to transaction blocks. The main things to be included are: +* Linking the trunk to the Merkle root of foliage blocks across epochs +* Adding to a Merkle Mountain Range of transaction blocks within sub-epochs +* Adding commitments to the root of subslots, including the number of blocks per branch for epochs + +Before the new weight proofs can be used, there will need to be a transition point between the old and new proofs. This will necessitate that both formats work simultaneously for some time. The current proposal is to put in a checkpoint some time after the 3.0 fork activates, and wait enough time before we use the new weight proof so that everyone agrees on the past before the checkpoint. + +After we can begin validating the new weight proofs (9-12 months after 3.0 is released), nodes and wallets won’t be required to sync. Their peers only will need to prove the peak height and its weight in order for their data to be proven trustworthy. The current requirement for block validation will instead become a recommendation. + +### New Block Hash Computation +In order to calculate block hashes, currently we hash the serialization blob of the block generator (a CLVM object). + +The 3.0 release will include an update to hash the generator as a sha256tree (just as we do with puzzle hashes), and then the particular serialization won’t matter. This will open the door to arbitrary compression mechanisms without forking. + +Beginning in block [todo], the new block hash computation will be accepted. The old method will continue to be accepted until block [todo], after which it will be ignored. + +The original CLVM cost of calculating the generator was `12'000 * len(blob)`. The new cost is `len(blob)`. + ## Test Cases -We will add any needed test cases prior to this CHIP’s completion. +All relevant test cases are included in CHIP-48. ## Reference Implementation -We will include links to the reference implementation prior to this CHIP’s completion. +The reference implementation is included in CHIP-48. ## Security -The majority of the security work for the new proof format can be found in CHIP-48. That said, CNI will also perform an internal audit of the code updates involved with this CHIP. +The majority of the security work for the new proof format can be found in CHIP-48. That said, CNI has also performed an internal audit of the code updates involved with this CHIP. ## Additional Assets None From 8001f8cd2d586908f8e0967b56654910ff7c00d5 Mon Sep 17 00:00:00 2001 From: danieljperry Date: Fri, 16 Jan 2026 12:20:29 +0800 Subject: [PATCH 08/24] New updates --- CHIPs/chip-0049.md | 160 ++++++++++++++++++++++++--------------------- 1 file changed, 85 insertions(+), 75 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index 073e71c7..20d8e9d9 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -21,7 +21,7 @@ The hypothetical issue is plot grinding. This is where a farmer creates an entir The other issue is plot "compression," where bits are dropped during a plot's creation, and added back in while farming. The result is a farm that squeezes more proofs into the same space. Plot compression is described in detail in a [blog post](https://www.chia.net/2023/01/21/plot-compression-is-here/). -Neither of these issues is an attack on the network itself, but in both cases, they make time-space tradeoffs, which cause the plots’ Proof of Space to begin to resemble Proof of Work (PoW). As a consequence, the network uses more compute than what was originally intended. +Neither of these issues is an attack on the network itself, but in both cases, they make time-space tradeoffs, which cause the network's Proof of Space consensus to resemble Proof of Work (PoW). As a consequence, the network uses more compute than what was originally intended. In the first half of 2024, we made the decision to sunset the existing proof format in favor of a new one that will be significantly more resilient to bit dropping and other time-space tradeoffs. Farmers will need to replace their existing plots with new ones, so we have built this format with minimizing future disruptions in mind. @@ -32,67 +32,58 @@ We will future-proof the new format with two independent mechanisms: Both of these adjustments are detailed in the [Specification](#specification) section. ## Backwards Compatibility -This CHIP proposes a hard fork to upgrade the proof format. Hard forks relax rules. Blocks that are invalid by the existing rules will be considered valid by the new rules (and sometimes vice versa). This is why every node must update for a hard fork to be accepted. If this CHIP is accepted, then there will be a window of several months prior to its activation for all full nodes, farmers, and harvesters to be upgraded. +This CHIP proposes a hard fork to upgrade the proof format. Hard forks relax rules. Blocks that are invalid by the existing rules will be considered valid by the new rules (and sometimes vice versa). This is why every node must be upgraded in order for a hard fork to be accepted. There will be a window of several months prior to this CHIP's activation, giving farmers ample time to upgrade their software. -Even though the original plot format will be disabled by this CHIP, it will remain valid until the end of a phase-out period, which starts at hard fork activation. +Even though the original plot format will be disabled by this CHIP, it will remain valid until the end of the phase-out period, which is described in detail below. ## Specification The specification for each of this CHIP’s features will be listed individually. ### Fork activation We will release Chia version 3.0.0, which will implement the hard fork. The fork will activate in the block immediately following the first *transaction* block, with a later signage point, at or above height [todo]. This is expected to happen around [todo]. -A signage point may have multiple blocks. If the block immediately following the transaction block at the activation height happens to be on the same signage point, it will also be pre-activation. The hard fork activates with the next signage point. +A single signage point may produce multiple blocks. If the block immediately following the transaction block at the activation height happens to be on the same signage point, it will also be pre-activation. The hard fork would then activate with the next signage point. Starting with the block in which the hard fork is activated, the new Proof of Space will be accepted. This hard fork is different from previous forks in that it affects the validity of Proofs of Space. When farming a block, the harvester does not know (exactly) at what height its proof may be infused. However, it *can* know what the most recent transaction block was. ### Phase-out period -During the phase-out period, original Proofs of Space will become increasingly unlikely to win a block. The probability of winning a block will be scaled down, linearly, starting at the activation block, to reach 0 probability after 256 days (technically, 4608 x 256 blocks). +During the phase-out period, original Proofs of Space will become less likely to win a block over time. The probability of winning a block will be scaled down, linearly, starting at the activation block, to reach 0 probability after 256 days (technically, 4608 x 256 blocks). -In order for a plot to win a block, it first needs to pass the plot filter. The proof’s quality then needs to yield a low enough required iterations, lower than the signage point interval iterations. The required iterations count is part of the block’s infusion iterations calculation: +In order to validate a PoS v1 proof after the hard fork has activated, we will look at the last byte of the quality string, and filter it based on the number of epochs since activation. We don't track the actual epoch; we just divide the number of blocks since activation by 4608 (the number of blocks per epoch). -```infusion_iterations = (signage_point_iterations + 3 * signage_point_interval_iterations + required_iterations) % sub-slot_iterations``` +After 256 epochs after the fork's activation, no original proof will ever be valid. This ends the phase-out period and effectively disables the original Proof of Space. -A higher required iteration count means the proof is less likely to be valid. +[todo update heights in this table] -The phase-out counter (`i`) starts at 0 at the hard fork activation. Every 4608 blocks, it’s incremented by 1. When computing `required_iterations` for original Proofs of Space, we add `signage_point_interval_iterations * (i // 256)` to required iterations, so the calculation becomes: - -```infusion_iterations = (signage_point_iterations + 3 * signage_point_interval_iterations * (i // 256) + required_iterations) % sub-slot_iterations``` - -[todo] (i // 256) might be wrong - -Just like the hard fork activation, each increment of `i` happens immediately following the first transaction block whose height is [todo (activation height)] + i * 4608 or above. - -Once `i` reaches 256, we end up adding `signage_point_interval_iterations` (or more) to the required iterations, so no original proof will ever be valid. This ends the phase-out period and effectively disables the original Proof of Space. - -[todo update heights ni this table] - -| Blocks w/prev. TX block >= | i | Win prob. factor | -|:-------------------------- | :-- | :--------------- | -| 8800000 | 0 | 1.000 | -| 8804608 | 1 | 0.996 | -| 8809216 | 2 | 0.992 | -| 8813824 | 3 | 0.988 | -| … | … | … | -| 9970432 | 254 | 0.008 | -| 9975040 | 255 | 0.004 | -| 9979648 | 256 | 0.000 | +| Blocks w/prev. TX block >= | epochs | Win prob. factor | +|:-------------------------- | :----- | :--------------- | +| 8800000 | 0 | 1.000 | +| 8804608 | 1 | 0.996 | +| 8809216 | 2 | 0.992 | +| 8813824 | 3 | 0.988 | +| … | … | … | +| 9970432 | 254 | 0.008 | +| 9975040 | 255 | 0.004 | +| 9979648 | 256 | 0.000 | ### Protocol -A `FullNode` object contains a `ProofOfSpace` which has these fields: + +In both the original and new Proof of Space formats, a `FullNode` object contains a `ProofOfSpace`, which has these fields: ``` size: u8, proof: Bytes, ``` -The `size` is not allowed to be less than 32 or greater than 50. After the hard fork, the most significant bit in the `size` field indicates whether the proof is the original Proof of Space (0) or the new Proof of Space (1). -The remaining 7 bits then indicate either: +In the original format, `size` is not allowed to be less than 32 or greater than 50. Therefore, only the six least significant bits can be used, and the two most significant bits are meaningless. + +After the hard fork activates, the most significant bit in the `size` field will indicate whether the proof is the original Proof of Space (0) or the new Proof of Space (1). + +The remaining 7 bits will indicate either: * The k-size of the plot that produced the proof (original Proof of Space), or * The strength of the plot that produced the proof (new Proof of Space) -The only valid k-size in the new Proof of Space is 28 (mainnet/testnet) and 18 (testnet only). -The `proof`s are either v1 or v2 Proof of Space, depending on the most significant bit in the `size` field. +Note that the only valid k-size in the new Proof of Space on mainnet and testnets is k28 (around 1 GB per plot). Simulations can use other sizes; CNI's simulator code will use k18 (around 1 MB per plot). ### Filter and strength adjustments We have two ways to future-proof the network against rental attacks, and plot grinding more generally: automatic reductions in the base filter, and manual increases in the network's minimum plot strength. Both of these will be detailed in this section. @@ -104,17 +95,17 @@ The base filter indicates the lowest filter allowed for all plots across the net The reason to reduce the base filter over time is to decrease the leverage a rental attacker is able to gain. This topic is covered extensively in [CHIP-12](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0012.md). In summary, a rental attacker can opt to exclusively create plots that will pass the filter, so the amount of space they are able to spoof is multiplied by a given plot's ID filter ([described below](#plot-id-filter-definition)). As GPUs become faster, we can initially protect the network against rental attacks by proactively reducing the Plot ID filter. However, for technical reasons covered in CHIP-48, we won't reduce the filter to be lower than `64`. The next protection against rental attacks will come from increasing the minimum plot strength, which will be [covered later](#minimum-strength-plan). -Cutting the base filter in half every two years will have two impacts for all farmers: higher disk usage, and longer plot stability. +Cutting the base filter in half every two years will have two impacts for all farmers: higher [disk usage](#disk-usage), and longer [plot stability](#plot-stability). ##### Disk usage Each time the base filter is cut in half, the likelihood that a plot will pass it is doubled. The load on individual disks will therefore roughly double as well. -HDDs can operate at 20% of capacity without significantly shortening their life expectancy. The filter will be cut in half four times over the course of eight years, so if a farmer expects their disks to last for eight years, then they should plot so that their disks initially run at 1% of capacity or lower. That way, their disks will never run at more than 16% of capacity, so they will remain viable for farming for their entire life expectancy. +HDDs can operate at 20% of their read capacity without significantly shortening their life expectancy. The filter will be cut in half four times over the course of eight years, so if a farmer expects their disks to last for eight years, then they should plot so that their disks initially run at 1% of their read capacity or lower. That way, their disks will never run at more than 16% of their read capacity, so they will remain viable for farming for their entire life expectancy. Read speeds of SSDs are much faster than those of HDDs, so farmers can safely plot their SSDs at the minimum strength without running into issues related to high disk usage. However, they should still plan according to the expected scheduling for minimum strength increases, which are [covered later](#minimum-strength-plan). ##### Plot stability -By decreasing the base filter every two years for the first eight years of the new Proof of Space's existence, we expect to be able to keep the minimum strength at `0` for that time frame. This means that all plots created at the minimum strength are expected to be valid for at least eight years, pending unexpected advancements in technology. +By decreasing the base filter every two years for the first eight years of the new Proof of Space's existence, we expect to be able to keep the minimum strength at `0` for that time frame. This means that all plots created at the minimum strength are expected to be valid for at least eight years, barring unexpected advancements in technology. Starting around 2034, plot stability will come entirely from plotting to a higher strength than the minimum. @@ -124,10 +115,10 @@ Each plot will have its own `plot ID filter`, which determines the likelihood th The formula to calculate a given plot's ID filter is: `plot ID filter = base filter * (2^(plot strength - min strength))` -For each level that a given plot's strength is higher than the network's base strength, the plot ID filter will be doubled. +For each level that a given plot's strength is higher than the network's base strength, the plot's ID filter will be doubled. #### Plot strength definition -As detailed in CHIP-48, every plot will include a “strength” parameter, which will adjust how much time is required to create the plot, _ceteris paribus_. If a given plot's strength is `n`, then creating the plot will require `2^n` times longer than the minimum amount of time. (Harvesting time is unaffected by the plot’s strength.) At a given block height, the network will only accept plots that meet the current minimum strength threshold. +As detailed in CHIP-48, every plot will include a “strength” parameter, which will adjust how much time is required to create the plot, _ceteris paribus_. If a given plot's strength is `n`, then creating the plot will require `2^n` times longer than the minimum amount of time. (Harvesting time and plot size are both unaffected by the plot’s strength.) At a given block height, the network will only accept plots that meet the current minimum strength threshold. By definition, `strength = 0` indicates the minimum compute required to create a plot, with no additional arbitrary computation. @@ -138,9 +129,9 @@ The network's minimum strength will start at `0`, and will be adjusted upward as The minimum strength should only ever be increased with time. It can be increased by any integer, but typically we will only increase it by 1 in a given soft fork. Because any plots with the current minimum strength will need to be recreated when the minimum strength is increased, we plan provide a lengthy warning (perhaps six or twelve months) for a fork that increases the minimum strength to activate. -In order to decrease the number of expected replots, some farmers might initially choose to plot to a high strength. In order to keep up with advancements in technology, we might need to increase the minimum strength every two years (though keep in mind that this is a rough estimate). +In order to decrease their number of expected replots, some farmers might initially choose to plot to a high strength. In order to keep up with advancements in technology, we might need to increase the minimum strength every two years (though keep in mind that this is a rough estimate). -One thing to note is that a given farm can contain plots with various strength levels. Some farmers may choose a strategy of plotting their entire farm at the minimum current strength, and then gradually replacing their plots with higher-strength plots over time. A plot's size is unaffected by its strength. +One thing to note is that a given farm can contain plots with various strength levels. Some farmers may choose a strategy of plotting their entire farm at the minimum current strength, and then gradually replacing their plots with higher-strength plots over time. #### Expected base filter and strength To recap: @@ -149,7 +140,7 @@ The base filter will start at `1024` and will be cut in half every two years unt The minimum strength will start at `0` and will be increased via a soft fork as needed. We won't plan to increase the minimum strength until at least 2036, though this is subject to change. -The following table illustrates how we expect these adjustments to occur. The second column from the right shows the plot ID filter for a plot created at `strength = 3`, and the rightmost column shows how often that plot will pass the filter, on average. This plot will take eight times longer than the minimum to be created, and is expected to be valid into the 2040s. It will only become invalid when the minimum strength reaches `4`. +The following table illustrates how we expect these adjustments to occur. The third column from the right shows the network's hypothetical minimum strength. While this number will only be increased as needed, the table does show a realistic expectation of what may occur. The second column from the right shows the plot ID filter for a plot created at `strength = 3`, and the rightmost column shows how often that plot will pass the filter, on average. This plot will take eight times longer than the minimum to be created, and is expected to be valid into the 2040s. It will only become invalid when the minimum strength reaches `4`. | Block height | Month/Year (app.) | Base Filter | Min Str | Filter at Str=3 | Pass Frequency | | :----------- | :---------------- | :---------- | :------ | :-------------- | :------------- | @@ -164,33 +155,48 @@ The following table illustrates how we expect these adjustments to occur. The se | TBD | TBD | 64 | 4 | Invalid | N/A | ### Plot groupings -In PoS v2, farmers are recommended to combine multiple plots into a single _group_. This will work by combining multiple plots together, as if they were the same plot. +With the new Proof of Space format, farmers are recommended to add multiple plots with the same public key to a single _group_. This will work by combining multiple plots together, as if they were the same plot. -The length of a plot ID 256 bits (32 bytes). The first 240 bits are define the plot itself, and the final 16 bits represent that plot's slot in the group. Plots that are part of the same group will have IDs that begin with the same 240 bits. For example, if two plots are to be grouped together, their IDs might look like this (shown in base-16): +A plot's group ID is determined by hashing its k-size, version, strength, public key, and either its puzzle hash or its pool public key: -1. [todo]0 -2. [todo]1 +``` + sha256( + k: u8, + version: u8, + plot_strength: u8, + plot_pk: Serialized_PK, + + one_of: + puzzle_hash: Puzzle_Hash, + pool_public_key: Serialized_PK, + ) +``` -[todo] Add naming convention here, will it include k-size and creation date? Also, will it actually be 512 bit (64 hex chars)? -[todo] describe how memory is used and managed when combining plots, how much extra memory and compute are needed? +The plot's ID is then determined by hashing its group ID, index, and [meta group](#meta-groupings) (explained below): -Because the final 16 bits are used to determine the slot in the group for each plot, the maximum number of plots that can be included in a group is 2**16 (65,536), or about 65 TB. +``` + sha256( + plot_group_id: [256*8]u8, + plot_index: u16, + meta_group: u8, + ) +``` +The `plot_index` represents that plot's slot in the group. This means that the maximum number of plots that can be included in a group is 2^16 (65,536), or about 65 TB. Grouping multiple plots together is required beyond a few thousand plots on HDDs, and is recommended on SSDs as well. If plots are not grouped together, then multiple lookups will be needed at each signage point. -For example, a 20-TB HDD will hold around 20,000 plots. If the plot ID filter for these plots is 256, and the plots are not grouped, then an average of around 78 plots will pass each the filter at each signage point. This will require a large amount of lookups, which could affect the harvester's ability to respond on time. +For example, a 20-TB HDD will hold around 20,000 plots. If the plot ID filter for these plots is `256`, and the plots are not grouped, then an average of around 78 plots will pass the filter at each signage point. This will require a large amount of lookups, which could affect the harvester's ability to respond on time. However, grouping _too many_ plots together could also cause issues, though they would be minor in comparison. Due to the extra memory required to group plots together, creating a group with more than 128 plots is not generally recommended. In addition, because a plot group acts as a single plot, larger groups will also increase the volatility of block rewards being won. This volatility is only noticeable in the short term, though -- the long-term expected win rate will be unaffected by large group sizes. -Keeping the above considerations in mind, the recommended group size is 128. This will yield plot groups of around 120 GB, which is roughly the same size as v1 plots. For plotters with lower RAM, grouping 64 plots together is also fine. +Keeping the above considerations in mind, the recommended group size is `128`. This will yield plot groups of around 120 GB, which is roughly the same size as v1 plots. For plotters with lower RAM, grouping 64 plots together is also fine. -However, there are exceptions to these recommendations For example, older HDDs with low capacities may not be profitable for some farmers due to ongoing electricity costs. However, these HDDs could be filled with plots that are grouped together so that the entire HDD consists of a single "plot". These HDDs could then be powered down until their plot is about to pass the filter, which would save on electricity. This is [described in detail](#powering-down-hdds) below. +However, there are exceptions to these recommendations. For example, older HDDs with low capacities may not be profitable for some farmers due to ongoing electricity costs. However, these HDDs could be filled with plots that are grouped together so that the entire HDD consists of a single "plot". These HDDs could then be powered down until their plot is about to pass the filter, which would save on electricity. This is [described in detail](#powering-down-hdds) below. ### Meta groupings All plots in a standard plot group will pass the plot ID filter together. However, the plot groups themselves will occasionally also pass the filter together. By using _meta groupings_, one can guarantee that separate groups will never pass the filter together. This can be beneficial, for example, in order to reduce the chances that a disk becomes overloaded from excessive lookups. It also will somewhat help to smooth out rewards. -[todo] other advantages? -[todo] are we still doing meta groupings? +A plot's meta group is a single byte, so up to 256 meta groups can be created in one farm. ### Plot ID filter calculation The formula to determine whether a given plot passes the plot ID filter will be modified for the new Proof of Space protocol. In this section, we'll start by describing this formula for PoS v1, along with its deficiencies. Next, we'll describe the new formula for PoS v2, along with its advantages. @@ -200,37 +206,36 @@ In the original Proof of Space protocol, plots randomly pass (or don't pass) the `plot filter bits = sha256(plot ID + sub slot challenge + challenge chain signage point)` -If `plot filter bits` begins with a certain number of zeroes, then the plot passes the filter. For example, if the plot filter is `256`, at each signage point, a plot will have will have a 1 in 256 chance of passing the filter (`plot filter bits` must begin with eight zeroes in this case). Because `plot filter bits` is calculated from a `sha256` hash, the plot has an equal chance of passing the filter at any given signage point. +If `plot filter bits` begins with a certain number of zeroes, then the plot passes the filter. For example, if the plot filter is `256`, then at each signage point, a plot will have will have a 1 in 256 chance of passing the filter (`plot filter bits` must begin with eight zeroes in this case). Because `plot filter bits` is calculated from a `sha256` hash, the plot has an equal chance of passing the filter at any given signage point. There is also no mechanism to prevent the plot from passing the filter at multiple consecutive signage points. By analogy, if I roll a die three times, the result might be `1` each time. This means that a plot will have a 1 in 65,536 (256 * 256) chance of passing two consecutive signage points, and a 1 in 16,777,216 (256 * 256 * 256) chance of passing three consecutive signage points. -Plot grinders can generate a plot ID without creating the plot, so they can grind through millions of plot IDs per second. This means that at any given signage point, they can grind a plot ID that will pass it, as well as the next two signage points, giving them extra leverage. The details of plot grinding, and the leverage gained, are shown in [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). +Plot grinders can generate a plot ID without creating the plot, so they can grind through millions of plot IDs per second. This means that at any given signage point, they can grind a plot ID that will pass it, as well as the next two signage points, thereby increasing their leverage. The details of plot grinding, and the leverage gained, are shown in [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). #### New formula -[todo] update this formula; currently it's for up to 10 minutes of lead time, but we'll change it to 40-120 seconds In order to prevent the extra grinding leverage described above, the Proof of Space v2 protocol will change the formula to determine whether a plot passes the filter. We'll start with some definitions: -* `challenge_value` -- the challenge from the beginning of a subslot. It should kick in several signage points after being calculated and last for one subslot (64 signage points) -* `challenge_height` -- the subslot's offset within the range it applies (must be an integer from `0` to `63`) -* `filter_bits` -- the strength of the plot group -* `plot_group_id` -- the hash of everything which defines the group -* `meta_group` -- used to make sure the load from different plot groups is spread out (must be an integer from `0` to `2**filter_bits`) + +* `plot_group_id` -- the ID of the relevant plot +* `group_strength` -- the strength of the plot group in bits (the group has a 1/2^z change of passing) +* `meta_group` -- used to make sure the load from different plot groups is spread out +* `filter_challenge` -- the value from the relevant signage point for the window from 4 signage points before the beginning +* `challenge_index` -- the position in the window, from 0-15 These values apply the same to all specific plots within the group. Their only difference is an index. The following function uses the above values to determine whether a plot passes the filter at a given signage point: + ```python -def passes_plot_id_filter(challenge_value, challenge_height, filter_bits, plot_group_id, meta_group): - mask = (1 << filter_bits) - 1 - multiplier = ((challenge_value >> filter_bits) | 1) & mask - current_value = ((challenge_value << 6) & mask) | challenge_height - return current_value == (plot_group_id ^ ((meta_group * multiplier) & 63)) & mask +def plot_id_check(plot_group_id, group_strength, meta_group, filter_challenge, challenge_index): + mask = (1 << group_strength) - 1 + return hash(plot_group_id + filter_challenge) & mask == (challenge_index ^ meta_group) & mask ``` -The main two advantages of using this new formula is that it removes the potential extra leverage from plot grinding, and that it makes it possible to power down HDDs between times when they pass the filter. Both of these advantages are detailed below. +The main two advantages of using this new formula are that it removes the potential extra leverage from plot grinding, and that it makes it possible to power down HDDs between times when they pass the filter. Both of these advantages are detailed below. #### No extra leverage when grinding -By using the new formula, we can guarantee that a plot group won't pass the plot ID filter more than once every four signage points. This means that the extra leverage the could previously be gained from grinding a plot's ID is no longer applicable. Plot grinders will be able to create plots on the fly, but it won't be possible to have a multiplier effect. The new formula will therefore accomplish the original goal of the defunct [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). +By using the new formula, we can guarantee that a plot group won't pass the plot ID filter more than once every four signage points. This means that the extra leverage that could previously be gained from grinding a plot's ID is no longer applicable. Plot grinders will be able to create plots on the fly, but it won't be possible to have a multiplier effect. The new formula will therefore accomplish the original goal of the defunct [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). #### Powering down HDDs In addition, it will now be possible to predict between 4 to 20 signage points (~37 seconds to two minutes) in advance when a plot group will pass the filter. This will make it possible to power down a hard drive, and start it up in advance of the plot group passing the filter. A few guidelines should be followed in order to maximize the efficiency of this use case. @@ -246,18 +251,23 @@ Per the above table, plot groups that were created at strength `3` will initiall #### Determining when a plot group will pass [todo] describe how to figure this out so that you have plenty of time to start your HDD +This will be described in https://chia-network.atlassian.net/browse/CHIA-3815 For example, if my plot will pass the filter at signage point 0, is this going to be determined from the previous subslot's challenge? [answer] The ideas is that every 16th challenge point is used for the plot id filter and it applies to the challenge points 4-20 ahead of it +### Other updates + +This section will describe the updates that will go into the hard fork, but are not part of the new Proof of Space format. + ### keccak256 The `keccak256` operator was previously added via soft fork, and is therefore only available under the `softfork` operator. Its usage (both inside and outside the `softfork` guard) is described in [the Specification section of CHIP-36](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0036.md#specification). The hard fork gives us the opportunity to promote `keccak256` to be allowed outside the `softfork` guard. This makes it easier to use. -After block 8,800,000, the `keccak256` operator will become part of the core CLVM, so it will be usable by calling it directly. It will also continue to be usable from inside the `softfork` guard. +After block [TODO], the `keccak256` operator will become part of the core CLVM, so it will be usable by calling it directly. It will also continue to be usable from inside the `softfork` guard. ### sha256tree -Many puzzles use the [sha256tree](https://github.com/Chia-Network/chia_puzzles/blob/0b46a6ebfc3b432d68edf9b91e6cef0ec13da2e7/puzzles/sha256tree.clib) library, which calculates the puzzle hash of a given puzzle program. This library is used so frequently, in fact, that it makes sense to include it as a native CLVM operator in the hard fork. Another advantage of including `sha256tree` in the CLVM is that it will be cheaper to call, both in terms of CPU compute and CLVM cost. +Many puzzles use the [sha256tree](https://github.com/Chia-Network/chia_puzzles/blob/0b46a6ebfc3b432d68edf9b91e6cef0ec13da2e7/puzzles/sha256tree.clib) library, which calculates the puzzle hash of a given puzzle program. This library is used so frequently, in fact, that it makes sense to include it as a native CLVM operator in the hard fork. Another advantage of including `sha256tree` in the CLVM is that it will be cheaper to call, both in terms of CPU compute and CLVM cost. Finally, a native operator also opens the door to future optimizations via caching. #### Technical info about sha256tree Opcode: 63 @@ -268,16 +278,16 @@ Returns: The `sha256` puzzle hash (Merkle root) of the input tree Usage: (sha256tree (TREE)) -CLVM Cost: [todo] +CLVM Cost: Variable -- `sha256tree` is the first CLVM operator whose parameter is a tree, which makes for more dimensions to consider for the cost model. See [our GitHub writeup](https://github.com/Chia-Network/clvm_rs/blob/7a2784b22093264e2c22e1cce606722db2d8ef3f/docs/sha256tree.md) for more information about how costing works for this operator. ### Conditions with cost -Currently, only `CREATE_COIN`, the `AGG_SIG_*`-family and `SOFTFORK` conditions have a cost. All other conditions are free and could therefore risk being a DoS vector. The full node currently limits the number of announce-family conditions per coin spend to 1024 (See [CHIP-25](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0025.md#clvm-cost)). Conditions in this family are expensive because they require memory allocation during validation. +Currently, only `CREATE_COIN`, the `AGG_SIG_*`-family and `SOFTFORK` conditions have a cost. All other conditions are free and could therefore risk being DoS vectors. The full node currently limits the number of announce-family conditions per coin spend to 1024 (See [CHIP-25](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0025.md#clvm-cost)). Conditions in this family are expensive because they require memory allocation during validation. With [Vaults](https://www.chia.net/2025/01/31/chia-vaults-a-secure-and-flexible-way-to-manage-your-digital-assets/), each coin spend requires a message to be sent from the vault to the coin. This makes the 1024 limit at risk of being hit by legitimate uses. After the hard fork activates, the limit of 1024 announcement conditions per spend will be removed. -Instead, for each CoinSpend, conditions will have a cost of 500, **except** for the first 100 conditions, which will not incur an additional cost. This is in addition to any existing cost for the condition. This cost applies to all conditions, including unknown conditions, `SOFTFORK`, `CREATE_COIN` and `AGG_SIG_*` conditions. +Instead, for each coin spend, conditions will have a cost of 500, **except** for the first 100 conditions, which will not incur an additional cost. This is in addition to any existing cost for the condition. This cost applies to all conditions, including unknown conditions, `SOFTFORK`, `CREATE_COIN` and `AGG_SIG_*` conditions. ### New Weight Proof Commitments The 3.0 fork will include [new weight proof commitments](https://github.com/Chia-Network/chia-blockchain/pull/20340) that use Merkle Mountain Ranges for easier and faster validation. These include commitments to block headers, as well as to transaction blocks. The main things to be included are: From c9b04e2e71492d6e8debade34db18b348bb2f360 Mon Sep 17 00:00:00 2001 From: danieljperry Date: Tue, 27 Jan 2026 14:44:34 +0800 Subject: [PATCH 09/24] Update effective strength and other definitions --- CHIPs/chip-0049.md | 135 +++++++++++++++++++++++++++------------------ 1 file changed, 80 insertions(+), 55 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index 20d8e9d9..2bd138cc 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -15,7 +15,7 @@ Requires | [0048](https://github.com/Chia-Network/chips/pull/160) [CHIP-48](https://github.com/Chia-Network/chips/pull/160), which introduces the new Proof of Space format (PoS v2), requires a hard fork of the Chia blockchain. This document describes how PoS v2 will be integrated with the blockchain, as well as how original plots will be phased out. This CHIP also proposes a few other hard-fork changes, unrelated to the new proof format. ## Motivation -The current Proof of Space format (PoS v1) was released in July 2020, during the Chia blockchain’s beta phase. Five years later, the format remains secure. However, two broad issues exist, one of which remains hypothetical, and the other of which is in production today. +The current Proof of Space format (PoS v1) was released in July 2020, during the Chia blockchain’s beta phase. Five years later, the format remains secure. However, two broad issues exist, one of which is still hypothetical, and the other of which is in production today. The hypothetical issue is plot grinding. This is where a farmer creates an entire plot and submits a proof within around 28 seconds. Plot grinding is described in detail in [CHIP-12](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0012.md). @@ -32,9 +32,9 @@ We will future-proof the new format with two independent mechanisms: Both of these adjustments are detailed in the [Specification](#specification) section. ## Backwards Compatibility -This CHIP proposes a hard fork to upgrade the proof format. Hard forks relax rules. Blocks that are invalid by the existing rules will be considered valid by the new rules (and sometimes vice versa). This is why every node must be upgraded in order for a hard fork to be accepted. There will be a window of several months prior to this CHIP's activation, giving farmers ample time to upgrade their software. +This CHIP proposes a hard fork to upgrade the proof format. Hard forks relax rules. Blocks that are invalid by the existing rules will be considered valid by the new rules (and sometimes vice versa). The majority of nodes and netspace must be upgraded in order for a hard fork to succeed. There will be a window of several months prior to this CHIP's activation, giving farmers ample time to upgrade their software. -Even though the original plot format will be disabled by this CHIP, it will remain valid until the end of the phase-out period, which is described in detail below. +Even though the original plot format will be disabled by this CHIP, it will remain valid until the end of the phase-out period, which is [described](#phase-out-period) in detail below. ## Specification The specification for each of this CHIP’s features will be listed individually. @@ -67,6 +67,8 @@ After 256 epochs after the fork's activation, no original proof will ever be val | 9975040 | 255 | 0.004 | | 9979648 | 256 | 0.000 | +As for the new Proof of Space format, its value will be 100% beginning at the fork's activation. In other words, its win probability factor will be 1.000. There will be no planned phase-out (or phase-in) for the new format. + ### Protocol In both the original and new Proof of Space formats, a `FullNode` object contains a `ProofOfSpace`, which has these fields: @@ -77,7 +79,7 @@ proof: Bytes, In the original format, `size` is not allowed to be less than 32 or greater than 50. Therefore, only the six least significant bits can be used, and the two most significant bits are meaningless. -After the hard fork activates, the most significant bit in the `size` field will indicate whether the proof is the original Proof of Space (0) or the new Proof of Space (1). +After the hard fork activates, the most significant bit in the `size` field will indicate whether the proof is of the original Proof of Space (0) or the new Proof of Space (1). The remaining 7 bits will indicate either: * The k-size of the plot that produced the proof (original Proof of Space), or @@ -88,75 +90,89 @@ Note that the only valid k-size in the new Proof of Space on mainnet and testnet ### Filter and strength adjustments We have two ways to future-proof the network against rental attacks, and plot grinding more generally: automatic reductions in the base filter, and manual increases in the network's minimum plot strength. Both of these will be detailed in this section. -At every signage point, a certain number of plots are excluded from participating in the challenge. In the original Proof of Space protocol, this was known as the `plot filter`, and is described in [our documentation](https://docs.chia.net/chia-blockchain/consensus/chains/signage-and-infusion-points/). In Proof of Space v2, there are now two related filters to consider: the network's base filter, and an individual plot's ID filter. +#### Filter definition + +At every signage point, a certain number of plots are excluded from participating in the challenge. In the original Proof of Space protocol, this was known as the `plot filter`, and is described in [our documentation](https://docs.chia.net/chia-blockchain/consensus/chains/signage-and-infusion-points/). In Proof of Space v2, there are two related filters to consider: the network's base filter, and the effective filter for a plot or a group (see below for more info on [plot groups](#plot-groups)). #### Base filter definition and plan The base filter indicates the lowest filter allowed for all plots across the network. This filter will start `1024` and will automatically be adjusted downward every two years at pre-defined block heights, until it reaches `64`. It will remain at `64` thereafter. -The reason to reduce the base filter over time is to decrease the leverage a rental attacker is able to gain. This topic is covered extensively in [CHIP-12](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0012.md). In summary, a rental attacker can opt to exclusively create plots that will pass the filter, so the amount of space they are able to spoof is multiplied by a given plot's ID filter ([described below](#plot-id-filter-definition)). As GPUs become faster, we can initially protect the network against rental attacks by proactively reducing the Plot ID filter. However, for technical reasons covered in CHIP-48, we won't reduce the filter to be lower than `64`. The next protection against rental attacks will come from increasing the minimum plot strength, which will be [covered later](#minimum-strength-plan). +The reason to reduce the base filter over time is to decrease the leverage a rental attacker is able to gain. This topic is covered extensively in [CHIP-12](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0012.md). In summary, a rental attacker can opt to exclusively create plots that will pass the filter, so the amount of space they are able to spoof is multiplied by a given plot's effective filter ([described below](#effective-filter-definition)). As GPUs become faster, we can initially protect the network against rental attacks by proactively reducing the base filter. However, for technical reasons covered in CHIP-48, we won't reduce the base filter to be lower than `64`. The next protection against rental attacks will come from increasing the minimum plot strength, which will be [covered later](#minimum-strength-plan). Cutting the base filter in half every two years will have two impacts for all farmers: higher [disk usage](#disk-usage), and longer [plot stability](#plot-stability). ##### Disk usage Each time the base filter is cut in half, the likelihood that a plot will pass it is doubled. The load on individual disks will therefore roughly double as well. -HDDs can operate at 20% of their read capacity without significantly shortening their life expectancy. The filter will be cut in half four times over the course of eight years, so if a farmer expects their disks to last for eight years, then they should plot so that their disks initially run at 1% of their read capacity or lower. That way, their disks will never run at more than 16% of their read capacity, so they will remain viable for farming for their entire life expectancy. +HDDs can operate at 20% of their read capacity without significantly shortening their life expectancy. The base filter will be cut in half four times over the course of eight years, so if a farmer expects their disks to last for eight years, then they should plot so that their disks initially run at 1% of their read capacity or lower. That way, their disks will never run at more than 16% of their read capacity, so they will remain viable for farming for their entire life expectancy. Read speeds of SSDs are much faster than those of HDDs, so farmers can safely plot their SSDs at the minimum strength without running into issues related to high disk usage. However, they should still plan according to the expected scheduling for minimum strength increases, which are [covered later](#minimum-strength-plan). ##### Plot stability -By decreasing the base filter every two years for the first eight years of the new Proof of Space's existence, we expect to be able to keep the minimum strength at `0` for that time frame. This means that all plots created at the minimum strength are expected to be valid for at least eight years, barring unexpected advancements in technology. - -Starting around 2034, plot stability will come entirely from plotting to a higher strength than the minimum. - -#### Plot ID filter definition -Each plot will have its own `plot ID filter`, which determines the likelihood that it is eligible to participate in a challenge at a given signage point. The plot ID filter is calculated based on a given plot's strength. [CHIP-48](https://github.com/Chia-Network/chips/pull/160) provides the technical details. - -The formula to calculate a given plot's ID filter is: -`plot ID filter = base filter * (2^(plot strength - min strength))` +By decreasing the base filter every two years for the first 10 years of the new Proof of Space's existence, we expect to be able to keep the minimum strength at `2` for that time frame. This means that all plots created at the minimum strength are expected to be valid for at least 10 years, barring unexpected advancements in technology. -For each level that a given plot's strength is higher than the network's base strength, the plot's ID filter will be doubled. +Starting around 2036, plot stability will come entirely from plotting to a higher strength than the minimum. #### Plot strength definition -As detailed in CHIP-48, every plot will include a “strength” parameter, which will adjust how much time is required to create the plot, _ceteris paribus_. If a given plot's strength is `n`, then creating the plot will require `2^n` times longer than the minimum amount of time. (Harvesting time and plot size are both unaffected by the plot’s strength.) At a given block height, the network will only accept plots that meet the current minimum strength threshold. +As detailed in CHIP-48, every plot will include a “strength” parameter, which will adjust how much time is required to create the plot, _ceteris paribus_. If a given plot's strength is `n`, then creating the plot will require `2^n` times longer than the minimum amount of time. (Harvesting time and plot size are both minimally affected by the plot’s strength.) At a given block height, the network will only accept plots that meet the current minimum strength threshold. By definition, `strength = 0` indicates the minimum compute required to create a plot, with no additional arbitrary computation. The maximum allowed strength will be [TODO]. This strength is capped arbitrarily, in order to prevent future attacks which may emerge from applying an extremely high strength to one or more plots. +#### Effective filter definition +Each plot will have its own `effective filter`, which determines the likelihood that it is eligible to participate in a challenge at a given signage point. The effective filter is calculated based on a given plot's strength. [CHIP-48](https://github.com/Chia-Network/chips/pull/160) provides the technical details. + +The formula to calculate a given plot's effective filter is: +`effective filter = base filter * (2^(plot strength - min strength))` + +For each level that a given plot's strength is higher than the network's base strength, the plot's effective filter will be doubled. However, the maximum `effective filter` is `8192`, regardless of the plot's strength. + +For example, if the network's `base filter` is `1024` and the `minimum strength` is `2`, then a plot created at `strength = 6` should have an `effective filter` of `1024 * (2^(6-2)) = 16,384`. However, due to the maximum filter size, the plot's `effective filter` will be `8192` for this plot. If the network's `minimum strength` is later raised to `3`, then the same plot will have an `effective filter` of `1024 * (2^(6-3)) = 8192`. + +Some farmers may therefore choose to plot to a high strength in order to preserve the `effective filter` of `8192` even after the network's `minimum strength` is raised. + #### Minimum strength plan -The network's minimum strength will start at `0`, and will be adjusted upward as needed. Adjusting the minimum strength will require a soft fork. We won't plan to increase the minimum strength for the first eight years after the PoS2 fork activates, barring any unexpected advancements in technology. +The network's minimum strength will start at `2`, and will be adjusted upward as needed. Adjusting the minimum strength will require a soft fork. We won't plan to increase the minimum strength for the first ten years after the PoS2 fork activates, barring any unexpected advancements in technology. -The minimum strength should only ever be increased with time. It can be increased by any integer, but typically we will only increase it by 1 in a given soft fork. Because any plots with the current minimum strength will need to be recreated when the minimum strength is increased, we plan provide a lengthy warning (perhaps six or twelve months) for a fork that increases the minimum strength to activate. +The minimum strength should only ever be increased with time. It can be increased by any integer, but typically we will only increase it by 1 in a given soft fork (we could also build in multiple future increases with a single fork). Because any plots with the current minimum strength will need to be recreated when the minimum strength is increased, we plan provide a lengthy warning (perhaps six or twelve months) for a fork that increases the minimum strength to activate. -In order to decrease their number of expected replots, some farmers might initially choose to plot to a high strength. In order to keep up with advancements in technology, we might need to increase the minimum strength every two years (though keep in mind that this is a rough estimate). +In order to decrease their number of expected replots, some farmers might initially choose to plot to a high strength than the minimum. In order to keep up with advancements in technology, we might need to increase the minimum strength every two years (though keep in mind that this is a rough estimate). One thing to note is that a given farm can contain plots with various strength levels. Some farmers may choose a strategy of plotting their entire farm at the minimum current strength, and then gradually replacing their plots with higher-strength plots over time. #### Expected base filter and strength To recap: -The base filter will start at `1024` and will be cut in half every two years until it reaches `64`. These adjustments will happen automatically, and can be delayed with a soft fork. +The network's base filter will start at `1024` and will be cut in half every two years until it reaches `64`. These adjustments will happen automatically, and can be delayed with a soft fork. -The minimum strength will start at `0` and will be increased via a soft fork as needed. We won't plan to increase the minimum strength until at least 2036, though this is subject to change. +The maximum effective filter for any individual plot is `8192`, regardless of its strength. -The following table illustrates how we expect these adjustments to occur. The third column from the right shows the network's hypothetical minimum strength. While this number will only be increased as needed, the table does show a realistic expectation of what may occur. The second column from the right shows the plot ID filter for a plot created at `strength = 3`, and the rightmost column shows how often that plot will pass the filter, on average. This plot will take eight times longer than the minimum to be created, and is expected to be valid into the 2040s. It will only become invalid when the minimum strength reaches `4`. +The minimum strength will start at `2` and will be increased via a soft fork as needed. We won't plan to increase the minimum strength until at least 2036, though this is subject to change. -| Block height | Month/Year (app.) | Base Filter | Min Str | Filter at Str=3 | Pass Frequency | -| :----------- | :---------------- | :---------- | :------ | :-------------- | :------------- | -| TODO | July 2026 | 1024 | 0 | 8192 | 1 day | -| TODO | July 2028 | 512 | 0 | 4096 | 12 hours | -| TODO | July 2030 | 256 | 0 | 2048 | 6 hours | -| TODO | July 2032 | 128 | 0 | 1024 | 3 hours | -| TODO | July 2034 | 64 | 0 | 512 | 80 minutes | -| TBD | TBD | 64 | 1 | 256 | 40 minutes | -| TBD | TBD | 64 | 2 | 128 | 20 minutes | -| TBD | TBD | 64 | 3 | 64 | 10 minutes | -| TBD | TBD | 64 | 4 | Invalid | N/A | +The following table illustrates how we expect these adjustments to occur. The third column from the right shows the network's hypothetical minimum strength. While this number will only be increased as needed, the table does show a realistic expectation of what may occur. The second column from the right shows the effective filter for a plot created at `strength = 6`, and the rightmost column shows how often that plot will pass the filter, on average. This plot will take 16 times longer than the minimum to be created, and is expected to be valid into the 2040s. It will only become invalid when the minimum strength reaches `7`. -### Plot groupings +| Block height | Month/Year | Base Filter | Min Str | Filter at Str=6 | Frequency | +| :----------- | :--------- | :---------- | :------ | :-------------- | :-------- | +| TODO | July 2026 | 1024 | 2 | 8192 | 1 day | +| TODO | July 2028 | 512 | 2 | 8192 | 1 day | +| TODO | July 2030 | 256 | 2 | 4096 | 12 hours | +| TODO | July 2032 | 128 | 2 | 2048 | 6 hours | +| TODO | July 2034 | 64 | 2 | 1024 | 3 hours | +| TBD | TBD | 64 | 3 | 512 | 80 min | +| TBD | TBD | 64 | 4 | 256 | 40 min | +| TBD | TBD | 64 | 5 | 128 | 20 min | +| TBD | TBD | 64 | 6 | 64 | 10 min | +| TBD | TBD | 64 | 7 | Invalid | N/A | + +[TODO in the above table, we might want to reduce the base filter two more times until it reaches 16, and then stop] +[TODO update names (min strength) and functionality to match whatever we decide on] + +### Plot groups With the new Proof of Space format, farmers are recommended to add multiple plots with the same public key to a single _group_. This will work by combining multiple plots together, as if they were the same plot. +Note: Because `plot_strength` is part of the group ID, all plots contained within the same group must have the same strength. This means that a given plot group will have its own effective filter, equal to the effective filter of every plot contained within the group. + A plot's group ID is determined by hashing its k-size, version, strength, public key, and either its puzzle hash or its pool public key: ``` @@ -172,7 +188,7 @@ A plot's group ID is determined by hashing its k-size, version, strength, public ) ``` -The plot's ID is then determined by hashing its group ID, index, and [meta group](#meta-groupings) (explained below): +The plot's ID is then determined by hashing its group ID, index, and [meta group](#meta-groups) (explained below): ``` sha256( @@ -181,25 +197,25 @@ The plot's ID is then determined by hashing its group ID, index, and [meta group meta_group: u8, ) ``` -The `plot_index` represents that plot's slot in the group. This means that the maximum number of plots that can be included in a group is 2^16 (65,536), or about 65 TB. +The `plot_index` represents a plot's slot within its group. The maximum number of plots that can be included in a group is 2^16 (65,536), or about 65 TB. Grouping multiple plots together is required beyond a few thousand plots on HDDs, and is recommended on SSDs as well. If plots are not grouped together, then multiple lookups will be needed at each signage point. -For example, a 20-TB HDD will hold around 20,000 plots. If the plot ID filter for these plots is `256`, and the plots are not grouped, then an average of around 78 plots will pass the filter at each signage point. This will require a large amount of lookups, which could affect the harvester's ability to respond on time. +For example, a 20-TB HDD will hold around 20,000 plots. If the effective filter for these plots is `256`, and the plots are not grouped, then an average of around 78 plots will pass the filter at each signage point. This will require a large amount of lookups, which could affect the harvester's ability to respond on time. However, grouping _too many_ plots together could also cause issues, though they would be minor in comparison. Due to the extra memory required to group plots together, creating a group with more than 128 plots is not generally recommended. In addition, because a plot group acts as a single plot, larger groups will also increase the volatility of block rewards being won. This volatility is only noticeable in the short term, though -- the long-term expected win rate will be unaffected by large group sizes. Keeping the above considerations in mind, the recommended group size is `128`. This will yield plot groups of around 120 GB, which is roughly the same size as v1 plots. For plotters with lower RAM, grouping 64 plots together is also fine. -However, there are exceptions to these recommendations. For example, older HDDs with low capacities may not be profitable for some farmers due to ongoing electricity costs. However, these HDDs could be filled with plots that are grouped together so that the entire HDD consists of a single "plot". These HDDs could then be powered down until their plot is about to pass the filter, which would save on electricity. This is [described in detail](#powering-down-hdds) below. +However, there are exceptions to these recommendations. For example, older HDDs with low capacities may not be profitable for some farmers due to ongoing electricity costs. Instead, these HDDs could be filled with plots that are grouped together so that the entire HDD consists of a single "plot". These HDDs could then be powered down until their plot is about to pass the filter, which would save on electricity. This technique is [described in detail](#powering-down-hdds) below. -### Meta groupings -All plots in a standard plot group will pass the plot ID filter together. However, the plot groups themselves will occasionally also pass the filter together. By using _meta groupings_, one can guarantee that separate groups will never pass the filter together. This can be beneficial, for example, in order to reduce the chances that a disk becomes overloaded from excessive lookups. It also will somewhat help to smooth out rewards. +### Meta groups +All plots in a standard plot group will pass the filter together. However, the plot groups themselves will occasionally also pass the filter together. By using _meta groups_, one can guarantee that separate groups will never pass the filter together. This can be beneficial, for example, in order to reduce the chances that a disk becomes overloaded from excessive lookups. It also will somewhat help to smooth out rewards. A plot's meta group is a single byte, so up to 256 meta groups can be created in one farm. -### Plot ID filter calculation -The formula to determine whether a given plot passes the plot ID filter will be modified for the new Proof of Space protocol. In this section, we'll start by describing this formula for PoS v1, along with its deficiencies. Next, we'll describe the new formula for PoS v2, along with its advantages. +### Effective filter calculation +The formula to determine whether a given plot passes the filter will be modified for the new Proof of Space protocol. In this section, we'll start by describing this formula for PoS v1, along with its deficiencies. Next, we'll describe the new formula for PoS v2, along with its advantages. #### Old formula and deficiencies In the original Proof of Space protocol, plots randomly pass (or don't pass) the filter at each signage point. This is determined by hashing the plot ID concatenated with the current challenge and signage point: @@ -208,9 +224,9 @@ In the original Proof of Space protocol, plots randomly pass (or don't pass) the If `plot filter bits` begins with a certain number of zeroes, then the plot passes the filter. For example, if the plot filter is `256`, then at each signage point, a plot will have will have a 1 in 256 chance of passing the filter (`plot filter bits` must begin with eight zeroes in this case). Because `plot filter bits` is calculated from a `sha256` hash, the plot has an equal chance of passing the filter at any given signage point. -There is also no mechanism to prevent the plot from passing the filter at multiple consecutive signage points. By analogy, if I roll a die three times, the result might be `1` each time. This means that a plot will have a 1 in 65,536 (256 * 256) chance of passing two consecutive signage points, and a 1 in 16,777,216 (256 * 256 * 256) chance of passing three consecutive signage points. +There is also no mechanism to prevent the plot from passing the filter at multiple consecutive signage points. By analogy, if someone rolls a die three times, the result might be `1` each time. This means that a plot will have a 1 in 65,536 (256 * 256) chance of passing two consecutive signage points, and a 1 in 16,777,216 (256 * 256 * 256) chance of passing three consecutive signage points. -Plot grinders can generate a plot ID without creating the plot, so they can grind through millions of plot IDs per second. This means that at any given signage point, they can grind a plot ID that will pass it, as well as the next two signage points, thereby increasing their leverage. The details of plot grinding, and the leverage gained, are shown in [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). +Plot grinders can generate a plot ID without creating the plot, so they can grind through millions of plot IDs per second. This means that at any given signage point, they can grind a plot ID that will pass it, as well as the previous two signage points, thereby increasing their leverage. The details of plot grinding, and the leverage gained, are shown in [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). #### New formula @@ -235,25 +251,34 @@ def plot_id_check(plot_group_id, group_strength, meta_group, filter_challenge, c The main two advantages of using this new formula are that it removes the potential extra leverage from plot grinding, and that it makes it possible to power down HDDs between times when they pass the filter. Both of these advantages are detailed below. #### No extra leverage when grinding -By using the new formula, we can guarantee that a plot group won't pass the plot ID filter more than once every four signage points. This means that the extra leverage that could previously be gained from grinding a plot's ID is no longer applicable. Plot grinders will be able to create plots on the fly, but it won't be possible to have a multiplier effect. The new formula will therefore accomplish the original goal of the defunct [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). +By using the new formula, we can guarantee that a plot group won't pass the filter more than once every four signage points. This means that the extra leverage that could previously be gained from grinding a plot's ID is no longer applicable. Plot grinders will be able to create plots on the fly, but it won't be possible to have a multiplier effect. The new formula will therefore accomplish the original goal of the defunct [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). #### Powering down HDDs -In addition, it will now be possible to predict between 4 to 20 signage points (~37 seconds to two minutes) in advance when a plot group will pass the filter. This will make it possible to power down a hard drive, and start it up in advance of the plot group passing the filter. A few guidelines should be followed in order to maximize the efficiency of this use case. +In addition, it will now be possible to predict between 4 to 20 signage points (~37 seconds to three minutes) in advance when a plot group will pass the filter. This will make it possible to power down a hard drive most of the time, and only start it up in advance of the plot group passing the filter. A few guidelines should be followed in order to maximize the efficiency of this use case. ##### Group many plots together -If a farmer's goal is to maximize the timing between wake-ups (as opposed to smoothing rewards), an HDD should ideally be filled with a single plot group. If a 20-TB HDD were filled with 4 plot groups of 5 TB, and the filter for those plots were 8192, then the HDD would need to be started and stopped four times daily, on average. But if the same HDD were filled with a single plot group of 20 TB and the same filter, then it would only need to be started and stopped once daily. +If a farmer's goal is to maximize the timing between wake-ups (as opposed to smoothing rewards), an HDD can be filled with a single plot group. If a 20-TB HDD were filled with 4 plot groups of 5 TB, and the effective filter for those groups were 8192, then the HDD would need to be started and stopped four times daily, on average. But if the same HDD were filled with a single plot group of 20 TB and the same effective filter, then it would only need to be started and stopped once daily. ##### Use smaller HDDs -HDDs use a similar amount of electricity, regardless of their capacity. In PoS v1, this made small HDDs economically unprofitable. In PoS v2, powering down these smaller disks will potentially make them profitable. However, the advantage of powering down an HDD is reduced as the HDD's capacity is increased. It may turn out that there is little advantage to powering down a modern, large-capacity HDD. It may actually be a disadvantage due to the increased compute needed to create a plot group for the large HDD, as well as due to the extra wear caused by repeatedly shutting down and starting up an HDD. +HDDs use a similar amount of electricity, regardless of their capacity. In PoS v1, this made small HDDs economically unprofitable. In PoS v2, powering down these smaller disks will potentially make them profitable. However, the advantage of powering down an HDD is reduced as the HDD's capacity is increased. It may turn out that there is little advantage to powering down a modern, large-capacity HDD. In fact, it may actually be a disadvantage due to the increased compute needed to create a plot group for the large HDD, as well as due to the extra wear caused by repeatedly shutting down and starting up an HDD. ##### Plot to a high strength -Per the above table, plot groups that were created at strength `3` will initially pass the filter once per day. After two years, this frequency will be reduced to 12 hours, and after four years, it will be reduced to 6 hours. Farmers may not be comfortable with starting and stopping their HDDs more than four times daily, so in order to take advantage of this use case for six years, they will need to plot to at least strength `3`, which requires 8x the compute of strength `0`. +Per the above table, plot groups that were created at strength `6` will initially pass the filter once per day. After two years, this frequency will be reduced to 12 hours, and after four years, it will be reduced to 6 hours. Farmers may not be comfortable with starting and stopping their HDDs more than four times daily, so in order to take advantage of this use case for six years, they will need to plot to at least strength `6`, which requires 16x the compute of strength `2`. #### Determining when a plot group will pass -[todo] describe how to figure this out so that you have plenty of time to start your HDD -This will be described in https://chia-network.atlassian.net/browse/CHIA-3815 -For example, if my plot will pass the filter at signage point 0, is this going to be determined from the previous subslot's challenge? -[answer] The ideas is that every 16th challenge point is used for the plot id filter and it applies to the challenge points 4-20 ahead of it +Every subslot is 600 seconds, and has 64 signage points, which occur every 9.375 seconds. See [our documentation](https://docs.chia.net/chia-blockchain/consensus/chains/signage-and-infusion-points/) for more information on subslots and signage points. + +In the old Proof of Space algorithm, the determination as to whether a plot passes the filter is made at each signage point. + +In the new Proof of Space algorithm, this determination is only made at signage points 0, 16, 32, and 48. When one of these _n_ signage points is reached, the filter is calculated for signage points `n+4` through `n+20`. This algorithm guarantees that the determination as to whether a plot group will pass the filter is known at least 37.5 (9.375 * 4) seconds in advance, and at most 187.5 (9.375 * 20) signage points in advance. After signage point 63 is reached, a new subslot will begin with signage point 0. The first four signage points of a subslot are therefore determined during the previous subslot. + +This algorithm will allow harvesters to determine when their plot groups will pass the filter with some advanced warning. If a disk that contains a plot group that will pass the filter in the next 4-20 signage points is currently shut down, then the harvester can start the disk. + +The reason to set the minimum advanced notice to 37.5 seconds is because it could take up to 30 seconds to start some slower HDDs that have been completely shut down. Even in the worst-case scenario of a slow disk being given the minimum amount of advanced notice, there will still be ample time for the disk to be started. + +The reason to set the maximum advanced notice to 187.5 seconds is to ensure that tape drives are not viable for farming. These drives provide cheaper storage than HDDs and SSDs, giving them an unfair advantage. While a tape drive might perform some seeks in less than the maximum time, it often will fail to load the needed information in time to be used in the blockchain's consensus. + +Note that even though most of the signage points will no longer determine whether a plot group will pass the filter, every signage point will continue to be used for consensus purposes. ### Other updates From 171797aca623f31cde15b53ff1058250cffd0afd Mon Sep 17 00:00:00 2001 From: danieljperry Date: Thu, 29 Jan 2026 15:53:24 +0800 Subject: [PATCH 10/24] Propose block heights and update other info --- CHIPs/chip-0049.md | 135 ++++++++++++++++++++++++++++----------------- 1 file changed, 83 insertions(+), 52 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index 2bd138cc..7fd6df9f 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -15,7 +15,7 @@ Requires | [0048](https://github.com/Chia-Network/chips/pull/160) [CHIP-48](https://github.com/Chia-Network/chips/pull/160), which introduces the new Proof of Space format (PoS v2), requires a hard fork of the Chia blockchain. This document describes how PoS v2 will be integrated with the blockchain, as well as how original plots will be phased out. This CHIP also proposes a few other hard-fork changes, unrelated to the new proof format. ## Motivation -The current Proof of Space format (PoS v1) was released in July 2020, during the Chia blockchain’s beta phase. Five years later, the format remains secure. However, two broad issues exist, one of which is still hypothetical, and the other of which is in production today. +The current Proof of Space format (PoS v1) was released in July 2020, during the Chia blockchain’s beta phase. Today, the format remains secure. However, two broad issues exist, one of which is still hypothetical, and the other of which is already in production. The hypothetical issue is plot grinding. This is where a farmer creates an entire plot and submits a proof within around 28 seconds. Plot grinding is described in detail in [CHIP-12](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0012.md). @@ -40,7 +40,8 @@ Even though the original plot format will be disabled by this CHIP, it will rema The specification for each of this CHIP’s features will be listed individually. ### Fork activation -We will release Chia version 3.0.0, which will implement the hard fork. The fork will activate in the block immediately following the first *transaction* block, with a later signage point, at or above height [todo]. This is expected to happen around [todo]. +We will release Chia version 3.0.0, which will implement the hard fork. The fork will activate in the block immediately following the first *transaction* block, with a later signage point, at or above height `9'562'000` (nine million, five hundred and sixty-two thousand). This is expected to happen around November 10, 2026, though it could drift a few days in either direction. + A single signage point may produce multiple blocks. If the block immediately following the transaction block at the activation height happens to be on the same signage point, it will also be pre-activation. The hard fork would then activate with the next signage point. Starting with the block in which the hard fork is activated, the new Proof of Space will be accepted. @@ -54,18 +55,16 @@ In order to validate a PoS v1 proof after the hard fork has activated, we will l After 256 epochs after the fork's activation, no original proof will ever be valid. This ends the phase-out period and effectively disables the original Proof of Space. -[todo update heights in this table] - | Blocks w/prev. TX block >= | epochs | Win prob. factor | |:-------------------------- | :----- | :--------------- | -| 8800000 | 0 | 1.000 | -| 8804608 | 1 | 0.996 | -| 8809216 | 2 | 0.992 | -| 8813824 | 3 | 0.988 | +| 9562000 | 0 | 1.000 | +| 9566608 | 1 | 0.996 | +| 9571216 | 2 | 0.992 | +| 9575824 | 3 | 0.988 | | … | … | … | -| 9970432 | 254 | 0.008 | -| 9975040 | 255 | 0.004 | -| 9979648 | 256 | 0.000 | +| 10732432 | 254 | 0.008 | +| 10737040 | 255 | 0.004 | +| 10741648 | 256 | 0.000 | As for the new Proof of Space format, its value will be 100% beginning at the fork's activation. In other words, its win probability factor will be 1.000. There will be no planned phase-out (or phase-in) for the new format. @@ -85,7 +84,7 @@ The remaining 7 bits will indicate either: * The k-size of the plot that produced the proof (original Proof of Space), or * The strength of the plot that produced the proof (new Proof of Space) -Note that the only valid k-size in the new Proof of Space on mainnet and testnets is k28 (around 1 GB per plot). Simulations can use other sizes; CNI's simulator code will use k18 (around 1 MB per plot). +Note that the only valid k-size in the new Proof of Space on mainnet and testnets is k28 (around 1 GB per plot). Simulators can use other sizes; CNI's simulator code will use k18 (around 1 MB per plot). ### Filter and strength adjustments We have two ways to future-proof the network against rental attacks, and plot grinding more generally: automatic reductions in the base filter, and manual increases in the network's minimum plot strength. Both of these will be detailed in this section. @@ -95,30 +94,34 @@ We have two ways to future-proof the network against rental attacks, and plot gr At every signage point, a certain number of plots are excluded from participating in the challenge. In the original Proof of Space protocol, this was known as the `plot filter`, and is described in [our documentation](https://docs.chia.net/chia-blockchain/consensus/chains/signage-and-infusion-points/). In Proof of Space v2, there are two related filters to consider: the network's base filter, and the effective filter for a plot or a group (see below for more info on [plot groups](#plot-groups)). #### Base filter definition and plan -The base filter indicates the lowest filter allowed for all plots across the network. This filter will start `1024` and will automatically be adjusted downward every two years at pre-defined block heights, until it reaches `64`. It will remain at `64` thereafter. +The base filter indicates the lowest filter allowed for all plots across the network. This filter will start `512` and will automatically be adjusted downward every 3-6 years at pre-defined block heights, until it reaches `1`. It will remain at `1` thereafter. -The reason to reduce the base filter over time is to decrease the leverage a rental attacker is able to gain. This topic is covered extensively in [CHIP-12](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0012.md). In summary, a rental attacker can opt to exclusively create plots that will pass the filter, so the amount of space they are able to spoof is multiplied by a given plot's effective filter ([described below](#effective-filter-definition)). As GPUs become faster, we can initially protect the network against rental attacks by proactively reducing the base filter. However, for technical reasons covered in CHIP-48, we won't reduce the base filter to be lower than `64`. The next protection against rental attacks will come from increasing the minimum plot strength, which will be [covered later](#minimum-strength-plan). +The reason to reduce the base filter over time is to decrease the leverage a rental attacker is able to gain. This topic is covered extensively in [CHIP-12](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0012.md). In summary, a rental attacker can opt to exclusively create plots that will pass the filter, so the amount of space they are able to spoof is multiplied by a given plot's effective filter ([described below](#effective-filter-definition)). As GPUs become faster, we can protect the network against rental attacks by proactively reducing the base filter. We also can protect against rental attacks by increasing the minimum plot strength, which will be [covered later](#minimum-strength-plan). -Cutting the base filter in half every two years will have two impacts for all farmers: higher [disk usage](#disk-usage), and longer [plot stability](#plot-stability). +Cutting the base filter in half will have two impacts for all farmers: higher [disk usage](#disk-usage), and longer [plot stability](#plot-stability). ##### Disk usage Each time the base filter is cut in half, the likelihood that a plot will pass it is doubled. The load on individual disks will therefore roughly double as well. -HDDs can operate at 20% of their read capacity without significantly shortening their life expectancy. The base filter will be cut in half four times over the course of eight years, so if a farmer expects their disks to last for eight years, then they should plot so that their disks initially run at 1% of their read capacity or lower. That way, their disks will never run at more than 16% of their read capacity, so they will remain viable for farming for their entire life expectancy. +HDDs can operate at 20% of their read capacity without significantly shortening their life expectancy. The base filter will be cut in half two times over the course of nine years, so if a farmer expects their disks to last for nine years, then they should plot so that their disks initially run at 5% of their read capacity or lower. That way, their disks will never run at more than 20% of their read capacity, so they will remain viable for farming for their entire life expectancy. -Read speeds of SSDs are much faster than those of HDDs, so farmers can safely plot their SSDs at the minimum strength without running into issues related to high disk usage. However, they should still plan according to the expected scheduling for minimum strength increases, which are [covered later](#minimum-strength-plan). +Read speeds of SSDs are much faster than those of HDDs, so farmers can safely plot their SSDs at the minimum strength without running into issues related to high disk usage. However, they should still keep in mind that any plots created at the minimum strength will no longer be valid after the minimum strength is increased. A rough plan for these increases is [covered later](#minimum-strength-plan). ##### Plot stability -By decreasing the base filter every two years for the first 10 years of the new Proof of Space's existence, we expect to be able to keep the minimum strength at `2` for that time frame. This means that all plots created at the minimum strength are expected to be valid for at least 10 years, barring unexpected advancements in technology. - -Starting around 2036, plot stability will come entirely from plotting to a higher strength than the minimum. +The automatic reductions in the base filter should allow us to keep the minimum strength at `0` for ten years or more, barring unexpected advancements in technology. If all goes according to plan, then for the subsequent 21 years, we will rely on a combination of reducing the base filter and increasing the minimum strength. Finally, starting around 2057, plot stability will come entirely from plotting to a higher strength than the minimum. #### Plot strength definition -As detailed in CHIP-48, every plot will include a “strength” parameter, which will adjust how much time is required to create the plot, _ceteris paribus_. If a given plot's strength is `n`, then creating the plot will require `2^n` times longer than the minimum amount of time. (Harvesting time and plot size are both minimally affected by the plot’s strength.) At a given block height, the network will only accept plots that meet the current minimum strength threshold. +As detailed in CHIP-48, every plot will include a “strength” parameter, which will adjust how much work is required to create the plot. If a given plot's strength is `n`, then creating the plot will require around `2^n` times more effort than the minimum. One caveat is that there is a small amount of overhead that remains constant at all levels. Because of this overhead, incrementing at the lowest levels will incur a bit less than double the work. At `strength = 5` and above, the overhead is negligible. + +At a given block height, the network will only accept plots that meet the current minimum strength threshold. By definition, `strength = 0` indicates the minimum compute required to create a plot, with no additional arbitrary computation. -The maximum allowed strength will be [TODO]. This strength is capped arbitrarily, in order to prevent future attacks which may emerge from applying an extremely high strength to one or more plots. +The maximum allowed strength will be 17 minus the number of bits in the base filter. For example, if the base filter is 512, then the number of bits in the base filter is 9 (`log(512)`). The maximum strength is therefore `17 - 9 = 8`. When the base filter reaches `1`, there will be `log(1) = 0` bits in the base filter, so it can't go any lower. + +Strength needs to be capped in order to ensure that the network's minimum spec hardware can validate a proof from a plot created at that strength in a timely manner. The assumption is that eventually the minimum spec hardware will also be increased as technology improves, but there isn't a preplanned date for this to occur. If a plot has a strength that is greater than the current maximum, then it will be considered invalid by the blockchain's consensus. + +As for the size of a plot, as well as the time/effort required for harvesting a plot, these are both minimally affected by the plot’s strength. #### Effective filter definition Each plot will have its own `effective filter`, which determines the likelihood that it is eligible to participate in a challenge at a given signage point. The effective filter is calculated based on a given plot's strength. [CHIP-48](https://github.com/Chia-Network/chips/pull/160) provides the technical details. @@ -128,12 +131,12 @@ The formula to calculate a given plot's effective filter is: For each level that a given plot's strength is higher than the network's base strength, the plot's effective filter will be doubled. However, the maximum `effective filter` is `8192`, regardless of the plot's strength. -For example, if the network's `base filter` is `1024` and the `minimum strength` is `2`, then a plot created at `strength = 6` should have an `effective filter` of `1024 * (2^(6-2)) = 16,384`. However, due to the maximum filter size, the plot's `effective filter` will be `8192` for this plot. If the network's `minimum strength` is later raised to `3`, then the same plot will have an `effective filter` of `1024 * (2^(6-3)) = 8192`. +For example, if the network's `base filter` is `512` and the `minimum strength` is `0`, then a plot created at `strength = 5` should have an `effective filter` of `512 * (2^(5-0)) = 16,384`. However, due to the maximum filter size, the plot's `effective filter` will be `8192` for this plot. If the network's `minimum strength` is later raised to `1`, then the same plot will have an `effective filter` of `512 * (2^(5-1)) = 8192`. Some farmers may therefore choose to plot to a high strength in order to preserve the `effective filter` of `8192` even after the network's `minimum strength` is raised. #### Minimum strength plan -The network's minimum strength will start at `2`, and will be adjusted upward as needed. Adjusting the minimum strength will require a soft fork. We won't plan to increase the minimum strength for the first ten years after the PoS2 fork activates, barring any unexpected advancements in technology. +The network's minimum strength will start at `0`, and will be adjusted upward as needed. Adjusting the minimum strength will require a soft fork. We won't plan to increase the minimum strength for the first ten years after the PoS2 fork activates, barring any unexpected advancements in technology. The minimum strength should only ever be increased with time. It can be increased by any integer, but typically we will only increase it by 1 in a given soft fork (we could also build in multiple future increases with a single fork). Because any plots with the current minimum strength will need to be recreated when the minimum strength is increased, we plan provide a lengthy warning (perhaps six or twelve months) for a fork that increases the minimum strength to activate. @@ -144,29 +147,57 @@ One thing to note is that a given farm can contain plots with various strength l #### Expected base filter and strength To recap: -The network's base filter will start at `1024` and will be cut in half every two years until it reaches `64`. These adjustments will happen automatically, and can be delayed with a soft fork. - -The maximum effective filter for any individual plot is `8192`, regardless of its strength. - -The minimum strength will start at `2` and will be increased via a soft fork as needed. We won't plan to increase the minimum strength until at least 2036, though this is subject to change. - -The following table illustrates how we expect these adjustments to occur. The third column from the right shows the network's hypothetical minimum strength. While this number will only be increased as needed, the table does show a realistic expectation of what may occur. The second column from the right shows the effective filter for a plot created at `strength = 6`, and the rightmost column shows how often that plot will pass the filter, on average. This plot will take 16 times longer than the minimum to be created, and is expected to be valid into the 2040s. It will only become invalid when the minimum strength reaches `7`. - -| Block height | Month/Year | Base Filter | Min Str | Filter at Str=6 | Frequency | -| :----------- | :--------- | :---------- | :------ | :-------------- | :-------- | -| TODO | July 2026 | 1024 | 2 | 8192 | 1 day | -| TODO | July 2028 | 512 | 2 | 8192 | 1 day | -| TODO | July 2030 | 256 | 2 | 4096 | 12 hours | -| TODO | July 2032 | 128 | 2 | 2048 | 6 hours | -| TODO | July 2034 | 64 | 2 | 1024 | 3 hours | -| TBD | TBD | 64 | 3 | 512 | 80 min | -| TBD | TBD | 64 | 4 | 256 | 40 min | -| TBD | TBD | 64 | 5 | 128 | 20 min | -| TBD | TBD | 64 | 6 | 64 | 10 min | -| TBD | TBD | 64 | 7 | Invalid | N/A | - -[TODO in the above table, we might want to reduce the base filter two more times until it reaches 16, and then stop] -[TODO update names (min strength) and functionality to match whatever we decide on] +The network's base filter will start at `512` and will be cut in half every 3-6 years until it reaches `1`, at which point every plot will pass the filter at each signage point. These adjustments will happen automatically, and can be delayed with a soft fork. + +The maximum strength will be 17 minus the number of bits in the base filter. The maximum strength will increase every 3-6 years as the base filter falls. + +The maximum effective filter for any individual plot is always `8192`, regardless of its strength. If a plot was created at a high enough strength that this number should be greater than `8192`, then it will automatically be capped. This is done to prevent certain attacks that could occur with very high strengths. + +The following table shows the block height for each built-in adjustment to the base filter, as well as the corresponding maximum strength at that base filter. The block height from 2026 was pre-determined. The subsequent block heights were calculated with the following formula (the calculation for 2032 is shown at each step of the way): +* multiply 365 by 3 (or 6) + * `365 * 6 = 2190` +* add 0, 1, or 2 to account for leap days + * `2190 + 2 = 2192` (there are leap days in 2028 and 2032) +* multiply the result by 4608 (the average number of blocks in a day) + * `2192 * 4608 = 10'100'736` +* add the previous block height to the total + * `9'562'000 + 10'100'736 = 19'662'736` +* save the result for the next block height's calculation + * `19'662'736` +* round to the nearest thousand + * `19'663'000` + +| Block height | Year | Base Filter Bits | Base Filter | Max Strength | +| :----------- | :--- | :--------------- | :---------- | :----------- | +| ` 9'562'000` | 2026 | 9 | 512 | 8 | +| `19'663'000` | 2032 | 8 | 256 | 9 | +| `24'708'000` | 2035 | 7 | 128 | 10 | +| `29'759'000` | 2038 | 6 | 64 | 11 | +| `34'809'000` | 2041 | 5 | 32 | 12 | +| `39'860'000` | 2044 | 4 | 16 | 13 | +| `44'905'000` | 2047 | 3 | 8 | 14 | +| `49'956'000` | 2051 | 2 | 4 | 15 | +| `55'006'000` | 2054 | 1 | 2 | 16 | +| `60'056'000` | 2057 | 0 | 1 | 17 | + +The first built-in reduction in the base filter will occur six years after the fork is activated. The subsequent built-in reductions will occur every three years thereafter by default. This is a somewhat aggressive schedule to keep up with advancing technology. In the scenario where we feel comfortable with delaying these reductions, we will do so with a soft fork. + +As a reminder, the minimum strength will start at `0` and will be increased via a soft fork as needed. We won't plan to increase the minimum strength until at least 2036 (10 years after the 3.0 release), though this is subject to change. If/when we do decide to increase the minimum strength, we will provide a window of _at least_ 90 days so that any plots at the current minimum will have time to be upgraded before they become invalid. While 90 days is the minimum warning when increasing the minimum strength, we will do our best to provide 6-12 months' warning whenever possible. + +The following table shows some hypothetical adjustments to the original strength, along with the built-in adjustments to the base filter. In this scenario, we will increase the minimum strength every two years, starting in 2036. In certain years in this table, both the base filter and minimum strength will be adjusted at the same block. Keep in mind that the strength adjustments will only be undertaken as needed, so this is only an example to illustrate how the adjustments might look. The second column from the right shows the effective filter for a plot created at `strength = 5`, and the rightmost column shows how often that plot will pass the filter, on average. + +| Block height | Year | Base Filter | Min Str | Effective Filter at Str=5 | Frequency | +| :----------- | :--- | :---------- | :------ | :------------------------ | :-------- | +| `9'562'000` | 2026 | 512 | 0 | 8192 (capped) | 1 day | +| `19'663'000` | 2032 | 256 | 0 | 8192 (256 * 2^(5-0)) | 1 day | +| `24'708'000` | 2035 | 128 | 0 | 4096 (128 * 2^(5-0)) | 12 hours | +| TBD | 2036 | 128 | 1 | 2048 (128 * 2^(5-1)) | 6 hours | +| `29'759'000` | 2038 | 64 | 2 | 512 (64 * 2^(5-2)) | 80 mins | +| TBD | 2040 | 64 | 3 | 256 (64 * 2^(5-3)) | 40 mins | +| `34'809'000` | 2041 | 32 | 3 | 128 (32 * 2^(5-3)) | 20 mins | +| TBD | 2042 | 32 | 4 | 64 (32 * 2^(5-4)) | 10 mins | +| `39'860'000` | 2044 | 16 | 5 | 16 (16 * 2^(5-5)) | 150 secs | +| TBD | 2046 | 16 | 6 | Invalid | N/A | ### Plot groups With the new Proof of Space format, farmers are recommended to add multiple plots with the same public key to a single _group_. This will work by combining multiple plots together, as if they were the same plot. @@ -224,7 +255,7 @@ In the original Proof of Space protocol, plots randomly pass (or don't pass) the If `plot filter bits` begins with a certain number of zeroes, then the plot passes the filter. For example, if the plot filter is `256`, then at each signage point, a plot will have will have a 1 in 256 chance of passing the filter (`plot filter bits` must begin with eight zeroes in this case). Because `plot filter bits` is calculated from a `sha256` hash, the plot has an equal chance of passing the filter at any given signage point. -There is also no mechanism to prevent the plot from passing the filter at multiple consecutive signage points. By analogy, if someone rolls a die three times, the result might be `1` each time. This means that a plot will have a 1 in 65,536 (256 * 256) chance of passing two consecutive signage points, and a 1 in 16,777,216 (256 * 256 * 256) chance of passing three consecutive signage points. +There is also no mechanism to prevent the plot from passing the filter at multiple consecutive signage points. By analogy, if someone rolls a die three times, the result might be `1` each time. In the original Proof of Space protocol, a plot will have a 1 in 65,536 (256 * 256) chance of passing two consecutive signage points, and a 1 in 16,777,216 (256 * 256 * 256) chance of passing three consecutive signage points. Plot grinders can generate a plot ID without creating the plot, so they can grind through millions of plot IDs per second. This means that at any given signage point, they can grind a plot ID that will pass it, as well as the previous two signage points, thereby increasing their leverage. The details of plot grinding, and the leverage gained, are shown in [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). @@ -260,10 +291,10 @@ In addition, it will now be possible to predict between 4 to 20 signage points ( If a farmer's goal is to maximize the timing between wake-ups (as opposed to smoothing rewards), an HDD can be filled with a single plot group. If a 20-TB HDD were filled with 4 plot groups of 5 TB, and the effective filter for those groups were 8192, then the HDD would need to be started and stopped four times daily, on average. But if the same HDD were filled with a single plot group of 20 TB and the same effective filter, then it would only need to be started and stopped once daily. ##### Use smaller HDDs -HDDs use a similar amount of electricity, regardless of their capacity. In PoS v1, this made small HDDs economically unprofitable. In PoS v2, powering down these smaller disks will potentially make them profitable. However, the advantage of powering down an HDD is reduced as the HDD's capacity is increased. It may turn out that there is little advantage to powering down a modern, large-capacity HDD. In fact, it may actually be a disadvantage due to the increased compute needed to create a plot group for the large HDD, as well as due to the extra wear caused by repeatedly shutting down and starting up an HDD. +HDDs use a similar amount of electricity, regardless of their capacity. In PoS v1, this made lower-capacity HDDs economically unprofitable. In PoS v2, powering down these smaller disks will potentially make them profitable. However, the advantage of powering down an HDD is reduced as the HDD's capacity is increased. It may turn out that there is little advantage to powering down a modern, large-capacity HDD. In fact, it may actually be a disadvantage due to the increased compute needed to create a plot group for the large HDD, as well as due to the extra wear caused by repeatedly shutting down and starting up an HDD. ##### Plot to a high strength -Per the above table, plot groups that were created at strength `6` will initially pass the filter once per day. After two years, this frequency will be reduced to 12 hours, and after four years, it will be reduced to 6 hours. Farmers may not be comfortable with starting and stopping their HDDs more than four times daily, so in order to take advantage of this use case for six years, they will need to plot to at least strength `6`, which requires 16x the compute of strength `2`. +Plot groups that were created at strength `4` will initially pass the filter once per day. After six years, this frequency will be reduced to 12 hours, and after nine years, it will be reduced to 6 hours. Farmers may not be comfortable with starting and stopping their HDDs more than four times daily, so in order to take advantage of this use case for longer timeframes, they will need to plot to higher strengths. #### Determining when a plot group will pass Every subslot is 600 seconds, and has 64 signage points, which occur every 9.375 seconds. See [our documentation](https://docs.chia.net/chia-blockchain/consensus/chains/signage-and-infusion-points/) for more information on subslots and signage points. @@ -289,7 +320,7 @@ The `keccak256` operator was previously added via soft fork, and is therefore on The hard fork gives us the opportunity to promote `keccak256` to be allowed outside the `softfork` guard. This makes it easier to use. -After block [TODO], the `keccak256` operator will become part of the core CLVM, so it will be usable by calling it directly. It will also continue to be usable from inside the `softfork` guard. +After block `9'562'000`, the `keccak256` operator will become part of the core CLVM, so it will be usable by calling it directly. It will also continue to be usable from inside the `softfork` guard. ### sha256tree Many puzzles use the [sha256tree](https://github.com/Chia-Network/chia_puzzles/blob/0b46a6ebfc3b432d68edf9b91e6cef0ec13da2e7/puzzles/sha256tree.clib) library, which calculates the puzzle hash of a given puzzle program. This library is used so frequently, in fact, that it makes sense to include it as a native CLVM operator in the hard fork. Another advantage of including `sha256tree` in the CLVM is that it will be cheaper to call, both in terms of CPU compute and CLVM cost. Finally, a native operator also opens the door to future optimizations via caching. @@ -329,7 +360,7 @@ In order to calculate block hashes, currently we hash the serialization blob of The 3.0 release will include an update to hash the generator as a sha256tree (just as we do with puzzle hashes), and then the particular serialization won’t matter. This will open the door to arbitrary compression mechanisms without forking. -Beginning in block [todo], the new block hash computation will be accepted. The old method will continue to be accepted until block [todo], after which it will be ignored. +Beginning in block `9'562'000`, the new block hash computation will be accepted. The old method will continue to be accepted until block [todo], after which it will be ignored. The original CLVM cost of calculating the generator was `12'000 * len(blob)`. The new cost is `len(blob)`. From cf0d58233a05f270f1514e57d92fe2531346d670 Mon Sep 17 00:00:00 2001 From: danieljperry Date: Fri, 30 Jan 2026 16:06:02 +0800 Subject: [PATCH 11/24] Add diagram to describe how the filter will work with groups and meta groups --- CHIPs/chip-0049.md | 2 ++ .../chip-0049/challenge_filter_meta_groups.png | Bin 0 -> 136355 bytes 2 files changed, 2 insertions(+) create mode 100644 assets/chip-0049/challenge_filter_meta_groups.png diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index 7fd6df9f..8ec03127 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -303,6 +303,8 @@ In the old Proof of Space algorithm, the determination as to whether a plot pass In the new Proof of Space algorithm, this determination is only made at signage points 0, 16, 32, and 48. When one of these _n_ signage points is reached, the filter is calculated for signage points `n+4` through `n+20`. This algorithm guarantees that the determination as to whether a plot group will pass the filter is known at least 37.5 (9.375 * 4) seconds in advance, and at most 187.5 (9.375 * 20) signage points in advance. After signage point 63 is reached, a new subslot will begin with signage point 0. The first four signage points of a subslot are therefore determined during the previous subslot. +We have included a [diagram](../assets/chip-0049/challenge_filter_meta_groups.png) that visualizes this algorithm for your reference. + This algorithm will allow harvesters to determine when their plot groups will pass the filter with some advanced warning. If a disk that contains a plot group that will pass the filter in the next 4-20 signage points is currently shut down, then the harvester can start the disk. The reason to set the minimum advanced notice to 37.5 seconds is because it could take up to 30 seconds to start some slower HDDs that have been completely shut down. Even in the worst-case scenario of a slow disk being given the minimum amount of advanced notice, there will still be ample time for the disk to be started. diff --git a/assets/chip-0049/challenge_filter_meta_groups.png b/assets/chip-0049/challenge_filter_meta_groups.png new file mode 100644 index 0000000000000000000000000000000000000000..ba07a247da2a55241a36d92c5df2072622d88c61 GIT binary patch literal 136355 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 Wi_2u>jO;t$-`UgZih1(pKK}y<1xj}S literal 0 HcmV?d00001 From 517ee88fb640e1c9296105d8a423541e39793024 Mon Sep 17 00:00:00 2001 From: danieljperry Date: Wed, 4 Feb 2026 15:32:14 +0800 Subject: [PATCH 12/24] Clarify that every plot needs to belong to a group, even if the group's size is 1 --- CHIPs/chip-0049.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index 8ec03127..5fffca9f 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -200,7 +200,7 @@ The following table shows some hypothetical adjustments to the original strength | TBD | 2046 | 16 | 6 | Invalid | N/A | ### Plot groups -With the new Proof of Space format, farmers are recommended to add multiple plots with the same public key to a single _group_. This will work by combining multiple plots together, as if they were the same plot. +With the new Proof of Space format, every plot will be part of a _group_. While it is possible for each individual plot to have its own group with a size of 1, farmers are recommended to add multiple plots with the same public key into a single group. This will work by combining multiple plots together, as if they were the same plot. Note: Because `plot_strength` is part of the group ID, all plots contained within the same group must have the same strength. This means that a given plot group will have its own effective filter, equal to the effective filter of every plot contained within the group. From f4d06b9711c0e4e0d8ed84fddeb0ea1c192706e9 Mon Sep 17 00:00:00 2001 From: danieljperry Date: Tue, 10 Feb 2026 12:54:41 +0800 Subject: [PATCH 13/24] More clarifications --- CHIPs/chip-0049.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index 5fffca9f..b8965b3c 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -70,7 +70,7 @@ As for the new Proof of Space format, its value will be 100% beginning at the fo ### Protocol -In both the original and new Proof of Space formats, a `FullNode` object contains a `ProofOfSpace`, which has these fields: +In both the original and new Proof of Space protocols, a `FullNode` object contains a `ProofOfSpace`, which has these fields: ``` size: u8, proof: Bytes, @@ -86,12 +86,14 @@ The remaining 7 bits will indicate either: Note that the only valid k-size in the new Proof of Space on mainnet and testnets is k28 (around 1 GB per plot). Simulators can use other sizes; CNI's simulator code will use k18 (around 1 MB per plot). +In addition, plots created for farming on a testnet will be incompatible with mainnet farming. When initiating the plot-creation process, users will need to designate whether the plot will be compatible with testnets or mainnet. + ### Filter and strength adjustments We have two ways to future-proof the network against rental attacks, and plot grinding more generally: automatic reductions in the base filter, and manual increases in the network's minimum plot strength. Both of these will be detailed in this section. #### Filter definition -At every signage point, a certain number of plots are excluded from participating in the challenge. In the original Proof of Space protocol, this was known as the `plot filter`, and is described in [our documentation](https://docs.chia.net/chia-blockchain/consensus/chains/signage-and-infusion-points/). In Proof of Space v2, there are two related filters to consider: the network's base filter, and the effective filter for a plot or a group (see below for more info on [plot groups](#plot-groups)). +At every signage point, a certain number of plots are excluded from participating in the challenge. In the original Proof of Space protocol, this was known as the `plot filter`, and is described in [our documentation](https://docs.chia.net/chia-blockchain/consensus/chains/signage-and-infusion-points/). In the new Proof of Space protocol, there are two related filters to consider: the network's base filter, and the effective filter for a plot or a group (see below for more info on [plot groups](#plot-groups)). #### Base filter definition and plan The base filter indicates the lowest filter allowed for all plots across the network. This filter will start `512` and will automatically be adjusted downward every 3-6 years at pre-defined block heights, until it reaches `1`. It will remain at `1` thereafter. @@ -204,11 +206,10 @@ With the new Proof of Space format, every plot will be part of a _group_. While Note: Because `plot_strength` is part of the group ID, all plots contained within the same group must have the same strength. This means that a given plot group will have its own effective filter, equal to the effective filter of every plot contained within the group. -A plot's group ID is determined by hashing its k-size, version, strength, public key, and either its puzzle hash or its pool public key: +A plot's group ID is determined by hashing its version, strength, public key, and either its puzzle hash or its pool public key: ``` sha256( - k: u8, version: u8, plot_strength: u8, plot_pk: Serialized_PK, @@ -241,9 +242,9 @@ Keeping the above considerations in mind, the recommended group size is `128`. T However, there are exceptions to these recommendations. For example, older HDDs with low capacities may not be profitable for some farmers due to ongoing electricity costs. Instead, these HDDs could be filled with plots that are grouped together so that the entire HDD consists of a single "plot". These HDDs could then be powered down until their plot is about to pass the filter, which would save on electricity. This technique is [described in detail](#powering-down-hdds) below. ### Meta groups -All plots in a standard plot group will pass the filter together. However, the plot groups themselves will occasionally also pass the filter together. By using _meta groups_, one can guarantee that separate groups will never pass the filter together. This can be beneficial, for example, in order to reduce the chances that a disk becomes overloaded from excessive lookups. It also will somewhat help to smooth out rewards. +All plots in a standard plot group will pass the filter together. However, the plot groups themselves will occasionally also pass the filter together. _Meta groups_ are a way to prevent this from happening. If two plot groups are part of separate meta groups, then they will never pass the filter together. This can be beneficial, for example, in order to reduce the chances that a disk becomes overloaded from excessive lookups. It also will somewhat help to smooth out rewards. -A plot's meta group is a single byte, so up to 256 meta groups can be created in one farm. +Plot groups will declare their own meta group. A plot's meta group is a single byte, so up to 256 meta groups can be created in one farm. Each meta group number will be `0` by default. Each meta group can contain up to 2^16 (65,536) plots. ### Effective filter calculation The formula to determine whether a given plot passes the filter will be modified for the new Proof of Space protocol. In this section, we'll start by describing this formula for PoS v1, along with its deficiencies. Next, we'll describe the new formula for PoS v2, along with its advantages. @@ -261,7 +262,7 @@ Plot grinders can generate a plot ID without creating the plot, so they can grin #### New formula -In order to prevent the extra grinding leverage described above, the Proof of Space v2 protocol will change the formula to determine whether a plot passes the filter. We'll start with some definitions: +In order to prevent the extra grinding leverage described above, the new Proof of Space protocol will change the formula to determine whether a plot passes the filter. We'll start with some definitions: * `plot_group_id` -- the ID of the relevant plot * `group_strength` -- the strength of the plot group in bits (the group has a 1/2^z change of passing) @@ -299,9 +300,9 @@ Plot groups that were created at strength `4` will initially pass the filter onc #### Determining when a plot group will pass Every subslot is 600 seconds, and has 64 signage points, which occur every 9.375 seconds. See [our documentation](https://docs.chia.net/chia-blockchain/consensus/chains/signage-and-infusion-points/) for more information on subslots and signage points. -In the old Proof of Space algorithm, the determination as to whether a plot passes the filter is made at each signage point. +In the old Proof of Space protocol, the determination as to whether a plot passes the filter is made at each signage point. -In the new Proof of Space algorithm, this determination is only made at signage points 0, 16, 32, and 48. When one of these _n_ signage points is reached, the filter is calculated for signage points `n+4` through `n+20`. This algorithm guarantees that the determination as to whether a plot group will pass the filter is known at least 37.5 (9.375 * 4) seconds in advance, and at most 187.5 (9.375 * 20) signage points in advance. After signage point 63 is reached, a new subslot will begin with signage point 0. The first four signage points of a subslot are therefore determined during the previous subslot. +In the new Proof of Space protocol, this determination is only made at signage points 0, 16, 32, and 48. When one of these _n_ signage points is reached, the filter is calculated for signage points `n+4` through `n+20`. This algorithm guarantees that the determination as to whether a plot group will pass the filter is known at least 37.5 (9.375 * 4) seconds in advance, and at most 187.5 (9.375 * 20) signage points in advance. After signage point 63 is reached, a new subslot will begin with signage point 0. The first four signage points of a subslot are therefore determined during the previous subslot. We have included a [diagram](../assets/chip-0049/challenge_filter_meta_groups.png) that visualizes this algorithm for your reference. @@ -315,7 +316,7 @@ Note that even though most of the signage points will no longer determine whethe ### Other updates -This section will describe the updates that will go into the hard fork, but are not part of the new Proof of Space format. +This section will describe the updates that will go into the hard fork, but are not part of the new Proof of Space protocol. ### keccak256 The `keccak256` operator was previously added via soft fork, and is therefore only available under the `softfork` operator. Its usage (both inside and outside the `softfork` guard) is described in [the Specification section of CHIP-36](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0036.md#specification). From 2832bf7c4f0bdc284b1e6c4a2c86f5167a408110 Mon Sep 17 00:00:00 2001 From: danieljperry Date: Wed, 11 Feb 2026 11:48:29 +0800 Subject: [PATCH 14/24] Clarify that the base filter reduces leverage, but doesn't eliminate it --- CHIPs/chip-0049.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index b8965b3c..3d566717 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -34,7 +34,7 @@ Both of these adjustments are detailed in the [Specification](#specification) se ## Backwards Compatibility This CHIP proposes a hard fork to upgrade the proof format. Hard forks relax rules. Blocks that are invalid by the existing rules will be considered valid by the new rules (and sometimes vice versa). The majority of nodes and netspace must be upgraded in order for a hard fork to succeed. There will be a window of several months prior to this CHIP's activation, giving farmers ample time to upgrade their software. -Even though the original plot format will be disabled by this CHIP, it will remain valid until the end of the phase-out period, which is [described](#phase-out-period) in detail below. +Even though the original plot format will be disabled by the hard fork, it will remain valid until the end of the phase-out period, which is [described](#phase-out-period) in detail below. ## Specification The specification for each of this CHIP’s features will be listed individually. @@ -262,7 +262,7 @@ Plot grinders can generate a plot ID without creating the plot, so they can grin #### New formula -In order to prevent the extra grinding leverage described above, the new Proof of Space protocol will change the formula to determine whether a plot passes the filter. We'll start with some definitions: +In order to reduce the extra grinding leverage described above, the new Proof of Space protocol will change the formula to determine whether a plot passes the filter. We'll start with some definitions: * `plot_group_id` -- the ID of the relevant plot * `group_strength` -- the strength of the plot group in bits (the group has a 1/2^z change of passing) @@ -280,10 +280,10 @@ def plot_id_check(plot_group_id, group_strength, meta_group, filter_challenge, c return hash(plot_group_id + filter_challenge) & mask == (challenge_index ^ meta_group) & mask ``` -The main two advantages of using this new formula are that it removes the potential extra leverage from plot grinding, and that it makes it possible to power down HDDs between times when they pass the filter. Both of these advantages are detailed below. +The main two advantages of using this new formula are that it reduces the potential extra leverage from plot grinding, and that it makes it possible to power down HDDs between times when they pass the filter. Both of these advantages are detailed below. -#### No extra leverage when grinding -By using the new formula, we can guarantee that a plot group won't pass the filter more than once every four signage points. This means that the extra leverage that could previously be gained from grinding a plot's ID is no longer applicable. Plot grinders will be able to create plots on the fly, but it won't be possible to have a multiplier effect. The new formula will therefore accomplish the original goal of the defunct [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). +#### Reduced leverage when grinding +By using the new formula, we can guarantee that a plot group won't pass the filter more than once every four signage points. This means that the extra leverage that could previously be gained from grinding a plot's ID is reduced by 75%. Plot grinders will be able to create plots on the fly, but it won't be possible to have a multiplier effect. The new formula will therefore accomplish the original goal of the defunct [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). #### Powering down HDDs In addition, it will now be possible to predict between 4 to 20 signage points (~37 seconds to three minutes) in advance when a plot group will pass the filter. This will make it possible to power down a hard drive most of the time, and only start it up in advance of the plot group passing the filter. A few guidelines should be followed in order to maximize the efficiency of this use case. From 85f08bd69e239747160adc9472486790a479b93c Mon Sep 17 00:00:00 2001 From: danieljperry Date: Wed, 11 Feb 2026 12:06:05 +0800 Subject: [PATCH 15/24] Clarify why there is a 75% reduction in leverage --- CHIPs/chip-0049.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index 3d566717..396b8a7d 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -283,7 +283,7 @@ def plot_id_check(plot_group_id, group_strength, meta_group, filter_challenge, c The main two advantages of using this new formula are that it reduces the potential extra leverage from plot grinding, and that it makes it possible to power down HDDs between times when they pass the filter. Both of these advantages are detailed below. #### Reduced leverage when grinding -By using the new formula, we can guarantee that a plot group won't pass the filter more than once every four signage points. This means that the extra leverage that could previously be gained from grinding a plot's ID is reduced by 75%. Plot grinders will be able to create plots on the fly, but it won't be possible to have a multiplier effect. The new formula will therefore accomplish the original goal of the defunct [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). +By using the new formula, we can guarantee that a plot group won't pass the filter more than once every four signage points. This means that the extra leverage that could previously be gained from grinding a plot's ID is reduced by 75%. Plot grinders will be able to create plots on the fly, but the only available multiplier effect will be to grind a plot ID that will pass the filter in one of the previous four signage points, as well as in one of the next four. The new formula will therefore accomplish the original goal of the defunct [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). #### Powering down HDDs In addition, it will now be possible to predict between 4 to 20 signage points (~37 seconds to three minutes) in advance when a plot group will pass the filter. This will make it possible to power down a hard drive most of the time, and only start it up in advance of the plot group passing the filter. A few guidelines should be followed in order to maximize the efficiency of this use case. From 1cb9dda58f589612f06bab8c6041c776225d0e87 Mon Sep 17 00:00:00 2001 From: danieljperry Date: Thu, 12 Feb 2026 15:20:32 +0800 Subject: [PATCH 16/24] Add info about including a CLVM cost when spending a coin --- CHIPs/chip-0049.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index 396b8a7d..93f5d38d 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -339,6 +339,32 @@ Usage: (sha256tree (TREE)) CLVM Cost: Variable -- `sha256tree` is the first CLVM operator whose parameter is a tree, which makes for more dimensions to consider for the cost model. See [our GitHub writeup](https://github.com/Chia-Network/clvm_rs/blob/7a2784b22093264e2c22e1cce606722db2d8ef3f/docs/sha256tree.md) for more information about how costing works for this operator. +### New secp operators + +The `secp256k1_verify` and `secp256r1_verify` operators were added to the CLVM as part of [CHIP-11](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0011.md). The opcodes for these operators are `0x13d61f00` and `0x1c3a8f00` respectively. These four-byte opcodes were chosen because they include constants for how much they should cost. + +In the 3.0 hard fork, we will reconfigure the cost of some CLVM opcodes. This gives us the opportunity to add new secp opcodes that are only one byte long. We will also preserve the original opcodes for backward compatibility. + +#### secp256k1_verify + +Opcode: [todo] + +Argument: [todo] + +Returns: [todo] + +Usage: [todo] + +#### secp256r1_verify + +Opcode: [todo] + +Argument: [todo] + +Returns: [todo] + +Usage: [todo] + ### Conditions with cost Currently, only `CREATE_COIN`, the `AGG_SIG_*`-family and `SOFTFORK` conditions have a cost. All other conditions are free and could therefore risk being DoS vectors. The full node currently limits the number of announce-family conditions per coin spend to 1024 (See [CHIP-25](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0025.md#clvm-cost)). Conditions in this family are expensive because they require memory allocation during validation. @@ -348,6 +374,14 @@ After the hard fork activates, the limit of 1024 announcement conditions per spe Instead, for each coin spend, conditions will have a cost of 500, **except** for the first 100 conditions, which will not incur an additional cost. This is in addition to any existing cost for the condition. This cost applies to all conditions, including unknown conditions, `SOFTFORK`, `CREATE_COIN` and `AGG_SIG_*` conditions. +### Create and spend coin costs + +Currently, the `CREATE_COIN` condition has a CLVM cost of 1.8 million, but there is no cost associated with spending a coin. The 3.0 fork will change this formula to make it more balanced. After the fork activates, the total cost will remain the same, but: +* `CREATE_COIN` will cost [todo] +* Spending a coin will cost [todo] + +The mempool will allow coins that were created before the fork's activation to be spent for the first [todo] blocks afterward without imposing an additional cost. From block [todo] onward, the cost of [todo] will be imposed on all coin spends. + ### New Weight Proof Commitments The 3.0 fork will include [new weight proof commitments](https://github.com/Chia-Network/chia-blockchain/pull/20340) that use Merkle Mountain Ranges for easier and faster validation. These include commitments to block headers, as well as to transaction blocks. The main things to be included are: * Linking the trunk to the Merkle root of foliage blocks across epochs From 8eec7675f725d7365c962a5660cb25dcc0efb899 Mon Sep 17 00:00:00 2001 From: danieljperry Date: Fri, 20 Feb 2026 11:03:16 +0800 Subject: [PATCH 17/24] CHIP cleanup --- CHIPs/chip-0049.md | 105 ++++++++++++++++++++++++++++++--------------- 1 file changed, 71 insertions(+), 34 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index 93f5d38d..ecf994f5 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -68,6 +68,19 @@ After 256 epochs after the fork's activation, no original proof will ever be val As for the new Proof of Space format, its value will be 100% beginning at the fork's activation. In other words, its win probability factor will be 1.000. There will be no planned phase-out (or phase-in) for the new format. +### Plot strength definition +As detailed in CHIP-48, every plot will include a “strength” parameter, which will adjust how much work is required to create the plot. If a given plot's strength is `n`, then creating the plot will require around `2^n` times more effort than the minimum. One caveat is that there is a small amount of overhead that remains constant at all levels. Because of this overhead, incrementing at the lowest levels will incur a bit less than double the work. At `strength = 5` and above, the overhead is negligible. + +At a given block height, the network will only accept plots that meet the current minimum strength threshold. + +By definition, `strength = 0` indicates the minimum compute required to create a plot, with no additional arbitrary computation. + +The maximum allowed strength will be 17 minus the number of bits in the base filter. For example, if the base filter is 512, then the number of bits in the base filter is 9 (`log(512)`). The maximum strength is therefore `17 - 9 = 8`. When the base filter reaches `1`, there will be `log(1) = 0` bits in the base filter, so it can't go any lower. + +Strength needs to be capped in order to ensure that the network's minimum spec hardware can validate a proof from a plot created at that strength in a timely manner. The assumption is that eventually the minimum spec hardware will also be increased as technology improves, but there isn't a preplanned date for this to occur. If a plot has a strength that is greater than the current maximum, then it will be considered invalid by the blockchain's consensus. + +As for the size of a plot, as well as the time/effort required for harvesting a plot, these are both minimally affected by the plot’s strength. + ### Protocol In both the original and new Proof of Space protocols, a `FullNode` object contains a `ProofOfSpace`, which has these fields: @@ -88,6 +101,15 @@ Note that the only valid k-size in the new Proof of Space on mainnet and testnet In addition, plots created for farming on a testnet will be incompatible with mainnet farming. When initiating the plot-creation process, users will need to designate whether the plot will be compatible with testnets or mainnet. +The FullNode will also need to be made aware of a plot's [strength](#plot-strength-definition), [plot_index](#plot-groups), and [meta_group](#meta-groups) parameters, each of which will be discussed later in this CHIP. Therefore, these parameters will be added to the [ProofOfSpace structure](https://github.com/Chia-Network/chia_rs/blob/3b53d490cfc2051c54a80b007823147a8dd2d1d4/crates/chia-protocol/src/proof_of_space.rs). + +#### Block hash computation +In the original Proof of Space, a block hash is computed by hashing all fields, in order and recursively, into the same SHA256 context. + +In Proof of Space v2, the proofs [hash a derived quality-string commitment](https://github.com/Chia-Network/chia_rs/pull/1350). The quality string itself is computed by concatenating the `plot_id`, `inferred k-size`, and the `proof validation`. + +Effectively, the block hash will now use a witness instead of hashing the aforementioned `ProofOfSpace` fields. This will allow us to prune certain data in the future. + ### Filter and strength adjustments We have two ways to future-proof the network against rental attacks, and plot grinding more generally: automatic reductions in the base filter, and manual increases in the network's minimum plot strength. Both of these will be detailed in this section. @@ -112,19 +134,6 @@ Read speeds of SSDs are much faster than those of HDDs, so farmers can safely pl ##### Plot stability The automatic reductions in the base filter should allow us to keep the minimum strength at `0` for ten years or more, barring unexpected advancements in technology. If all goes according to plan, then for the subsequent 21 years, we will rely on a combination of reducing the base filter and increasing the minimum strength. Finally, starting around 2057, plot stability will come entirely from plotting to a higher strength than the minimum. -#### Plot strength definition -As detailed in CHIP-48, every plot will include a “strength” parameter, which will adjust how much work is required to create the plot. If a given plot's strength is `n`, then creating the plot will require around `2^n` times more effort than the minimum. One caveat is that there is a small amount of overhead that remains constant at all levels. Because of this overhead, incrementing at the lowest levels will incur a bit less than double the work. At `strength = 5` and above, the overhead is negligible. - -At a given block height, the network will only accept plots that meet the current minimum strength threshold. - -By definition, `strength = 0` indicates the minimum compute required to create a plot, with no additional arbitrary computation. - -The maximum allowed strength will be 17 minus the number of bits in the base filter. For example, if the base filter is 512, then the number of bits in the base filter is 9 (`log(512)`). The maximum strength is therefore `17 - 9 = 8`. When the base filter reaches `1`, there will be `log(1) = 0` bits in the base filter, so it can't go any lower. - -Strength needs to be capped in order to ensure that the network's minimum spec hardware can validate a proof from a plot created at that strength in a timely manner. The assumption is that eventually the minimum spec hardware will also be increased as technology improves, but there isn't a preplanned date for this to occur. If a plot has a strength that is greater than the current maximum, then it will be considered invalid by the blockchain's consensus. - -As for the size of a plot, as well as the time/effort required for harvesting a plot, these are both minimally affected by the plot’s strength. - #### Effective filter definition Each plot will have its own `effective filter`, which determines the likelihood that it is eligible to participate in a challenge at a given signage point. The effective filter is calculated based on a given plot's strength. [CHIP-48](https://github.com/Chia-Network/chips/pull/160) provides the technical details. @@ -339,48 +348,58 @@ Usage: (sha256tree (TREE)) CLVM Cost: Variable -- `sha256tree` is the first CLVM operator whose parameter is a tree, which makes for more dimensions to consider for the cost model. See [our GitHub writeup](https://github.com/Chia-Network/clvm_rs/blob/7a2784b22093264e2c22e1cce606722db2d8ef3f/docs/sha256tree.md) for more information about how costing works for this operator. -### New secp operators +### Single-byte secp opcodes The `secp256k1_verify` and `secp256r1_verify` operators were added to the CLVM as part of [CHIP-11](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0011.md). The opcodes for these operators are `0x13d61f00` and `0x1c3a8f00` respectively. These four-byte opcodes were chosen because they include constants for how much they should cost. -In the 3.0 hard fork, we will reconfigure the cost of some CLVM opcodes. This gives us the opportunity to add new secp opcodes that are only one byte long. We will also preserve the original opcodes for backward compatibility. +In the 3.0 hard fork, we will reconfigure the cost of some CLVM opcodes. This gives us the opportunity to add new secp opcodes that are only one byte long. The operator names will remain the same. We will also preserve the original opcodes for backward compatibility. #### secp256k1_verify -Opcode: [todo] +Opcode: 64 + +Functionality: Verifies a signature that uses the secp256k1 curve + +Arguments: -Argument: [todo] +* `pubkey` -- the secp256k1 public key used for signing +* `msg_digest` -- the sha256 hash of the message that was signed +* `signature` -- the digital signature to verify -Returns: [todo] +Usage: `(secp256k1_verify pubkey msg_digest signature)` -Usage: [todo] +CLVM Cost: `1 300 000` #### secp256r1_verify -Opcode: [todo] +Opcode: 65 -Argument: [todo] +Functionality: Verifies a signature that uses the secp256r1 curve -Returns: [todo] +Arguments: -Usage: [todo] +* `pubkey` -- the secp256r1 public key used for signing +* `msg_digest` -- the sha256 hash of the message that was signed +* `signature` -- the digital signature to verify + +Usage: `(secp256r1_verify pubkey msg_digest signature)` + +CLVM Cost: `1 850 000` ### Conditions with cost Currently, only `CREATE_COIN`, the `AGG_SIG_*`-family and `SOFTFORK` conditions have a cost. All other conditions are free and could therefore risk being DoS vectors. The full node currently limits the number of announce-family conditions per coin spend to 1024 (See [CHIP-25](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0025.md#clvm-cost)). Conditions in this family are expensive because they require memory allocation during validation. With [Vaults](https://www.chia.net/2025/01/31/chia-vaults-a-secure-and-flexible-way-to-manage-your-digital-assets/), each coin spend requires a message to be sent from the vault to the coin. This makes the 1024 limit at risk of being hit by legitimate uses. -After the hard fork activates, the limit of 1024 announcement conditions per spend will be removed. - -Instead, for each coin spend, conditions will have a cost of 500, **except** for the first 100 conditions, which will not incur an additional cost. This is in addition to any existing cost for the condition. This cost applies to all conditions, including unknown conditions, `SOFTFORK`, `CREATE_COIN` and `AGG_SIG_*` conditions. +After the hard fork activates, the limit of 1024 `ANNOUNCEMENT` conditions per spend will be removed. -### Create and spend coin costs +Instead, for each coin spend, conditions will have a base cost of 500, **except** for the first 100 conditions, which will not incur an additional cost. This is in addition to any existing cost for the conditions. This cost applies to all conditions (except for `ANNOUNCEMENT` conditions, discussed below), including unknown conditions, `SOFTFORK`, `CREATE_COIN` and `AGG_SIG_*` conditions. -Currently, the `CREATE_COIN` condition has a CLVM cost of 1.8 million, but there is no cost associated with spending a coin. The 3.0 fork will change this formula to make it more balanced. After the fork activates, the total cost will remain the same, but: -* `CREATE_COIN` will cost [todo] -* Spending a coin will cost [todo] - -The mempool will allow coins that were created before the fork's activation to be spent for the first [todo] blocks afterward without imposing an additional cost. From block [todo] onward, the cost of [todo] will be imposed on all coin spends. +There is an exception to this rule. **All** `ANNOUNCEMENT` conditions will have a base cost of 500, including the first 100 conditions. This is in addition to any existing cost for the conditions. These conditions include: +* `CREATE_COIN_ANNOUNCEMENT` (opcode 60) +* `ASSERT_COIN_ANNOUNCEMENT` (opcode 61) +* `CREATE_PUZZLE_ANNOUNCEMENT` (opcode 62) +* `ASSERT_PUZZLE_ANNOUNCEMENT` (opcode 63) ### New Weight Proof Commitments The 3.0 fork will include [new weight proof commitments](https://github.com/Chia-Network/chia-blockchain/pull/20340) that use Merkle Mountain Ranges for easier and faster validation. These include commitments to block headers, as well as to transaction blocks. The main things to be included are: @@ -392,15 +411,33 @@ Before the new weight proofs can be used, there will need to be a transition poi After we can begin validating the new weight proofs (9-12 months after 3.0 is released), nodes and wallets won’t be required to sync. Their peers only will need to prove the peak height and its weight in order for their data to be proven trustworthy. The current requirement for block validation will instead become a recommendation. -### New Block Hash Computation +### Block Hash Generator In order to calculate block hashes, currently we hash the serialization blob of the block generator (a CLVM object). The 3.0 release will include an update to hash the generator as a sha256tree (just as we do with puzzle hashes), and then the particular serialization won’t matter. This will open the door to arbitrary compression mechanisms without forking. -Beginning in block `9'562'000`, the new block hash computation will be accepted. The old method will continue to be accepted until block [todo], after which it will be ignored. +| Aspect | Before | After | +| :--------- | :----------------------- | :---------------------- | +| Identity | SHA256(serialized_bytes) | SHA256_tree_hash(tree) | +| Cost basis | Serialized length | Interned tree structure | + +[Richard Kiss](https://github.com/richardkiss) has added the details of this specification to his GitHub Page: +* A [GitHub Gist](https://gist.github.com/richardkiss/59389ac2f96dd0665f2d7815baa7b30f) document summarizes these changes +* Also see the [technical specification](https://github.com/richardkiss/generator-identity-hf-analysis/blob/main/docs/GENERATOR_IDENTITY_HARDFORK.md) for these changes +* [Analysis and implementation](https://github.com/richardkiss/generator-identity-hf-analysis/?tab=readme-ov-file#installation) of the specification + +Beginning in block `9'562'000`, the new block hash computation will be accepted, and the old method will be ignored. The original CLVM cost of calculating the generator was `12'000 * len(blob)`. The new cost is `len(blob)`. +### Constrain block generators + +We have [added a new flag](https://github.com/Chia-Network/chia_rs/pull/1288) for `run_block_generator2()` which, before executing the block generator, ensures that it starts with a quote `(q or 1)`. This forces the generator to be a list, instead of an arbitrary program. + +This flag will be set at the hard fork's activation, at height `9'562'000`. After the flag is set, in addition to the block generators being constrained, we also won't pass in any block references nor the CLVM deserializer program when executing the generator. + +We will also [disallow block references](https://github.com/Chia-Network/chia-blockchain/pull/20218) in the hard fork, we have not used them, nor have we seen any benefit to using them. + ## Test Cases All relevant test cases are included in CHIP-48. From 5aef28b4624625fd398b810954fbd28c0b7ca04b Mon Sep 17 00:00:00 2001 From: danieljperry Date: Fri, 20 Feb 2026 14:12:52 +0800 Subject: [PATCH 18/24] More cleanup --- CHIPs/chip-0049.md | 74 ++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index ecf994f5..1cff7a15 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -32,9 +32,11 @@ We will future-proof the new format with two independent mechanisms: Both of these adjustments are detailed in the [Specification](#specification) section. ## Backwards Compatibility -This CHIP proposes a hard fork to upgrade the proof format. Hard forks relax rules. Blocks that are invalid by the existing rules will be considered valid by the new rules (and sometimes vice versa). The majority of nodes and netspace must be upgraded in order for a hard fork to succeed. There will be a window of several months prior to this CHIP's activation, giving farmers ample time to upgrade their software. +This CHIP proposes a hard fork to upgrade the proof format. Hard forks relax rules. Blocks that are invalid by the existing rules will be considered valid by the new rules (and sometimes vice versa). -Even though the original plot format will be disabled by the hard fork, it will remain valid until the end of the phase-out period, which is [described](#phase-out-period) in detail below. +To continue using Chia after the hard fork from this CHIP activates, full nodes, farmers, harvesters, pools, wallets, and other projects in the ecosystem will need to upgrade their software. In order to give everyone ample time to perform this upgrade, there will be a window of several months between the fork being added to version 3.0.0 and the fork's activation. + +Even though the original plot format will be disabled by the hard fork, it will remain valid until the end of the phase-out period, which is [described in detail](#phase-out-period) below. ## Specification The specification for each of this CHIP’s features will be listed individually. @@ -42,13 +44,15 @@ The specification for each of this CHIP’s features will be listed individually ### Fork activation We will release Chia version 3.0.0, which will implement the hard fork. The fork will activate in the block immediately following the first *transaction* block, with a later signage point, at or above height `9'562'000` (nine million, five hundred and sixty-two thousand). This is expected to happen around November 10, 2026, though it could drift a few days in either direction. -A single signage point may produce multiple blocks. If the block immediately following the transaction block at the activation height happens to be on the same signage point, it will also be pre-activation. The hard fork would then activate with the next signage point. +A single signage point may produce multiple blocks. If the block immediately following the transaction block at the activation height happens to be on the same signage point, it will also be pre-activation. The hard fork would then activate with the next signage point. Whenever the activation height is mentioned in this CHIP, it will follow the same logic as described here. Starting with the block in which the hard fork is activated, the new Proof of Space will be accepted. This hard fork is different from previous forks in that it affects the validity of Proofs of Space. When farming a block, the harvester does not know (exactly) at what height its proof may be infused. However, it *can* know what the most recent transaction block was. ### Phase-out period +The phase-out period will begin when the fork is activated, and will end 256 epochs later. + During the phase-out period, original Proofs of Space will become less likely to win a block over time. The probability of winning a block will be scaled down, linearly, starting at the activation block, to reach 0 probability after 256 days (technically, 4608 x 256 blocks). In order to validate a PoS v1 proof after the hard fork has activated, we will look at the last byte of the quality string, and filter it based on the number of epochs since activation. We don't track the actual epoch; we just divide the number of blocks since activation by 4608 (the number of blocks per epoch). @@ -75,7 +79,7 @@ At a given block height, the network will only accept plots that meet the curren By definition, `strength = 0` indicates the minimum compute required to create a plot, with no additional arbitrary computation. -The maximum allowed strength will be 17 minus the number of bits in the base filter. For example, if the base filter is 512, then the number of bits in the base filter is 9 (`log(512)`). The maximum strength is therefore `17 - 9 = 8`. When the base filter reaches `1`, there will be `log(1) = 0` bits in the base filter, so it can't go any lower. +The maximum allowed strength will be 17 minus the number of bits in the base filter ([described below](#base-filter-definition-and-plan)). For example, if the base filter is 512, then the number of bits in the base filter is 9 (`log(512)`). The maximum strength is therefore `17 - 9 = 8`. When the base filter reaches `1`, there will be `log(1) = 0` bits in the base filter, so it can't go any lower. Strength needs to be capped in order to ensure that the network's minimum spec hardware can validate a proof from a plot created at that strength in a timely manner. The assumption is that eventually the minimum spec hardware will also be increased as technology improves, but there isn't a preplanned date for this to occur. If a plot has a strength that is greater than the current maximum, then it will be considered invalid by the blockchain's consensus. @@ -89,24 +93,18 @@ size: u8, proof: Bytes, ``` -In the original format, `size` is not allowed to be less than 32 or greater than 50. Therefore, only the six least significant bits can be used, and the two most significant bits are meaningless. - -After the hard fork activates, the most significant bit in the `size` field will indicate whether the proof is of the original Proof of Space (0) or the new Proof of Space (1). +The only valid k-size in the new Proof of Space on mainnet and testnets is k28 (around 1 GB per plot). The `size` field will continue to be used for PoS v1 proofs without modification. For PoS2 v2 proofs, it will be set to `0` (it is not needed). -The remaining 7 bits will indicate either: -* The k-size of the plot that produced the proof (original Proof of Space), or -* The strength of the plot that produced the proof (new Proof of Space) +Note that simulators can use other sizes; CNI's simulator code will use k18 (around 1 MB per plot). -Note that the only valid k-size in the new Proof of Space on mainnet and testnets is k28 (around 1 GB per plot). Simulators can use other sizes; CNI's simulator code will use k18 (around 1 MB per plot). +In addition, PoS v2 plots created for farming on a testnet will be incompatible with mainnet farming. When initiating the plot-creation process, users will need to designate whether the plot will be compatible with testnets or mainnet. -In addition, plots created for farming on a testnet will be incompatible with mainnet farming. When initiating the plot-creation process, users will need to designate whether the plot will be compatible with testnets or mainnet. - -The FullNode will also need to be made aware of a plot's [strength](#plot-strength-definition), [plot_index](#plot-groups), and [meta_group](#meta-groups) parameters, each of which will be discussed later in this CHIP. Therefore, these parameters will be added to the [ProofOfSpace structure](https://github.com/Chia-Network/chia_rs/blob/3b53d490cfc2051c54a80b007823147a8dd2d1d4/crates/chia-protocol/src/proof_of_space.rs). +For PoS v2, the `FullNode` object will also need to be made aware of a plot's [strength](#plot-strength-definition), [plot_index](#plot-groups), and [meta_group](#meta-groups) parameters, each of which will be discussed later in this CHIP. These parameters will be added to the [ProofOfSpace structure](https://github.com/Chia-Network/chia_rs/blob/3b53d490cfc2051c54a80b007823147a8dd2d1d4/crates/chia-protocol/src/proof_of_space.rs). #### Block hash computation -In the original Proof of Space, a block hash is computed by hashing all fields, in order and recursively, into the same SHA256 context. +In PoS v1, a block hash is computed by hashing all fields, in order and recursively, into the same SHA256 context. -In Proof of Space v2, the proofs [hash a derived quality-string commitment](https://github.com/Chia-Network/chia_rs/pull/1350). The quality string itself is computed by concatenating the `plot_id`, `inferred k-size`, and the `proof validation`. +In PoS v2, the proofs [hash a derived quality-string commitment](https://github.com/Chia-Network/chia_rs/pull/1350). The quality string itself is computed by concatenating the `plot_id`, `inferred k-size`, and the `proof validation`. Effectively, the block hash will now use a witness instead of hashing the aforementioned `ProofOfSpace` fields. This will allow us to prune certain data in the future. @@ -115,7 +113,7 @@ We have two ways to future-proof the network against rental attacks, and plot gr #### Filter definition -At every signage point, a certain number of plots are excluded from participating in the challenge. In the original Proof of Space protocol, this was known as the `plot filter`, and is described in [our documentation](https://docs.chia.net/chia-blockchain/consensus/chains/signage-and-infusion-points/). In the new Proof of Space protocol, there are two related filters to consider: the network's base filter, and the effective filter for a plot or a group (see below for more info on [plot groups](#plot-groups)). +At every signage point, a certain number of plots are excluded from participating in the challenge. In the original Proof of Space protocol, this was known as the `plot filter`, and is described in [our documentation](https://docs.chia.net/chia-blockchain/consensus/chains/signage-and-infusion-points/). In the new Proof of Space protocol, there are two related filters to consider: the network's [base filter](#base-filter-definition-and-plan), and the effective filter for a plot or a group (see below for more info on [plot groups](#plot-groups)). #### Base filter definition and plan The base filter indicates the lowest filter allowed for all plots across the network. This filter will start `512` and will automatically be adjusted downward every 3-6 years at pre-defined block heights, until it reaches `1`. It will remain at `1` thereafter. @@ -127,7 +125,7 @@ Cutting the base filter in half will have two impacts for all farmers: higher [d ##### Disk usage Each time the base filter is cut in half, the likelihood that a plot will pass it is doubled. The load on individual disks will therefore roughly double as well. -HDDs can operate at 20% of their read capacity without significantly shortening their life expectancy. The base filter will be cut in half two times over the course of nine years, so if a farmer expects their disks to last for nine years, then they should plot so that their disks initially run at 5% of their read capacity or lower. That way, their disks will never run at more than 20% of their read capacity, so they will remain viable for farming for their entire life expectancy. +HDDs can operate at 20% of their read capacity without significantly shortening their life expectancy. The base filter will be cut in half two times over the course of the first nine years after the fork activates, so if a farmer expects their disks to last for nine years, then they should plot so that their disks initially run at 5% of their read capacity or lower. That way, their disks will never run at more than 20% of their read capacity, so they will remain viable for farming for their entire life expectancy. Read speeds of SSDs are much faster than those of HDDs, so farmers can safely plot their SSDs at the minimum strength without running into issues related to high disk usage. However, they should still keep in mind that any plots created at the minimum strength will no longer be valid after the minimum strength is increased. A rough plan for these increases is [covered later](#minimum-strength-plan). @@ -138,20 +136,24 @@ The automatic reductions in the base filter should allow us to keep the minimum Each plot will have its own `effective filter`, which determines the likelihood that it is eligible to participate in a challenge at a given signage point. The effective filter is calculated based on a given plot's strength. [CHIP-48](https://github.com/Chia-Network/chips/pull/160) provides the technical details. The formula to calculate a given plot's effective filter is: -`effective filter = base filter * (2^(plot strength - min strength))` +`effective filter = base filter * (2 ^ (plot strength - min strength))` + +For each level that a given plot's strength is higher than the network's minimum strength, the plot's effective filter will be doubled, until the [maximum effective filter](#maximum-effective-filter) is reached. + +#### Maximum effective filter -For each level that a given plot's strength is higher than the network's base strength, the plot's effective filter will be doubled. However, the maximum `effective filter` is `8192`, regardless of the plot's strength. +The `maximum effective filter` is `8192`, regardless of the plot's strength. This is imposed to prevent certain attacks that could occur with very high strengths. -For example, if the network's `base filter` is `512` and the `minimum strength` is `0`, then a plot created at `strength = 5` should have an `effective filter` of `512 * (2^(5-0)) = 16,384`. However, due to the maximum filter size, the plot's `effective filter` will be `8192` for this plot. If the network's `minimum strength` is later raised to `1`, then the same plot will have an `effective filter` of `512 * (2^(5-1)) = 8192`. +For example, if the network's `base filter` is `512` and the `minimum strength` is `0`, then a plot created at `strength = 5` should have an `effective filter` of `512 * (2 ^ (5 - 0)) = 16,384`. However, due to the `maximum effective filter`, this plot's `effective filter` will be `8192`. If the network's `minimum strength` is later raised to `1`, then the same plot will have an `effective filter` of `512 * (2 ^ (5 - 1)) = 8192`. Some farmers may therefore choose to plot to a high strength in order to preserve the `effective filter` of `8192` even after the network's `minimum strength` is raised. #### Minimum strength plan The network's minimum strength will start at `0`, and will be adjusted upward as needed. Adjusting the minimum strength will require a soft fork. We won't plan to increase the minimum strength for the first ten years after the PoS2 fork activates, barring any unexpected advancements in technology. -The minimum strength should only ever be increased with time. It can be increased by any integer, but typically we will only increase it by 1 in a given soft fork (we could also build in multiple future increases with a single fork). Because any plots with the current minimum strength will need to be recreated when the minimum strength is increased, we plan provide a lengthy warning (perhaps six or twelve months) for a fork that increases the minimum strength to activate. +The minimum strength should only ever be _increased_ with time. It can be increased by any integer, but typically we will only increase it by 1 in a given soft fork (we could also build in multiple future increases with a single fork). Because any plots with the current minimum strength will need to be recreated when the minimum strength is increased, we plan provide a lengthy warning (perhaps six or twelve months) for a fork that increases the minimum strength to activate. -In order to decrease their number of expected replots, some farmers might initially choose to plot to a high strength than the minimum. In order to keep up with advancements in technology, we might need to increase the minimum strength every two years (though keep in mind that this is a rough estimate). +In order to decrease their number of expected replots, some farmers might initially choose to plot to a higher strength than the minimum. In order to keep up with advancements in technology, we might need to increase the minimum strength every two years after the initial increase (though keep in mind that this is a rough estimate). One thing to note is that a given farm can contain plots with various strength levels. Some farmers may choose a strategy of plotting their entire farm at the minimum current strength, and then gradually replacing their plots with higher-strength plots over time. @@ -162,7 +164,7 @@ The network's base filter will start at `512` and will be cut in half every 3-6 The maximum strength will be 17 minus the number of bits in the base filter. The maximum strength will increase every 3-6 years as the base filter falls. -The maximum effective filter for any individual plot is always `8192`, regardless of its strength. If a plot was created at a high enough strength that this number should be greater than `8192`, then it will automatically be capped. This is done to prevent certain attacks that could occur with very high strengths. +The maximum effective filter for any individual plot is always `8192`, regardless of its strength. If a plot was created at a high enough strength that this number should be greater than `8192`, then it will automatically be capped. The following table shows the block height for each built-in adjustment to the base filter, as well as the corresponding maximum strength at that base filter. The block height from 2026 was pre-determined. The subsequent block heights were calculated with the following formula (the calculation for 2032 is shown at each step of the way): * multiply 365 by 3 (or 6) @@ -193,7 +195,7 @@ The following table shows the block height for each built-in adjustment to the b The first built-in reduction in the base filter will occur six years after the fork is activated. The subsequent built-in reductions will occur every three years thereafter by default. This is a somewhat aggressive schedule to keep up with advancing technology. In the scenario where we feel comfortable with delaying these reductions, we will do so with a soft fork. -As a reminder, the minimum strength will start at `0` and will be increased via a soft fork as needed. We won't plan to increase the minimum strength until at least 2036 (10 years after the 3.0 release), though this is subject to change. If/when we do decide to increase the minimum strength, we will provide a window of _at least_ 90 days so that any plots at the current minimum will have time to be upgraded before they become invalid. While 90 days is the minimum warning when increasing the minimum strength, we will do our best to provide 6-12 months' warning whenever possible. +As a reminder, the minimum strength will start at `0` and will be increased via a soft fork as needed. We won't plan to increase the minimum strength until at least 2036 (10 years after the 3.0 release), though this is subject to change. If/when we do decide to increase the minimum strength, we will do our best to provide a warning of 6-12 months so that any plots at the current minimum will have time to be upgraded before they become invalid. The following table shows some hypothetical adjustments to the original strength, along with the built-in adjustments to the base filter. In this scenario, we will increase the minimum strength every two years, starting in 2036. In certain years in this table, both the base filter and minimum strength will be adjusted at the same block. Keep in mind that the strength adjustments will only be undertaken as needed, so this is only an example to illustrate how the adjustments might look. The second column from the right shows the effective filter for a plot created at `strength = 5`, and the rightmost column shows how often that plot will pass the filter, on average. @@ -274,7 +276,7 @@ Plot grinders can generate a plot ID without creating the plot, so they can grin In order to reduce the extra grinding leverage described above, the new Proof of Space protocol will change the formula to determine whether a plot passes the filter. We'll start with some definitions: * `plot_group_id` -- the ID of the relevant plot -* `group_strength` -- the strength of the plot group in bits (the group has a 1/2^z change of passing) +* `group_strength` -- the strength of the plot group in bits (the group has a `1 / 2 ^ z` chance of passing) * `meta_group` -- used to make sure the load from different plot groups is spread out * `filter_challenge` -- the value from the relevant signage point for the window from 4 signage points before the beginning * `challenge_index` -- the position in the window, from 0-15 @@ -328,11 +330,11 @@ Note that even though most of the signage points will no longer determine whethe This section will describe the updates that will go into the hard fork, but are not part of the new Proof of Space protocol. ### keccak256 -The `keccak256` operator was previously added via soft fork, and is therefore only available under the `softfork` operator. Its usage (both inside and outside the `softfork` guard) is described in [the Specification section of CHIP-36](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0036.md#specification). +The `keccak256` operator was previously added via soft fork, and is therefore only available from inside the `softfork` guard. Its usage is described in [the Specification section of CHIP-36](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0036.md#specification). -The hard fork gives us the opportunity to promote `keccak256` to be allowed outside the `softfork` guard. This makes it easier to use. +The hard fork gives us the opportunity to promote `keccak256` to be available from outside the `softfork` guard. This makes it easier to use. -After block `9'562'000`, the `keccak256` operator will become part of the core CLVM, so it will be usable by calling it directly. It will also continue to be usable from inside the `softfork` guard. +After the hard fork activates, the `keccak256` operator will become part of the core CLVM, so it will be available by calling it directly. It will also continue to be available from inside the `softfork` guard. ### sha256tree Many puzzles use the [sha256tree](https://github.com/Chia-Network/chia_puzzles/blob/0b46a6ebfc3b432d68edf9b91e6cef0ec13da2e7/puzzles/sha256tree.clib) library, which calculates the puzzle hash of a given puzzle program. This library is used so frequently, in fact, that it makes sense to include it as a native CLVM operator in the hard fork. Another advantage of including `sha256tree` in the CLVM is that it will be cheaper to call, both in terms of CPU compute and CLVM cost. Finally, a native operator also opens the door to future optimizations via caching. @@ -389,11 +391,11 @@ CLVM Cost: `1 850 000` ### Conditions with cost Currently, only `CREATE_COIN`, the `AGG_SIG_*`-family and `SOFTFORK` conditions have a cost. All other conditions are free and could therefore risk being DoS vectors. The full node currently limits the number of announce-family conditions per coin spend to 1024 (See [CHIP-25](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0025.md#clvm-cost)). Conditions in this family are expensive because they require memory allocation during validation. -With [Vaults](https://www.chia.net/2025/01/31/chia-vaults-a-secure-and-flexible-way-to-manage-your-digital-assets/), each coin spend requires a message to be sent from the vault to the coin. This makes the 1024 limit at risk of being hit by legitimate uses. +With [Vaults](https://www.chia.net/2025/01/31/chia-vaults-a-secure-and-flexible-way-to-manage-your-digital-assets/), each coin spend requires a message to be sent from the vault to the coin. This puts the 1024 limit at risk of being hit by legitimate uses. After the hard fork activates, the limit of 1024 `ANNOUNCEMENT` conditions per spend will be removed. -Instead, for each coin spend, conditions will have a base cost of 500, **except** for the first 100 conditions, which will not incur an additional cost. This is in addition to any existing cost for the conditions. This cost applies to all conditions (except for `ANNOUNCEMENT` conditions, discussed below), including unknown conditions, `SOFTFORK`, `CREATE_COIN` and `AGG_SIG_*` conditions. +Instead, for each coin spend, conditions will have a base cost of 500, **except** for the first 100 conditions, which will not incur a base cost. This is in addition to any existing cost for the conditions. This cost applies to all conditions (except for `ANNOUNCEMENT` conditions, discussed below), including unknown conditions, `SOFTFORK`, `CREATE_COIN` and `AGG_SIG_*` conditions. There is an exception to this rule. **All** `ANNOUNCEMENT` conditions will have a base cost of 500, including the first 100 conditions. This is in addition to any existing cost for the conditions. These conditions include: * `CREATE_COIN_ANNOUNCEMENT` (opcode 60) @@ -407,7 +409,7 @@ The 3.0 fork will include [new weight proof commitments](https://github.com/Chia * Adding to a Merkle Mountain Range of transaction blocks within sub-epochs * Adding commitments to the root of subslots, including the number of blocks per branch for epochs -Before the new weight proofs can be used, there will need to be a transition point between the old and new proofs. This will necessitate that both formats work simultaneously for some time. The current proposal is to put in a checkpoint some time after the 3.0 fork activates, and wait enough time before we use the new weight proof so that everyone agrees on the past before the checkpoint. +Before the new weight proofs can be used, there will need to be a transition point between the old and new proofs. This will necessitate that both formats work simultaneously for some time. We will put in a checkpoint after the 3.0 fork activates, and wait enough time before we use the new weight proof so that everyone agrees on the past before the checkpoint. After we can begin validating the new weight proofs (9-12 months after 3.0 is released), nodes and wallets won’t be required to sync. Their peers only will need to prove the peak height and its weight in order for their data to be proven trustworthy. The current requirement for block validation will instead become a recommendation. @@ -422,11 +424,11 @@ The 3.0 release will include an update to hash the generator as a sha256tree (ju | Cost basis | Serialized length | Interned tree structure | [Richard Kiss](https://github.com/richardkiss) has added the details of this specification to his GitHub Page: -* A [GitHub Gist](https://gist.github.com/richardkiss/59389ac2f96dd0665f2d7815baa7b30f) document summarizes these changes -* Also see the [technical specification](https://github.com/richardkiss/generator-identity-hf-analysis/blob/main/docs/GENERATOR_IDENTITY_HARDFORK.md) for these changes +* [GitHub Gist](https://gist.github.com/richardkiss/59389ac2f96dd0665f2d7815baa7b30f) document summarizing these changes +* [Technical specification](https://github.com/richardkiss/generator-identity-hf-analysis/blob/main/docs/GENERATOR_IDENTITY_HARDFORK.md) for these changes * [Analysis and implementation](https://github.com/richardkiss/generator-identity-hf-analysis/?tab=readme-ov-file#installation) of the specification -Beginning in block `9'562'000`, the new block hash computation will be accepted, and the old method will be ignored. +Beginning at the hard fork's activation block, the new block hash computation will be accepted, and the old method will be ignored. The original CLVM cost of calculating the generator was `12'000 * len(blob)`. The new cost is `len(blob)`. @@ -434,7 +436,7 @@ The original CLVM cost of calculating the generator was `12'000 * len(blob)`. Th We have [added a new flag](https://github.com/Chia-Network/chia_rs/pull/1288) for `run_block_generator2()` which, before executing the block generator, ensures that it starts with a quote `(q or 1)`. This forces the generator to be a list, instead of an arbitrary program. -This flag will be set at the hard fork's activation, at height `9'562'000`. After the flag is set, in addition to the block generators being constrained, we also won't pass in any block references nor the CLVM deserializer program when executing the generator. +This flag will be set at the hard fork's activation. After the flag is set, in addition to the block generators being constrained, we also won't pass in any block references nor the CLVM deserializer program when executing the generator. We will also [disallow block references](https://github.com/Chia-Network/chia-blockchain/pull/20218) in the hard fork, we have not used them, nor have we seen any benefit to using them. From e2e361689f0e9edf92302e21f7486f17af2c9deb Mon Sep 17 00:00:00 2001 From: danieljperry Date: Mon, 23 Feb 2026 15:26:54 +0800 Subject: [PATCH 19/24] Respond to comments --- CHIPs/chip-0049.md | 157 +++++++++++++++++++++++---------------------- 1 file changed, 82 insertions(+), 75 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index 1cff7a15..e38bb910 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -12,10 +12,10 @@ Created | 2025-05-19 Requires | [0048](https://github.com/Chia-Network/chips/pull/160) ## Abstract -[CHIP-48](https://github.com/Chia-Network/chips/pull/160), which introduces the new Proof of Space format (PoS v2), requires a hard fork of the Chia blockchain. This document describes how PoS v2 will be integrated with the blockchain, as well as how original plots will be phased out. This CHIP also proposes a few other hard-fork changes, unrelated to the new proof format. +[CHIP-48](https://github.com/Chia-Network/chips/pull/160), which introduces the new Proof of Space format (PoS v2), requires a hard fork of the Chia blockchain. This document describes how PoS v2 will be integrated with the blockchain, as well as how original plots will be phased out. This CHIP also proposes a few other hard-fork changes, unrelated to PoS v2. ## Motivation -The current Proof of Space format (PoS v1) was released in July 2020, during the Chia blockchain’s beta phase. Today, the format remains secure. However, two broad issues exist, one of which is still hypothetical, and the other of which is already in production. +The current Proof of Space format (PoS v1) was released in July 2020, during the Chia blockchain’s beta phase. Today, PoS v1 remains secure. However, two broad issues exist, one of which is still hypothetical, and the other of which is already in production. The hypothetical issue is plot grinding. This is where a farmer creates an entire plot and submits a proof within around 28 seconds. Plot grinding is described in detail in [CHIP-12](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0012.md). @@ -23,20 +23,20 @@ The other issue is plot "compression," where bits are dropped during a plot's cr Neither of these issues is an attack on the network itself, but in both cases, they make time-space tradeoffs, which cause the network's Proof of Space consensus to resemble Proof of Work (PoW). As a consequence, the network uses more compute than what was originally intended. -In the first half of 2024, we made the decision to sunset the existing proof format in favor of a new one that will be significantly more resilient to bit dropping and other time-space tradeoffs. Farmers will need to replace their existing plots with new ones, so we have built this format with minimizing future disruptions in mind. +In the first half of 2024, we made the decision to sunset PoS v1 in favor of a new format that will be significantly more resilient to bit dropping and other time-space tradeoffs. Farmers will need to replace their existing plots with new ones, so we have built PoS v2 with minimizing future disruptions in mind. -We will future-proof the new format with two independent mechanisms: +We will future-proof PoS v2 with two independent mechanisms: 1. Automatically reducing the network's base filter (can be delayed with a soft fork) 2. Manually increasing the network's minimum plot strength (a soft fork) Both of these adjustments are detailed in the [Specification](#specification) section. ## Backwards Compatibility -This CHIP proposes a hard fork to upgrade the proof format. Hard forks relax rules. Blocks that are invalid by the existing rules will be considered valid by the new rules (and sometimes vice versa). +This CHIP proposes a hard fork to upgrade PoS v1. Hard forks relax rules. Blocks that are invalid by the existing rules will be considered valid by the new rules (and sometimes vice versa). To continue using Chia after the hard fork from this CHIP activates, full nodes, farmers, harvesters, pools, wallets, and other projects in the ecosystem will need to upgrade their software. In order to give everyone ample time to perform this upgrade, there will be a window of several months between the fork being added to version 3.0.0 and the fork's activation. -Even though the original plot format will be disabled by the hard fork, it will remain valid until the end of the phase-out period, which is [described in detail](#phase-out-period) below. +Even though PoS v1 will be disabled by the hard fork, it will remain valid until the end of the phase-out period, which is [described in detail](#phase-out-period) below. ## Specification The specification for each of this CHIP’s features will be listed individually. @@ -46,18 +46,18 @@ We will release Chia version 3.0.0, which will implement the hard fork. The fork A single signage point may produce multiple blocks. If the block immediately following the transaction block at the activation height happens to be on the same signage point, it will also be pre-activation. The hard fork would then activate with the next signage point. Whenever the activation height is mentioned in this CHIP, it will follow the same logic as described here. -Starting with the block in which the hard fork is activated, the new Proof of Space will be accepted. +Starting with the block in which the hard fork is activated, PoS v2 will be accepted. This hard fork is different from previous forks in that it affects the validity of Proofs of Space. When farming a block, the harvester does not know (exactly) at what height its proof may be infused. However, it *can* know what the most recent transaction block was. ### Phase-out period The phase-out period will begin when the fork is activated, and will end 256 epochs later. -During the phase-out period, original Proofs of Space will become less likely to win a block over time. The probability of winning a block will be scaled down, linearly, starting at the activation block, to reach 0 probability after 256 days (technically, 4608 x 256 blocks). +During the phase-out period, plots created with PoS v1 will become less likely to win a block over time. The probability of winning a block will be scaled down, linearly, starting at the activation block, to reach 0 probability after 256 days (technically, 4608 x 256 blocks). In order to validate a PoS v1 proof after the hard fork has activated, we will look at the last byte of the quality string, and filter it based on the number of epochs since activation. We don't track the actual epoch; we just divide the number of blocks since activation by 4608 (the number of blocks per epoch). -After 256 epochs after the fork's activation, no original proof will ever be valid. This ends the phase-out period and effectively disables the original Proof of Space. +After 256 epochs after the fork's activation, no original proof will ever be valid. This ends the phase-out period and effectively disables PoS v1. | Blocks w/prev. TX block >= | epochs | Win prob. factor | |:-------------------------- | :----- | :--------------- | @@ -70,10 +70,10 @@ After 256 epochs after the fork's activation, no original proof will ever be val | 10737040 | 255 | 0.004 | | 10741648 | 256 | 0.000 | -As for the new Proof of Space format, its value will be 100% beginning at the fork's activation. In other words, its win probability factor will be 1.000. There will be no planned phase-out (or phase-in) for the new format. +As for PoS v2, its value will be 100% beginning at the fork's activation. In other words, its win probability factor will be 1.000. There will be no planned phase-out (or phase-in) for PoS v2. ### Plot strength definition -As detailed in CHIP-48, every plot will include a “strength” parameter, which will adjust how much work is required to create the plot. If a given plot's strength is `n`, then creating the plot will require around `2^n` times more effort than the minimum. One caveat is that there is a small amount of overhead that remains constant at all levels. Because of this overhead, incrementing at the lowest levels will incur a bit less than double the work. At `strength = 5` and above, the overhead is negligible. +As detailed in CHIP-48, every plot will include a “strength” parameter, which will adjust how much work is required to create the plot. If a given plot's strength is `n`, then creating the plot will require around `2^n` times more effort than the minimum. One caveat is that there is a small amount of overhead that remains constant at all levels. Because of this overhead, incrementing strength at the lowest levels will incur a bit less than double the work. At `strength = 5` and above, the overhead is negligible. At a given block height, the network will only accept plots that meet the current minimum strength threshold. @@ -87,13 +87,13 @@ As for the size of a plot, as well as the time/effort required for harvesting a ### Protocol -In both the original and new Proof of Space protocols, a `FullNode` object contains a `ProofOfSpace`, which has these fields: +In both PoS v1 and v2, a `FullNode` object contains a `ProofOfSpace`, which has these fields: ``` size: u8, proof: Bytes, ``` -The only valid k-size in the new Proof of Space on mainnet and testnets is k28 (around 1 GB per plot). The `size` field will continue to be used for PoS v1 proofs without modification. For PoS2 v2 proofs, it will be set to `0` (it is not needed). +The only valid k-size in PoS v2 on mainnet and testnets is k28 (around 1 GB per plot). The `size` field will continue to be used for PoS v1 proofs without modification. For PoS2 v2 proofs, it will be set to `0` (it is not needed). Note that simulators can use other sizes; CNI's simulator code will use k18 (around 1 MB per plot). @@ -113,19 +113,23 @@ We have two ways to future-proof the network against rental attacks, and plot gr #### Filter definition -At every signage point, a certain number of plots are excluded from participating in the challenge. In the original Proof of Space protocol, this was known as the `plot filter`, and is described in [our documentation](https://docs.chia.net/chia-blockchain/consensus/chains/signage-and-infusion-points/). In the new Proof of Space protocol, there are two related filters to consider: the network's [base filter](#base-filter-definition-and-plan), and the effective filter for a plot or a group (see below for more info on [plot groups](#plot-groups)). +At every signage point, a certain number of plots are excluded from participating in the challenge. In PoS v1, this was known as the `plot filter`, and is described in [our documentation](https://docs.chia.net). In PoS v2, there are two related filters to consider: the network's [base filter](#base-filter-definition-and-plan), and the effective filter for a plot or a group (see below for more info on [plot groups](#plot-groups)). #### Base filter definition and plan -The base filter indicates the lowest filter allowed for all plots across the network. This filter will start `512` and will automatically be adjusted downward every 3-6 years at pre-defined block heights, until it reaches `1`. It will remain at `1` thereafter. +The base filter indicates the lowest filter allowed for all plots across the network. This filter will start `512` and will automatically be adjusted downward every 3-6 years at pre-defined block heights, until it reaches `1`, where it will remain. + +The first built-in reduction for the base filter will occur six years after the fork is activated. The subsequent built-in reductions will occur every three years thereafter by default. See the [filter reduction table](#filter-reduction-table) for the exact block heights for these reductions. The reason to reduce the base filter over time is to decrease the leverage a rental attacker is able to gain. This topic is covered extensively in [CHIP-12](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0012.md). In summary, a rental attacker can opt to exclusively create plots that will pass the filter, so the amount of space they are able to spoof is multiplied by a given plot's effective filter ([described below](#effective-filter-definition)). As GPUs become faster, we can protect the network against rental attacks by proactively reducing the base filter. We also can protect against rental attacks by increasing the minimum plot strength, which will be [covered later](#minimum-strength-plan). -Cutting the base filter in half will have two impacts for all farmers: higher [disk usage](#disk-usage), and longer [plot stability](#plot-stability). +This built-in filter reduction schedule is intentionally aggressive in order to keep up with advancing technology. In the scenario where we feel comfortable with delaying these reductions, we will do so with a soft fork. + +Cutting the base filter in half will have two impacts for all farmers: higher [disk usage](#disk-usage) and increased [plot stability](#plot-stability). ##### Disk usage -Each time the base filter is cut in half, the likelihood that a plot will pass it is doubled. The load on individual disks will therefore roughly double as well. +Each time the base filter is cut in half, the likelihood that a plot will pass it is doubled. The workload on individual disks will therefore roughly double as well. The life expectancy of HDDs depends on many factors, including workload, temperature, and environment. See our [blog post](https://www.chia.net/2021/12/16/how-do-hard-drives-fail/) on this topic for more info. -HDDs can operate at 20% of their read capacity without significantly shortening their life expectancy. The base filter will be cut in half two times over the course of the first nine years after the fork activates, so if a farmer expects their disks to last for nine years, then they should plot so that their disks initially run at 5% of their read capacity or lower. That way, their disks will never run at more than 20% of their read capacity, so they will remain viable for farming for their entire life expectancy. +While the minimum strength will be suitable for many HDDs, farmers should still consider the extra workload that will be incurred when the base filter is reduced. For example, because the base filter will be cut in half two times over the course of the first nine years after the fork activates, if a farmer expects their disks to last for nine years, then they should keep in mind that their disks' workload will be four times as heavy at the end of their expected lifespan as it was when the plots were created. Based on these factors, some farmers may choose to plot their HDDs at higher strengths than the minimum. Read speeds of SSDs are much faster than those of HDDs, so farmers can safely plot their SSDs at the minimum strength without running into issues related to high disk usage. However, they should still keep in mind that any plots created at the minimum strength will no longer be valid after the minimum strength is increased. A rough plan for these increases is [covered later](#minimum-strength-plan). @@ -151,7 +155,7 @@ Some farmers may therefore choose to plot to a high strength in order to preserv #### Minimum strength plan The network's minimum strength will start at `0`, and will be adjusted upward as needed. Adjusting the minimum strength will require a soft fork. We won't plan to increase the minimum strength for the first ten years after the PoS2 fork activates, barring any unexpected advancements in technology. -The minimum strength should only ever be _increased_ with time. It can be increased by any integer, but typically we will only increase it by 1 in a given soft fork (we could also build in multiple future increases with a single fork). Because any plots with the current minimum strength will need to be recreated when the minimum strength is increased, we plan provide a lengthy warning (perhaps six or twelve months) for a fork that increases the minimum strength to activate. +The minimum strength should only ever be _increased_ with time. It can be increased by any integer, but typically we will only increase it by 1 in a given soft fork (we could also build in multiple future increases with a single fork). Because any plots with the current minimum strength will need to be recreated when the minimum strength is increased, we plan to provide a lengthy warning (perhaps six or twelve months) for a fork that increases the minimum strength to activate. In order to decrease their number of expected replots, some farmers might initially choose to plot to a higher strength than the minimum. In order to keep up with advancements in technology, we might need to increase the minimum strength every two years after the initial increase (though keep in mind that this is a rough estimate). @@ -160,7 +164,7 @@ One thing to note is that a given farm can contain plots with various strength l #### Expected base filter and strength To recap: -The network's base filter will start at `512` and will be cut in half every 3-6 years until it reaches `1`, at which point every plot will pass the filter at each signage point. These adjustments will happen automatically, and can be delayed with a soft fork. +The network's base filter will start at `512` and will be cut in half every 3-6 years until it reaches `1`, at which point every plot will pass the filter at each signage point. The maximum strength will be 17 minus the number of bits in the base filter. The maximum strength will increase every 3-6 years as the base filter falls. @@ -180,6 +184,8 @@ The following table shows the block height for each built-in adjustment to the b * round to the nearest thousand * `19'663'000` +##### Filter reduction table + | Block height | Year | Base Filter Bits | Base Filter | Max Strength | | :----------- | :--- | :--------------- | :---------- | :----------- | | ` 9'562'000` | 2026 | 9 | 512 | 8 | @@ -193,8 +199,6 @@ The following table shows the block height for each built-in adjustment to the b | `55'006'000` | 2054 | 1 | 2 | 16 | | `60'056'000` | 2057 | 0 | 1 | 17 | -The first built-in reduction in the base filter will occur six years after the fork is activated. The subsequent built-in reductions will occur every three years thereafter by default. This is a somewhat aggressive schedule to keep up with advancing technology. In the scenario where we feel comfortable with delaying these reductions, we will do so with a soft fork. - As a reminder, the minimum strength will start at `0` and will be increased via a soft fork as needed. We won't plan to increase the minimum strength until at least 2036 (10 years after the 3.0 release), though this is subject to change. If/when we do decide to increase the minimum strength, we will do our best to provide a warning of 6-12 months so that any plots at the current minimum will have time to be upgraded before they become invalid. The following table shows some hypothetical adjustments to the original strength, along with the built-in adjustments to the base filter. In this scenario, we will increase the minimum strength every two years, starting in 2036. In certain years in this table, both the base filter and minimum strength will be adjusted at the same block. Keep in mind that the strength adjustments will only be undertaken as needed, so this is only an example to illustrate how the adjustments might look. The second column from the right shows the effective filter for a plot created at `strength = 5`, and the rightmost column shows how often that plot will pass the filter, on average. @@ -213,11 +217,11 @@ The following table shows some hypothetical adjustments to the original strength | TBD | 2046 | 16 | 6 | Invalid | N/A | ### Plot groups -With the new Proof of Space format, every plot will be part of a _group_. While it is possible for each individual plot to have its own group with a size of 1, farmers are recommended to add multiple plots with the same public key into a single group. This will work by combining multiple plots together, as if they were the same plot. +With PoS v2, every plot will be part of a _group_. While it is possible for each individual plot to have its own group with a size of 1, farmers are recommended to add multiple plots with the same public key into a single group. This will work by combining multiple plots together, as if they were the same plot. Note: Because `plot_strength` is part of the group ID, all plots contained within the same group must have the same strength. This means that a given plot group will have its own effective filter, equal to the effective filter of every plot contained within the group. -A plot's group ID is determined by hashing its version, strength, public key, and either its puzzle hash or its pool public key: +A plot's group ID is determined by hashing its version, strength, public key, and either its pool contract puzzle hash or its pool public key: ``` sha256( @@ -226,7 +230,7 @@ A plot's group ID is determined by hashing its version, strength, public key, an plot_pk: Serialized_PK, one_of: - puzzle_hash: Puzzle_Hash, + pool_contract_puzzle_hash: Pool_Contract_Puzzle_Hash, pool_public_key: Serialized_PK, ) ``` @@ -240,40 +244,46 @@ The plot's ID is then determined by hashing its group ID, index, and [meta group meta_group: u8, ) ``` -The `plot_index` represents a plot's slot within its group. The maximum number of plots that can be included in a group is 2^16 (65,536), or about 65 TB. - -Grouping multiple plots together is required beyond a few thousand plots on HDDs, and is recommended on SSDs as well. If plots are not grouped together, then multiple lookups will be needed at each signage point. +The `plot_index` represents a plot's slot within its group. Grouping multiple plots together is recommended for HDDs that contain more than a few thousand plots. The recommended group size is `128`. This will yield plot groups of around 120 GB, which is roughly the same size as PoS v1 plots. (For plotters with lower RAM, grouping 64 plots together is also fine.) The maximum number of plots that can be included in a group is 2^16 (65,536), or about 65 TB. -For example, a 20-TB HDD will hold around 20,000 plots. If the effective filter for these plots is `256`, and the plots are not grouped, then an average of around 78 plots will pass the filter at each signage point. This will require a large amount of lookups, which could affect the harvester's ability to respond on time. +To illustrate why grouping plots is recommended, we can examine a 20-TB HDD, which will hold around 20,000 plots. If the effective filter for these plots is `256`, and the plots are not grouped, then an average of around 78 plots will pass the filter at each signage point. This will require a large amount of lookups, which could affect the harvester's ability to respond on time. -However, grouping _too many_ plots together could also cause issues, though they would be minor in comparison. Due to the extra memory required to group plots together, creating a group with more than 128 plots is not generally recommended. In addition, because a plot group acts as a single plot, larger groups will also increase the volatility of block rewards being won. This volatility is only noticeable in the short term, though -- the long-term expected win rate will be unaffected by large group sizes. +Grouping _too many_ plots together could also cause issues, though they would be minor in comparison. Due to the extra memory required to group plots together, creating a group with more than 128 plots is not generally recommended. In addition, because a plot group acts as a single plot, larger groups will also increase the volatility of block rewards being won. This volatility is only noticeable in the short term, though -- the long-term expected win rate will be unaffected by large group sizes. -Keeping the above considerations in mind, the recommended group size is `128`. This will yield plot groups of around 120 GB, which is roughly the same size as v1 plots. For plotters with lower RAM, grouping 64 plots together is also fine. +There are exceptions to these recommendations. For example, older HDDs with low capacities may not be economical for some farmers due to ongoing electricity costs. Instead, these HDDs could be filled with plots that are grouped together so that the entire HDD consists of a single "plot". These HDDs could then be powered down until their plot is about to pass the filter, which would save on electricity. This technique is [described in detail](#advantage-2-ability-to-power-down-hdds) below. -However, there are exceptions to these recommendations. For example, older HDDs with low capacities may not be profitable for some farmers due to ongoing electricity costs. Instead, these HDDs could be filled with plots that are grouped together so that the entire HDD consists of a single "plot". These HDDs could then be powered down until their plot is about to pass the filter, which would save on electricity. This technique is [described in detail](#powering-down-hdds) below. +One way to think of grouping is that plots are _attracted_ to other plots with the same group ID. This is the opposite of meta groups, described next. ### Meta groups -All plots in a standard plot group will pass the filter together. However, the plot groups themselves will occasionally also pass the filter together. _Meta groups_ are a way to prevent this from happening. If two plot groups are part of separate meta groups, then they will never pass the filter together. This can be beneficial, for example, in order to reduce the chances that a disk becomes overloaded from excessive lookups. It also will somewhat help to smooth out rewards. +All plots in a standard plot group will pass the filter together (they are attracted to each other). However, the plot groups themselves will occasionally also pass the filter together. _Meta groups_ are a way to prevent this from happening. If two plot groups are part of separate meta groups, then they will never pass the filter together. In other words, meta groups _repel_ one another. This can be beneficial, for example, in order to reduce the chances that a disk becomes overloaded from excessive lookups. It also will somewhat help to smooth out rewards. -Plot groups will declare their own meta group. A plot's meta group is a single byte, so up to 256 meta groups can be created in one farm. Each meta group number will be `0` by default. Each meta group can contain up to 2^16 (65,536) plots. +Plots groups will declare their own meta group at the time of their creation, so that the meta group will become part of each plot's ID. A plot's meta group is a single byte, so up to 256 meta groups can be created in one farm. Each meta group number will be `0` by default. Each group ID can contain up to 256 meta groups, so each group can contain up to 16,777,216 (2^8 * 2^16) plots (~16.7 PB). -### Effective filter calculation -The formula to determine whether a given plot passes the filter will be modified for the new Proof of Space protocol. In this section, we'll start by describing this formula for PoS v1, along with its deficiencies. Next, we'll describe the new formula for PoS v2, along with its advantages. +### Effective filter formula +The formula to determine whether a given plot passes the filter will be modified for the PoS v2. In this section, we'll start by describing this formula for PoS v1, along with its deficiencies. Next, we'll describe the new formula for PoS v2, along with its advantages. -#### Old formula and deficiencies -In the original Proof of Space protocol, plots randomly pass (or don't pass) the filter at each signage point. This is determined by hashing the plot ID concatenated with the current challenge and signage point: +#### PoS v1 formula and deficiencies +In PoS v1, plots randomly pass (or don't pass) the filter at each signage point. This is determined by hashing the plot ID concatenated with the current challenge and signage point: `plot filter bits = sha256(plot ID + sub slot challenge + challenge chain signage point)` -If `plot filter bits` begins with a certain number of zeroes, then the plot passes the filter. For example, if the plot filter is `256`, then at each signage point, a plot will have will have a 1 in 256 chance of passing the filter (`plot filter bits` must begin with eight zeroes in this case). Because `plot filter bits` is calculated from a `sha256` hash, the plot has an equal chance of passing the filter at any given signage point. +If `plot filter bits` begins with a certain number of zeroes, then the plot passes the filter. For example, if the plot filter is `256`, then at each signage point, a plot will have a 1 in 256 chance of passing the filter (`plot filter bits` must begin with eight zeroes in this case). Because `plot filter bits` is calculated from a `sha256` hash, the plot has an equal chance of passing the filter at any given signage point. -There is also no mechanism to prevent the plot from passing the filter at multiple consecutive signage points. By analogy, if someone rolls a die three times, the result might be `1` each time. In the original Proof of Space protocol, a plot will have a 1 in 65,536 (256 * 256) chance of passing two consecutive signage points, and a 1 in 16,777,216 (256 * 256 * 256) chance of passing three consecutive signage points. +There is also no mechanism to prevent the plot from passing the filter at multiple consecutive signage points. By analogy, if someone rolls a die three times, the result might be `1` each time. In PoS v1, a plot will have a 1 in 65,536 (256 * 256) chance of passing two consecutive signage points, and a 1 in 16,777,216 (256 * 256 * 256) chance of passing three consecutive signage points. Plot grinders can generate a plot ID without creating the plot, so they can grind through millions of plot IDs per second. This means that at any given signage point, they can grind a plot ID that will pass it, as well as the previous two signage points, thereby increasing their leverage. The details of plot grinding, and the leverage gained, are shown in [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). -#### New formula +#### PoS v2 formula + +In order to reduce the extra grinding leverage described above, PoS v2 will change the formula to determine whether a plot passes the filter. The following function uses the above values to determine whether a plot passes the filter at a given signage point: + +```python +def plot_id_check(plot_group_id, group_strength, meta_group, filter_challenge, challenge_index): + mask = (1 << group_strength) - 1 + return hash(plot_group_id + filter_challenge) & mask == (challenge_index ^ meta_group) & mask +``` -In order to reduce the extra grinding leverage described above, the new Proof of Space protocol will change the formula to determine whether a plot passes the filter. We'll start with some definitions: +The variables used in this function are defined as: * `plot_group_id` -- the ID of the relevant plot * `group_strength` -- the strength of the plot group in bits (the group has a `1 / 2 ^ z` chance of passing) @@ -283,58 +293,52 @@ In order to reduce the extra grinding leverage described above, the new Proof of These values apply the same to all specific plots within the group. Their only difference is an index. -The following function uses the above values to determine whether a plot passes the filter at a given signage point: - -```python -def plot_id_check(plot_group_id, group_strength, meta_group, filter_challenge, challenge_index): - mask = (1 << group_strength) - 1 - return hash(plot_group_id + filter_challenge) & mask == (challenge_index ^ meta_group) & mask -``` - The main two advantages of using this new formula are that it reduces the potential extra leverage from plot grinding, and that it makes it possible to power down HDDs between times when they pass the filter. Both of these advantages are detailed below. -#### Reduced leverage when grinding -By using the new formula, we can guarantee that a plot group won't pass the filter more than once every four signage points. This means that the extra leverage that could previously be gained from grinding a plot's ID is reduced by 75%. Plot grinders will be able to create plots on the fly, but the only available multiplier effect will be to grind a plot ID that will pass the filter in one of the previous four signage points, as well as in one of the next four. The new formula will therefore accomplish the original goal of the defunct [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). +#### Advantage 1: reduced leverage when grinding +By using the new formula, we can guarantee that a plot group won't pass the filter more than once every four consecutive signage points, and more than once in each fixed set of 16 signage points (the diagram below demonstrates this). This means that the extra leverage that could previously be gained from grinding a plot's ID is reduced by 75%. Plot grinders will be able to create plots on the fly, but the only available multiplier effect will be to grind a plot ID that will pass the filter in one of the previous four signage points, as well as in one of the next four. For example, it will be possible to grind a plot ID that pass the filter in signage points 12 and 16. + +The new formula will therefore accomplish the original goal of the defunct [CHIP-13](https://github.com/Chia-Network/chips/blob/dad0822f4142bb0da70f31cb2d15aba366d64532/CHIPs/chip-0013.md). -#### Powering down HDDs -In addition, it will now be possible to predict between 4 to 20 signage points (~37 seconds to three minutes) in advance when a plot group will pass the filter. This will make it possible to power down a hard drive most of the time, and only start it up in advance of the plot group passing the filter. A few guidelines should be followed in order to maximize the efficiency of this use case. +#### Advantage 2: ability to power down HDDs +In addition, when combined with groups, the new formula will make it possible to predict between 4 to 20 signage points (~37 seconds to three minutes) in advance when a plot group will pass the filter. This will make it possible to power down a hard drive most of the time, and only power it up in advance of the plot group passing the filter. A few guidelines should be followed in order to maximize the efficiency when powering down HDDs. ##### Group many plots together -If a farmer's goal is to maximize the timing between wake-ups (as opposed to smoothing rewards), an HDD can be filled with a single plot group. If a 20-TB HDD were filled with 4 plot groups of 5 TB, and the effective filter for those groups were 8192, then the HDD would need to be started and stopped four times daily, on average. But if the same HDD were filled with a single plot group of 20 TB and the same effective filter, then it would only need to be started and stopped once daily. +If a farmer's goal is to maximize the timing between wake-ups (as opposed to smoothing rewards), an HDD can be filled with a single plot group. If a 20-TB HDD were filled with 4 plot groups of 5 TB, and the effective filter for those groups were 8192, then the HDD would need to be powered up and down four times daily, on average. But if the same HDD were filled with a single plot group of 20 TB and the same effective filter, then it would only need to be powered up and down once daily. ##### Use smaller HDDs -HDDs use a similar amount of electricity, regardless of their capacity. In PoS v1, this made lower-capacity HDDs economically unprofitable. In PoS v2, powering down these smaller disks will potentially make them profitable. However, the advantage of powering down an HDD is reduced as the HDD's capacity is increased. It may turn out that there is little advantage to powering down a modern, large-capacity HDD. In fact, it may actually be a disadvantage due to the increased compute needed to create a plot group for the large HDD, as well as due to the extra wear caused by repeatedly shutting down and starting up an HDD. +HDDs use a similar amount of electricity, regardless of their capacity. In PoS v1, this made lower-capacity HDDs uneconomical. In PoS v2, powering down these smaller disks will potentially make them economical. However, the advantage of powering down an HDD is reduced as the HDD's capacity is increased. It may turn out that there is little advantage to powering down a modern, large-capacity HDD. In fact, it may actually be a disadvantage due to the increased compute needed to create a plot group for the large HDD, as well as due to the extra wear caused by repeatedly powering up and down an HDD. ##### Plot to a high strength -Plot groups that were created at strength `4` will initially pass the filter once per day. After six years, this frequency will be reduced to 12 hours, and after nine years, it will be reduced to 6 hours. Farmers may not be comfortable with starting and stopping their HDDs more than four times daily, so in order to take advantage of this use case for longer timeframes, they will need to plot to higher strengths. +Plot groups that were created at strength `4` will initially pass the filter once per day. After six years, this frequency will be reduced to 12 hours, and after nine years, it will be reduced to 6 hours. Farmers may not be comfortable with powering up and down their HDDs more than four times daily, so in order to take advantage of this use case for longer timeframes, they will need to plot to higher strengths. #### Determining when a plot group will pass -Every subslot is 600 seconds, and has 64 signage points, which occur every 9.375 seconds. See [our documentation](https://docs.chia.net/chia-blockchain/consensus/chains/signage-and-infusion-points/) for more information on subslots and signage points. +Every subslot is 600 seconds, and has 64 signage points, which occur every 9.375 seconds. See [our documentation](https://docs.chia.net) for more information on subslots and signage points. -In the old Proof of Space protocol, the determination as to whether a plot passes the filter is made at each signage point. +In PoS v1, the determination as to whether a plot passes the filter is made at each signage point. -In the new Proof of Space protocol, this determination is only made at signage points 0, 16, 32, and 48. When one of these _n_ signage points is reached, the filter is calculated for signage points `n+4` through `n+20`. This algorithm guarantees that the determination as to whether a plot group will pass the filter is known at least 37.5 (9.375 * 4) seconds in advance, and at most 187.5 (9.375 * 20) signage points in advance. After signage point 63 is reached, a new subslot will begin with signage point 0. The first four signage points of a subslot are therefore determined during the previous subslot. +In PoS v2, this determination is only made at signage points 0, 16, 32, and 48. When one of these _n_ signage points is reached, the filter is calculated for signage points `n+4` through `n+20`. This algorithm guarantees that the determination as to whether a plot group will pass the filter is known at least 37.5 (9.375 * 4) seconds in advance, and at most 187.5 (9.375 * 20) seconds points in advance. After signage point 63 is reached, a new subslot will begin with signage point 0. The first four signage points of a subslot are therefore determined during the previous subslot. The algorithm also disallows plots from passing the filter more than once in any of these groupings of 16 signage points. -We have included a [diagram](../assets/chip-0049/challenge_filter_meta_groups.png) that visualizes this algorithm for your reference. +The following diagram visualizes this algorithm: -This algorithm will allow harvesters to determine when their plot groups will pass the filter with some advanced warning. If a disk that contains a plot group that will pass the filter in the next 4-20 signage points is currently shut down, then the harvester can start the disk. +![Diagram](../assets/chip-0049/challenge_filter_meta_groups.png) -The reason to set the minimum advanced notice to 37.5 seconds is because it could take up to 30 seconds to start some slower HDDs that have been completely shut down. Even in the worst-case scenario of a slow disk being given the minimum amount of advanced notice, there will still be ample time for the disk to be started. +This algorithm will allow harvesters to determine when their plot groups will pass the filter with some advanced warning. If a disk that contains a plot group that will pass the filter in the next 4-20 signage points is currently powered down, then the harvester can power up the disk. -The reason to set the maximum advanced notice to 187.5 seconds is to ensure that tape drives are not viable for farming. These drives provide cheaper storage than HDDs and SSDs, giving them an unfair advantage. While a tape drive might perform some seeks in less than the maximum time, it often will fail to load the needed information in time to be used in the blockchain's consensus. +The reason to set the minimum advanced notice to 37.5 seconds is to provide ample time for the disk to be powered up. -Note that even though most of the signage points will no longer determine whether a plot group will pass the filter, every signage point will continue to be used for consensus purposes. +The reason to set the maximum advanced notice to 187.5 seconds is to ensure that tape drives are not viable for farming. These drives provide cheaper storage than HDDs and SSDs, giving them an unfair advantage. While a tape drive might [perform some seeks](https://asset.fujifilm.com/master/americas/files/2020-08/9f5b0bdaa10596d3577f8748f18d6463/Horison_Tape-Performance_2020.pdf) in less than the maximum time, it often will fail to load the needed information in time to be used in the blockchain's consensus. ### Other updates -This section will describe the updates that will go into the hard fork, but are not part of the new Proof of Space protocol. +This section will describe the updates that will go into the hard fork, but are not part of PoS v2. ### keccak256 The `keccak256` operator was previously added via soft fork, and is therefore only available from inside the `softfork` guard. Its usage is described in [the Specification section of CHIP-36](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0036.md#specification). The hard fork gives us the opportunity to promote `keccak256` to be available from outside the `softfork` guard. This makes it easier to use. -After the hard fork activates, the `keccak256` operator will become part of the core CLVM, so it will be available by calling it directly. It will also continue to be available from inside the `softfork` guard. +After the hard fork activates, the `keccak256` operator will become part of the core CLVM, so it will be available by calling it directly. It will also continue to be available from inside the `softfork` guard for backward compatibility. ### sha256tree Many puzzles use the [sha256tree](https://github.com/Chia-Network/chia_puzzles/blob/0b46a6ebfc3b432d68edf9b91e6cef0ec13da2e7/puzzles/sha256tree.clib) library, which calculates the puzzle hash of a given puzzle program. This library is used so frequently, in fact, that it makes sense to include it as a native CLVM operator in the hard fork. Another advantage of including `sha256tree` in the CLVM is that it will be cheaper to call, both in terms of CPU compute and CLVM cost. Finally, a native operator also opens the door to future optimizations via caching. @@ -397,7 +401,7 @@ After the hard fork activates, the limit of 1024 `ANNOUNCEMENT` conditions per s Instead, for each coin spend, conditions will have a base cost of 500, **except** for the first 100 conditions, which will not incur a base cost. This is in addition to any existing cost for the conditions. This cost applies to all conditions (except for `ANNOUNCEMENT` conditions, discussed below), including unknown conditions, `SOFTFORK`, `CREATE_COIN` and `AGG_SIG_*` conditions. -There is an exception to this rule. **All** `ANNOUNCEMENT` conditions will have a base cost of 500, including the first 100 conditions. This is in addition to any existing cost for the conditions. These conditions include: +There is an exception to this rule. **All** `ANNOUNCEMENT` conditions will have a base cost of 500, **including** the first 100 conditions. This is in addition to any existing cost for the conditions. These conditions include: * `CREATE_COIN_ANNOUNCEMENT` (opcode 60) * `ASSERT_COIN_ANNOUNCEMENT` (opcode 61) * `CREATE_PUZZLE_ANNOUNCEMENT` (opcode 62) @@ -409,9 +413,9 @@ The 3.0 fork will include [new weight proof commitments](https://github.com/Chia * Adding to a Merkle Mountain Range of transaction blocks within sub-epochs * Adding commitments to the root of subslots, including the number of blocks per branch for epochs -Before the new weight proofs can be used, there will need to be a transition point between the old and new proofs. This will necessitate that both formats work simultaneously for some time. We will put in a checkpoint after the 3.0 fork activates, and wait enough time before we use the new weight proof so that everyone agrees on the past before the checkpoint. +Before the new weight proofs can be used, there will need to be a transition point between the old and new proofs. This will necessitate that PoS v1 and v2 work simultaneously for some time. We will put in a checkpoint after the 3.0 fork activates, and wait a sufficient number of blocks (perhaps 4608 blocks) before we use the new weight proof such that everyone agrees on the past before the checkpoint. -After we can begin validating the new weight proofs (9-12 months after 3.0 is released), nodes and wallets won’t be required to sync. Their peers only will need to prove the peak height and its weight in order for their data to be proven trustworthy. The current requirement for block validation will instead become a recommendation. +After we can begin validating the new weight proofs (9-12 months after 3.0 is released), nodes and wallets won’t be required to perform block validation when syncing. Their peers will only need to prove the peak height and its weight in order for their data to be proven trustworthy. The current requirement for block validation will instead become a recommendation. ### Block Hash Generator In order to calculate block hashes, currently we hash the serialization blob of the block generator (a CLVM object). @@ -428,7 +432,7 @@ The 3.0 release will include an update to hash the generator as a sha256tree (ju * [Technical specification](https://github.com/richardkiss/generator-identity-hf-analysis/blob/main/docs/GENERATOR_IDENTITY_HARDFORK.md) for these changes * [Analysis and implementation](https://github.com/richardkiss/generator-identity-hf-analysis/?tab=readme-ov-file#installation) of the specification -Beginning at the hard fork's activation block, the new block hash computation will be accepted, and the old method will be ignored. +Beginning at the hard fork's activation block, the new block hash computation will be accepted, and the old method will be ignored. Any nodes that have not been upgraded to 3.0+ by this block can expect to fall out of sync immediately. The original CLVM cost of calculating the generator was `12'000 * len(blob)`. The new cost is `len(blob)`. @@ -441,16 +445,19 @@ This flag will be set at the hard fork's activation. After the flag is set, in a We will also [disallow block references](https://github.com/Chia-Network/chia-blockchain/pull/20218) in the hard fork, we have not used them, nor have we seen any benefit to using them. ## Test Cases -All relevant test cases are included in CHIP-48. +All relevant test cases are included in [CHIP-48](https://github.com/Chia-Network/chips/blob/9a6783aa661255fa69d08d87f948bca65f149363/CHIPs/chip-0048.md#test-cases). ## Reference Implementation -The reference implementation is included in CHIP-48. +The reference implementation is included in [CHIP-48](https://github.com/Chia-Network/chips/blob/9a6783aa661255fa69d08d87f948bca65f149363/CHIPs/chip-0048.md#reference-implementation). ## Security -The majority of the security work for the new proof format can be found in CHIP-48. That said, CNI has also performed an internal audit of the code updates involved with this CHIP. +The security work for PoS v2 can be found in [CHIP-48](https://github.com/Chia-Network/chips/blob/9a6783aa661255fa69d08d87f948bca65f149363/CHIPs/chip-0048.md#security). For the non-PoS-v2 changes, CNI has also performed an internal audit. ## Additional Assets -None +* [Diagram](../assets/chip-0049/challenge_filter_meta_groups.png) illustrating the plot ID filter for PoS v2 +* [Analysis](https://asset.fujifilm.com/master/americas/files/2020-08/9f5b0bdaa10596d3577f8748f18d6463/Horison_Tape-Performance_2020.pdf) of tape drive performance, from [Horison Information Strategies](https://horison.com/) +* [Plot compression](https://www.chia.net/2023/01/21/plot-compression-is-here/) blog post +* [Why hard drives fail](https://www.chia.net/2021/12/16/how-do-hard-drives-fail/) blog post ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 5449f33b22085910b1fa9f328117e2e445df3fe0 Mon Sep 17 00:00:00 2001 From: danieljperry Date: Tue, 24 Feb 2026 14:26:36 +0800 Subject: [PATCH 20/24] Clarify benefit of meta groups --- CHIPs/chip-0049.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index e38bb910..d1d27edc 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -255,9 +255,13 @@ There are exceptions to these recommendations. For example, older HDDs with low One way to think of grouping is that plots are _attracted_ to other plots with the same group ID. This is the opposite of meta groups, described next. ### Meta groups -All plots in a standard plot group will pass the filter together (they are attracted to each other). However, the plot groups themselves will occasionally also pass the filter together. _Meta groups_ are a way to prevent this from happening. If two plot groups are part of separate meta groups, then they will never pass the filter together. In other words, meta groups _repel_ one another. This can be beneficial, for example, in order to reduce the chances that a disk becomes overloaded from excessive lookups. It also will somewhat help to smooth out rewards. +All plots in a standard plot group will pass the filter together (they are attracted to each other). However, the plot groups themselves will occasionally also pass the filter together. _Meta groups_ are a way to prevent this from happening. If two plot groups are part of separate meta groups, then they will never pass the filter together. In other words, meta groups _repel_ one another. -Plots groups will declare their own meta group at the time of their creation, so that the meta group will become part of each plot's ID. A plot's meta group is a single byte, so up to 256 meta groups can be created in one farm. Each meta group number will be `0` by default. Each group ID can contain up to 256 meta groups, so each group can contain up to 16,777,216 (2^8 * 2^16) plots (~16.7 PB). +Each plot group that exists on the same HDD is recommended to be assigned a unique meta group. The two main benefits of doing this are that it will reduce the disk's peak load and distribute CPU usage. This configuration guarantees (with one exception) that at most one group will pass the filter at a given signage point. + +The exception to this rule is that once every plot group on the same disk has an effective filter that is smaller than the total number of groups on the disk, it will no longer be possible for each group to pass the filter at different signage points. This may begin to be an issue in a few decades, when the network's base filter is much lower than it is today. However, by that point it is also likely that most farms will run on SSDs or a new storage medium, and thus meta groups won't carry the same degree of benefit as they do today. + +Plots groups will declare their own meta group at the time of their creation, so that the meta group will become part of each plot's ID. A plot's meta group is a single byte, so up to 256 meta groups can be created in one farm. Each meta group number will be `0` by default. Each group ID can contain up to 256 meta groups, so each group can support up to 16,777,216 (2^8 * 2^16) plots, or ~16.7 PB. ### Effective filter formula The formula to determine whether a given plot passes the filter will be modified for the PoS v2. In this section, we'll start by describing this formula for PoS v1, along with its deficiencies. Next, we'll describe the new formula for PoS v2, along with its advantages. From 2f42b19d5afd223e629cf922fc3546057113faf4 Mon Sep 17 00:00:00 2001 From: danieljperry Date: Fri, 27 Feb 2026 12:37:52 +0800 Subject: [PATCH 21/24] More updates --- CHIPs/chip-0049.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index d1d27edc..9675c5d2 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -2,7 +2,7 @@ CHIP Number | 0049 :------------|:---- Title | 3.0 Fork Info Description | Provide all info that will be included in the 3.0 fork -Author | [Arvid Norberg](https://github.com/arvidn) +Author | [Arvid Norberg](https://github.com/arvidn), [Richard Kiss](https://github.com/richardkiss) Editor | [Dan Perry](https://github.com/danieljperry) Comments-URI | [CHIPs repo, PR #161](https://github.com/Chia-Network/chips/pull/161) Status | Draft @@ -431,11 +431,6 @@ The 3.0 release will include an update to hash the generator as a sha256tree (ju | Identity | SHA256(serialized_bytes) | SHA256_tree_hash(tree) | | Cost basis | Serialized length | Interned tree structure | -[Richard Kiss](https://github.com/richardkiss) has added the details of this specification to his GitHub Page: -* [GitHub Gist](https://gist.github.com/richardkiss/59389ac2f96dd0665f2d7815baa7b30f) document summarizing these changes -* [Technical specification](https://github.com/richardkiss/generator-identity-hf-analysis/blob/main/docs/GENERATOR_IDENTITY_HARDFORK.md) for these changes -* [Analysis and implementation](https://github.com/richardkiss/generator-identity-hf-analysis/?tab=readme-ov-file#installation) of the specification - Beginning at the hard fork's activation block, the new block hash computation will be accepted, and the old method will be ignored. Any nodes that have not been upgraded to 3.0+ by this block can expect to fall out of sync immediately. The original CLVM cost of calculating the generator was `12'000 * len(blob)`. The new cost is `len(blob)`. From cef568754f13510f3bd10999a10bd83d8f8b30a8 Mon Sep 17 00:00:00 2001 From: danieljperry Date: Fri, 27 Feb 2026 16:21:48 +0800 Subject: [PATCH 22/24] Add links to generator identity docs --- CHIPs/chip-0049.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index 9675c5d2..5ccf9a1e 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -443,6 +443,8 @@ This flag will be set at the hard fork's activation. After the flag is set, in a We will also [disallow block references](https://github.com/Chia-Network/chia-blockchain/pull/20218) in the hard fork, we have not used them, nor have we seen any benefit to using them. +The complete breakdown of these updates can be found in [our documentation](https://docs.chia.net/chia-blockchain/resources/generator-identity/). + ## Test Cases All relevant test cases are included in [CHIP-48](https://github.com/Chia-Network/chips/blob/9a6783aa661255fa69d08d87f948bca65f149363/CHIPs/chip-0048.md#test-cases). @@ -457,6 +459,7 @@ The security work for PoS v2 can be found in [CHIP-48](https://github.com/Chia-N * [Analysis](https://asset.fujifilm.com/master/americas/files/2020-08/9f5b0bdaa10596d3577f8748f18d6463/Horison_Tape-Performance_2020.pdf) of tape drive performance, from [Horison Information Strategies](https://horison.com/) * [Plot compression](https://www.chia.net/2023/01/21/plot-compression-is-here/) blog post * [Why hard drives fail](https://www.chia.net/2021/12/16/how-do-hard-drives-fail/) blog post +* [Generator identity](https://docs.chia.net/chia-blockchain/resources/generator-identity/) analysis ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 9a9370169d07b3d1bc7b57764d1b92df36b36911 Mon Sep 17 00:00:00 2001 From: danieljperry Date: Fri, 27 Feb 2026 16:29:20 +0800 Subject: [PATCH 23/24] Move CHIP-49 into Review --- CHIPs/chip-0049.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index 5ccf9a1e..9d3a60ee 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -5,7 +5,7 @@ Description | Provide all info that will be included in the 3.0 fork Author | [Arvid Norberg](https://github.com/arvidn), [Richard Kiss](https://github.com/richardkiss) Editor | [Dan Perry](https://github.com/danieljperry) Comments-URI | [CHIPs repo, PR #161](https://github.com/Chia-Network/chips/pull/161) -Status | Draft +Status | Review Category | Standards Track Sub-Category | Core Created | 2025-05-19 From bd70582d5b82a6770d49e907ca4bf174a4eb918f Mon Sep 17 00:00:00 2001 From: danieljperry Date: Fri, 27 Feb 2026 16:32:01 +0800 Subject: [PATCH 24/24] Move link --- CHIPs/chip-0049.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHIPs/chip-0049.md b/CHIPs/chip-0049.md index 9d3a60ee..172f69b2 100644 --- a/CHIPs/chip-0049.md +++ b/CHIPs/chip-0049.md @@ -435,6 +435,8 @@ Beginning at the hard fork's activation block, the new block hash computation wi The original CLVM cost of calculating the generator was `12'000 * len(blob)`. The new cost is `len(blob)`. +The complete breakdown of these updates can be found in [our documentation](https://docs.chia.net/chia-blockchain/resources/generator-identity/). + ### Constrain block generators We have [added a new flag](https://github.com/Chia-Network/chia_rs/pull/1288) for `run_block_generator2()` which, before executing the block generator, ensures that it starts with a quote `(q or 1)`. This forces the generator to be a list, instead of an arbitrary program. @@ -443,8 +445,6 @@ This flag will be set at the hard fork's activation. After the flag is set, in a We will also [disallow block references](https://github.com/Chia-Network/chia-blockchain/pull/20218) in the hard fork, we have not used them, nor have we seen any benefit to using them. -The complete breakdown of these updates can be found in [our documentation](https://docs.chia.net/chia-blockchain/resources/generator-identity/). - ## Test Cases All relevant test cases are included in [CHIP-48](https://github.com/Chia-Network/chips/blob/9a6783aa661255fa69d08d87f948bca65f149363/CHIPs/chip-0048.md#test-cases).