1616 HashDigestList ,
1717 HashDigestVector ,
1818 HashTreeLayer ,
19+ HashTreeLayers ,
1920 HashTreeOpening ,
2021 Parameter ,
2122)
@@ -72,10 +73,12 @@ class HashSubTree(StrictBaseModel):
7273 layers 16 through 32 (the root).
7374 """
7475
75- layers : List [ HashTreeLayer ]
76+ layers : HashTreeLayers
7677 """
7778 The layers of this subtree, from `lowest_layer` to the root.
7879
80+ SSZ notation: `List[HashTreeLayer, LAYERS_LIMIT]`
81+
7982 - `layers[0]` corresponds to layer `lowest_layer` in the full tree
8083 - `layers[-1]` corresponds to the highest layer in this subtree
8184 - For bottom trees: the last layer contains a single root
@@ -179,7 +182,11 @@ def new(
179182 layers .append (current_layer )
180183
181184 # Return the completed subtree.
182- return cls (depth = Uint64 (depth ), lowest_layer = Uint64 (lowest_layer ), layers = layers )
185+ return cls (
186+ depth = Uint64 (depth ),
187+ lowest_layer = Uint64 (lowest_layer ),
188+ layers = HashTreeLayers (data = layers ),
189+ )
183190
184191 @classmethod
185192 def new_top_tree (
@@ -326,7 +333,7 @@ def new_bottom_tree(
326333 # the bottom_tree_index (if it's the left child of its parent in the top tree)
327334 # or bottom_tree_index (if it's the right child). Since we're at layer depth/2,
328335 # the position is simply bottom_tree_index.
329- middle_layer = full_tree .layers [depth // 2 ]
336+ middle_layer = cast ( HashTreeLayer , full_tree .layers . data [depth // 2 ])
330337
331338 # The root is at position (start_index >> (depth // 2)) = bottom_tree_index
332339 # within the middle layer. We need to find it in the stored nodes.
@@ -336,7 +343,7 @@ def new_bottom_tree(
336343 root = list (root_data )
337344
338345 # Truncate layers to keep only 0 through depth/2 - 1.
339- truncated_layers = full_tree .layers [: (depth // 2 )]
346+ truncated_layers = list ( full_tree .layers . data [: (depth // 2 )])
340347
341348 # Add a final layer containing just the root.
342349 root_vector = HashDigestVector (data = root )
@@ -345,7 +352,11 @@ def new_bottom_tree(
345352 )
346353 truncated_layers .append (root_layer )
347354
348- return cls (depth = Uint64 (depth ), lowest_layer = Uint64 (0 ), layers = truncated_layers )
355+ return cls (
356+ depth = Uint64 (depth ),
357+ lowest_layer = Uint64 (0 ),
358+ layers = HashTreeLayers (data = truncated_layers ),
359+ )
349360
350361 def root (self ) -> HashDigestVector :
351362 """
@@ -363,7 +374,7 @@ def root(self) -> HashDigestVector:
363374 if len (self .layers ) == 0 :
364375 raise ValueError ("Cannot get root of empty subtree." )
365376
366- highest_layer = self .layers [- 1 ]
377+ highest_layer = cast ( HashTreeLayer , self .layers . data [- 1 ])
367378 if len (highest_layer .nodes .data ) == 0 :
368379 raise ValueError ("Highest layer of subtree is empty." )
369380
@@ -394,7 +405,7 @@ def path(self, position: Uint64) -> HashTreeOpening:
394405 if len (self .layers ) == 0 :
395406 raise ValueError ("Cannot generate path for empty subtree." )
396407
397- lowest_layer = self .layers [0 ]
408+ lowest_layer = cast ( HashTreeLayer , self .layers . data [0 ])
398409 if position < lowest_layer .start_index :
399410 raise ValueError ("Position is before the subtree's start index." )
400411
@@ -407,8 +418,9 @@ def path(self, position: Uint64) -> HashTreeOpening:
407418
408419 # Iterate through layers from lowest to highest, EXCLUDING the final root layer.
409420 # The root layer doesn't contribute a sibling to the authentication path.
410- # self.layers[:-1] gives all layers except the last (root) layer.
411- for layer in self .layers [:- 1 ]:
421+ # self.layers.data[:-1] gives all layers except the last (root) layer.
422+ for layer_raw in self .layers .data [:- 1 ]:
423+ layer = cast (HashTreeLayer , layer_raw )
412424 # Determine the sibling's position by flipping the last bit.
413425 sibling_position = current_position ^ Uint64 (1 )
414426 sibling_index = sibling_position - layer .start_index
@@ -498,7 +510,7 @@ def combined_path(
498510 # Verify that the provided bottom_tree actually corresponds to this position.
499511 # The bottom tree's lowest layer starts at bottom_tree_index * leafs_per_bottom_tree.
500512 expected_start = bottom_tree_index * Uint64 (leafs_per_bottom_tree )
501- actual_start = bottom_tree .layers [0 ].start_index
513+ actual_start = cast ( HashTreeLayer , bottom_tree .layers . data [0 ]) .start_index
502514
503515 if actual_start != expected_start :
504516 raise ValueError (
0 commit comments