@@ -75,6 +75,41 @@ defmodule LambdaEthereumConsensus.SszEx do
75
75
@ spec hash_tree_root! ( non_neg_integer , { :int , non_neg_integer } ) :: Types . root ( )
76
76
def hash_tree_root! ( value , { :int , size } ) , do: pack ( value , { :int , size } )
77
77
78
+ @ spec hash_tree_root! ( binary , { :bytes , non_neg_integer } ) :: Types . root ( )
79
+ def hash_tree_root! ( value , { :bytes , size } ) do
80
+ packed_chunks = pack ( value , { :bytes , size } )
81
+ leaf_count = packed_chunks |> get_chunks_len ( ) |> next_pow_of_two ( )
82
+ root = merkleize_chunks_with_virtual_padding ( packed_chunks , leaf_count )
83
+ root
84
+ end
85
+
86
+ @ spec hash_tree_root! ( list ( ) , { :list , any , non_neg_integer } ) :: Types . root ( )
87
+ def hash_tree_root! ( list , { :list , type , size } ) do
88
+ { :ok , root } = hash_tree_root ( list , { :list , type , size } )
89
+ root
90
+ end
91
+
92
+ @ spec hash_tree_root! ( list ( ) , { :vector , any , non_neg_integer } ) :: Types . root ( )
93
+ def hash_tree_root! ( vector , { :vector , type , size } ) do
94
+ { :ok , root } = hash_tree_root ( vector , { :vector , type , size } )
95
+ root
96
+ end
97
+
98
+ @ spec hash_tree_root! ( struct ( ) , atom ( ) ) :: Types . root ( )
99
+ def hash_tree_root! ( container , module ) when is_map ( container ) do
100
+ chunks =
101
+ module . schema ( )
102
+ |> Enum . reduce ( << >> , fn { key , schema } , acc_root ->
103
+ value = container |> Map . get ( key )
104
+ root = hash_tree_root! ( value , schema )
105
+ acc_root <> root
106
+ end )
107
+
108
+ leaf_count = chunks |> get_chunks_len ( ) |> next_pow_of_two ( )
109
+ root = merkleize_chunks_with_virtual_padding ( chunks , leaf_count )
110
+ root
111
+ end
112
+
78
113
@ spec hash_tree_root ( list ( ) , { :list , any , non_neg_integer } ) ::
79
114
{ :ok , Types . root ( ) } | { :error , String . t ( ) }
80
115
def hash_tree_root ( list , { :list , type , size } ) do
@@ -207,6 +242,11 @@ defmodule LambdaEthereumConsensus.SszEx do
207
242
<< value :: size ( size ) - little >> |> pack_bytes ( )
208
243
end
209
244
245
+ @ spec pack ( binary , { :bytes , non_neg_integer } ) :: binary ( )
246
+ def pack ( value , { :bytes , _size } ) do
247
+ value |> pack_bytes ( )
248
+ end
249
+
210
250
@ spec pack ( list ( ) , { :list | :vector , any , non_neg_integer } ) :: binary ( ) | :error
211
251
def pack ( list , { type , schema , _ } ) when type in [ :vector , :list ] do
212
252
if variable_size? ( schema ) do
0 commit comments