From cdcadac91cf96fe57d8a811095330c67e0ebf441 Mon Sep 17 00:00:00 2001 From: NoahMaizels Date: Mon, 16 Mar 2026 16:16:49 +0700 Subject: [PATCH 1/4] fix: update calculators to use new utilisation tables, add encryption/erasure inputs, fix erasure coding base and Paranoid off-by-one --- docs/concepts/DISC/erasure-coding.md | 18 +- docs/concepts/incentives/postage-stamps.md | 568 +++++++-------- .../tools-and-features/buy-a-stamp-batch.md | 29 +- src/components/AmountAndDepthCalc.js | 650 +++++++++++++----- src/components/RedundancyCalc.js | 65 +- src/components/VolumeAndDurationCalc.js | 174 ++++- swarm-cli | 1 + 7 files changed, 975 insertions(+), 530 deletions(-) create mode 160000 swarm-cli diff --git a/docs/concepts/DISC/erasure-coding.md b/docs/concepts/DISC/erasure-coding.md index 82c978f14..107d5ccac 100644 --- a/docs/concepts/DISC/erasure-coding.md +++ b/docs/concepts/DISC/erasure-coding.md @@ -1,6 +1,7 @@ --- title: Erasure Coding id: erasure-coding +description: Explains optional data protection technique using redundant chunks at multiple protection levels to ensure reliable data recovery. --- Erasure coding (also known as erasure code) is an efficient and flexible approach to data protection which is an optional feature for Swarm uploads. It is a technique that increases data protection by enabling the recovery of original data even when some encoded chunks are lost or corrupted. When used, it ensures that data on Swarm can always be accessed reliably, even if some nodes or entire neighborhoods go offline. Refer to the [official erasure coding paper](https://papers.ethswarm.org/p/erasure/) for more in depth details. @@ -19,11 +20,12 @@ For an 8KB image, if we set **m = 2** and **k = 1**, we create 3 chunks (2 origi ### Levels of Protection -In Swarm's implementation of erasure coding, there are four named levels of protection, Medium, Strong, Insane, and Paranoid. For each level, the **m** and **k** values have been adjusted in order to meet a certain level of data protection: +In Swarm's implementation of erasure coding, there are five levels of protection, None, Medium, Strong, Insane, and Paranoid. For each level, the **m** and **k** values have been adjusted in order to meet a certain level of data protection: ***Table A:*** | Redundancy Level Value | Level Name | Chunk Loss Tolerance | | ---------------- | --------- | ----------------------------------- | +| 0 | None | 0% | | 1 | Medium | 1% | | 2 | Strong | 5% | | 3 | Insane | 10% | @@ -35,21 +37,22 @@ Note that this guarantee of retrievability is for each 128 chunk segment, and th ## Usage -For usage instructions, see the [erasure coding page in the "Develop" section](/docs/develop/tools-and-features/erasure-coding). +For usage instructions, see the [erasure coding page in the "Develop" section](./../../develop/tools-and-features/erasure-coding.md). ## Cost Calculation -In Swarm's implementation of erasure coding, there are four levels of protection: Medium, Strong, Insane, and Paranoid. Each level adds additional parity chunks for a corresponding increase in data protection (and also cost). +In Swarm's implementation of erasure coding, there are five levels of protection: None, Medium, Strong, Insane, and Paranoid. Each level adds additional parity chunks for a corresponding increase in data protection (and also cost). The table below shows the number of parities and data chunks for each level, as well as the percent increase in cost vs a non-erasure coded upload. ***Table B:*** | Redundancy | Parities | Data Chunks | Percent | Chunks Encrypted | Percent Encrypted | |----------|----------|--------|---------|------------------|-------------------| -| Medium | 9 | 119 | *7.6%* | 59 | 15% | -| Strong | 21 | 107 | *19.6%* | 53 | 40% | -| Insane | 31 | 97 | 32% | 48 | 65% | -| Paranoid | 90 | 38 | 240.5% | 18 | 494% | +| None | 0 | 128 | *0%* | 64 | 0% | +| Medium | 9 | 119 | *7.6%* | 59 | 15.3% | +| Strong | 21 | 107 | *19.6%* | 53 | 39.6% | +| Insane | 31 | 97 | 32% | 48 | 64.6% | +| Paranoid | 90 | 38 | 236.8% | 19 | 473.7% | For each redundancy level, there are **m + k** = 128 chunks, where **m** are the data chunks (shown in column "Data Chunks") and **k** are the parity chunks (shown in column "Parities"). The "Percent" and "Percent Encrypted" columns show percent of "parity overhead" cost increase from using erasure coding for normal and encrypted uploads respectively. @@ -151,6 +154,7 @@ To find the percent increase in cost for uploads of less than 128 chunks, refer | Paranoid | 86 | 35 | 245.7% | 17 | 505.9% | | Paranoid | 87 | 36 | 241.7% | 18 | 483.3% | | Paranoid | 89 | 37 | 240.5% | 18 | 494.4% | +| Paranoid | 90 | 38 | 236.8% | 19 | 473.7% | ### Example Cost Calculation diff --git a/docs/concepts/incentives/postage-stamps.md b/docs/concepts/incentives/postage-stamps.md index f7381a56a..589e11889 100644 --- a/docs/concepts/incentives/postage-stamps.md +++ b/docs/concepts/incentives/postage-stamps.md @@ -1,11 +1,12 @@ --- title: Postage Stamps id: postage-stamps +description: Details prepaid batch system for uploading data to Swarm with dynamic pricing based on network redundancy signals. --- Postage stamps are used to pay for storing data on Swarm. They are purchased in batches, granting a prepaid right to store data on Swarm, similar to how real-world postage stamps pay for mail delivery. -When a node uploads data to Swarm, it 'attaches' postage stamps to each [chunk](/docs/concepts/DISC/) of data. The value assigned to a stamp indicates how much it is worth to persist the associated data on Swarm, which nodes use to prioritize which chunks to remove from their reserve first. +When a node uploads data to Swarm, it 'attaches' postage stamps to each [chunk](./../DISC/DISC.mdx) of data. The value assigned to a stamp indicates how much it is worth to persist the associated data on Swarm, which nodes use to prioritize which chunks to remove from their reserve first. The value of a postage stamp decreases over time as if storage rent was regularly deducted from the batch balance. A stamp expires when its batch runs out of balance. Chunks with expired stamps cannot be used as proof in the redistribution game, meaning storer nodes will no longer receive rewards for storing them and can safely remove them from their reserves. @@ -32,17 +33,17 @@ $$ $$ :::info -Note that due how buckets fill as described above, a batch can become fully utilised before its theoretical maximum volume has been reached. See [batch utilisation section below](/docs/concepts/incentives/postage-stamps#batch-utilisation) for more information. +Note that due how buckets fill as described above, a batch can become fully utilised before its theoretical maximum volume has been reached. See [batch utilisation section below](./postage-stamps.md#batch-utilisation) for more information. ::: ## Batch Depth and Batch Amount -Each batch of stamps has two key parameters, `batch depth` and `amount`, which are recorded on Gnosis Chain at issuance. Note that these "depths" do not refer to the depth terms used to describe topology which are outlined [here in the glossary](/docs/references/glossary#depth-types). +Each batch of stamps has two key parameters, `batch depth` and `amount`, which are recorded on Gnosis Chain at issuance. Note that these "depths" do not refer to the depth terms used to describe topology which are outlined [here in the glossary](./../../references/glossary.md#depth-types). ### Batch Depth :::caution -The minimum value for `depth` is 17, however higher depths are recommended for most use cases due to the [mechanics of stamp batch utilisation](#batch-utilisation). See [the depths utilisation table](#effective-utilisation-table) to help decide which depth is best for your use case. +The minimum value for `depth` is 17, however higher depths are recommended for most use cases due to the [mechanics of stamp batch utilisation](#batch-utilisation). See [the depths utilisation table](#effective-utilisation-tables) to help decide which depth is best for your use case. ::: `Batch depth` determines how much data can be stored by a batch. The number of chunks which can be stored (stamped) by a batch is equal to $$2^{batchDepth}$$. @@ -55,7 +56,7 @@ $$ \text{Theoretical maximum batch volume} = 2^{batchDepth} \times \text{4 kb} $$ -However, due to the way postage stamp batches are utilised, batches will become fully utilised before stamping the theoretical maximum number of chunks. Therefore when deciding which batch depth to use, it is important to consider the effective amount of data that can be stored by a batch, and not the theoretical maximum. The effective rate of utilisation increases along with the batch depth. See [section on stamp batch utilisation below](/docs/concepts/incentives/postage-stamps#batch-utilisation) for more information. +However, due to the way postage stamp batches are utilised, batches will become fully utilised before stamping the theoretical maximum number of chunks. Therefore when deciding which batch depth to use, it is important to consider the effective amount of data that can be stored by a batch, and not the theoretical maximum. The effective rate of utilisation increases along with the batch depth. See [section on stamp batch utilisation below](./postage-stamps.md#batch-utilisation) for more information. ### Batch Amount (& Batch Cost) @@ -103,7 +104,7 @@ Utilisation of an immutable batch is computed using a hash map of size $$2^{buck ![](/img/batches_01.png) -As chunks are uploaded to Swarm, each chunk is assigned to a bucket based the first 16 binary digits of the [chunk's hash](/docs/concepts/DISC/#chunks). The chunk will be assigned to whichever bucket's key matches the first 16 bits of its hash, and that bucket's counter will be incremented by 1. +As chunks are uploaded to Swarm, each chunk is assigned to a bucket based the first 16 binary digits of the [chunk's hash](./../DISC/DISC.mdx#chunks). The chunk will be assigned to whichever bucket's key matches the first 16 bits of its hash, and that bucket's counter will be incremented by 1. The batch is deemed "full" when ANY of these counters reach a certain max value. The max value is computed from the batch depth as such: $$2^{(batchDepth-bucketDepth)}$$. For example with batch depth of 24, the max value is $$2^{(24-16)}$$ or 256. A bucket can be thought of as have a number of "slots" equal to this maximum value, and every time the bucket's counter is incremented, one of its slots gets filled. @@ -176,20 +177,22 @@ The implications of this behaviour are that even a small change to the data of a ### Implications for Swarm Users -Due to the nature of batch utilisation described above, batches are often fully utilised before reaching their theoretical maximum storage amount. However as the batch depth increases, the chance of a postage batch becoming fully utilised early decreases. At batch depth 24, there is a 0.1% chance that a batch will be fully utilised/start replacing old chunks before reaching 64.33% of its theoretical maximum. +Due to the nature of batch utilisation described above, batches are often fully utilised before reaching their theoretical maximum storage amount. However as the batch depth increases, the chance of a postage batch becoming fully utilised early decreases. At batch depth 24 (unencrypted, no erasure coding), there is a 0.1% chance that a batch will be fully utilised/start replacing old chunks before reaching 68.48% of its theoretical maximum. -Let's look at an example to make it clearer. Using the method of calculating the theoretical maximum storage amount [outlined above](/docs/concepts/incentives/postage-stamps#batch-depth), we can see that for a batch depth of 24, the theoretical maximum amount which can be stored is 68.72 gb: +Let's look at an example to make it clearer. Using the method of calculating the theoretical maximum storage amount [outlined above](./postage-stamps.md#batch-depth), we can see that for a batch depth of 24, the theoretical maximum amount which can be stored is 68.72 gb: $$ 2^{24+12} = \text{68,719,476,736 bytes} = \text{68.72 gb} $$ -Therefore we should use 64.33% the effective rate of usage for the stamp batch: +Therefore we should use 68.48% the effective rate of usage for the stamp batch: $$ -\text{68.72 gb} \times{0.6433} = \text{44.21 gb } +\text{68.72 gb} \times{0.6848} = \text{47.06 gb } $$ +Note that the effective volume also depends on the encryption and erasure coding settings used. The example above assumes unencrypted data with no erasure coding. See the [effective utilisation tables below](#effective-utilisation-tables) for the full set of effective volumes. + ## Effective Utilisation Tables @@ -198,14 +201,13 @@ When a user buys a batch of stamps they may make the naive assumption that they Columns: * **Theoretical Volume:** The theoretical maximum volume which can be reached if the batch is completely utilized. -* **Effective Volume:** The actual volume which a batch can be expected to store based with a failure rate of less than or equal to 0.1% (1 in 1000) +* **Effective Volume:** The actual volume which a batch can be expected to store with a failure rate of less than or equal to 0.1% (1 in 1000). * **Batch Depth:** The batch depth value. -* **Utilization Rate:** The percentage of the theoretical volume which can be expected to be used according to the effective volume. :::info The title of each table below states whether it is for encrypted or unencrypted uploads along with the erasure coding level. -[Erasure coding](/docs/concepts/DISC/erasure-coding) on Swarm has five named levels: +[Erasure coding](./../DISC/erasure-coding.md) on Swarm has five named levels: 1. NONE 2. MEDIUM @@ -216,300 +218,300 @@ The title of each table below states whether it is for encrypted or unencrypted ### Unencrypted - NONE -| Theoretical Volume | Effective Volume | Batch Depth | Utilization Rate | -| ------------- | ------------- | ------------- | ------------- | -| 536.87 MB | 44.70 kB | 17 | 0.01% | -| 1.07 GB | 6.66 MB | 18 | 0.61% | -| 2.15 GB | 112.06 MB | 19 | 5.09% | -| 4.29 GB | 687.62 MB | 20 | 15.65% | -| 8.59 GB | 2.60 GB | 21 | 30.27% | -| 17.18 GB | 7.73 GB | 22 | 44.99% | -| 34.36 GB | 19.94 GB | 23 | 58.03% | -| 68.72 GB | 47.06 GB | 24 | 68.48% | -| 137.44 GB | 105.51 GB | 25 | 76.77% | -| 274.88 GB | 227.98 GB | 26 | 82.94% | -| 549.76 GB | 476.68 GB | 27 | 86.71% | -| 1.10 TB | 993.65 GB | 28 | 88.37% | -| 2.20 TB | 2.04 TB | 29 | 92.88% | -| 4.40 TB | 4.17 TB | 30 | 94.81% | -| 8.80 TB | 8.45 TB | 31 | 96.06% | -| 17.59 TB | 17.07 TB | 32 | 97.01% | -| 35.18 TB | 34.36 TB | 33 | 97.65% | -| 70.37 TB | 69.04 TB | 34 | 98.11% | -| 140.74 TB | 138.54 TB | 35 | 98.44% | -| 281.47 TB | 277.72 TB | 36 | 98.67% | -| 562.95 TB | 556.35 TB | 37 | 98.83% | -| 1.13 PB | 1.11 PB | 38 | 98.91% | -| 2.25 PB | 2.23 PB | 39 | 98.96% | -| 4.50 PB | 4.46 PB | 40 | 98.98% | -| 9.01 PB | 8.93 PB | 41 | 99.11% | +| Theoretical Volume | Effective Volume | Batch Depth | +| ------------- | ------------- | ------------- | +| 536.87 MB | 44.70 kB | 17 | +| 1.07 GB | 6.66 MB | 18 | +| 2.15 GB | 112.06 MB | 19 | +| 4.29 GB | 687.62 MB | 20 | +| 8.59 GB | 2.60 GB | 21 | +| 17.18 GB | 7.73 GB | 22 | +| 34.36 GB | 19.94 GB | 23 | +| 68.72 GB | 47.06 GB | 24 | +| 137.44 GB | 105.51 GB | 25 | +| 274.88 GB | 227.98 GB | 26 | +| 549.76 GB | 476.68 GB | 27 | +| 1.10 TB | 993.65 GB | 28 | +| 2.20 TB | 2.04 TB | 29 | +| 4.40 TB | 4.17 TB | 30 | +| 8.80 TB | 8.45 TB | 31 | +| 17.59 TB | 17.07 TB | 32 | +| 35.18 TB | 34.36 TB | 33 | +| 70.37 TB | 69.04 TB | 34 | +| 140.74 TB | 138.54 TB | 35 | +| 281.47 TB | 277.72 TB | 36 | +| 562.95 TB | 556.35 TB | 37 | +| 1.13 PB | 1.11 PB | 38 | +| 2.25 PB | 2.23 PB | 39 | +| 4.50 PB | 4.46 PB | 40 | +| 9.01 PB | 8.93 PB | 41 | ### Unencrypted - MEDIUM -| Theoretical Volume | Effective Volume | Batch Depth | Utilization Rate | -| ------------- | ------------- | ------------- | ------------- | -| 536.87 MB | 41.56 kB | 17 | 0.01% | -| 1.07 GB | 6.19 MB | 18 | 0.57% | -| 2.15 GB | 104.18 MB | 19 | 4.73% | -| 4.29 GB | 639.27 MB | 20 | 14.54% | -| 8.59 GB | 2.41 GB | 21 | 28.11% | -| 17.18 GB | 7.18 GB | 22 | 41.79% | -| 34.36 GB | 18.54 GB | 23 | 53.95% | -| 68.72 GB | 43.75 GB | 24 | 63.66% | -| 137.44 GB | 98.09 GB | 25 | 71.37% | -| 274.88 GB | 211.95 GB | 26 | 77.11% | -| 549.76 GB | 443.16 GB | 27 | 80.61% | -| 1.10 TB | 923.78 GB | 28 | 82.16% | -| 2.20 TB | 1.90 TB | 29 | 86.30% | -| 4.40 TB | 3.88 TB | 30 | 88.14% | -| 8.80 TB | 7.86 TB | 31 | 89.26% | -| 17.59 TB | 15.87 TB | 32 | 90.21% | -| 35.18 TB | 31.94 TB | 33 | 90.77% | -| 70.37 TB | 64.19 TB | 34 | 91.22% | -| 140.74 TB | 128.80 TB | 35 | 91.52% | -| 281.47 TB | 258.19 TB | 36 | 91.73% | -| 562.95 TB | 517.23 TB | 37 | 91.88% | -| 1.13 PB | 1.04 PB | 38 | 91.95% | -| 2.25 PB | 2.07 PB | 39 | 92.00% | -| 4.50 PB | 4.15 PB | 40 | 92.15% | -| 9.01 PB | 8.30 PB | 41 | 92.14% | +| Theoretical Volume | Effective Volume | Batch Depth | +| ------------- | ------------- | ------------- | +| 536.87 MB | 41.56 kB | 17 | +| 1.07 GB | 6.19 MB | 18 | +| 2.15 GB | 104.18 MB | 19 | +| 4.29 GB | 639.27 MB | 20 | +| 8.59 GB | 2.41 GB | 21 | +| 17.18 GB | 7.18 GB | 22 | +| 34.36 GB | 18.54 GB | 23 | +| 68.72 GB | 43.75 GB | 24 | +| 137.44 GB | 98.09 GB | 25 | +| 274.88 GB | 211.95 GB | 26 | +| 549.76 GB | 443.16 GB | 27 | +| 1.10 TB | 923.78 GB | 28 | +| 2.20 TB | 1.90 TB | 29 | +| 4.40 TB | 3.88 TB | 30 | +| 8.80 TB | 7.86 TB | 31 | +| 17.59 TB | 15.87 TB | 32 | +| 35.18 TB | 31.94 TB | 33 | +| 70.37 TB | 64.19 TB | 34 | +| 140.74 TB | 128.80 TB | 35 | +| 281.47 TB | 258.19 TB | 36 | +| 562.95 TB | 517.23 TB | 37 | +| 1.13 PB | 1.04 PB | 38 | +| 2.25 PB | 2.07 PB | 39 | +| 4.50 PB | 4.15 PB | 40 | +| 9.01 PB | 8.30 PB | 41 | ### Unencrypted - STRONG -| Theoretical Volume | Effective Volume | Batch Depth | Utilization Rate | -| ------------- | ------------- | ------------- | ------------- | -| 536.87 MB | 37.37 kB | 17 | 0.01% | -| 1.07 GB | 5.57 MB | 18 | 0.51% | -| 2.15 GB | 93.68 MB | 19 | 4.25% | -| 4.29 GB | 574.81 MB | 20 | 13.07% | -| 8.59 GB | 2.17 GB | 21 | 25.26% | -| 17.18 GB | 6.46 GB | 22 | 37.58% | -| 34.36 GB | 16.67 GB | 23 | 48.50% | -| 68.72 GB | 39.34 GB | 24 | 57.24% | -| 137.44 GB | 88.20 GB | 25 | 64.17% | -| 274.88 GB | 190.58 GB | 26 | 69.33% | -| 549.76 GB | 398.47 GB | 27 | 72.48% | -| 1.10 TB | 830.63 GB | 28 | 73.85% | -| 2.20 TB | 1.71 TB | 29 | 77.59% | -| 4.40 TB | 3.49 TB | 30 | 79.27% | -| 8.80 TB | 7.07 TB | 31 | 80.34% | -| 17.59 TB | 14.27 TB | 32 | 81.12% | -| 35.18 TB | 28.72 TB | 33 | 81.63% | -| 70.37 TB | 57.71 TB | 34 | 82.01% | -| 140.74 TB | 115.81 TB | 35 | 82.29% | -| 281.47 TB | 232.16 TB | 36 | 82.48% | -| 562.95 TB | 465.07 TB | 37 | 82.61% | -| 1.13 PB | 931.23 TB | 38 | 82.67% | -| 2.25 PB | 1.86 PB | 39 | 82.71% | -| 4.50 PB | 3.73 PB | 40 | 82.78% | -| 9.01 PB | 7.46 PB | 41 | 82.79% | +| Theoretical Volume | Effective Volume | Batch Depth | +| ------------- | ------------- | ------------- | +| 536.87 MB | 37.37 kB | 17 | +| 1.07 GB | 5.57 MB | 18 | +| 2.15 GB | 93.68 MB | 19 | +| 4.29 GB | 574.81 MB | 20 | +| 8.59 GB | 2.17 GB | 21 | +| 17.18 GB | 6.46 GB | 22 | +| 34.36 GB | 16.67 GB | 23 | +| 68.72 GB | 39.34 GB | 24 | +| 137.44 GB | 88.20 GB | 25 | +| 274.88 GB | 190.58 GB | 26 | +| 549.76 GB | 398.47 GB | 27 | +| 1.10 TB | 830.63 GB | 28 | +| 2.20 TB | 1.71 TB | 29 | +| 4.40 TB | 3.49 TB | 30 | +| 8.80 TB | 7.07 TB | 31 | +| 17.59 TB | 14.27 TB | 32 | +| 35.18 TB | 28.72 TB | 33 | +| 70.37 TB | 57.71 TB | 34 | +| 140.74 TB | 115.81 TB | 35 | +| 281.47 TB | 232.16 TB | 36 | +| 562.95 TB | 465.07 TB | 37 | +| 1.13 PB | 931.23 TB | 38 | +| 2.25 PB | 1.86 PB | 39 | +| 4.50 PB | 3.73 PB | 40 | +| 9.01 PB | 7.46 PB | 41 | ### Unencrypted - INSANE -| Theoretical Volume | Effective Volume | Batch Depth | Utilization Rate | -| ------------- | ------------- | ------------- | ------------- | -| 536.87 MB | 33.88 kB | 17 | 0.01% | -| 1.07 GB | 5.05 MB | 18 | 0.46% | -| 2.15 GB | 84.92 MB | 19 | 3.86% | -| 4.29 GB | 521.09 MB | 20 | 11.85% | -| 8.59 GB | 1.97 GB | 21 | 22.90% | -| 17.18 GB | 5.86 GB | 22 | 34.09% | -| 34.36 GB | 15.11 GB | 23 | 43.97% | -| 68.72 GB | 35.66 GB | 24 | 51.90% | -| 137.44 GB | 79.96 GB | 25 | 58.18% | -| 274.88 GB | 172.77 GB | 26 | 62.85% | -| 549.76 GB | 361.23 GB | 27 | 65.70% | -| 1.10 TB | 753.00 GB | 28 | 66.95% | -| 2.20 TB | 1.55 TB | 29 | 70.38% | -| 4.40 TB | 3.16 TB | 30 | 71.92% | -| 8.80 TB | 6.41 TB | 31 | 72.85% | -| 17.59 TB | 12.93 TB | 32 | 73.53% | -| 35.18 TB | 26.04 TB | 33 | 74.01% | -| 70.37 TB | 52.32 TB | 34 | 74.35% | -| 140.74 TB | 104.99 TB | 35 | 74.60% | -| 281.47 TB | 210.46 TB | 36 | 74.77% | -| 562.95 TB | 421.61 TB | 37 | 74.89% | -| 1.13 PB | 844.20 TB | 38 | 74.94% | -| 2.25 PB | 1.69 PB | 39 | 74.98% | -| 4.50 PB | 3.38 PB | 40 | 75.03% | -| 9.01 PB | 6.77 PB | 41 | 75.10% | +| Theoretical Volume | Effective Volume | Batch Depth | +| ------------- | ------------- | ------------- | +| 536.87 MB | 33.88 kB | 17 | +| 1.07 GB | 5.05 MB | 18 | +| 2.15 GB | 84.92 MB | 19 | +| 4.29 GB | 521.09 MB | 20 | +| 8.59 GB | 1.97 GB | 21 | +| 17.18 GB | 5.86 GB | 22 | +| 34.36 GB | 15.11 GB | 23 | +| 68.72 GB | 35.66 GB | 24 | +| 137.44 GB | 79.96 GB | 25 | +| 274.88 GB | 172.77 GB | 26 | +| 549.76 GB | 361.23 GB | 27 | +| 1.10 TB | 753.00 GB | 28 | +| 2.20 TB | 1.55 TB | 29 | +| 4.40 TB | 3.16 TB | 30 | +| 8.80 TB | 6.41 TB | 31 | +| 17.59 TB | 12.93 TB | 32 | +| 35.18 TB | 26.04 TB | 33 | +| 70.37 TB | 52.32 TB | 34 | +| 140.74 TB | 104.99 TB | 35 | +| 281.47 TB | 210.46 TB | 36 | +| 562.95 TB | 421.61 TB | 37 | +| 1.13 PB | 844.20 TB | 38 | +| 2.25 PB | 1.69 PB | 39 | +| 4.50 PB | 3.38 PB | 40 | +| 9.01 PB | 6.77 PB | 41 | ### Unencrypted - PARANOID -| Theoretical Volume | Effective Volume | Batch Depth | Utilization Rate | -| ------------- | ------------- | ------------- | ------------- | -| 536.87 MB | 13.27 kB | 17 | 0.00% | -| 1.07 GB | 1.98 MB | 18 | 0.18% | -| 2.15 GB | 33.27 MB | 19 | 1.51% | -| 4.29 GB | 204.14 MB | 20 | 4.64% | -| 8.59 GB | 771.13 MB | 21 | 8.75% | -| 17.18 GB | 2.29 GB | 22 | 13.34% | -| 34.36 GB | 5.92 GB | 23 | 17.22% | -| 68.72 GB | 13.97 GB | 24 | 20.33% | -| 137.44 GB | 31.32 GB | 25 | 22.79% | -| 274.88 GB | 67.68 GB | 26 | 24.62% | -| 549.76 GB | 141.51 GB | 27 | 25.74% | -| 1.10 TB | 294.99 GB | 28 | 26.23% | -| 2.20 TB | 606.90 GB | 29 | 27.56% | -| 4.40 TB | 1.24 TB | 30 | 28.15% | -| 8.80 TB | 2.51 TB | 31 | 28.54% | -| 17.59 TB | 5.07 TB | 32 | 28.82% | -| 35.18 TB | 10.20 TB | 33 | 28.99% | -| 70.37 TB | 20.50 TB | 34 | 29.13% | -| 140.74 TB | 41.13 TB | 35 | 29.22% | -| 281.47 TB | 82.45 TB | 36 | 29.29% | -| 562.95 TB | 165.17 TB | 37 | 29.34% | -| 1.13 PB | 330.72 TB | 38 | 29.37% | -| 2.25 PB | 661.97 TB | 39 | 29.39% | -| 4.50 PB | 1.32 PB | 40 | 29.41% | -| 9.01 PB | 2.65 PB | 41 | 29.43% | +| Theoretical Volume | Effective Volume | Batch Depth | +| ------------- | ------------- | ------------- | +| 536.87 MB | 13.27 kB | 17 | +| 1.07 GB | 1.98 MB | 18 | +| 2.15 GB | 33.27 MB | 19 | +| 4.29 GB | 204.14 MB | 20 | +| 8.59 GB | 771.13 MB | 21 | +| 17.18 GB | 2.29 GB | 22 | +| 34.36 GB | 5.92 GB | 23 | +| 68.72 GB | 13.97 GB | 24 | +| 137.44 GB | 31.32 GB | 25 | +| 274.88 GB | 67.68 GB | 26 | +| 549.76 GB | 141.51 GB | 27 | +| 1.10 TB | 294.99 GB | 28 | +| 2.20 TB | 606.90 GB | 29 | +| 4.40 TB | 1.24 TB | 30 | +| 8.80 TB | 2.51 TB | 31 | +| 17.59 TB | 5.07 TB | 32 | +| 35.18 TB | 10.20 TB | 33 | +| 70.37 TB | 20.50 TB | 34 | +| 140.74 TB | 41.13 TB | 35 | +| 281.47 TB | 82.45 TB | 36 | +| 562.95 TB | 165.17 TB | 37 | +| 1.13 PB | 330.72 TB | 38 | +| 2.25 PB | 661.97 TB | 39 | +| 4.50 PB | 1.32 PB | 40 | +| 9.01 PB | 2.65 PB | 41 | ### Encrypted - NONE -| Theoretical Volume | Effective Volume | Batch Depth | Utilization Rate | -| ------------- | ------------- | ------------- | ------------- | -| 536.87 MB | 44.35 kB | 17 | 0.01% | -| 1.07 GB | 6.61 MB | 18 | 0.60% | -| 2.15 GB | 111.18 MB | 19 | 5.05% | -| 4.29 GB | 682.21 MB | 20 | 15.52% | -| 8.59 GB | 2.58 GB | 21 | 30.04% | -| 17.18 GB | 7.67 GB | 22 | 44.62% | -| 34.36 GB | 19.78 GB | 23 | 57.56% | -| 68.72 GB | 46.69 GB | 24 | 67.93% | -| 137.44 GB | 104.68 GB | 25 | 76.16% | -| 274.88 GB | 226.19 GB | 26 | 82.29% | -| 549.76 GB | 472.93 GB | 27 | 86.02% | -| 1.10 TB | 985.83 GB | 28 | 87.66% | -| 2.20 TB | 2.03 TB | 29 | 92.25% | -| 4.40 TB | 4.14 TB | 30 | 94.21% | -| 8.80 TB | 8.39 TB | 31 | 95.37% | -| 17.59 TB | 16.93 TB | 32 | 96.22% | -| 35.18 TB | 34.09 TB | 33 | 96.88% | -| 70.37 TB | 68.50 TB | 34 | 97.34% | -| 140.74 TB | 137.45 TB | 35 | 97.67% | -| 281.47 TB | 275.53 TB | 36 | 97.89% | -| 562.95 TB | 551.97 TB | 37 | 98.05% | -| 1.13 PB | 1.11 PB | 38 | 98.13% | -| 2.25 PB | 2.21 PB | 39 | 98.18% | -| 4.50 PB | 4.43 PB | 40 | 98.36% | -| 9.01 PB | 8.86 PB | 41 | 98.37% | +| Theoretical Volume | Effective Volume | Batch Depth | +| ------------- | ------------- | ------------- | +| 536.87 MB | 44.35 kB | 17 | +| 1.07 GB | 6.61 MB | 18 | +| 2.15 GB | 111.18 MB | 19 | +| 4.29 GB | 682.21 MB | 20 | +| 8.59 GB | 2.58 GB | 21 | +| 17.18 GB | 7.67 GB | 22 | +| 34.36 GB | 19.78 GB | 23 | +| 68.72 GB | 46.69 GB | 24 | +| 137.44 GB | 104.68 GB | 25 | +| 274.88 GB | 226.19 GB | 26 | +| 549.76 GB | 472.93 GB | 27 | +| 1.10 TB | 985.83 GB | 28 | +| 2.20 TB | 2.03 TB | 29 | +| 4.40 TB | 4.14 TB | 30 | +| 8.80 TB | 8.39 TB | 31 | +| 17.59 TB | 16.93 TB | 32 | +| 35.18 TB | 34.09 TB | 33 | +| 70.37 TB | 68.50 TB | 34 | +| 140.74 TB | 137.45 TB | 35 | +| 281.47 TB | 275.53 TB | 36 | +| 562.95 TB | 551.97 TB | 37 | +| 1.13 PB | 1.11 PB | 38 | +| 2.25 PB | 2.21 PB | 39 | +| 4.50 PB | 4.43 PB | 40 | +| 9.01 PB | 8.86 PB | 41 | ### Encrypted - MEDIUM -| Theoretical Volume | Effective Volume | Batch Depth | Utilization Rate | -| ------------- | ------------- | ------------- | ------------- | -| 536.87 MB | 40.89 kB | 17 | 0.01% | -| 1.07 GB | 6.09 MB | 18 | 0.56% | -| 2.15 GB | 102.49 MB | 19 | 4.65% | -| 4.29 GB | 628.91 MB | 20 | 14.30% | -| 8.59 GB | 2.38 GB | 21 | 27.68% | -| 17.18 GB | 7.07 GB | 22 | 41.15% | -| 34.36 GB | 18.24 GB | 23 | 53.09% | -| 68.72 GB | 43.04 GB | 24 | 62.63% | -| 137.44 GB | 96.50 GB | 25 | 70.21% | -| 274.88 GB | 208.52 GB | 26 | 75.86% | -| 549.76 GB | 435.98 GB | 27 | 79.30% | -| 1.10 TB | 908.81 GB | 28 | 80.82% | -| 2.20 TB | 1.87 TB | 29 | 84.98% | -| 4.40 TB | 3.81 TB | 30 | 86.67% | -| 8.80 TB | 7.73 TB | 31 | 87.84% | -| 17.59 TB | 15.61 TB | 32 | 88.74% | -| 35.18 TB | 31.43 TB | 33 | 89.34% | -| 70.37 TB | 63.15 TB | 34 | 89.74% | -| 140.74 TB | 126.71 TB | 35 | 90.03% | -| 281.47 TB | 254.01 TB | 36 | 90.24% | -| 562.95 TB | 508.85 TB | 37 | 90.39% | -| 1.13 PB | 1.02 PB | 38 | 90.47% | -| 2.25 PB | 2.04 PB | 39 | 90.51% | -| 4.50 PB | 4.08 PB | 40 | 90.64% | -| 9.01 PB | 8.17 PB | 41 | 90.65% | +| Theoretical Volume | Effective Volume | Batch Depth | +| ------------- | ------------- | ------------- | +| 536.87 MB | 40.89 kB | 17 | +| 1.07 GB | 6.09 MB | 18 | +| 2.15 GB | 102.49 MB | 19 | +| 4.29 GB | 628.91 MB | 20 | +| 8.59 GB | 2.38 GB | 21 | +| 17.18 GB | 7.07 GB | 22 | +| 34.36 GB | 18.24 GB | 23 | +| 68.72 GB | 43.04 GB | 24 | +| 137.44 GB | 96.50 GB | 25 | +| 274.88 GB | 208.52 GB | 26 | +| 549.76 GB | 435.98 GB | 27 | +| 1.10 TB | 908.81 GB | 28 | +| 2.20 TB | 1.87 TB | 29 | +| 4.40 TB | 3.81 TB | 30 | +| 8.80 TB | 7.73 TB | 31 | +| 17.59 TB | 15.61 TB | 32 | +| 35.18 TB | 31.43 TB | 33 | +| 70.37 TB | 63.15 TB | 34 | +| 140.74 TB | 126.71 TB | 35 | +| 281.47 TB | 254.01 TB | 36 | +| 562.95 TB | 508.85 TB | 37 | +| 1.13 PB | 1.02 PB | 38 | +| 2.25 PB | 2.04 PB | 39 | +| 4.50 PB | 4.08 PB | 40 | +| 9.01 PB | 8.17 PB | 41 | ### Encrypted - STRONG -| Theoretical Volume | Effective Volume | Batch Depth | Utilization Rate | -| ------------- | ------------- | ------------- | ------------- | -| 536.87 MB | 36.73 kB | 17 | 0.01% | -| 1.07 GB | 5.47 MB | 18 | 0.50% | -| 2.15 GB | 92.07 MB | 19 | 4.18% | -| 4.29 GB | 564.95 MB | 20 | 12.85% | -| 8.59 GB | 2.13 GB | 21 | 24.86% | -| 17.18 GB | 6.35 GB | 22 | 36.97% | -| 34.36 GB | 16.38 GB | 23 | 47.67% | -| 68.72 GB | 38.66 GB | 24 | 56.26% | -| 137.44 GB | 86.69 GB | 25 | 63.07% | -| 274.88 GB | 187.31 GB | 26 | 68.14% | -| 549.76 GB | 391.64 GB | 27 | 71.24% | -| 1.10 TB | 816.39 GB | 28 | 72.59% | -| 2.20 TB | 1.68 TB | 29 | 76.34% | -| 4.40 TB | 3.43 TB | 30 | 77.89% | -| 8.80 TB | 6.94 TB | 31 | 78.86% | -| 17.59 TB | 14.02 TB | 32 | 79.71% | -| 35.18 TB | 28.23 TB | 33 | 80.23% | -| 70.37 TB | 56.72 TB | 34 | 80.60% | -| 140.74 TB | 113.82 TB | 35 | 80.88% | -| 281.47 TB | 228.18 TB | 36 | 81.06% | -| 562.95 TB | 457.10 TB | 37 | 81.20% | -| 1.13 PB | 915.26 TB | 38 | 81.26% | -| 2.25 PB | 1.83 PB | 39 | 81.30% | -| 4.50 PB | 3.67 PB | 40 | 81.43% | -| 9.01 PB | 7.34 PB | 41 | 81.45% | +| Theoretical Volume | Effective Volume | Batch Depth | +| ------------- | ------------- | ------------- | +| 536.87 MB | 36.73 kB | 17 | +| 1.07 GB | 5.47 MB | 18 | +| 2.15 GB | 92.07 MB | 19 | +| 4.29 GB | 564.95 MB | 20 | +| 8.59 GB | 2.13 GB | 21 | +| 17.18 GB | 6.35 GB | 22 | +| 34.36 GB | 16.38 GB | 23 | +| 68.72 GB | 38.66 GB | 24 | +| 137.44 GB | 86.69 GB | 25 | +| 274.88 GB | 187.31 GB | 26 | +| 549.76 GB | 391.64 GB | 27 | +| 1.10 TB | 816.39 GB | 28 | +| 2.20 TB | 1.68 TB | 29 | +| 4.40 TB | 3.43 TB | 30 | +| 8.80 TB | 6.94 TB | 31 | +| 17.59 TB | 14.02 TB | 32 | +| 35.18 TB | 28.23 TB | 33 | +| 70.37 TB | 56.72 TB | 34 | +| 140.74 TB | 113.82 TB | 35 | +| 281.47 TB | 228.18 TB | 36 | +| 562.95 TB | 457.10 TB | 37 | +| 1.13 PB | 915.26 TB | 38 | +| 2.25 PB | 1.83 PB | 39 | +| 4.50 PB | 3.67 PB | 40 | +| 9.01 PB | 7.34 PB | 41 | ### Encrypted - INSANE -| Theoretical Volume | Effective Volume | Batch Depth | Utilization Rate | -| ------------- | ------------- | ------------- | ------------- | -| 536.87 MB | 33.26 kB | 17 | 0.01% | -| 1.07 GB | 4.96 MB | 18 | 0.45% | -| 2.15 GB | 83.38 MB | 19 | 3.79% | -| 4.29 GB | 511.65 MB | 20 | 11.64% | -| 8.59 GB | 1.93 GB | 21 | 22.52% | -| 17.18 GB | 5.75 GB | 22 | 33.50% | -| 34.36 GB | 14.84 GB | 23 | 43.19% | -| 68.72 GB | 35.02 GB | 24 | 50.96% | -| 137.44 GB | 78.51 GB | 25 | 57.12% | -| 274.88 GB | 169.64 GB | 26 | 61.71% | -| 549.76 GB | 354.69 GB | 27 | 64.52% | -| 1.10 TB | 739.37 GB | 28 | 65.74% | -| 2.20 TB | 1.52 TB | 29 | 69.15% | -| 4.40 TB | 3.10 TB | 30 | 70.56% | -| 8.80 TB | 6.29 TB | 31 | 71.48% | -| 17.59 TB | 12.70 TB | 32 | 72.18% | -| 35.18 TB | 25.57 TB | 33 | 72.67% | -| 70.37 TB | 51.37 TB | 34 | 73.00% | -| 140.74 TB | 103.08 TB | 35 | 73.24% | -| 281.47 TB | 206.65 TB | 36 | 73.42% | -| 562.95 TB | 413.98 TB | 37 | 73.54% | -| 1.13 PB | 828.91 TB | 38 | 73.59% | -| 2.25 PB | 1.66 PB | 39 | 73.62% | -| 4.50 PB | 3.32 PB | 40 | 73.72% | -| 9.01 PB | 6.64 PB | 41 | 73.74% | +| Theoretical Volume | Effective Volume | Batch Depth | +| ------------- | ------------- | ------------- | +| 536.87 MB | 33.26 kB | 17 | +| 1.07 GB | 4.96 MB | 18 | +| 2.15 GB | 83.38 MB | 19 | +| 4.29 GB | 511.65 MB | 20 | +| 8.59 GB | 1.93 GB | 21 | +| 17.18 GB | 5.75 GB | 22 | +| 34.36 GB | 14.84 GB | 23 | +| 68.72 GB | 35.02 GB | 24 | +| 137.44 GB | 78.51 GB | 25 | +| 274.88 GB | 169.64 GB | 26 | +| 549.76 GB | 354.69 GB | 27 | +| 1.10 TB | 739.37 GB | 28 | +| 2.20 TB | 1.52 TB | 29 | +| 4.40 TB | 3.10 TB | 30 | +| 8.80 TB | 6.29 TB | 31 | +| 17.59 TB | 12.70 TB | 32 | +| 35.18 TB | 25.57 TB | 33 | +| 70.37 TB | 51.37 TB | 34 | +| 140.74 TB | 103.08 TB | 35 | +| 281.47 TB | 206.65 TB | 36 | +| 562.95 TB | 413.98 TB | 37 | +| 1.13 PB | 828.91 TB | 38 | +| 2.25 PB | 1.66 PB | 39 | +| 4.50 PB | 3.32 PB | 40 | +| 9.01 PB | 6.64 PB | 41 | ### Encrypted - PARANOID -| Theoretical Volume | Effective Volume | Batch Depth | Utilization Rate | -| ------------- | ------------- | ------------- | ------------- | -| 536.87 MB | 13.17 kB | 17 | 0.00% | -| 1.07 GB | 1.96 MB | 18 | 0.18% | -| 2.15 GB | 33.01 MB | 19 | 1.50% | -| 4.29 GB | 202.53 MB | 20 | 4.61% | -| 8.59 GB | 765.05 MB | 21 | 8.68% | -| 17.18 GB | 2.28 GB | 22 | 13.27% | -| 34.36 GB | 5.87 GB | 23 | 17.08% | -| 68.72 GB | 13.86 GB | 24 | 20.17% | -| 137.44 GB | 31.08 GB | 25 | 22.61% | -| 274.88 GB | 67.15 GB | 26 | 24.43% | -| 549.76 GB | 140.40 GB | 27 | 25.54% | -| 1.10 TB | 292.67 GB | 28 | 26.03% | -| 2.20 TB | 602.12 GB | 29 | 27.35% | -| 4.40 TB | 1.23 TB | 30 | 27.94% | -| 8.80 TB | 2.49 TB | 31 | 28.32% | -| 17.59 TB | 5.03 TB | 32 | 28.60% | -| 35.18 TB | 10.12 TB | 33 | 28.77% | -| 70.37 TB | 20.34 TB | 34 | 28.91% | -| 140.74 TB | 40.80 TB | 35 | 29.00% | -| 281.47 TB | 81.80 TB | 36 | 29.06% | -| 562.95 TB | 163.87 TB | 37 | 29.11% | -| 1.13 PB | 328.11 TB | 38 | 29.14% | -| 2.25 PB | 656.76 TB | 39 | 29.16% | -| 4.50 PB | 1.31 PB | 40 | 29.18% | -| 9.01 PB | 2.63 PB | 41 | 29.19% | \ No newline at end of file +| Theoretical Volume | Effective Volume | Batch Depth | +| ------------- | ------------- | ------------- | +| 536.87 MB | 13.17 kB | 17 | +| 1.07 GB | 1.96 MB | 18 | +| 2.15 GB | 33.01 MB | 19 | +| 4.29 GB | 202.53 MB | 20 | +| 8.59 GB | 765.05 MB | 21 | +| 17.18 GB | 2.28 GB | 22 | +| 34.36 GB | 5.87 GB | 23 | +| 68.72 GB | 13.86 GB | 24 | +| 137.44 GB | 31.08 GB | 25 | +| 274.88 GB | 67.15 GB | 26 | +| 549.76 GB | 140.40 GB | 27 | +| 1.10 TB | 292.67 GB | 28 | +| 2.20 TB | 602.12 GB | 29 | +| 4.40 TB | 1.23 TB | 30 | +| 8.80 TB | 2.49 TB | 31 | +| 17.59 TB | 5.03 TB | 32 | +| 35.18 TB | 10.12 TB | 33 | +| 70.37 TB | 20.34 TB | 34 | +| 140.74 TB | 40.80 TB | 35 | +| 281.47 TB | 81.80 TB | 36 | +| 562.95 TB | 163.87 TB | 37 | +| 1.13 PB | 328.11 TB | 38 | +| 2.25 PB | 656.76 TB | 39 | +| 4.50 PB | 1.31 PB | 40 | +| 9.01 PB | 2.63 PB | 41 | \ No newline at end of file diff --git a/docs/develop/tools-and-features/buy-a-stamp-batch.md b/docs/develop/tools-and-features/buy-a-stamp-batch.md index 8b9c6d384..be51797c9 100644 --- a/docs/develop/tools-and-features/buy-a-stamp-batch.md +++ b/docs/develop/tools-and-features/buy-a-stamp-batch.md @@ -1,6 +1,7 @@ --- title: Postage Stamp Batches id: buy-a-stamp-batch +description: Guide for purchasing postage stamp batches required for uploading data to Swarm. --- import VolumeAndDurationCalc from '@site/src/components/VolumeAndDurationCalc.js'; import AmountAndDepthCalc from '@site/src/components/AmountAndDepthCalc.js'; @@ -12,18 +13,18 @@ import { globalVariables } from '/src/config/globalVariables' -A postage batch is required to upload data to Swarm. Postage stamp batches represent _right to write_ data on Swarm's [DISC (Distributed Immutable Store of Chunks)](/docs/concepts/DISC/). The parameters which control the duration and quantity of data that can be stored by a postage batch are `depth` and `amount`, with `depth` determining data volume that can be uploaded by the batch and `amount` determining storage duration of data uploaded with the batch. +A postage batch is required to upload data to Swarm. Postage stamp batches represent _right to write_ data on Swarm's [DISC (Distributed Immutable Store of Chunks)](./../../concepts/DISC/DISC.mdx). The parameters which control the duration and quantity of data that can be stored by a postage batch are `depth` and `amount`, with `depth` determining data volume that can be uploaded by the batch and `amount` determining storage duration of data uploaded with the batch. :::info - The storage volume and duration are both non-deterministic. Volume is non-deterministic due to the details of how [postage stamp batch utilization](/docs/concepts/incentives/postage-stamps#batch-utilisation) works. While duration is non-deterministic due to price changes made by the [price oracle contract](/docs/concepts/incentives/price-oracle). + The storage volume and duration are both non-deterministic. Volume is non-deterministic due to the details of how [postage stamp batch utilization](./../../concepts/incentives/postage-stamps.md#batch-utilisation) works. While duration is non-deterministic due to price changes made by the [price oracle contract](./../../concepts/incentives/price-oracle.md). **Storage volume and `depth`:** - When purchasing stamp batches for larger volumes of data (by increasing the `depth` value), the amount of data which can be stored becomes increasingly more predictable. For example, at `depth` 22 a batch can store between 4.93 GB and 17.18 GB, while at `depth` 28, a batch can store between 1.0 and 1.1 TB of data, and at higher depths the difference between the minimum and maximum storage volumes approach the same value. + When purchasing stamp batches for larger volumes of data (by increasing the `depth` value), the amount of data which can be stored becomes increasingly more predictable. For example, at `depth` 22 a batch can store between 2.28 GB (encrypted, paranoid erasure coding) and 17.18 GB (theoretical max), while at `depth` 28, a batch can store between 292.67 GB and 1.1 TB of data, and at higher depths the difference between the minimum and maximum storage volumes approach the same value. The effective volume also depends on the encryption and erasure coding settings used. See the [effective utilisation tables](./../../concepts/incentives/postage-stamps.md#effective-utilisation-tables) for the full details. **Storage duration and `amount`:** - The duration of time for which a batch can store data is also non-deterministic since the price of storage is automatically adjusted over time by the [price oracle contract](/docs/concepts/incentives/price-oracle). However, limits have been placed on how swiftly the price of storage can change, so there is no danger of a rapid change in price causing postage batches to unexpectedly expire due to a rapid increase in price. You can view a history of price changes by inspecting the events emitted by the oracle contract, or also through the [Swarmscan API](https://api.swarmscan.io/v1/events/storage-price-oracle/price-update). As you can see, if and when postage batch prices are updated, the updates are quite small. Still, since it is not entirely deterministic, it is important to monitor your stamp batch TTL (time to live) as it will change along with price oracle changes. You can inspect your batch's TTL using the `/stamps` endpoint of the API: + The duration of time for which a batch can store data is also non-deterministic since the price of storage is automatically adjusted over time by the [price oracle contract](./../../concepts/incentives/price-oracle.md). However, limits have been placed on how swiftly the price of storage can change, so there is no danger of a rapid change in price causing postage batches to unexpectedly expire due to a rapid increase in price. You can view a history of price changes by inspecting the events emitted by the oracle contract, or also through the [Swarmscan API](https://api.swarmscan.io/v1/events/storage-price-oracle/price-update). As you can see, if and when postage batch prices are updated, the updates are quite small. Still, since it is not entirely deterministic, it is important to monitor your stamp batch TTL (time to live) as it will change along with price oracle changes. You can inspect your batch's TTL using the `/stamps` endpoint of the API: ```bash root@noah-bee:~# curl -s localhost:1633/stamps | jq @@ -49,7 +50,7 @@ A postage batch is required to upload data to Swarm. Postage stamp batches repre ::: -For a deeper understanding of how `depth` and `amount` parameters determine the data volume and storage duration of a postage batch, see the [postage stamp page](/docs/concepts/incentives/postage-stamps/). +For a deeper understanding of how `depth` and `amount` parameters determine the data volume and storage duration of a postage batch, see the [postage stamp page](./../../concepts/incentives/postage-stamps.md). ## Fund your node's wallet. @@ -59,7 +60,7 @@ xBZZ can be obtained from a variety of different centralized and decentralized e xDAI can be obtained from a wide range of centralized and decentralized exchanges. See [this list of exchanges](https://docs.gnosischain.com/about/tokens/xdai) from the Gnosis Chain documentation to get started. -You can learn more details from the [Fund Your Node](/docs/bee/installation/fund-your-node/) section. +You can learn more details from the [Fund Your Node](./../../bee/installation/fund-your-node.md) section. ## Buying a stamp batch @@ -133,12 +134,12 @@ When purchasing a batch of stamps there are several parameters and options which ### Choosing *depth* :::caution -The minimum value for `depth` is 17, however a higher depth value is recommended for most use cases due to the [mechanics of stamp batch utilisation](/docs/concepts/incentives/postage-stamps/#batch-utilisation). See [the depths utilisation table](/docs/concepts/incentives/postage-stamps/#effective-utilisation-table) to help decide which depth is best for your use case. +The minimum value for `depth` is 17, however a higher depth value is recommended for most use cases due to the [mechanics of stamp batch utilisation](./../../concepts/incentives/postage-stamps.md#batch-utilisation). See [the depths utilisation table](./../../concepts/incentives/postage-stamps.md#effective-utilisation-tables) to help decide which depth is best for your use case. ::: One notable aspect of batch utilisation is that the entire batch is considered fully utilised as soon as any one of its buckets are filled. This means that the actual amount of chunks storable by a batch is less than the nominal maximum amount. -See the [postage stamp page](/docs/concepts/incentives/postage-stamps) for a more complete explanation of how batch utilisation works and a [table](/docs/concepts/incentives/postage-stamps#effective-utilisation-table) with the specific amounts of data which can be safely uploaded for each `depth` value. +See the [postage stamp page](./../../concepts/incentives/postage-stamps.md) for a more complete explanation of how batch utilisation works and a [table](./../../concepts/incentives/postage-stamps.md#effective-utilisation-tables) with the specific amounts of data which can be safely uploaded for each `depth` value. ### Choosing *amount* @@ -146,18 +147,18 @@ See the [postage stamp page](/docs/concepts/incentives/postage-stamps) for a mor The minimum `amount` value for purchasing stamps is required to be at least enough to pay for 24 hours of storage. To find this value multiply the lastPrice value from the postage stamp contract times 17280 (the number of blocks in 24 hours). You can also use the [calculator](#calculators) below. This requirement is in place in order to prevent spamming the network. ::: -The `amount` parameter determines how much xBZZ is assigned per chunk for a postage stamp batch. You can use the calculators below to find the appropriate `amount` value for your target duration of storage and can also preview the price. For more information see the [postage stamp](/docs/concepts/incentives/postage-stamps#batch-depth-and-batch-amount) page where a more complete description is included. +The `amount` parameter determines how much xBZZ is assigned per chunk for a postage stamp batch. You can use the calculators below to find the appropriate `amount` value for your target duration of storage and can also preview the price. For more information see the [postage stamp](./../../concepts/incentives/postage-stamps.md#batch-depth-and-batch-amount) page where a more complete description is included. ### Mutable or Immutable? -Depending on the use case, uploaders may desire to use mutable or immutable batches. The fundamental difference between immutable and mutable batches is that immutable batches become unusable once their capacity is filled, while for mutable batches, once their capacity is filled, they may continue to be used, however older chunks of data will be overwritten with the newer once over capacity. The default batch type is immutable. In order to set the batch type to mutable, the `immutable` header should be set to `false`. See [this section on postage stamp batch utilisation](/docs/concepts/incentives/postage-stamps#which-type-of-batch-to-use) to learn more about mutable vs immutable batches, and about which type may be right for your use case. +Depending on the use case, uploaders may desire to use mutable or immutable batches. The fundamental difference between immutable and mutable batches is that immutable batches become unusable once their capacity is filled, while for mutable batches, once their capacity is filled, they may continue to be used, however older chunks of data will be overwritten with the newer once over capacity. The default batch type is immutable. In order to set the batch type to mutable, the `immutable` header should be set to `false`. See [this section on postage stamp batch utilisation](./../../concepts/incentives/postage-stamps.md#which-type-of-batch-to-use) to learn more about mutable vs immutable batches, and about which type may be right for your use case. ## Calculators The following postage batch calculators allow you to conveniently find the depth and amount values for a given storage duration and storage volume, or to find the storage duration and storage volume for a given depth and amount. The results will display the cost in xBZZ for the postage batch. The current pricing information is sourced from the Swarmscan API and will vary over time. :::info -The 'effective volume' is the volume of data that can safely stored for each storage depth. The 'theoretical max volume' is significantly lower than the effective volume at lower depths and the two values trend towards the same value at higher depths. The lowest depth with an effective volume above zero is 22, with an effective depth of 4.93 GB. Lower depth values can be used for smaller uploads but do not come with the same storage guarantees. [Learn more here](/docs/concepts/incentives/postage-stamps#effective-utilisation-table). +The 'effective volume' is the volume of data that can be safely stored for each batch depth, with a failure rate of less than 0.1%. The 'theoretical max volume' is significantly higher than the effective volume at lower depths, and the two values trend towards the same value at higher depths. Effective volumes are available for all depths from 17 to 41, and depend on the encryption and erasure coding settings selected. For example, at depth 17, the effective volume ranges from 13.17 kB (encrypted, paranoid) to 44.70 kB (unencrypted, no erasure coding). [Learn more here](./../../concepts/incentives/postage-stamps.md#effective-utilisation-tables). ::: ### Depth & Amount to Time & Volume Calculator @@ -166,7 +167,7 @@ The 'effective volume' is the volume of data that can safely stored for each sto ### Time & Volume to Depth & Amount Calculator -The recommended depth in this calculator's results is the lowest depth value whose [effective volume](/docs/concepts/incentives/postage-stamps#effective-utilisation-table) is greater than the entered volume. +The recommended depth in this calculator's results is the lowest depth value whose [effective volume](./../../concepts/incentives/postage-stamps.md#effective-utilisation-tables) is greater than the entered volume. @@ -244,7 +245,7 @@ It is not possible to reupload unencrypted content which was stamped using an ex At present, TTL is a primitive calculation based on the current storage price and the assumption that storage price will remain static in the future. As more data is uploaded into Swarm, the price of storage will begin to increase. For data that it is important to keep alive, make sure your batches have plenty of time to live! ::: -In order to make sure your *batch* has sufficient *remaining balance* to be stored and served by nodes in its [*area of responsibility*](/docs/references/glossary#2-area-of-responsibility-related-depths), you must regularly check on its _time to live_ and act accordingly. The *time to live* is the number of seconds before the chunks will be considered for garbage collection by nodes in the network. +In order to make sure your *batch* has sufficient *remaining balance* to be stored and served by nodes in its [*area of responsibility*](./../../references/glossary.md#2-area-of-responsibility-related-depths), you must regularly check on its _time to live_ and act accordingly. The *time to live* is the number of seconds before the chunks will be considered for garbage collection by nodes in the network. The remaining *time to live* in seconds is shown in the API in the returned json object as the value for `batchTTL`, and with Swarm CLI you will see the formatted TTL as the `TTL` value. @@ -503,7 +504,7 @@ Amount: 100010002000 ## Stewardship -The stewardship endpoint in combination with [pinning](/docs/develop/tools-and-features/pinning) can be used to guarantee that important content is always available. It is used for checking whether the content for a Swarm reference is retrievable and for re-uploading the content if it is not. +The stewardship endpoint in combination with [pinning](./pinning.md) can be used to guarantee that important content is always available. It is used for checking whether the content for a Swarm reference is retrievable and for re-uploading the content if it is not. An HTTP GET request to the `stewardship` endpoint checks to see whether the content for the specified Swarm reference is retrievable: diff --git a/src/components/AmountAndDepthCalc.js b/src/components/AmountAndDepthCalc.js index e04910ab9..479efc2ad 100644 --- a/src/components/AmountAndDepthCalc.js +++ b/src/components/AmountAndDepthCalc.js @@ -6,6 +6,8 @@ function FetchPriceComponent() { const [timeUnit, setTimeUnit] = useState('hours'); const [volume, setVolume] = useState(''); const [volumeUnit, setVolumeUnit] = useState('GB'); + const [isEncrypted, setIsEncrypted] = useState(false); + const [erasureLevel, setErasureLevel] = useState('none'); const [convertedTime, setConvertedTime] = useState(null); const [minimumDepth, setMinimumDepth] = useState(null); const [depth, setDepth] = useState(null); @@ -16,53 +18,303 @@ function FetchPriceComponent() { const [timeError, setTimeError] = useState(''); const [volumeError, setVolumeError] = useState(''); - // Volume in GB - const volumeToDepth = { - "4.93" : 22, - "17.03": 23, - "44.21": 24, - "102.78": 25, - "225.86": 26, - "480.43": 27, - "1024.00": 28, - "2109.44": 29, - "4300.80": 30, - "8724.48": 31, - "17612.80": 32, - "35461.12": 33, - "71249.92": 34, - "142981.12": 35, - "286627.84": 36, - "574187.52": 37, - "1174405.12": 38, - "2359296.00": 39, - "4718592.00": 40, - "9437184.00": 41 + // Effective volume tables from Gyuri's simulations (ν=16, logBucketSize 1-25, i.e. depth 17-41) + // These account for batch utilization (0.1% failure quantile), PAC overhead, and erasure coding overhead. + // label: human-readable effective volume, gb: value in GB for comparison + const depthToEffectiveVolume = { + unencrypted: { + none: { + 17: { label: "44.70 kB", gb: 0.000043 }, + 18: { label: "6.66 MB", gb: 0.006504 }, + 19: { label: "112.06 MB", gb: 0.109434 }, + 20: { label: "687.62 MB", gb: 0.671504 }, + 21: { label: "2.60 GB", gb: 2.60 }, + 22: { label: "7.73 GB", gb: 7.73 }, + 23: { label: "19.94 GB", gb: 19.94 }, + 24: { label: "47.06 GB", gb: 47.06 }, + 25: { label: "105.51 GB", gb: 105.51 }, + 26: { label: "227.98 GB", gb: 227.98 }, + 27: { label: "476.68 GB", gb: 476.68 }, + 28: { label: "993.65 GB", gb: 993.65 }, + 29: { label: "2.04 TB", gb: 2088.96 }, + 30: { label: "4.17 TB", gb: 4270.08 }, + 31: { label: "8.45 TB", gb: 8652.80 }, + 32: { label: "17.07 TB", gb: 17479.68 }, + 33: { label: "34.36 TB", gb: 35184.64 }, + 34: { label: "69.04 TB", gb: 70696.96 }, + 35: { label: "138.54 TB", gb: 141864.96 }, + 36: { label: "277.72 TB", gb: 284385.28 }, + 37: { label: "556.35 TB", gb: 569702.40 }, + 38: { label: "1.11 PB", gb: 1163919.36 }, + 39: { label: "2.23 PB", gb: 2338324.48 }, + 40: { label: "4.46 PB", gb: 4676648.96 }, + 41: { label: "8.93 PB", gb: 9363783.68 }, + }, + medium: { + 17: { label: "41.56 kB", gb: 0.000040 }, + 18: { label: "6.19 MB", gb: 0.006045 }, + 19: { label: "104.18 MB", gb: 0.101738 }, + 20: { label: "639.27 MB", gb: 0.624287 }, + 21: { label: "2.41 GB", gb: 2.41 }, + 22: { label: "7.18 GB", gb: 7.18 }, + 23: { label: "18.54 GB", gb: 18.54 }, + 24: { label: "43.75 GB", gb: 43.75 }, + 25: { label: "98.09 GB", gb: 98.09 }, + 26: { label: "211.95 GB", gb: 211.95 }, + 27: { label: "443.16 GB", gb: 443.16 }, + 28: { label: "923.78 GB", gb: 923.78 }, + 29: { label: "1.90 TB", gb: 1945.60 }, + 30: { label: "3.88 TB", gb: 3973.12 }, + 31: { label: "7.86 TB", gb: 8048.64 }, + 32: { label: "15.87 TB", gb: 16250.88 }, + 33: { label: "31.94 TB", gb: 32706.56 }, + 34: { label: "64.19 TB", gb: 65730.56 }, + 35: { label: "128.80 TB", gb: 131891.20 }, + 36: { label: "258.19 TB", gb: 264386.56 }, + 37: { label: "517.23 TB", gb: 529643.52 }, + 38: { label: "1.04 PB", gb: 1090519.04 }, + 39: { label: "2.07 PB", gb: 2170552.32 }, + 40: { label: "4.15 PB", gb: 4351590.40 }, + 41: { label: "8.30 PB", gb: 8703180.80 }, + }, + strong: { + 17: { label: "37.37 kB", gb: 0.000036 }, + 18: { label: "5.57 MB", gb: 0.005439 }, + 19: { label: "93.68 MB", gb: 0.091484 }, + 20: { label: "574.81 MB", gb: 0.561338 }, + 21: { label: "2.17 GB", gb: 2.17 }, + 22: { label: "6.46 GB", gb: 6.46 }, + 23: { label: "16.67 GB", gb: 16.67 }, + 24: { label: "39.34 GB", gb: 39.34 }, + 25: { label: "88.20 GB", gb: 88.20 }, + 26: { label: "190.58 GB", gb: 190.58 }, + 27: { label: "398.47 GB", gb: 398.47 }, + 28: { label: "830.63 GB", gb: 830.63 }, + 29: { label: "1.71 TB", gb: 1751.04 }, + 30: { label: "3.49 TB", gb: 3573.76 }, + 31: { label: "7.07 TB", gb: 7239.68 }, + 32: { label: "14.27 TB", gb: 14612.48 }, + 33: { label: "28.72 TB", gb: 29409.28 }, + 34: { label: "57.71 TB", gb: 59095.04 }, + 35: { label: "115.81 TB", gb: 118589.44 }, + 36: { label: "232.16 TB", gb: 237731.84 }, + 37: { label: "465.07 TB", gb: 476231.68 }, + 38: { label: "931.23 TB", gb: 953579.52 }, + 39: { label: "1.86 PB", gb: 1950351.36 }, + 40: { label: "3.73 PB", gb: 3911188.48 }, + 41: { label: "7.46 PB", gb: 7822376.96 }, + }, + insane: { + 17: { label: "33.88 kB", gb: 0.000032 }, + 18: { label: "5.05 MB", gb: 0.004932 }, + 19: { label: "84.92 MB", gb: 0.082930 }, + 20: { label: "521.09 MB", gb: 0.508877 }, + 21: { label: "1.97 GB", gb: 1.97 }, + 22: { label: "5.86 GB", gb: 5.86 }, + 23: { label: "15.11 GB", gb: 15.11 }, + 24: { label: "35.66 GB", gb: 35.66 }, + 25: { label: "79.96 GB", gb: 79.96 }, + 26: { label: "172.77 GB", gb: 172.77 }, + 27: { label: "361.23 GB", gb: 361.23 }, + 28: { label: "753.00 GB", gb: 753.00 }, + 29: { label: "1.55 TB", gb: 1587.20 }, + 30: { label: "3.16 TB", gb: 3235.84 }, + 31: { label: "6.41 TB", gb: 6563.84 }, + 32: { label: "12.93 TB", gb: 13240.32 }, + 33: { label: "26.04 TB", gb: 26664.96 }, + 34: { label: "52.32 TB", gb: 53575.68 }, + 35: { label: "104.99 TB", gb: 107509.76 }, + 36: { label: "210.46 TB", gb: 215511.04 }, + 37: { label: "421.61 TB", gb: 431728.64 }, + 38: { label: "844.20 TB", gb: 864460.80 }, + 39: { label: "1.69 PB", gb: 1772093.44 }, + 40: { label: "3.38 PB", gb: 3544186.88 }, + 41: { label: "6.77 PB", gb: 7098859.52 }, + }, + paranoid: { + 17: { label: "13.27 kB", gb: 0.000013 }, + 18: { label: "1.98 MB", gb: 0.001934 }, + 19: { label: "33.27 MB", gb: 0.032490 }, + 20: { label: "204.14 MB", gb: 0.199355 }, + 21: { label: "771.13 MB", gb: 0.753057 }, + 22: { label: "2.29 GB", gb: 2.29 }, + 23: { label: "5.92 GB", gb: 5.92 }, + 24: { label: "13.97 GB", gb: 13.97 }, + 25: { label: "31.32 GB", gb: 31.32 }, + 26: { label: "67.68 GB", gb: 67.68 }, + 27: { label: "141.51 GB", gb: 141.51 }, + 28: { label: "294.99 GB", gb: 294.99 }, + 29: { label: "606.90 GB", gb: 606.90 }, + 30: { label: "1.24 TB", gb: 1269.76 }, + 31: { label: "2.51 TB", gb: 2570.24 }, + 32: { label: "5.07 TB", gb: 5191.68 }, + 33: { label: "10.20 TB", gb: 10444.80 }, + 34: { label: "20.50 TB", gb: 20992.00 }, + 35: { label: "41.13 TB", gb: 42117.12 }, + 36: { label: "82.45 TB", gb: 84428.80 }, + 37: { label: "165.17 TB", gb: 169134.08 }, + 38: { label: "330.72 TB", gb: 338657.28 }, + 39: { label: "661.97 TB", gb: 677857.28 }, + 40: { label: "1.32 PB", gb: 1384120.32 }, + 41: { label: "2.65 PB", gb: 2778726.40 }, + }, + }, + encrypted: { + none: { + 17: { label: "44.35 kB", gb: 0.000042 }, + 18: { label: "6.61 MB", gb: 0.006455 }, + 19: { label: "111.18 MB", gb: 0.108574 }, + 20: { label: "682.21 MB", gb: 0.666221 }, + 21: { label: "2.58 GB", gb: 2.58 }, + 22: { label: "7.67 GB", gb: 7.67 }, + 23: { label: "19.78 GB", gb: 19.78 }, + 24: { label: "46.69 GB", gb: 46.69 }, + 25: { label: "104.68 GB", gb: 104.68 }, + 26: { label: "226.19 GB", gb: 226.19 }, + 27: { label: "472.93 GB", gb: 472.93 }, + 28: { label: "985.83 GB", gb: 985.83 }, + 29: { label: "2.03 TB", gb: 2078.72 }, + 30: { label: "4.14 TB", gb: 4239.36 }, + 31: { label: "8.39 TB", gb: 8591.36 }, + 32: { label: "16.93 TB", gb: 17336.32 }, + 33: { label: "34.09 TB", gb: 34908.16 }, + 34: { label: "68.50 TB", gb: 70144.00 }, + 35: { label: "137.45 TB", gb: 140748.80 }, + 36: { label: "275.53 TB", gb: 282142.72 }, + 37: { label: "551.97 TB", gb: 565217.28 }, + 38: { label: "1.11 PB", gb: 1163919.36 }, + 39: { label: "2.21 PB", gb: 2317352.96 }, + 40: { label: "4.43 PB", gb: 4645191.68 }, + 41: { label: "8.86 PB", gb: 9290383.36 }, + }, + medium: { + 17: { label: "40.89 kB", gb: 0.000039 }, + 18: { label: "6.09 MB", gb: 0.005947 }, + 19: { label: "102.49 MB", gb: 0.100088 }, + 20: { label: "628.91 MB", gb: 0.614170 }, + 21: { label: "2.38 GB", gb: 2.38 }, + 22: { label: "7.07 GB", gb: 7.07 }, + 23: { label: "18.24 GB", gb: 18.24 }, + 24: { label: "43.04 GB", gb: 43.04 }, + 25: { label: "96.50 GB", gb: 96.50 }, + 26: { label: "208.52 GB", gb: 208.52 }, + 27: { label: "435.98 GB", gb: 435.98 }, + 28: { label: "908.81 GB", gb: 908.81 }, + 29: { label: "1.87 TB", gb: 1914.88 }, + 30: { label: "3.81 TB", gb: 3901.44 }, + 31: { label: "7.73 TB", gb: 7915.52 }, + 32: { label: "15.61 TB", gb: 15984.64 }, + 33: { label: "31.43 TB", gb: 32184.32 }, + 34: { label: "63.15 TB", gb: 64665.60 }, + 35: { label: "126.71 TB", gb: 129751.04 }, + 36: { label: "254.01 TB", gb: 260106.24 }, + 37: { label: "508.85 TB", gb: 521062.40 }, + 38: { label: "1.02 PB", gb: 1069547.52 }, + 39: { label: "2.04 PB", gb: 2139095.04 }, + 40: { label: "4.08 PB", gb: 4278190.08 }, + 41: { label: "8.17 PB", gb: 8566865.92 }, + }, + strong: { + 17: { label: "36.73 kB", gb: 0.000035 }, + 18: { label: "5.47 MB", gb: 0.005342 }, + 19: { label: "92.07 MB", gb: 0.089912 }, + 20: { label: "564.95 MB", gb: 0.551709 }, + 21: { label: "2.13 GB", gb: 2.13 }, + 22: { label: "6.35 GB", gb: 6.35 }, + 23: { label: "16.38 GB", gb: 16.38 }, + 24: { label: "38.66 GB", gb: 38.66 }, + 25: { label: "86.69 GB", gb: 86.69 }, + 26: { label: "187.31 GB", gb: 187.31 }, + 27: { label: "391.64 GB", gb: 391.64 }, + 28: { label: "816.39 GB", gb: 816.39 }, + 29: { label: "1.68 TB", gb: 1720.32 }, + 30: { label: "3.43 TB", gb: 3512.32 }, + 31: { label: "6.94 TB", gb: 7106.56 }, + 32: { label: "14.02 TB", gb: 14356.48 }, + 33: { label: "28.23 TB", gb: 28907.52 }, + 34: { label: "56.72 TB", gb: 58081.28 }, + 35: { label: "113.82 TB", gb: 116551.68 }, + 36: { label: "228.18 TB", gb: 233656.32 }, + 37: { label: "457.10 TB", gb: 468070.40 }, + 38: { label: "915.26 TB", gb: 937226.24 }, + 39: { label: "1.83 PB", gb: 1918894.08 }, + 40: { label: "3.67 PB", gb: 3848273.92 }, + 41: { label: "7.34 PB", gb: 7696547.84 }, + }, + insane: { + 17: { label: "33.26 kB", gb: 0.000032 }, + 18: { label: "4.96 MB", gb: 0.004844 }, + 19: { label: "83.38 MB", gb: 0.081426 }, + 20: { label: "511.65 MB", gb: 0.499658 }, + 21: { label: "1.93 GB", gb: 1.93 }, + 22: { label: "5.75 GB", gb: 5.75 }, + 23: { label: "14.84 GB", gb: 14.84 }, + 24: { label: "35.02 GB", gb: 35.02 }, + 25: { label: "78.51 GB", gb: 78.51 }, + 26: { label: "169.64 GB", gb: 169.64 }, + 27: { label: "354.69 GB", gb: 354.69 }, + 28: { label: "739.37 GB", gb: 739.37 }, + 29: { label: "1.52 TB", gb: 1556.48 }, + 30: { label: "3.10 TB", gb: 3174.40 }, + 31: { label: "6.29 TB", gb: 6440.96 }, + 32: { label: "12.70 TB", gb: 13004.80 }, + 33: { label: "25.57 TB", gb: 26183.68 }, + 34: { label: "51.37 TB", gb: 52602.88 }, + 35: { label: "103.08 TB", gb: 105553.92 }, + 36: { label: "206.65 TB", gb: 211609.60 }, + 37: { label: "413.98 TB", gb: 423915.52 }, + 38: { label: "828.91 TB", gb: 848803.84 }, + 39: { label: "1.66 PB", gb: 1740636.16 }, + 40: { label: "3.32 PB", gb: 3481272.32 }, + 41: { label: "6.64 PB", gb: 6962544.64 }, + }, + paranoid: { + 17: { label: "13.17 kB", gb: 0.000013 }, + 18: { label: "1.96 MB", gb: 0.001914 }, + 19: { label: "33.01 MB", gb: 0.032236 }, + 20: { label: "202.53 MB", gb: 0.197783 }, + 21: { label: "765.05 MB", gb: 0.747119 }, + 22: { label: "2.28 GB", gb: 2.28 }, + 23: { label: "5.87 GB", gb: 5.87 }, + 24: { label: "13.86 GB", gb: 13.86 }, + 25: { label: "31.08 GB", gb: 31.08 }, + 26: { label: "67.15 GB", gb: 67.15 }, + 27: { label: "140.40 GB", gb: 140.40 }, + 28: { label: "292.67 GB", gb: 292.67 }, + 29: { label: "602.12 GB", gb: 602.12 }, + 30: { label: "1.23 TB", gb: 1259.52 }, + 31: { label: "2.49 TB", gb: 2549.76 }, + 32: { label: "5.03 TB", gb: 5150.72 }, + 33: { label: "10.12 TB", gb: 10362.88 }, + 34: { label: "20.34 TB", gb: 20828.16 }, + 35: { label: "40.80 TB", gb: 41779.20 }, + 36: { label: "81.80 TB", gb: 83763.20 }, + 37: { label: "163.87 TB", gb: 167802.88 }, + 38: { label: "328.11 TB", gb: 335984.64 }, + 39: { label: "656.76 TB", gb: 672522.24 }, + 40: { label: "1.31 PB", gb: 1373634.56 }, + 41: { label: "2.63 PB", gb: 2757754.88 }, + }, + }, }; - const depthToVolume = { - 22: "4.93 GB", - 23: "17.03 GB", - 24: "44.21 GB", - 25: "102.78 GB", - 26: "225.86 GB", - 27: "480.43 GB", - 28: "1.00 TB", - 29: "2.06 TB", - 30: "4.20 TB", - 31: "8.52 TB", - 32: "17.20 TB", - 33: "34.63 TB", - 34: "69.58 TB", - 35: "139.63 TB", - 36: "279.91 TB", - 37: "560.73 TB", - 38: "1.12 PB", - 39: "2.25 PB", - 40: "4.50 PB", - 41: "9.00 PB", - }; + function formatBytes(bytes) { + const KB = 1000; + const MB = KB ** 2; + const GB = KB ** 3; + const TB = KB ** 4; + const PB = KB ** 5; + if (bytes < GB) { + return (bytes / MB).toFixed(2) + ' MB'; + } else if (bytes < TB) { + return (bytes / GB).toFixed(2) + ' GB'; + } else if (bytes < PB) { + return (bytes / TB).toFixed(2) + ' TB'; + } else { + return (bytes / PB).toFixed(2) + ' PB'; + } + } useEffect(() => { fetchPrice(); @@ -75,7 +327,7 @@ function FetchPriceComponent() { if (minimumDepth !== null && amount !== null) { calculateMinimumDepthStorageCost(); } - }, [depth, amount, minimumDepth]); + }, [depth, amount, minimumDepth]); const fetchPrice = async () => { try { @@ -92,6 +344,10 @@ function FetchPriceComponent() { } }; + const getEffectiveVolumeTable = () => { + const encKey = isEncrypted ? 'encrypted' : 'unencrypted'; + return depthToEffectiveVolume[encKey][erasureLevel]; + }; const handleCalculate = () => { if (!price) { @@ -102,53 +358,63 @@ function FetchPriceComponent() { setShowResults(false); setTimeError(''); setVolumeError(''); - + const hours = convertTimeToHours(time, timeUnit); const gigabytes = convertVolumeToGB(volume, volumeUnit); - - if (!hours || !gigabytes) return; - + + if (!hours || !gigabytes) return; + setConvertedTime(hours); - calculateDepth(gigabytes); - setMinimumDepth(calculateMinimumDepth(gigabytes)); - calculateAmount(hours * 3600 / 5); - setShowResults(true); - }; - + const table = getEffectiveVolumeTable(); + + // Find the smallest depth whose effective volume (in GB) >= requested volume + let foundDepth = null; + for (let d = 17; d <= 41; d++) { + if (table[d] && table[d].gb >= gigabytes) { + foundDepth = d; + break; + } + } - const calculateDepth = (gigabytes) => { - const keys = Object.keys(volumeToDepth).map(key => parseFloat(key)).sort((a, b) => a - b); - let foundKey = keys.find(key => key >= gigabytes); - setDepth(foundKey ? volumeToDepth[foundKey.toFixed(2)] : 'No suitable depth found'); + if (!foundDepth) { + setVolumeError('Requested volume exceeds maximum available effective volume for the selected settings.'); + return; + } + + setDepth(foundDepth); + + // Minimum depth: based on theoretical max volume (2^(depth+12) bytes), ignoring utilization + const minDepth = calculateMinimumDepth(gigabytes); + setMinimumDepth(minDepth); + + // Amount: blocks * price + const blocks = hours * 3600 / 5; + const totalAmount = blocks * price; + setAmount(totalAmount); + + setShowResults(true); }; const calculateMinimumDepth = (gigabytes) => { - for (let depth = 17; depth <= 41; depth++) { - if (gigabytes <= Math.pow(2, 12 + depth) / (1024 ** 3)) { - return depth; + for (let d = 17; d <= 41; d++) { + if (gigabytes <= Math.pow(2, 12 + d) / (1024 ** 3)) { + return d; } } return null; }; - const calculateAmount = (blocks) => { - if (price !== null) { - const totalAmount = blocks * price; - setAmount(totalAmount); - } - }; - const calculateStorageCost = () => { if (depth !== null && amount !== null) { - const cost = ((2**depth) * amount) / 1e16; + const cost = ((2 ** depth) * amount) / 1e16; setStorageCost(cost.toFixed(4)); } }; const calculateMinimumDepthStorageCost = () => { if (minimumDepth !== null && amount !== null) { - const cost = ((2**minimumDepth) * amount) / 1e16; + const cost = ((2 ** minimumDepth) * amount) / 1e16; setMinimumDepthStorageCost(cost.toFixed(4)); } }; @@ -166,7 +432,6 @@ function FetchPriceComponent() { } return hours; }; - const convertVolumeToGB = (volume, unit) => { const num = parseFloat(volume); @@ -174,118 +439,173 @@ function FetchPriceComponent() { setVolumeError('Volume must be a positive number.'); return 0; } - const gigabytes = num * (unit === 'TB' ? 1024 : unit === 'PB' ? 1048576 : unit === 'MB' ? 1/1024 : 1); - if (gigabytes <= 0 || gigabytes > 9437184) { - setVolumeError('Volume must be greater than 0 and less than 9 PB.'); + const gigabytes = num * (unit === 'TB' ? 1024 : unit === 'PB' ? 1048576 : unit === 'MB' ? 1 / 1024 : unit === 'kB' ? 1 / (1024 * 1024) : 1); + if (gigabytes <= 0) { + setVolumeError('Volume must be greater than 0.'); + return 0; + } + + // Check against max effective volume for the selected settings + const table = getEffectiveVolumeTable(); + const maxGb = table[41].gb; + if (gigabytes > maxGb) { + setVolumeError(`Volume exceeds maximum effective volume (${table[41].label}) for the selected encryption and erasure settings.`); return 0; } return gigabytes; }; - - + + const getEffectiveVolumeLabel = (d) => { + const table = getEffectiveVolumeTable(); + return table[d] ? table[d].label : "N/A"; + }; + + const erasureLevelLabels = { + none: "None", + medium: "Medium", + strong: "Strong", + insane: "Insane", + paranoid: "Paranoid", + }; return ( -
+
setTime(e.target.value)} - placeholder="Enter time (>= 24 hrs)" + id="timeInput" + style={{ marginRight: '5px', padding: '8px' }} + value={time} + onChange={e => setTime(e.target.value)} + placeholder="Enter time (>= 24 hrs)" /> {timeError &&

{timeError}

}
-
- - setVolume(e.target.value)} - placeholder="Enter volume (<= 9 PB)" - /> - +
+ + setVolume(e.target.value)} + placeholder="Enter volume" + /> + + {volumeError &&

{volumeError}

} +
+
+ + +
+
+ +
+
+ +
- {volumeError &&

{volumeError}

} -
-
- -
- {showResults && !timeError && !volumeError && ( -
-
- {`In order to store ${volume} ${volumeUnit} of data for ${time} ${timeUnit}, a depth of ${depth} and an amount value of ${amount} should be used.`} +
+
+ {`In order to store ${volume} ${volumeUnit} of data for ${time} ${timeUnit}`} + {` (${isEncrypted ? 'encrypted' : 'unencrypted'}, ${erasureLevelLabels[erasureLevel]} erasure coding),`} + {` a depth of ${depth} and an amount value of ${amount} should be used.`} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldValue
Time{convertedTime} hours
Volume{`${volume} ${volumeUnit}`}
Encryption{isEncrypted ? 'Yes' : 'No'}
Erasure Coding{erasureLevelLabels[erasureLevel]}
Suggested Minimum Amount{amount + 10} PLUR
Suggested Safe Depth{`${depth} (for an `}effective volume{` of ${getEffectiveVolumeLabel(depth)})`}
Suggested Minimum Depth{minimumDepth} (see batch utilisation - may require dilution)
Batch Cost for Safe Depth{storageCost} xBZZ
Batch Cost for Minimum Depth{minimumDepthStorageCost} xBZZ
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldValue
Time{convertedTime} hours
Volume{`${volume} ${volumeUnit}`}
Suggested Minimum Amount{amount +10} PLUR
Suggested Safe Depth{`${depth} (for an `}effective volume{` of ${depthToVolume[depth]})`}
Suggested Minimum Depth{minimumDepth} (see batch utilisation - may require dilution)
Batch Cost for Safe Depth{storageCost} xBZZ
Batch Cost for Minimum Depth{minimumDepthStorageCost} xBZZ
-
)}
); diff --git a/src/components/RedundancyCalc.js b/src/components/RedundancyCalc.js index d8cb825df..1ecf968d8 100644 --- a/src/components/RedundancyCalc.js +++ b/src/components/RedundancyCalc.js @@ -9,10 +9,11 @@ export default function UploadCostCalc() { const [redundancy, setRedundancy] = useState(""); const [isEncrypted, setIsEncrypted] = useState(false); const [unit, setUnit] = useState("chunks"); - const maxChunks = [119, 107, 97, 37]; + const maxChunks = [119, 107, 97, 38]; const maxParities = [9, 21, 31, 90]; - const maxChunksEncrypted = [59, 53, 48, 18]; + const maxChunksEncrypted = [59, 53, 48, 19]; const errorTolerances = { + None: "0%", Medium: "1%", Strong: "5%", Insane: "10%", @@ -26,6 +27,10 @@ export default function UploadCostCalc() { return formattedNum; }; + const formatChunks = (num) => { + return Math.round(num).toLocaleString(); + }; + const handleDataSizeChange = (e) => { setDataSize(e.target.value); }; @@ -95,25 +100,32 @@ export default function UploadCostCalc() { // Add PAC overhead to total chunks const totalChunksWithPac = totalChunks + pacOverheadChunks; - const redundancyLevels = { Medium: 0, Strong: 1, Insane: 2, Paranoid: 3 }; + const redundancyLevels = { None: -1, Medium: 0, Strong: 1, Insane: 2, Paranoid: 3 }; const redundancyLevel = redundancyLevels[redundancy]; - - const quotient = isEncrypted - ? Math.floor(totalChunksWithPac / maxChunksEncrypted[redundancyLevel]) - : Math.floor(totalChunksWithPac / maxChunks[redundancyLevel]); - const remainder = isEncrypted - ? totalChunksWithPac % maxChunksEncrypted[redundancyLevel] - : totalChunksWithPac % maxChunks[redundancyLevel]; - - let remainderParities = 0; - if (remainder > 0) { - const remainderIndex = remainder - 1 < 0 ? 0 : remainder - 1; - const selectedParities = isEncrypted ? paritiesEncrypted : parities; - remainderParities = selectedParities[redundancyLevel][remainderIndex] || 0; + + let totalParities = 0; + + if (redundancyLevel >= 0) { + // Apply erasure coding to the original totalChunks (NOT totalChunksWithPac) + const quotient = isEncrypted + ? Math.floor(totalChunks / maxChunksEncrypted[redundancyLevel]) + : Math.floor(totalChunks / maxChunks[redundancyLevel]); + const remainder = isEncrypted + ? totalChunks % maxChunksEncrypted[redundancyLevel] + : totalChunks % maxChunks[redundancyLevel]; + + let remainderParities = 0; + if (remainder > 0) { + const remainderIndex = remainder - 1; + const selectedParities = isEncrypted ? paritiesEncrypted : parities; + remainderParities = selectedParities[redundancyLevel][remainderIndex] || 0; + } + + totalParities = quotient * maxParities[redundancyLevel] + remainderParities; } - - const totalParities = quotient * maxParities[redundancyLevel] + remainderParities; - const totalDataWithParity = totalChunksWithPac + totalParities; + + // Total = original data + parity chunks + PAC overhead for both + const totalDataWithParity = totalChunks + totalParities + pacOverheadChunks; const percentDifference = ((totalDataWithParity - totalChunks) / totalChunks) * 100; // Calculate parity size in KB and GB @@ -133,14 +145,14 @@ export default function UploadCostCalc() { { name: "PAC overhead", value: unit === "gb" - ? `${formatNumberCustom(pacOverheadInKb / (1024 * 1024))} GB (${formatNumberCustom(pacOverheadChunks)} chunks)` - : `${formatNumberCustom(pacOverheadInKb)} KB (${formatNumberCustom(pacOverheadChunks)} chunks)`, + ? `${formatNumberCustom(pacOverheadInKb / (1024 * 1024))} GB (${formatChunks(pacOverheadChunks)} chunks)` + : `${formatNumberCustom(pacOverheadInKb)} KB (${formatChunks(pacOverheadChunks)} chunks)`, }, { name: "Parity data size", value: unit === "gb" - ? `${formatNumberCustom(parityDataInGb)} GB (${formatNumberCustom(totalParities)} chunks)` - : `${formatNumberCustom(parityDataInKb)} KB (${formatNumberCustom(totalParities)} chunks)`, + ? `${formatNumberCustom(parityDataInGb)} GB (${formatChunks(totalParities)} chunks)` + : `${formatNumberCustom(parityDataInKb)} KB (${formatChunks(totalParities)} chunks)`, }, { name: "Total overhead", @@ -150,15 +162,15 @@ export default function UploadCostCalc() { }, { name: "Source data in chunks", - value: formatNumberCustom(totalChunks) + value: formatChunks(totalChunks) }, { name: "Source with PAC overhead", - value: formatNumberCustom(totalChunksWithPac) + value: formatChunks(totalChunksWithPac) }, { name: "Total with parity", - value: formatNumberCustom(totalDataWithParity) + value: formatChunks(totalDataWithParity) }, { name: "Percent cost increase", @@ -225,6 +237,7 @@ export default function UploadCostCalc() {
Redundancy Level:
setErasureLevel(e.target.value)} + > + + + + + + + + + @@ -192,4 +296,4 @@ export default function DepthCalc() { )}
); -} \ No newline at end of file +} diff --git a/swarm-cli b/swarm-cli new file mode 160000 index 000000000..33ea54706 --- /dev/null +++ b/swarm-cli @@ -0,0 +1 @@ +Subproject commit 33ea54706007d848360b445c4fb927be39da21c5 From c4cd350a63931ccdaf2ec8a7584a4546bbec0739 Mon Sep 17 00:00:00 2001 From: NoahMaizels Date: Mon, 16 Mar 2026 16:26:45 +0700 Subject: [PATCH 2/4] fix: untrack files --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ef91acb0b..46284862a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .docusaurus +.claude node_modules .DS_Store build @@ -9,4 +10,5 @@ resources # Generated content /src/pages/awesome-swarm.mdx test -*.zip \ No newline at end of file +*.zip +swarm-cli \ No newline at end of file From b793a0801c431669a657d65d6f3796de41d7d3bb Mon Sep 17 00:00:00 2001 From: NoahMaizels Date: Mon, 16 Mar 2026 16:31:05 +0700 Subject: [PATCH 3/4] fix: untrack files --- src/components.zip | Bin 9782 -> 0 bytes swarm-cli | 1 - 2 files changed, 1 deletion(-) delete mode 100644 src/components.zip delete mode 160000 swarm-cli diff --git a/src/components.zip b/src/components.zip deleted file mode 100644 index 9e860f5c0eda0b2ac050c472a65e0dcdb732dcbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9782 zcma)i18`DWfcw(WeeZ6_Vuwr$(#*k&i`I33%5r~m)n_s)5B&$<6zyVhE} zR@E50_MWq9)RK!iX>b~g5QwkEdDP7E&Yut30Izt8?P zsj9#OL2i%XSOh@iSo~fU{sjaD^vC%BfC&EzBxqyjV(TnuYb;`7?`$q?U~NQi>GXH# z;q+PmLT|>ga9WUf;8uMLjS0n@Ac`l`;;ZLnHSjBT9Vn3qsm6<-Mys^3BChOKq8TxL z+j{K2NLi#KzzW#`P0{UrO-ZtEH-x6REayL<*pD}+>fYxorEtHuWGhsbTQ*LqBP*u} zQ}MmN8(W}gq|LdB8`@_*SQrvTkvo=#s4~QHsuaY}0#U50wu82960~+1=y+WQBVJf^8=g06vkhSkz&nSOVsSl=>13MFH$x}O0bk>&rF#WF8mO$Z_r9S`edFcXlx z%kSC}3JIDbkCz~g8p~`}6Fhg8p{YqNB93IfdyKb=pG(Sz0W7eu2 zTw*R>Y)EBfOo00n0uoYKF zjb6wmd?}mG;s%}8VkB7DHN4u>HCtH!U}WCb1Nbw4pcGg4YC(Q+I@x2l&gz_>;>l~l ztl2q-58qtHw^Jb6d1susB1A2eJDJVlJLVT%E!1Yt2mHal1)G4@!b6TTVB@#TBq~ zRPBe5u;bQ&Uv>>Dpu?*@2dP5*STvw3?+g!vXy)x)U-mawaMO2t;Znd_#8*)W7UYHM zsT7{elUu3(22sN@Y7-xcLJn`~!jeV-f5O292al7-?3e~etcyM{8F0*!vk#nwzA%vx z+{;Hqz<)5*6-b$dEKLf=i4zO$N_n#vE8@BcvN&2#6#QnMAv#OZL|!`R|2?5}lcqQ2 zK1SCvLU3;}Y4o+19`%geb3S$2Kk9KI)LjaW|7u@wK_rfpB^Zwo9n8(A%w3}y{IJq_ z)%vA!R_^l6I9=|26#;O&Y%{O5ialR~!&GXh!x4OHA(DARt_7}dNY^Urc}kgT(wGUc z6B+a~K5Y|uF1z}Ld;C(vQQ6Y@u$0s^t1i=XOhUDF=3Qtn;QW#*l1`bNcuh$!D$>6<9kSjHInnG&>M)*r{6Kg(Wud`ekb!3@ruy?at6ci3| zw(y%4f7F|m!0cO5f)%_6hyh_ro=uwIf;-I0SX}V6_6>oM9_q+LLJ1Yv=ww;J_aX{R zA6$_;lbq!3#prR)gpvytA@VFJ=#a`fX=a*y9_d{rL=OXc&=(MaD1SXT4<+p5A%7kf zj2#qc*RpDacJ2CJlG%h#%bu`bJY+w3vR+pZvn-1U79p;FO^&b3Iu0y?!!k&=`@RXr zz^FxU*emU-wMt9RqIc~3Bi-91XGy)@4;$FnP~iN4&}-+G%HPN0;$_()KW5R5t7h7f zED=hGRp<4Pv0-v!S(qSA7-hc$_I|BB-OA@*cQ?bPQ5(>Gp@H3&C`Ts{z=7uuHp8E| zksoc|K1);^x;?|yt zYMtR{{_Et0+XL8-g#n?)z#i0PFhdb$gwn!W^S{`V79h@Br2hckh}>P9tW%lioPS$byG=p09iKL`Sde(>lL3HlDv zUm*QI3Agk5;@UdemByju5SW<^ueDnt$9k>f17OYy5LJeST)YfPZ=pT)X~|wz#1>ZJ z7aO;x!|-uZ3F}B0nN^ERMxH}Y9o>|*luH}N#ewV>xtC@zSbB-_eQH@*P?%wKq{#m^#w9D z)CIaN&Yc{1igK7v0lKKVI2B1G`ZQpIW0jO8l1jxZAWWo$bHJyB_j7rVW9lT^!4kY+?Tb45$nDw*q*?F$@i)XAF3K+ZU|R$Y4Mp;_}7rz)sE zi3iQ79niC^JK+sFq2Am+<36lFPo5V|gBm}|Rhc)`Q^rfV!TX}fyE*PS%-2eaRG(~M zmo74*iSI;uyW{q9`ApF8YP5qYzzP5^1KeOH-YJ?6J60Qo4W$Hl{$j6im$00R+sR?A=wE8r?kk7)Stcw)j_ortY z84Z-}qks_`_p-cwfNs@LvV>>9>CHPTA1{BRu*!SHEvm-Hej^?s-#4^Wt9ryf;v)Po zk(4nfXaK6c2nKkYqzM)L*-XZ*bZhyyXZpN4cErq64qs5M+F(2e0NQgU8eLAs1Tiq{ zipm?~F6;^9(sh3#j0j;0jJ@ZK@9+U^o0#)3dxt~~8Z~rzdIKe#2%K&x3yhd-&r>Cs zmw>z-G7#YcCI@i|08Sb0M z+n1TK?#W+H83AM>yrHPiQpT<1)W^A<(;3=tw=0iZ(jUeAg(6+xtEb?q{us+NNrbDH z19DPkdz#Gp3r*1Z=^#>Ta69b7W-U$7@^-lV?B72pR9`^Rw>-A@S@sOjO88;|l@&vp zB^}C2uF8%BwX0ul83J!k$4g!IUPHHGb!WG#{V0^A#@t-{o1cR6@bWN6saUcg-Hl)E zFvv4T2?7|$Ie5MOs5#J+n!|ypI)-zdX3}RxyQ=!r2olKG^cbtg-hbHjdaJ|t{E<^z z1xP^D@UVnfxsFpzVv;>k$qHT~n7J}X-A@C#e$!rQQ|liwkc^**3eu2JCpL{%-(Y}% z@JWGy{$A)}{8i}M8#r1xTbMZg2lBRBead#75v~Vvl=}%-X0d=&n(K^9KNJ|$71t9A z!wz*XF;#TKmMS>x5mj>aO>m@V_FLimoyGEa6Y^GS&kzJvO=!qv<4v4nE1YH4ZsInT& zZuWCoPLS=8qt${9YRVklf--5Q3_ee0AhF(r(KrnjUkX6Zumc~@DxbNe+TVgf6B8#o z(u^Ol@;@aRib^)$Z%$)~^-rjX7NxHR_mt-{FU2sMo5m_zlG9!b?k^^ID4p^FN+ss~ zQ4HlXfOl#!0-%yTa;Nu=9_27ZCLXR z>~!A5u-HuB?N_NO{^@3HBfFkV5;JWuto9s_0T~|(H^)I4I)%@zvQq!VyrpSK`Q<# zOynX4Kc6uom|nkW@Nf^xfBd~=1cp6u86A1A2!YL`w+Xp%m z;dkLk?%NMLuJh1gK6Y{A(T5(K@wH#t?Cra`9bTlq@4OtIUvKqJi+*w$KippL`@Hqk z#F}A-wI1(R0)Lm-gE)JS2EGaxTDuDLb<=0#b=XLW{s;t)c1LqNDqKw098STF#sp(g(J!1 zpi;r{2fj*Is*&zcf@tDEpEtIE4^b`P$`qz+=EI5h0nBu|07rwM0tytu_B3^$en}KJ zoybVBsxpfS+?SBZ7CWCbGfRO7ttdiKqWamFI}ZdZ26{xJL$v*PR=<{C_3)b<#B;?J zp{>0vn9v2)kJm^y-ARDY7#gHj9}Y@L z5y1{vce7#W8X365p4Mk2)=e&JX|FQEOlWOf<&mQY|H49IQp$*G@41lcymwy>>|TXx z9lynk6z$5?k;AiNDW#=wN`WEXQO)RHA%Ud#1xsUT!t9n5Hem)+Zjkb-Q#b5Eok|ge z#y-z^ZfN>OO;-4md8@!xp3LNHGNg&gS8dbOne2h~bFIGi77z2x7JzO}Y-!{=1Hao! z>6^_8n=kP1NR?~{65;(LQqQ3ODN=F&8mUSq#xAzT2DU~X|Dl&r4Y09W=Ro<;&HFT1 zb^}b5uP|6Fqz<)M<`D2l7*1YY?!-72hQwixGu-pw#ANUQztqE0qV4Y$uoe4w8Wp3n|<@D{#wq zlkmz~=o8)M)!&}Om+uxZQ|gou4EGDLUr!jbeaaOT?u%1;mK2n;5ID6!0i=st3|C{G zFgQk$QDQ9k8mIK2tJM}_VG+4-d>6wy98^LnTK7go55HS!6}Ust5< z*iRhoWFReD*O3uCK<;x<`}xJ%38iFld$K?v;|85U26^*qq^%Mf82Wp}Ms|crQ5R0^ z)|~;5=Ta#9)8pIHeZ8Q2zEE_Lggc`c&f7QUh9gpabZb(6k(Yr(Z})2)@UG=!(Z!xY zBH39A5UoM9ZPfcfYZtKWYu!?YRC)l4IIK1oZR&JEl1P$r^f>EcqKLz`laTg7WP9AG zvh-N?$XG<(%nwVk#06TDv{+^P0_&x~@=E8pB0#vuT5yKM}G0ff>)c97NPngbZe0i9g| z%?i!3+iwNuap!qnh}J6!{6F*cz<(Lkj|puEcipg1mSAQ$QV6TckK+)p1aflps+i=L z#^Kb_3rQ(OoD$t*A(gc;mfKozPzINGQQA6{_fGOEnp}Dm%@o8kv*;I*kw;=fAEXR* z_@~=rWX~)vjigt%R`_16=%o$jj+sHuDZc>2GCM5}=+*`+rX8^eX3k#wBW9^W{WL-O zEO*{1MkraJa<(v%nS8QsL>{9}ROmIbm`Zl3fLly;R!c^ybY4mC#2E1&=6;4G2yj`Xce+`Z)c(ySR_2;yGvI ztjyi5=eFyIjCfmSd0L)0W4+&?W5bhlHSia*+8Mo6-f#!(p-LT`r5$Dkj%kO>c#ken z?hSmkrjw^0;}MqAf)ZVjobOh3*9XWR9X?{O0_MOk2Ek)oy~MxLriBH*iyBURFRBJ< zm~!YKk|lC<9`>FpJ<>;}tE{+QEiZt>q$u^1Or)i{zVGQK-|US%P$H|g@tfbPE-9-S zLDJ>Bga+*OO>`>-UBOk0{U9tV58zsZVdZmQLgi$~>1wHKC_}Dpx*L3i|Kd>tb4C2n zF_kfE2dt%w#8-cm!Bg2ON^^};bn^9cS5^$p&VJz<<@X>Eg;ms z16Wim)6uv?dyPW!!Ao2zcrR*E$#CPFO8qg>8UPELd$lq?Pf_%NiWR&_usz zK@d3D4-QYa7w=Z|>oWAOPjrHmm#9{ACSCZ3=_zPgu14@S7HKG7v~ZTQNoaNKvgAc$ z@frj|f&+Pr7Rsi^@pEnFp9awxiW z=FM(w*SM8Hw{Zp9u*NB8+wf3tbI8MM<@P+jY99NT*n{cXZjqU$M*l)gp4-dXd4gU@ z)w|}AAJXi-{(ZVSnze zrc_rP9f~v^|MUPLpcj}`awu(it=ttP_0rq!c+K#w3~$vMSu_5Cjx5ZL>x^=!&jPi^ zrKw_Ol@em{Q=Q<*^zm01TNv%FmegqM#tyl~$kVV3lkP3!uM9XM=3l zQgXLKew43&WP~799$MHPp%W9sKg~aZ6-kn)SH{7|q6pLdx@{tfQ`p;an${adft~^< zkk~w*yk%aev3q+#i|`&19iM&`AJH(63fa|do37f((bsp!f*{-=7vFV?o*GdUbju%E zw4RoQi{v6{g5?pS8zLsNoHkJV>lY9g3xj?H@APWAf~>dgyRU3uyUe z4_>RAjy@cEtz8^Y3`qyse6<$pcrS+-J^Rx-Iy;iId|YU8CtuQOUe}B%b1!z=(p@%g z-E1fwa2@#B6y-vc8r3$-d#e51C%i@_HLc3q$3IeTK@m><2#UHko@%T;^=VdzS#Rvi z_r|x_aBtu${=Js{dp!}U+^eX}h0h_X>WNl; zx4vfs1~k>b?FodG8+D1a=csg8frErLcgoUbZxC?{@})hL9v9^*QB>}qw^6}!fM zge|19SoP&QcAK%;sz}uu{RXfADLamxI|Ux^jG5yoVT9Wt(ODVF^y^>8>+E)0vlQWv z$63aIXfli$_wR;J66#*h{z1&8;Onh+K&G^EoEy&pK2TH#C=Q5wN{I{RO>*#*;TjlD z;oWhu4F0GY1wPOp0KOiu63PAql>q)RaoDaYI{VQufr2VW)3w;#zGWd zx*XajGa~PCNu&}k{F@&_BLJ)xbvJ@t2U;9+YEY*+1|DR=&@48n;sDnFz5 zU=nrI;C|6WEI1b?q*Gn8&6xi_BPX zYa;#)Ki7=NrV{bT_z1GrT0z7uVlaIwFIIM#DIID{NLr1c<{3+`Vvp&Vu*pV75fU@P zS^kfPLS2sl9LZzR@{`u2p%|M`ppJ3KryWQ}z7C>jOfTreZ2$yDX>=p8q*U$I;%-S2 z_vL0XLGf+1TJ<8Wq-aSGQ=Gd(AIMFZI9hs$>1tCX=OmOVIIc$(K%t3^H%LjeiF{f+fH zgR!J=K_hy*s>90SIj!{a0izap0h%)7vD5{ntmrLp`M{B}gNvVKu7vN$LbaUzQ7Q+s zO{7J*LTn`Y5s@5cPUp$>ux~>BG91@*ktHnkXw9@u4c`3P0K>gPLN#NNFBtv6&M_S$ zn-)y#CbyIhwsAh;oH}{i<1H9(ADtE_*f*DP)7OJ6C&Tt@$&^ibM7#l%!V@JLF-%}m zsI>MJ2Tz!gWbfi)LfbOt-)W7&BFn9N&fGRa0C+R)`d~6I`Vd!DFf+^{iNvm`cti8f z8ucvOeIy7mWUy3&O7$#h`omO$8=W>({Gq3{zOUFAqez9!Xr_P!eWSn}`wsaZxamhe#jKi~qdaIGB;x}p9#;~0Q?>9}~Sr!X`O)!sasK z92Z16a}wX`#oZ%KipTM1ZK-UnU=laojB1URHxWs`jh?d=PCL>fNy4g)Fw?`89sZI{ zueURED+PG$!4CF zx9vt0ZDu|9k;KHvN{p=2EgMYMN}vU0BC|03A;m)D5;(kb=SkDp5e@L33Z64b_u%;D zek@ESJXuGRB6d_#9PND?Gm#XC)Lfr zNA1qt=9Sxt)ts^!fK88Y>bjJ z2*^z2R>qx+B!~6O-SD#J>%M0eDA<1RSL|A65NXj`!vy{qaPM^Tm<;A~pm`Y4!n^Eh zC{`k-2IG=qC8tSlZZh13NnG@FeYO6TQM_wv`_RS059CQ>?0ORLw+( z>4ZDyQJnJxm39M>7H*6hJ;LmzKBb6xV>-+(9*pTnzJz{p%mRfEGDIYnXsGkFRkB7J zp-g{*BmnD4=}}cc__Jy%^^*qNG4f|2kYtN8NaN`XcJ5c-#)0-FH}NbPNr54Cs;?w; z?8G!9?E^Fi`8c4Dj=;_*F=T#u*BHJBtgS=ew)hr5E~}){%jy) z{DtK!>|b8{pDHeYgZ*dAkKixZc7NE_fBGcodUg#;V)S?{v`SR^nU Date: Mon, 16 Mar 2026 16:33:55 +0700 Subject: [PATCH 4/4] fix: remove stale swarm-cli submodule reference --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 195e3102c..182429f06 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,6 @@ resources /src/pages/awesome-swarm.mdx test *.zip -swarm-cli *.csv # Tools .claude