create-sia-app 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/package.json +2 -6
  2. package/template/AGENTS.md +143 -0
  3. package/template/CLAUDE.md +25 -46
  4. package/template/README.md +6 -12
  5. package/template/_gitignore +0 -1
  6. package/template/dist/assets/index-BEylY2j7.css +1 -0
  7. package/template/dist/assets/index-CnYqArKN.js +8741 -0
  8. package/template/dist/assets/sia_bg-BTOHUC1A.wasm +0 -0
  9. package/template/dist/assets/slab-download-worker-DhW6ZBJs.js +2 -0
  10. package/template/dist/assets/slab-upload-worker-B2uSB2iY.js +2 -0
  11. package/template/dist/index.html +13 -0
  12. package/template/e2e/smoke.spec.ts +20 -0
  13. package/template/index.html +0 -1
  14. package/template/package.json +2 -2
  15. package/template/playwright.config.ts +13 -0
  16. package/template/src/components/Navbar.tsx +3 -3
  17. package/template/src/components/auth/ApproveScreen.tsx +10 -13
  18. package/template/src/components/auth/AuthFlow.tsx +13 -10
  19. package/template/src/components/auth/ConnectScreen.tsx +2 -3
  20. package/template/src/components/auth/RecoveryScreen.tsx +7 -7
  21. package/template/src/components/upload/UploadZone.tsx +192 -74
  22. package/template/src/index.css +14 -4
  23. package/template/src/stores/auth.ts +6 -12
  24. package/template/test-results/.last-run.json +4 -0
  25. package/template/tsconfig.app.json +1 -1
  26. package/template/tsconfig.node.json +0 -1
  27. package/template/vite.config.ts +2 -3
  28. package/template/rust/README.md +0 -16
  29. package/template/rust/sia-sdk-rs/.changeset/added_cancel_function_to_cancel_inflight_packed_uploads.md +0 -6
  30. package/template/rust/sia-sdk-rs/.changeset/check_if_we_have_enough_hosts_prior_to_encoding_in_upload_slabs.md +0 -16
  31. package/template/rust/sia-sdk-rs/.changeset/fix_slab_length_in_packed_object.md +0 -5
  32. package/template/rust/sia-sdk-rs/.changeset/fix_upload_racing_race_conditon.md +0 -13
  33. package/template/rust/sia-sdk-rs/.changeset/improved_parallelism_of_packed_uploads.md +0 -5
  34. package/template/rust/sia-sdk-rs/.changeset/progress_callback_will_now_be_called_as_expected_for_packed_uploads.md +0 -5
  35. package/template/rust/sia-sdk-rs/.github/dependabot.yml +0 -10
  36. package/template/rust/sia-sdk-rs/.github/workflows/main.yml +0 -36
  37. package/template/rust/sia-sdk-rs/.github/workflows/prepare-release.yml +0 -34
  38. package/template/rust/sia-sdk-rs/.github/workflows/release.yml +0 -30
  39. package/template/rust/sia-sdk-rs/.rustfmt.toml +0 -4
  40. package/template/rust/sia-sdk-rs/Cargo.lock +0 -4127
  41. package/template/rust/sia-sdk-rs/Cargo.toml +0 -3
  42. package/template/rust/sia-sdk-rs/LICENSE +0 -21
  43. package/template/rust/sia-sdk-rs/README.md +0 -30
  44. package/template/rust/sia-sdk-rs/indexd/CHANGELOG.md +0 -79
  45. package/template/rust/sia-sdk-rs/indexd/Cargo.toml +0 -79
  46. package/template/rust/sia-sdk-rs/indexd/benches/upload.rs +0 -258
  47. package/template/rust/sia-sdk-rs/indexd/src/app_client.rs +0 -1710
  48. package/template/rust/sia-sdk-rs/indexd/src/builder.rs +0 -354
  49. package/template/rust/sia-sdk-rs/indexd/src/download.rs +0 -379
  50. package/template/rust/sia-sdk-rs/indexd/src/hosts.rs +0 -659
  51. package/template/rust/sia-sdk-rs/indexd/src/lib.rs +0 -827
  52. package/template/rust/sia-sdk-rs/indexd/src/mock.rs +0 -162
  53. package/template/rust/sia-sdk-rs/indexd/src/object_encryption.rs +0 -125
  54. package/template/rust/sia-sdk-rs/indexd/src/quic.rs +0 -575
  55. package/template/rust/sia-sdk-rs/indexd/src/rhp4.rs +0 -52
  56. package/template/rust/sia-sdk-rs/indexd/src/slabs.rs +0 -497
  57. package/template/rust/sia-sdk-rs/indexd/src/upload.rs +0 -629
  58. package/template/rust/sia-sdk-rs/indexd/src/wasm_time.rs +0 -41
  59. package/template/rust/sia-sdk-rs/indexd/src/web_transport.rs +0 -398
  60. package/template/rust/sia-sdk-rs/indexd_ffi/CHANGELOG.md +0 -76
  61. package/template/rust/sia-sdk-rs/indexd_ffi/Cargo.toml +0 -47
  62. package/template/rust/sia-sdk-rs/indexd_ffi/examples/python/README.md +0 -10
  63. package/template/rust/sia-sdk-rs/indexd_ffi/examples/python/example.py +0 -130
  64. package/template/rust/sia-sdk-rs/indexd_ffi/src/bin/uniffi-bindgen.rs +0 -3
  65. package/template/rust/sia-sdk-rs/indexd_ffi/src/builder.rs +0 -377
  66. package/template/rust/sia-sdk-rs/indexd_ffi/src/io.rs +0 -155
  67. package/template/rust/sia-sdk-rs/indexd_ffi/src/lib.rs +0 -1039
  68. package/template/rust/sia-sdk-rs/indexd_ffi/src/logging.rs +0 -58
  69. package/template/rust/sia-sdk-rs/indexd_ffi/src/tls.rs +0 -23
  70. package/template/rust/sia-sdk-rs/indexd_wasm/Cargo.toml +0 -33
  71. package/template/rust/sia-sdk-rs/indexd_wasm/src/lib.rs +0 -818
  72. package/template/rust/sia-sdk-rs/knope.toml +0 -54
  73. package/template/rust/sia-sdk-rs/sia_derive/CHANGELOG.md +0 -38
  74. package/template/rust/sia-sdk-rs/sia_derive/Cargo.toml +0 -19
  75. package/template/rust/sia-sdk-rs/sia_derive/src/lib.rs +0 -278
  76. package/template/rust/sia-sdk-rs/sia_sdk/CHANGELOG.md +0 -91
  77. package/template/rust/sia-sdk-rs/sia_sdk/Cargo.toml +0 -59
  78. package/template/rust/sia-sdk-rs/sia_sdk/benches/merkle_root.rs +0 -12
  79. package/template/rust/sia-sdk-rs/sia_sdk/src/blake2.rs +0 -22
  80. package/template/rust/sia-sdk-rs/sia_sdk/src/consensus.rs +0 -767
  81. package/template/rust/sia-sdk-rs/sia_sdk/src/encoding/v1.rs +0 -257
  82. package/template/rust/sia-sdk-rs/sia_sdk/src/encoding/v2.rs +0 -291
  83. package/template/rust/sia-sdk-rs/sia_sdk/src/encoding.rs +0 -26
  84. package/template/rust/sia-sdk-rs/sia_sdk/src/encoding_async/v2.rs +0 -367
  85. package/template/rust/sia-sdk-rs/sia_sdk/src/encoding_async.rs +0 -6
  86. package/template/rust/sia-sdk-rs/sia_sdk/src/encryption.rs +0 -303
  87. package/template/rust/sia-sdk-rs/sia_sdk/src/erasure_coding.rs +0 -347
  88. package/template/rust/sia-sdk-rs/sia_sdk/src/lib.rs +0 -15
  89. package/template/rust/sia-sdk-rs/sia_sdk/src/macros.rs +0 -435
  90. package/template/rust/sia-sdk-rs/sia_sdk/src/merkle.rs +0 -112
  91. package/template/rust/sia-sdk-rs/sia_sdk/src/rhp/merkle.rs +0 -357
  92. package/template/rust/sia-sdk-rs/sia_sdk/src/rhp/rpc.rs +0 -1507
  93. package/template/rust/sia-sdk-rs/sia_sdk/src/rhp/types.rs +0 -146
  94. package/template/rust/sia-sdk-rs/sia_sdk/src/rhp.rs +0 -7
  95. package/template/rust/sia-sdk-rs/sia_sdk/src/seed.rs +0 -278
  96. package/template/rust/sia-sdk-rs/sia_sdk/src/signing.rs +0 -236
  97. package/template/rust/sia-sdk-rs/sia_sdk/src/types/common.rs +0 -677
  98. package/template/rust/sia-sdk-rs/sia_sdk/src/types/currency.rs +0 -450
  99. package/template/rust/sia-sdk-rs/sia_sdk/src/types/specifier.rs +0 -110
  100. package/template/rust/sia-sdk-rs/sia_sdk/src/types/spendpolicy.rs +0 -778
  101. package/template/rust/sia-sdk-rs/sia_sdk/src/types/utils.rs +0 -117
  102. package/template/rust/sia-sdk-rs/sia_sdk/src/types/v1.rs +0 -1737
  103. package/template/rust/sia-sdk-rs/sia_sdk/src/types/v2.rs +0 -1726
  104. package/template/rust/sia-sdk-rs/sia_sdk/src/types/work.rs +0 -59
  105. package/template/rust/sia-sdk-rs/sia_sdk/src/types.rs +0 -16
  106. package/template/scripts/setup-rust.js +0 -29
  107. package/template/src/lib/format.ts +0 -35
  108. package/template/src/lib/hex.ts +0 -13
  109. package/template/src/lib/sdk.ts +0 -25
  110. package/template/src/lib/wasm-env.ts +0 -5
  111. package/template/wasm/indexd_wasm/indexd_wasm.d.ts +0 -309
  112. package/template/wasm/indexd_wasm/indexd_wasm.js +0 -1507
  113. package/template/wasm/indexd_wasm/indexd_wasm_bg.wasm +0 -0
  114. package/template/wasm/indexd_wasm/package.json +0 -31
@@ -1,767 +0,0 @@
1
- use crate::address;
2
- use chrono::{DateTime, Duration, Utc};
3
- use serde::ser::SerializeStruct;
4
- use serde::{Deserialize, Serialize, Serializer};
5
-
6
- use crate::encoding::{self, SiaDecodable, SiaEncodable};
7
- use crate::types::{Address, BlockID, ChainIndex, Currency, Hash256, SiacoinOutput, Work};
8
-
9
- /// HardforkDevAddr contains the parameters for a hardfork that changed
10
- /// the developer address.
11
- #[derive(PartialEq, Debug, Serialize, Deserialize)]
12
- #[serde(rename_all = "camelCase")]
13
- pub struct HardforkDevAddr {
14
- pub height: u64,
15
- pub old_address: Address,
16
- pub new_address: Address,
17
- }
18
-
19
- /// HardforkTax contains the parameters for a hardfork that changed the
20
- /// SiaFund file contract tax calculation.
21
- #[derive(PartialEq, Debug, Serialize, Deserialize)]
22
- #[serde(rename_all = "camelCase")]
23
- pub struct HardforkTax {
24
- pub height: u64,
25
- }
26
-
27
- /// HardforkStorageProof contains the parameters for a hardfork that changed
28
- /// the leaf selection algorithm for storage proofs.
29
- #[derive(PartialEq, Debug, Serialize, Deserialize)]
30
- #[serde(rename_all = "camelCase")]
31
- pub struct HardforkStorageProof {
32
- pub height: u64,
33
- }
34
-
35
- /// HardforkBlockSubsidy contains the parameters for a hardfork that changed
36
- /// the difficulty adjustment algorithm.
37
- #[derive(PartialEq, Debug, Serialize, Deserialize)]
38
- #[serde(rename_all = "camelCase")]
39
- pub struct HardforkOak {
40
- pub height: u64,
41
- pub fix_height: u64,
42
- pub genesis_timestamp: DateTime<Utc>,
43
- }
44
-
45
- /// HardforkASIC contains the parameters for a hardfork that changed the mining algorithm
46
- /// to Blake2B-Sia
47
- #[derive(PartialEq, Debug, Serialize, Deserialize)]
48
- #[serde(rename_all = "camelCase")]
49
- pub struct HardforkASIC {
50
- pub height: u64,
51
- #[serde(with = "crate::types::utils::nano_second_duration")]
52
- pub oak_time: Duration,
53
- pub oak_target: BlockID,
54
- }
55
-
56
- /// HardforkFoundation contains the parameters for a hardfork that introduced the Foundation
57
- /// subsidy.
58
- #[derive(PartialEq, Debug, Serialize, Deserialize)]
59
- #[serde(rename_all = "camelCase")]
60
- pub struct HardforkFoundation {
61
- pub height: u64,
62
- pub primary_address: Address,
63
- pub failsafe_address: Address,
64
- }
65
-
66
- /// HardforkV2 contains the parameters for the v2 consensus hardfork.
67
- #[derive(PartialEq, Debug, Serialize, Deserialize)]
68
- #[serde(rename_all = "camelCase")]
69
- pub struct HardforkV2 {
70
- pub allow_height: u64,
71
- pub require_height: u64,
72
- }
73
-
74
- /// Network contains consensus parameters that are network-specific.
75
- #[derive(PartialEq, Debug, Serialize, Deserialize)]
76
- #[serde(rename_all = "camelCase")]
77
- pub struct Network {
78
- pub name: String,
79
-
80
- pub initial_coinbase: Currency,
81
- pub minimum_coinbase: Currency,
82
- pub initial_target: BlockID,
83
- #[serde(with = "crate::types::utils::nano_second_duration")]
84
- pub block_interval: Duration,
85
- pub maturity_delay: u64,
86
-
87
- pub hardfork_dev_addr: HardforkDevAddr,
88
- pub hardfork_tax: HardforkTax,
89
- pub hardfork_storage_proof: HardforkStorageProof,
90
- pub hardfork_oak: HardforkOak,
91
- #[serde(rename = "hardforkASIC")]
92
- pub hardfork_asic: HardforkASIC,
93
- pub hardfork_foundation: HardforkFoundation,
94
- pub hardfork_v2: HardforkV2,
95
- }
96
-
97
- const fn unix_timestamp(secs: i64) -> DateTime<Utc> {
98
- match DateTime::from_timestamp_secs(secs) {
99
- Some(t) => t,
100
- None => panic!("invalid timestamp"),
101
- }
102
- }
103
-
104
- impl Network {
105
- pub fn mainnet() -> Self {
106
- Network {
107
- name: "mainnet".to_string(),
108
- initial_coinbase: Currency::siacoins(300_000),
109
- minimum_coinbase: Currency::siacoins(30_000),
110
- initial_target: BlockID::new([
111
- 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112
- 0, 0, 0, 0, 0,
113
- ]),
114
- block_interval: Duration::minutes(10),
115
- maturity_delay: 144,
116
-
117
- hardfork_dev_addr: HardforkDevAddr {
118
- height: 10000,
119
- old_address: address!(
120
- "7d0c44f7664e2d34e53efde0661a6f628ec9264785ae8e3cd7c973e8d190c3c97b5e3ecbc567"
121
- ),
122
- new_address: address!(
123
- "f371c70bce9eb8979cd5099f599ec4e4fcb14e0afcf31f9791e03e6496a4c0b358c98279730b"
124
- ),
125
- },
126
- hardfork_tax: HardforkTax { height: 21000 },
127
- hardfork_storage_proof: HardforkStorageProof { height: 100000 },
128
- hardfork_oak: HardforkOak {
129
- height: 135000,
130
- fix_height: 139000,
131
- genesis_timestamp: unix_timestamp(1433600000), // June 6th, 2015 @ 2:13pm UTC
132
- },
133
- hardfork_asic: HardforkASIC {
134
- height: 179000,
135
- oak_time: Duration::seconds(120000),
136
- oak_target: BlockID::new([
137
- 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
138
- 0, 0, 0, 0, 0, 0,
139
- ]),
140
- },
141
- hardfork_foundation: HardforkFoundation {
142
- height: 298000,
143
- primary_address: address!(
144
- "053b2def3cbdd078c19d62ce2b4f0b1a3c5e0ffbeeff01280efb1f8969b2f5bb4fdc680f0807"
145
- ),
146
- failsafe_address: address!(
147
- "27c22a6c6e6645802a3b8fa0e5374657438ef12716d2205d3e866272de1b644dbabd53d6d560"
148
- ),
149
- },
150
- hardfork_v2: HardforkV2 {
151
- allow_height: 1000000,
152
- require_height: 1025000,
153
- },
154
- }
155
- }
156
-
157
- pub fn zen() -> Self {
158
- Network {
159
- name: "zen".to_string(),
160
- initial_coinbase: Currency::siacoins(300_000),
161
- minimum_coinbase: Currency::siacoins(300_000),
162
- initial_target: BlockID::new([
163
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
164
- 0, 0, 0, 0,
165
- ]),
166
- block_interval: Duration::minutes(10),
167
- maturity_delay: 144,
168
-
169
- hardfork_dev_addr: HardforkDevAddr {
170
- height: 1,
171
- old_address: Address::new([0u8; 32]),
172
- new_address: Address::new([0u8; 32]),
173
- },
174
- hardfork_tax: HardforkTax { height: 2 },
175
- hardfork_storage_proof: HardforkStorageProof { height: 5 },
176
- hardfork_oak: HardforkOak {
177
- height: 10,
178
- fix_height: 12,
179
- genesis_timestamp: unix_timestamp(1673600000), // January 13, 2023 @ 08:53 GMT
180
- },
181
- hardfork_asic: HardforkASIC {
182
- height: 20,
183
- oak_time: Duration::seconds(10000),
184
- oak_target: BlockID::new([
185
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
186
- 0, 0, 0, 0, 0, 0,
187
- ]),
188
- },
189
- hardfork_foundation: HardforkFoundation {
190
- height: 30,
191
- primary_address: address!(
192
- "053b2def3cbdd078c19d62ce2b4f0b1a3c5e0ffbeeff01280efb1f8969b2f5bb4fdc680f0807"
193
- ),
194
- failsafe_address: Address::new([0u8; 32]),
195
- },
196
- hardfork_v2: HardforkV2 {
197
- allow_height: 100000,
198
- require_height: 102000,
199
- },
200
- }
201
- }
202
-
203
- pub fn anagami() -> Self {
204
- Network {
205
- name: "anagami".to_string(),
206
- initial_coinbase: Currency::siacoins(300_000),
207
- minimum_coinbase: Currency::siacoins(300_000),
208
- initial_target: BlockID::new([
209
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
210
- 0, 0, 0, 0,
211
- ]),
212
- block_interval: Duration::minutes(10),
213
- maturity_delay: 144,
214
-
215
- hardfork_dev_addr: HardforkDevAddr {
216
- height: 1,
217
- old_address: Address::new([0u8; 32]),
218
- new_address: Address::new([0u8; 32]),
219
- },
220
- hardfork_tax: HardforkTax { height: 2 },
221
- hardfork_storage_proof: HardforkStorageProof { height: 5 },
222
- hardfork_oak: HardforkOak {
223
- height: 10,
224
- fix_height: 12,
225
- genesis_timestamp: unix_timestamp(1724284800), // August 22, 2024 @ 0:00 UTC
226
- },
227
- hardfork_asic: HardforkASIC {
228
- height: 20,
229
- oak_time: Duration::seconds(10000),
230
- oak_target: BlockID::new([
231
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
232
- 0, 0, 0, 0, 0, 0,
233
- ]),
234
- },
235
- hardfork_foundation: HardforkFoundation {
236
- height: 30,
237
- primary_address: address!(
238
- "241352c83da002e61f57e96b14f3a5f8b5de22156ce83b753ea495e64f1affebae88736b2347"
239
- ),
240
- failsafe_address: Address::new([0u8; 32]),
241
- },
242
- hardfork_v2: HardforkV2 {
243
- allow_height: 2016,
244
- require_height: 2016 + 288,
245
- },
246
- }
247
- }
248
- }
249
-
250
- fn has_tree_at_height(num_leaves: &u64, height: usize) -> bool {
251
- num_leaves & (1 << height) != 0
252
- }
253
-
254
- #[derive(PartialEq, Debug)]
255
- pub struct ElementAccumulator {
256
- pub num_leaves: u64,
257
- pub trees: [Hash256; 64],
258
- }
259
-
260
- impl Default for ElementAccumulator {
261
- fn default() -> Self {
262
- ElementAccumulator {
263
- num_leaves: 0,
264
- trees: [Hash256::default(); 64],
265
- }
266
- }
267
- }
268
-
269
- impl SiaEncodable for ElementAccumulator {
270
- fn encode<W: std::io::Write>(&self, w: &mut W) -> encoding::Result<()> {
271
- self.num_leaves.encode(w)?;
272
- for (i, root) in self.trees.iter().enumerate() {
273
- if has_tree_at_height(&self.num_leaves, i) {
274
- root.encode(w)?;
275
- }
276
- }
277
- Ok(())
278
- }
279
- }
280
-
281
- impl SiaDecodable for ElementAccumulator {
282
- fn decode<R: std::io::Read>(r: &mut R) -> encoding::Result<Self> {
283
- let num_leaves = u64::decode(r)?;
284
- let mut trees = [Hash256::default(); 64];
285
- for (i, root) in trees.iter_mut().enumerate() {
286
- if has_tree_at_height(&num_leaves, i) {
287
- let h = Hash256::decode(r)?;
288
- *root = h;
289
- }
290
- }
291
- Ok(ElementAccumulator { num_leaves, trees })
292
- }
293
- }
294
-
295
- impl Serialize for ElementAccumulator {
296
- fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
297
- let mut state = serializer.serialize_struct("ElementAccumulator", 2)?;
298
- state.serialize_field("numLeaves", &self.num_leaves)?;
299
- let trees: Vec<Hash256> = self
300
- .trees
301
- .iter()
302
- .enumerate()
303
- .filter(|(i, _)| has_tree_at_height(&self.num_leaves, *i))
304
- .map(|(_, root)| *root)
305
- .collect();
306
- state.serialize_field("trees", &trees)?;
307
- state.end()
308
- }
309
- }
310
-
311
- impl<'de> Deserialize<'de> for ElementAccumulator {
312
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
313
- where
314
- D: serde::Deserializer<'de>,
315
- {
316
- #[derive(Deserialize)]
317
- #[serde(rename_all = "camelCase")]
318
- struct InterElementAccumulator {
319
- num_leaves: u64,
320
- trees: Vec<Hash256>,
321
- }
322
-
323
- let inter = InterElementAccumulator::deserialize(deserializer)?;
324
-
325
- if inter.trees.len() != inter.num_leaves.count_ones() as usize {
326
- return Err(serde::de::Error::custom("invalid number of trees"));
327
- }
328
-
329
- let mut ea = ElementAccumulator {
330
- num_leaves: inter.num_leaves,
331
- trees: [Hash256::default(); 64],
332
- };
333
- let mut trees_iter = inter.trees.into_iter();
334
- for i in 0..64 {
335
- if has_tree_at_height(&ea.num_leaves, i) {
336
- if let Some(root) = trees_iter.next() {
337
- ea.trees[i] = root
338
- } else {
339
- return Err(serde::de::Error::custom("missing tree"));
340
- }
341
- }
342
- }
343
- Ok(ea)
344
- }
345
- }
346
-
347
- /// State represents the state of the chain as of a particular block.
348
- #[derive(PartialEq, Debug, Serialize, Deserialize)]
349
- #[serde(rename_all = "camelCase")]
350
- pub struct State {
351
- pub index: ChainIndex,
352
- #[serde(with = "crate::types::utils::timestamp_array")]
353
- pub prev_timestamps: [DateTime<Utc>; 11],
354
- pub depth: BlockID,
355
- pub child_target: BlockID,
356
- pub siafund_pool: Currency,
357
-
358
- // Oak hardfork state
359
- #[serde(with = "crate::types::utils::nano_second_duration")]
360
- pub oak_time: Duration,
361
- pub oak_target: BlockID,
362
-
363
- // Foundation hardfork state
364
- pub foundation_primary_address: Address,
365
- pub foundation_failsafe_address: Address,
366
- // v2 hardfork state
367
- pub total_work: Work,
368
- pub difficulty: Work,
369
- pub oak_work: Work,
370
- pub elements: ElementAccumulator,
371
- pub attestations: u64,
372
- }
373
-
374
- impl SiaEncodable for State {
375
- fn encode<W: std::io::Write>(&self, w: &mut W) -> crate::encoding::Result<()> {
376
- self.index.encode(w)?;
377
- let timestamps_count = if self.index.child_height() < 11 {
378
- self.index.child_height() as usize
379
- } else {
380
- 11
381
- };
382
- self.prev_timestamps
383
- .iter()
384
- .take(timestamps_count)
385
- .for_each(|ts| ts.encode(w).unwrap());
386
- self.depth.encode(w)?;
387
- self.child_target.encode(w)?;
388
- self.siafund_pool.encode(w)?;
389
- self.oak_time.encode(w)?;
390
- self.oak_target.encode(w)?;
391
- self.foundation_primary_address.encode(w)?;
392
- self.foundation_failsafe_address.encode(w)?;
393
- self.total_work.encode(w)?;
394
- self.difficulty.encode(w)?;
395
- self.oak_work.encode(w)?;
396
- self.elements.encode(w)?;
397
- self.attestations.encode(w)?;
398
- Ok(())
399
- }
400
- }
401
-
402
- impl SiaDecodable for State {
403
- fn decode<R: std::io::Read>(r: &mut R) -> crate::encoding::Result<Self> {
404
- let index = ChainIndex::decode(r)?;
405
- let timestamps_count = if index.child_height() < 11 {
406
- index.child_height() as usize
407
- } else {
408
- 11
409
- };
410
- let mut prev_timestamps = [DateTime::UNIX_EPOCH; 11];
411
- prev_timestamps[..timestamps_count]
412
- .iter_mut()
413
- .try_for_each(|ts| -> encoding::Result<()> {
414
- *ts = DateTime::<Utc>::decode(r)?;
415
- Ok(())
416
- })?;
417
- Ok(State {
418
- index,
419
- prev_timestamps,
420
- depth: BlockID::decode(r)?,
421
- child_target: BlockID::decode(r)?,
422
- siafund_pool: Currency::decode(r)?,
423
- oak_time: Duration::decode(r)?,
424
- oak_target: BlockID::decode(r)?,
425
- foundation_primary_address: Address::decode(r)?,
426
- foundation_failsafe_address: Address::decode(r)?,
427
- total_work: Work::decode(r)?,
428
- difficulty: Work::decode(r)?,
429
- oak_work: Work::decode(r)?,
430
- elements: ElementAccumulator::decode(r)?,
431
- attestations: u64::decode(r)?,
432
- })
433
- }
434
- }
435
-
436
- /// ChainState contains the network parameters and the state of the chain.
437
- /// It is used to determine the consensus rules in effect for a particular block.
438
- #[derive(PartialEq, Debug, Serialize, Deserialize)]
439
- pub struct ChainState {
440
- pub network: Network,
441
- pub state: State,
442
- }
443
-
444
- impl ChainState {
445
- /// child_height returns the height of the next block
446
- pub fn child_height(&self) -> u64 {
447
- self.state.index.child_height()
448
- }
449
-
450
- /// block_reward returns the reward for mining a child block
451
- pub fn block_reward(&self) -> Currency {
452
- let reward = self
453
- .network
454
- .initial_coinbase
455
- .checked_sub(Currency::siacoins(self.child_height()));
456
-
457
- match reward {
458
- Some(reward) if reward >= self.network.minimum_coinbase => reward,
459
- _ => self.network.minimum_coinbase,
460
- }
461
- }
462
-
463
- /// maturity_height is the height at which outputs created by the child block will "mature" (become spendable).
464
- pub fn maturity_height(&self) -> u64 {
465
- self.child_height() + self.network.maturity_delay
466
- }
467
-
468
- /// siafund_count is the number of siafunds in existence
469
- pub fn siafund_count(&self) -> u64 {
470
- 10000
471
- }
472
-
473
- /// ancestor_depth is used to determine the target timestamp in the pre-Oak difficulty adjustment algorithm
474
- pub fn ancestor_depth(&self) -> u64 {
475
- 1000
476
- }
477
-
478
- // blocks_per_month estimates the number of blocks expected in a calendar month
479
- pub fn blocks_per_month(&self) -> u64 {
480
- (Duration::days(365).num_milliseconds()
481
- / 12
482
- / self.network.block_interval.num_milliseconds()) as u64
483
- }
484
-
485
- /// foundation_subsidy returns the Foundation subsidy output for the child block.
486
- /// If no subsidy is due, returns None.
487
- pub fn foundation_subsidy(&self) -> Option<SiacoinOutput> {
488
- if self.child_height() < self.network.hardfork_foundation.height {
489
- return None;
490
- }
491
- let blocks_per_month = self.blocks_per_month();
492
- if !(self.child_height() - self.network.hardfork_foundation.height)
493
- .is_multiple_of(blocks_per_month)
494
- {
495
- return None;
496
- }
497
-
498
- let subsidy_per_block = Currency::siacoins(30000);
499
- Some(SiacoinOutput {
500
- value: if self.child_height() == self.network.hardfork_foundation.height {
501
- subsidy_per_block * Currency::new(12)
502
- } else {
503
- subsidy_per_block
504
- },
505
- address: self.network.hardfork_foundation.primary_address.clone(),
506
- })
507
- }
508
-
509
- pub fn replay_prefix(&self) -> &[u8] {
510
- if self.state.index.height >= self.network.hardfork_v2.allow_height {
511
- return &[2];
512
- } else if self.state.index.height >= self.network.hardfork_foundation.height {
513
- return &[1];
514
- } else if self.state.index.height >= self.network.hardfork_asic.height {
515
- return &[0];
516
- }
517
- &[]
518
- }
519
-
520
- pub fn nonce_factor(&self) -> u64 {
521
- if self.child_height() < self.network.hardfork_asic.height {
522
- return 1;
523
- }
524
- 1009
525
- }
526
-
527
- pub fn max_block_weight(&self) -> u64 {
528
- 2_000_000
529
- }
530
- }
531
-
532
- #[cfg(test)]
533
- mod tests {
534
- use crate::{block_id, hash_256};
535
-
536
- use super::*;
537
- use chrono::FixedOffset;
538
- use serde_json;
539
-
540
- #[test]
541
- fn test_serialize_network() {
542
- let test_cases = vec![
543
- (
544
- Network::anagami(),
545
- "{\"name\":\"anagami\",\"initialCoinbase\":\"300000000000000000000000000000\",\"minimumCoinbase\":\"300000000000000000000000000000\",\"initialTarget\":\"0000000100000000000000000000000000000000000000000000000000000000\",\"blockInterval\":600000000000,\"maturityDelay\":144,\"hardforkDevAddr\":{\"height\":1,\"oldAddress\":\"000000000000000000000000000000000000000000000000000000000000000089eb0d6a8a69\",\"newAddress\":\"000000000000000000000000000000000000000000000000000000000000000089eb0d6a8a69\"},\"hardforkTax\":{\"height\":2},\"hardforkStorageProof\":{\"height\":5},\"hardforkOak\":{\"height\":10,\"fixHeight\":12,\"genesisTimestamp\":\"2024-08-22T00:00:00Z\"},\"hardforkASIC\":{\"height\":20,\"oakTime\":10000000000000,\"oakTarget\":\"0000000100000000000000000000000000000000000000000000000000000000\"},\"hardforkFoundation\":{\"height\":30,\"primaryAddress\":\"241352c83da002e61f57e96b14f3a5f8b5de22156ce83b753ea495e64f1affebae88736b2347\",\"failsafeAddress\":\"000000000000000000000000000000000000000000000000000000000000000089eb0d6a8a69\"},\"hardforkV2\":{\"allowHeight\":2016,\"requireHeight\":2304}}",
546
- ),
547
- (
548
- Network::mainnet(),
549
- "{\"name\":\"mainnet\",\"initialCoinbase\":\"300000000000000000000000000000\",\"minimumCoinbase\":\"30000000000000000000000000000\",\"initialTarget\":\"0000000020000000000000000000000000000000000000000000000000000000\",\"blockInterval\":600000000000,\"maturityDelay\":144,\"hardforkDevAddr\":{\"height\":10000,\"oldAddress\":\"7d0c44f7664e2d34e53efde0661a6f628ec9264785ae8e3cd7c973e8d190c3c97b5e3ecbc567\",\"newAddress\":\"f371c70bce9eb8979cd5099f599ec4e4fcb14e0afcf31f9791e03e6496a4c0b358c98279730b\"},\"hardforkTax\":{\"height\":21000},\"hardforkStorageProof\":{\"height\":100000},\"hardforkOak\":{\"height\":135000,\"fixHeight\":139000,\"genesisTimestamp\":\"2015-06-06T14:13:20Z\"},\"hardforkASIC\":{\"height\":179000,\"oakTime\":120000000000000,\"oakTarget\":\"0000000000000000200000000000000000000000000000000000000000000000\"},\"hardforkFoundation\":{\"height\":298000,\"primaryAddress\":\"053b2def3cbdd078c19d62ce2b4f0b1a3c5e0ffbeeff01280efb1f8969b2f5bb4fdc680f0807\",\"failsafeAddress\":\"27c22a6c6e6645802a3b8fa0e5374657438ef12716d2205d3e866272de1b644dbabd53d6d560\"},\"hardforkV2\":{\"allowHeight\":1000000,\"requireHeight\":1025000}}",
550
- ),
551
- (
552
- Network::zen(),
553
- "{\"name\":\"zen\",\"initialCoinbase\":\"300000000000000000000000000000\",\"minimumCoinbase\":\"300000000000000000000000000000\",\"initialTarget\":\"0000000100000000000000000000000000000000000000000000000000000000\",\"blockInterval\":600000000000,\"maturityDelay\":144,\"hardforkDevAddr\":{\"height\":1,\"oldAddress\":\"000000000000000000000000000000000000000000000000000000000000000089eb0d6a8a69\",\"newAddress\":\"000000000000000000000000000000000000000000000000000000000000000089eb0d6a8a69\"},\"hardforkTax\":{\"height\":2},\"hardforkStorageProof\":{\"height\":5},\"hardforkOak\":{\"height\":10,\"fixHeight\":12,\"genesisTimestamp\":\"2023-01-13T08:53:20Z\"},\"hardforkASIC\":{\"height\":20,\"oakTime\":10000000000000,\"oakTarget\":\"0000000100000000000000000000000000000000000000000000000000000000\"},\"hardforkFoundation\":{\"height\":30,\"primaryAddress\":\"053b2def3cbdd078c19d62ce2b4f0b1a3c5e0ffbeeff01280efb1f8969b2f5bb4fdc680f0807\",\"failsafeAddress\":\"000000000000000000000000000000000000000000000000000000000000000089eb0d6a8a69\"},\"hardforkV2\":{\"allowHeight\":100000,\"requireHeight\":102000}}",
554
- ),
555
- ];
556
-
557
- for (network, expected) in test_cases {
558
- let serialized = serde_json::to_string(&network).unwrap();
559
- assert_eq!(expected, serialized, "{} failed", network.name);
560
- let deserialized: Network = serde_json::from_str(&serialized).unwrap();
561
- assert_eq!(network, deserialized, "{} failed", network.name);
562
- }
563
- }
564
-
565
- #[test]
566
- fn test_serialize_state() {
567
- let s = State {
568
- index: ChainIndex {
569
- height: 0,
570
- id: block_id!("0000000000000000000000000000000000000000000000000000000000000000"),
571
- },
572
- prev_timestamps: [DateTime::UNIX_EPOCH; 11],
573
- depth: block_id!("0000000000000000000000000000000000000000000000000000000000000000"),
574
- child_target: block_id!(
575
- "0000000000000000000000000000000000000000000000000000000000000000"
576
- ),
577
- siafund_pool: Currency::zero(),
578
- oak_time: Duration::zero(),
579
- oak_target: block_id!(
580
- "0000000000000000000000000000000000000000000000000000000000000000"
581
- ),
582
- foundation_primary_address: address!(
583
- "000000000000000000000000000000000000000000000000000000000000000089eb0d6a8a69"
584
- ),
585
- foundation_failsafe_address: address!(
586
- "000000000000000000000000000000000000000000000000000000000000000089eb0d6a8a69"
587
- ),
588
- total_work: Work::zero(),
589
- difficulty: Work::zero(),
590
- oak_work: Work::zero(),
591
- elements: ElementAccumulator {
592
- num_leaves: 0,
593
- trees: [Hash256::default(); 64],
594
- },
595
- attestations: 0,
596
- };
597
-
598
- const EMPTY_JSON_STR: &str = "{\"index\":{\"height\":0,\"id\":\"0000000000000000000000000000000000000000000000000000000000000000\"},\"prevTimestamps\":[\"1970-01-01T00:00:00+00:00\",\"1970-01-01T00:00:00+00:00\",\"1970-01-01T00:00:00+00:00\",\"1970-01-01T00:00:00+00:00\",\"1970-01-01T00:00:00+00:00\",\"1970-01-01T00:00:00+00:00\",\"1970-01-01T00:00:00+00:00\",\"1970-01-01T00:00:00+00:00\",\"1970-01-01T00:00:00+00:00\",\"1970-01-01T00:00:00+00:00\",\"1970-01-01T00:00:00+00:00\"],\"depth\":\"0000000000000000000000000000000000000000000000000000000000000000\",\"childTarget\":\"0000000000000000000000000000000000000000000000000000000000000000\",\"siafundPool\":\"0\",\"oakTime\":0,\"oakTarget\":\"0000000000000000000000000000000000000000000000000000000000000000\",\"foundationPrimaryAddress\":\"000000000000000000000000000000000000000000000000000000000000000089eb0d6a8a69\",\"foundationFailsafeAddress\":\"000000000000000000000000000000000000000000000000000000000000000089eb0d6a8a69\",\"totalWork\":\"0\",\"difficulty\":\"0\",\"oakWork\":\"0\",\"elements\":{\"numLeaves\":0,\"trees\":[]},\"attestations\":0}";
599
-
600
- let serialized = serde_json::to_string(&s).unwrap();
601
- assert_eq!(EMPTY_JSON_STR, serialized);
602
- let deserialized: State = serde_json::from_str(&serialized).unwrap();
603
- assert_eq!(s, deserialized);
604
-
605
- const EMPTY_BINARY_STR: &str = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
606
-
607
- let mut serialized = Vec::new();
608
- s.encode(&mut serialized).unwrap();
609
- assert_eq!(EMPTY_BINARY_STR, hex::encode(serialized.clone()));
610
- let deserialized = State::decode(&mut &serialized[..]).unwrap();
611
- assert_eq!(s, deserialized);
612
-
613
- let s = State {
614
- index: ChainIndex {
615
- height: 16173070238323073115,
616
- id: block_id!("54b6800181215b654a2b64e8a0f39da6d5ad20f4e6eda87d50d36e93efd9cdb9"),
617
- },
618
- prev_timestamps: [
619
- DateTime::<FixedOffset>::parse_from_rfc3339("2167-03-18T17:08:40-07:00")
620
- .unwrap()
621
- .to_utc(),
622
- DateTime::<FixedOffset>::parse_from_rfc3339("1971-03-30T07:40:44-08:00")
623
- .unwrap()
624
- .to_utc(),
625
- DateTime::<FixedOffset>::parse_from_rfc3339("2226-11-12T19:51:30-08:00")
626
- .unwrap()
627
- .to_utc(),
628
- DateTime::<FixedOffset>::parse_from_rfc3339("2013-09-10T15:07:20-07:00")
629
- .unwrap()
630
- .to_utc(),
631
- DateTime::<FixedOffset>::parse_from_rfc3339("2230-05-18T20:13:07-07:00")
632
- .unwrap()
633
- .to_utc(),
634
- DateTime::<FixedOffset>::parse_from_rfc3339("1983-10-27T20:37:21-07:00")
635
- .unwrap()
636
- .to_utc(),
637
- DateTime::<FixedOffset>::parse_from_rfc3339("2068-03-31T10:25:10-07:00")
638
- .unwrap()
639
- .to_utc(),
640
- DateTime::<FixedOffset>::parse_from_rfc3339("2159-06-29T18:46:49-07:00")
641
- .unwrap()
642
- .to_utc(),
643
- DateTime::<FixedOffset>::parse_from_rfc3339("2089-05-02T23:45:50-07:00")
644
- .unwrap()
645
- .to_utc(),
646
- DateTime::<FixedOffset>::parse_from_rfc3339("2073-02-27T00:01:11-08:00")
647
- .unwrap()
648
- .to_utc(),
649
- DateTime::<FixedOffset>::parse_from_rfc3339("2005-07-10T11:50:37-07:00")
650
- .unwrap()
651
- .to_utc(),
652
- ],
653
- depth: block_id!("fb66f6dd0517bd80a57c6fc1dd186eeb25a5f7dc550adc94a996731734f4a478"),
654
- child_target: block_id!(
655
- "188d65bc61f7398757be167c70139bc79e2f387551bd0338b81f3938850033c2"
656
- ),
657
- siafund_pool: Currency::new(184937863921143879963732603265618430015),
658
- oak_time: Duration::nanoseconds(5097318764767379519),
659
- oak_target: block_id!(
660
- "5e7e960e017d5772f3341bd8d80fc797de245c760a3f9e84f4da66f9e0ee95aa"
661
- ),
662
- foundation_primary_address: address!(
663
- "95ae9eb00188ade3367e57e5bdc522a16e95a8d28e1b940d2d128273aa7a833001a060dec431"
664
- ),
665
- foundation_failsafe_address: address!(
666
- "cfb49736296ae52965fd7d66d55720eeadfc2be586db65699050bce175c56056d3fbc1803e15"
667
- ),
668
- total_work: Work::from_dec_str(
669
- "74729819229046869798018345563024899883189146032533830356652983039509219541660",
670
- )
671
- .unwrap(),
672
- difficulty: Work::from_dec_str(
673
- "65194889020289389878379369533805235500859175566680960159551424936807420310662",
674
- )
675
- .unwrap(),
676
- oak_work: Work::from_dec_str(
677
- "57256974569838769713335634640292932580615837804690422146878608831130432685755",
678
- )
679
- .unwrap(),
680
- elements: ElementAccumulator {
681
- num_leaves: 4899977171010125798,
682
- trees: [
683
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
684
- hash_256!("78a9fabda865dafcaf474d48bdb1272595513cf92290917392ff58ca8bea591a"),
685
- hash_256!("e6a5ea278d90592e0518fbf2e83f41507486fe57e8e4ffbe152f13250df696bf"),
686
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
687
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
688
- hash_256!("2488cae3f7046f8b04aec217a09358db22d8ae36f883d1ccae9382edca79c54e"),
689
- hash_256!("e498f1adbe88c58bc9dabf487437b8d191a78fbb3d8cfe19a4c1759ae232b4f4"),
690
- hash_256!("96130e35228422970057745ef4b92d285434c25187c44110922554d0ae040678"),
691
- hash_256!("44f29b39d6e4f509d5d41834db4fd6a831ccca33bb46185a5ad01f2789581337"),
692
- hash_256!("75f0b42f9d291c4ff4e57f403893e0ca18fdc64f0723e0f29b6aeed834db1ac2"),
693
- hash_256!("4ce129d69c69971497c556d9eeec0de8c1dd9cc4b0750be9fffd9ec3226ce7a3"),
694
- hash_256!("f3321bf48aed89100db44b3080f3f350d10b6de213527b19ad57bdd1cd47576a"),
695
- hash_256!("724c8bf4c8459625190ae18b2fc1d9353d2d3b34c80d4d4fbcd48258c9a11c97"),
696
- hash_256!("062b2371de9dfad15931a1e72c46afe492ad697447680ea43300ed516bcc2742"),
697
- hash_256!("b23ca0a83b0367755e2c53c1f7ed9e6d372c220ae0f344082cf5d52c40287893"),
698
- hash_256!("9b1b446dd599fd5dab08e83738b92651d8aaa7be072db313d237c68ce1094ea1"),
699
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
700
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
701
- hash_256!("a03c962c184055ccbf7a42c9a13a0d4c38125535a830832a6fff3029d6deada3"),
702
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
703
- hash_256!("df5d9e1e3a220d2429f9064adecb86ecae916619c93e17d237b5972692e558fd"),
704
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
705
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
706
- hash_256!("2d6315b7a91d62bd31e4738259f56f58075bd14ee2f1e2625738f506a7564176"),
707
- hash_256!("26b1d48ab8c3f0707bd5afdf4a3ef757abc9b6a0be75b8a3cecbcd5994473a72"),
708
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
709
- hash_256!("f897c92aca8d6ef46a41a3a50aff0527bd09be029355d28c2360ec9cb309b1ae"),
710
- hash_256!("f80ff7cbcad8c465278a59588a3a0d000cc3130e96fb56d257229c1a50d93125"),
711
- hash_256!("7a84f42433ecd9352e2ffd8bdc8556c87ec93697cf4c4873d4ab51d2b85c44c1"),
712
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
713
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
714
- hash_256!("00c03e0af90a26d0a4bb4b243f99b2d361de2412d82f357f6224eceb2f19c142"),
715
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
716
- hash_256!("e0a8f77abd726e928580656d7ab49dc276603e936e04b9caf53a2a27338e3cd1"),
717
- hash_256!("e376ebd2f0c93013cf6c856fb76e7b60e64a300a9a4b839844074cac4da42b8d"),
718
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
719
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
720
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
721
- hash_256!("5fcc77f29cfdb51aac9fff250e1ee7607457ce5a280e946150931d793272593a"),
722
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
723
- hash_256!("ad34b2dce6a7136584c5ffea74c66e5613593dddac9eb666ff6a6aef42386968"),
724
- hash_256!("3d1afa6b931fea014211bb6b08d9508389dd0a9c47a25670ca110bcc8ce8ead1"),
725
- hash_256!("df427b938f6ef07cd67da1ab11ad8fb4e6b0a97c03325c1fc8b1c3b0c4b8f7f4"),
726
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
727
- hash_256!("8c3d435fdb6ee44e26155c116a86f4dc2b54b05becb08777a63e1d1ad7c3cbc2"),
728
- hash_256!("11671f5bd2856de1b4925ee0b82f9cda6179db132c9930431d26f0ccdbb8a822"),
729
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
730
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
731
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
732
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
733
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
734
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
735
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
736
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
737
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
738
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
739
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
740
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
741
- hash_256!("19dcd3ac59669e10420b36d4e588206ae123a0c8ae64b20e1ede697efc556291"),
742
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
743
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
744
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
745
- hash_256!("65542a8b2c1bca8d78d6517357853c1d54f6b53f04a8327f28ae2d5d022c5597"),
746
- hash_256!("0000000000000000000000000000000000000000000000000000000000000000"),
747
- ],
748
- },
749
- attestations: 4796228701811883082,
750
- };
751
-
752
- const JSON_STR: &str = "{\"index\":{\"height\":16173070238323073115,\"id\":\"54b6800181215b654a2b64e8a0f39da6d5ad20f4e6eda87d50d36e93efd9cdb9\"},\"prevTimestamps\":[\"2167-03-19T00:08:40+00:00\",\"1971-03-30T15:40:44+00:00\",\"2226-11-13T03:51:30+00:00\",\"2013-09-10T22:07:20+00:00\",\"2230-05-19T03:13:07+00:00\",\"1983-10-28T03:37:21+00:00\",\"2068-03-31T17:25:10+00:00\",\"2159-06-30T01:46:49+00:00\",\"2089-05-03T06:45:50+00:00\",\"2073-02-27T08:01:11+00:00\",\"2005-07-10T18:50:37+00:00\"],\"depth\":\"fb66f6dd0517bd80a57c6fc1dd186eeb25a5f7dc550adc94a996731734f4a478\",\"childTarget\":\"188d65bc61f7398757be167c70139bc79e2f387551bd0338b81f3938850033c2\",\"siafundPool\":\"184937863921143879963732603265618430015\",\"oakTime\":5097318764767379519,\"oakTarget\":\"5e7e960e017d5772f3341bd8d80fc797de245c760a3f9e84f4da66f9e0ee95aa\",\"foundationPrimaryAddress\":\"95ae9eb00188ade3367e57e5bdc522a16e95a8d28e1b940d2d128273aa7a833001a060dec431\",\"foundationFailsafeAddress\":\"cfb49736296ae52965fd7d66d55720eeadfc2be586db65699050bce175c56056d3fbc1803e15\",\"totalWork\":\"74729819229046869798018345563024899883189146032533830356652983039509219541660\",\"difficulty\":\"65194889020289389878379369533805235500859175566680960159551424936807420310662\",\"oakWork\":\"57256974569838769713335634640292932580615837804690422146878608831130432685755\",\"elements\":{\"numLeaves\":4899977171010125798,\"trees\":[\"78a9fabda865dafcaf474d48bdb1272595513cf92290917392ff58ca8bea591a\",\"e6a5ea278d90592e0518fbf2e83f41507486fe57e8e4ffbe152f13250df696bf\",\"2488cae3f7046f8b04aec217a09358db22d8ae36f883d1ccae9382edca79c54e\",\"e498f1adbe88c58bc9dabf487437b8d191a78fbb3d8cfe19a4c1759ae232b4f4\",\"96130e35228422970057745ef4b92d285434c25187c44110922554d0ae040678\",\"44f29b39d6e4f509d5d41834db4fd6a831ccca33bb46185a5ad01f2789581337\",\"75f0b42f9d291c4ff4e57f403893e0ca18fdc64f0723e0f29b6aeed834db1ac2\",\"4ce129d69c69971497c556d9eeec0de8c1dd9cc4b0750be9fffd9ec3226ce7a3\",\"f3321bf48aed89100db44b3080f3f350d10b6de213527b19ad57bdd1cd47576a\",\"724c8bf4c8459625190ae18b2fc1d9353d2d3b34c80d4d4fbcd48258c9a11c97\",\"062b2371de9dfad15931a1e72c46afe492ad697447680ea43300ed516bcc2742\",\"b23ca0a83b0367755e2c53c1f7ed9e6d372c220ae0f344082cf5d52c40287893\",\"9b1b446dd599fd5dab08e83738b92651d8aaa7be072db313d237c68ce1094ea1\",\"a03c962c184055ccbf7a42c9a13a0d4c38125535a830832a6fff3029d6deada3\",\"df5d9e1e3a220d2429f9064adecb86ecae916619c93e17d237b5972692e558fd\",\"2d6315b7a91d62bd31e4738259f56f58075bd14ee2f1e2625738f506a7564176\",\"26b1d48ab8c3f0707bd5afdf4a3ef757abc9b6a0be75b8a3cecbcd5994473a72\",\"f897c92aca8d6ef46a41a3a50aff0527bd09be029355d28c2360ec9cb309b1ae\",\"f80ff7cbcad8c465278a59588a3a0d000cc3130e96fb56d257229c1a50d93125\",\"7a84f42433ecd9352e2ffd8bdc8556c87ec93697cf4c4873d4ab51d2b85c44c1\",\"00c03e0af90a26d0a4bb4b243f99b2d361de2412d82f357f6224eceb2f19c142\",\"e0a8f77abd726e928580656d7ab49dc276603e936e04b9caf53a2a27338e3cd1\",\"e376ebd2f0c93013cf6c856fb76e7b60e64a300a9a4b839844074cac4da42b8d\",\"5fcc77f29cfdb51aac9fff250e1ee7607457ce5a280e946150931d793272593a\",\"ad34b2dce6a7136584c5ffea74c66e5613593dddac9eb666ff6a6aef42386968\",\"3d1afa6b931fea014211bb6b08d9508389dd0a9c47a25670ca110bcc8ce8ead1\",\"df427b938f6ef07cd67da1ab11ad8fb4e6b0a97c03325c1fc8b1c3b0c4b8f7f4\",\"8c3d435fdb6ee44e26155c116a86f4dc2b54b05becb08777a63e1d1ad7c3cbc2\",\"11671f5bd2856de1b4925ee0b82f9cda6179db132c9930431d26f0ccdbb8a822\",\"19dcd3ac59669e10420b36d4e588206ae123a0c8ae64b20e1ede697efc556291\",\"65542a8b2c1bca8d78d6517357853c1d54f6b53f04a8327f28ae2d5d022c5597\"]},\"attestations\":4796228701811883082}";
753
-
754
- let serialized = serde_json::to_string(&s).unwrap();
755
- assert_eq!(JSON_STR, serialized);
756
- let deserialized: State = serde_json::from_str(&serialized).unwrap();
757
- assert_eq!(s, deserialized);
758
-
759
- const BINARY_STR: &str = "5b60b072b14972e054b6800181215b654a2b64e8a0f39da6d5ad20f4e6eda87d50d36e93efd9cdb9086ff17201000000fc13560200000000420d26e30100000018982f5200000000c378c1e901000000f146ff1900000000f6f6ccb80000000089116d64010000009eb377e000000000c79509c200000000fd6dd14200000000fb66f6dd0517bd80a57c6fc1dd186eeb25a5f7dc550adc94a996731734f4a478188d65bc61f7398757be167c70139bc79e2f387551bd0338b81f3938850033c23f48064ca312d68970452ce1abbc218b3f80e4e86850bd465e7e960e017d5772f3341bd8d80fc797de245c760a3f9e84f4da66f9e0ee95aa95ae9eb00188ade3367e57e5bdc522a16e95a8d28e1b940d2d128273aa7a8330cfb49736296ae52965fd7d66d55720eeadfc2be586db65699050bce175c56056a537942b3dcc3fb364ca2cdd33416f2ad78e92cd50081c59c5c9f67c9a64829c9022ffe17973176b934cf5ab04186591c97b2b86f290de9dace84dac6fe2b4867e964c967126699e34e7e3114292eca3140a6f0a94e76e39c047b064bfdbc6bbe6ff949d4637004478a9fabda865dafcaf474d48bdb1272595513cf92290917392ff58ca8bea591ae6a5ea278d90592e0518fbf2e83f41507486fe57e8e4ffbe152f13250df696bf2488cae3f7046f8b04aec217a09358db22d8ae36f883d1ccae9382edca79c54ee498f1adbe88c58bc9dabf487437b8d191a78fbb3d8cfe19a4c1759ae232b4f496130e35228422970057745ef4b92d285434c25187c44110922554d0ae04067844f29b39d6e4f509d5d41834db4fd6a831ccca33bb46185a5ad01f278958133775f0b42f9d291c4ff4e57f403893e0ca18fdc64f0723e0f29b6aeed834db1ac24ce129d69c69971497c556d9eeec0de8c1dd9cc4b0750be9fffd9ec3226ce7a3f3321bf48aed89100db44b3080f3f350d10b6de213527b19ad57bdd1cd47576a724c8bf4c8459625190ae18b2fc1d9353d2d3b34c80d4d4fbcd48258c9a11c97062b2371de9dfad15931a1e72c46afe492ad697447680ea43300ed516bcc2742b23ca0a83b0367755e2c53c1f7ed9e6d372c220ae0f344082cf5d52c402878939b1b446dd599fd5dab08e83738b92651d8aaa7be072db313d237c68ce1094ea1a03c962c184055ccbf7a42c9a13a0d4c38125535a830832a6fff3029d6deada3df5d9e1e3a220d2429f9064adecb86ecae916619c93e17d237b5972692e558fd2d6315b7a91d62bd31e4738259f56f58075bd14ee2f1e2625738f506a756417626b1d48ab8c3f0707bd5afdf4a3ef757abc9b6a0be75b8a3cecbcd5994473a72f897c92aca8d6ef46a41a3a50aff0527bd09be029355d28c2360ec9cb309b1aef80ff7cbcad8c465278a59588a3a0d000cc3130e96fb56d257229c1a50d931257a84f42433ecd9352e2ffd8bdc8556c87ec93697cf4c4873d4ab51d2b85c44c100c03e0af90a26d0a4bb4b243f99b2d361de2412d82f357f6224eceb2f19c142e0a8f77abd726e928580656d7ab49dc276603e936e04b9caf53a2a27338e3cd1e376ebd2f0c93013cf6c856fb76e7b60e64a300a9a4b839844074cac4da42b8d5fcc77f29cfdb51aac9fff250e1ee7607457ce5a280e946150931d793272593aad34b2dce6a7136584c5ffea74c66e5613593dddac9eb666ff6a6aef423869683d1afa6b931fea014211bb6b08d9508389dd0a9c47a25670ca110bcc8ce8ead1df427b938f6ef07cd67da1ab11ad8fb4e6b0a97c03325c1fc8b1c3b0c4b8f7f48c3d435fdb6ee44e26155c116a86f4dc2b54b05becb08777a63e1d1ad7c3cbc211671f5bd2856de1b4925ee0b82f9cda6179db132c9930431d26f0ccdbb8a82219dcd3ac59669e10420b36d4e588206ae123a0c8ae64b20e1ede697efc55629165542a8b2c1bca8d78d6517357853c1d54f6b53f04a8327f28ae2d5d022c55974abc07c197a08f42";
760
-
761
- let mut serialized = Vec::new();
762
- s.encode(&mut serialized).unwrap();
763
- assert_eq!(BINARY_STR, hex::encode(serialized.clone()));
764
- let deserialized = State::decode(&mut &serialized[..]).unwrap();
765
- assert_eq!(s, deserialized);
766
- }
767
- }