@@ -6,8 +6,8 @@ use std::{
6
6
use ssz:: { Decode , DecodeError , Encode } ;
7
7
use ssz_derive:: { Decode , Encode } ;
8
8
use thiserror:: Error ;
9
- use tree_hash:: { PackedEncoding , TreeHash , TreeHashType } ;
10
- use zerocopy :: IntoBytes ;
9
+ use tree_hash:: { merkle_root , mix_in_length , MerkleHasher , PackedEncoding , TreeHash , TreeHashType } ;
10
+ use types :: Hash256 ;
11
11
12
12
use crate :: {
13
13
message:: {
@@ -82,16 +82,17 @@ impl TreeHash for MsgType {
82
82
}
83
83
84
84
fn tree_hash_packed_encoding ( & self ) -> PackedEncoding {
85
- todo ! ( )
85
+ let value = self . clone ( ) as u64 ;
86
+ value. tree_hash_packed_encoding ( )
86
87
}
87
88
88
89
fn tree_hash_packing_factor ( ) -> usize {
89
- 1
90
+ u64 :: tree_hash_packing_factor ( )
90
91
}
91
92
92
93
fn tree_hash_root ( & self ) -> tree_hash:: Hash256 {
93
- let encoding = self . tree_hash_packed_encoding ( ) ;
94
- tree_hash :: Hash256 :: from_slice ( encoding . as_bytes ( ) )
94
+ let value = self . clone ( ) as u64 ;
95
+ value . tree_hash_root ( )
95
96
}
96
97
}
97
98
@@ -181,19 +182,44 @@ pub struct SSVMessage {
181
182
182
183
impl TreeHash for SSVMessage {
183
184
fn tree_hash_type ( ) -> TreeHashType {
184
- todo ! ( )
185
+ TreeHashType :: Container
185
186
}
186
187
187
188
fn tree_hash_packed_encoding ( & self ) -> PackedEncoding {
188
- todo ! ( )
189
+ unreachable ! ( "Container should not be packed" )
189
190
}
190
191
191
192
fn tree_hash_packing_factor ( ) -> usize {
192
- todo ! ( )
193
+ unreachable ! ( "Container should not be packed" )
193
194
}
194
195
195
196
fn tree_hash_root ( & self ) -> tree_hash:: Hash256 {
196
- todo ! ( )
197
+ let mut hasher = MerkleHasher :: with_leaves ( 3 ) ;
198
+
199
+ hasher
200
+ . write ( self . msg_type . tree_hash_root ( ) . as_slice ( ) )
201
+ . unwrap ( ) ;
202
+ hasher
203
+ . write ( self . msg_id . tree_hash_root ( ) . as_slice ( ) )
204
+ . unwrap ( ) ;
205
+ // Field 2: Data - variable-length byte array
206
+ // First get the data index
207
+ // Calculate chunks needed ((max_size + 31) / 32)
208
+ let chunks_needed = ( 722412 + 31 ) / 32 ;
209
+
210
+ // Merkleize the data with the calculated chunk count
211
+ let data_root = merkle_root ( & self . data , chunks_needed) ;
212
+
213
+ // Mix in the length - this is equivalent to MerkleizeWithMixin in Go
214
+ let data_with_length = mix_in_length ( & data_root, self . data . len ( ) ) ;
215
+
216
+ // Add hashed data to the main tree
217
+ hasher
218
+ . write ( data_with_length. as_slice ( ) )
219
+ . expect ( "Failed to write data" ) ;
220
+
221
+ // Finalize and return the root
222
+ hasher. finish ( ) . expect ( "Failed to finish hashing" )
197
223
}
198
224
}
199
225
@@ -331,19 +357,91 @@ pub struct SignedSSVMessage {
331
357
332
358
impl TreeHash for SignedSSVMessage {
333
359
fn tree_hash_type ( ) -> TreeHashType {
334
- todo ! ( )
360
+ TreeHashType :: Container
335
361
}
336
362
337
363
fn tree_hash_packed_encoding ( & self ) -> PackedEncoding {
338
- todo ! ( )
364
+ unreachable ! ( "Container should never be packed." )
339
365
}
340
366
341
367
fn tree_hash_packing_factor ( ) -> usize {
342
- todo ! ( )
368
+ unreachable ! ( "Container should never be packed." )
343
369
}
344
370
345
- fn tree_hash_root ( & self ) -> tree_hash:: Hash256 {
346
- todo ! ( )
371
+ fn tree_hash_root ( & self ) -> Hash256 {
372
+ // Create hasher for 4 fields
373
+ let mut hasher = MerkleHasher :: with_leaves ( 4 ) ;
374
+
375
+ let signatures_root = self . hash_signatures ( ) ;
376
+ hasher
377
+ . write ( signatures_root. as_slice ( ) )
378
+ . expect ( "Failed to write signatures" ) ;
379
+
380
+ let operator_ids_root = self . hash_operator_ids ( ) ;
381
+ hasher
382
+ . write ( operator_ids_root. as_slice ( ) )
383
+ . expect ( "Failed to write operator IDs" ) ;
384
+
385
+ hasher
386
+ . write ( self . ssv_message . tree_hash_root ( ) . as_slice ( ) )
387
+ . expect ( "Failed to write SSV message" ) ;
388
+
389
+ let max_chunks = ( 8388836 + 31 ) / 32 ;
390
+ let full_data_root = merkle_root ( & self . full_data , max_chunks) ;
391
+ let full_data_with_length = mix_in_length ( & full_data_root, self . full_data . len ( ) ) ;
392
+
393
+ hasher
394
+ . write ( full_data_with_length. as_slice ( ) )
395
+ . expect ( "Failed to write full data" ) ;
396
+
397
+ // Finalize and return root hash
398
+ hasher. finish ( ) . expect ( "Failed to finish hashing" )
399
+ }
400
+ }
401
+
402
+ // Helper methods to keep the main implementation cleaner
403
+ impl SignedSSVMessage {
404
+ fn hash_signatures ( & self ) -> Hash256 {
405
+ // Create a hasher for the signatures list
406
+ let mut signatures_hasher = MerkleHasher :: with_leaves ( self . signatures . len ( ) ) ;
407
+
408
+ // Hash each signature
409
+ for signature in & self . signatures {
410
+ // Each signature is a variable-length byte array with max 256 bytes
411
+ let signature_chunks = ( 256 + 31 ) / 32 ;
412
+ let signature_root = merkle_root ( signature, signature_chunks) ;
413
+ let signature_with_length = mix_in_length ( & signature_root, signature. len ( ) ) ;
414
+
415
+ signatures_hasher
416
+ . write ( signature_with_length. as_slice ( ) )
417
+ . expect ( "Failed to write signature" ) ;
418
+ }
419
+
420
+ // Get the signatures list root and mix in length
421
+ let root = signatures_hasher
422
+ . finish ( )
423
+ . expect ( "Failed to hash signatures" ) ;
424
+ mix_in_length ( & root, self . signatures . len ( ) )
425
+ }
426
+
427
+ fn hash_operator_ids ( & self ) -> Hash256 {
428
+ // Create a hasher for the operator IDs list
429
+ let mut operators_hasher = MerkleHasher :: with_leaves ( self . operator_ids . len ( ) ) ;
430
+
431
+ // Hash each operator ID
432
+ for operator_id in & self . operator_ids {
433
+ // Assuming OperatorId can be converted to u64
434
+ let id_value: u64 = operator_id. 0 ;
435
+ operators_hasher
436
+ . write ( id_value. tree_hash_root ( ) . as_slice ( ) )
437
+ . expect ( "Failed to write operator ID" ) ;
438
+ }
439
+
440
+ // Get the operator IDs list root and mix in length
441
+ let root = operators_hasher
442
+ . finish ( )
443
+ . expect ( "Failed to hash operator IDs" ) ;
444
+ mix_in_length ( & root, self . operator_ids . len ( ) )
347
445
}
348
446
}
349
447
0 commit comments