@@ -2,6 +2,7 @@ package codetrie
22
33import (
44 "encoding/binary"
5+ "errors"
56 "math"
67
78 sszlib "github.com/ferranbt/fastssz"
@@ -25,6 +26,12 @@ type Trie interface {
2526 Update (key , value []byte )
2627}
2728
29+ type CodeTrie interface {
30+ HashTreeRoot () ([32 ]byte , error )
31+ HashTreeRootWith (* sszlib.Hasher ) error
32+ GetTree () (* sszlib.Node , error )
33+ }
34+
2835type Chunk struct {
2936 fio uint8 // firstInstructionOffset
3037 code []byte
@@ -72,6 +79,7 @@ func GetSSZTree(code []byte, chunkSize uint) (*sszlib.Node, error) {
7279
7380 return codeTrie .GetTree ()
7481}
82+
7583func MerkleizeSSZSha (code []byte , chunkSize uint ) (common.Hash , error ) {
7684 codeTrie , err := prepareSSZ (code , chunkSize )
7785 if err != nil {
@@ -104,20 +112,64 @@ func MerkleizeSSZKeccak(code []byte, chunkSize uint) (common.Hash, error) {
104112 return common .BytesToHash (root [:]), err
105113}
106114
107- func prepareSSZ (code []byte , chunkSize uint ) (* ssz. CodeTrie , error ) {
115+ func prepareSSZ (code []byte , chunkSize uint ) (CodeTrie , error ) {
108116 rawChunks := Chunkify (code , chunkSize )
109- chunks := make ([]* ssz.Chunk , len (rawChunks ))
117+ metadata := & ssz.Metadata {Version : 0 , CodeHash : crypto .Keccak256 (code ), CodeLength : uint16 (len (code ))}
118+ switch chunkSize {
119+ case 24 :
120+ chunks := prepareSSZChunks24 (rawChunks )
121+ return & ssz.CodeTrie24 {Metadata : metadata , Chunks : chunks }, nil
122+ case 32 :
123+ chunks := prepareSSZChunks32 (rawChunks )
124+ return & ssz.CodeTrie32 {Metadata : metadata , Chunks : chunks }, nil
125+ case 40 :
126+ chunks := prepareSSZChunks40 (rawChunks )
127+ return & ssz.CodeTrie40 {Metadata : metadata , Chunks : chunks }, nil
128+ default :
129+ return nil , errors .New ("chunk size should be one of (24, 32, 40)" )
130+ }
131+ }
132+
133+ func prepareSSZChunks24 (rawChunks []* Chunk ) []* ssz.Chunk24 {
134+ chunks := make ([]* ssz.Chunk24 , len (rawChunks ))
110135 for i , rc := range rawChunks {
111136 code := rc .code
112- if uint (len (code )) < chunkSize {
113- code = make ([]byte , chunkSize )
137+ if uint (len (code )) < 24 {
138+ code = make ([]byte , 24 )
114139 copy (code [:len (rc .code )], rc .code )
115140 }
116- chunks [i ] = & ssz.Chunk {FIO : rc .fio , Code : code }
141+ chunks [i ] = & ssz.Chunk24 {FIO : rc .fio , Code : code }
117142 }
118143
119- metadata := & ssz.Metadata {Version : 0 , CodeHash : crypto .Keccak256 (code ), CodeLength : uint16 (len (code ))}
120- return & ssz.CodeTrie {Metadata : metadata , Chunks : chunks }, nil
144+ return chunks
145+ }
146+
147+ func prepareSSZChunks32 (rawChunks []* Chunk ) []* ssz.Chunk32 {
148+ chunks := make ([]* ssz.Chunk32 , len (rawChunks ))
149+ for i , rc := range rawChunks {
150+ code := rc .code
151+ if uint (len (code )) < 32 {
152+ code = make ([]byte , 32 )
153+ copy (code [:len (rc .code )], rc .code )
154+ }
155+ chunks [i ] = & ssz.Chunk32 {FIO : rc .fio , Code : code }
156+ }
157+
158+ return chunks
159+ }
160+
161+ func prepareSSZChunks40 (rawChunks []* Chunk ) []* ssz.Chunk40 {
162+ chunks := make ([]* ssz.Chunk40 , len (rawChunks ))
163+ for i , rc := range rawChunks {
164+ code := rc .code
165+ if uint (len (code )) < 40 {
166+ code = make ([]byte , 40 )
167+ copy (code [:len (rc .code )], rc .code )
168+ }
169+ chunks [i ] = & ssz.Chunk40 {FIO : rc .fio , Code : code }
170+ }
171+
172+ return chunks
121173}
122174
123175func merkleize (code []byte , chunkSize uint , trie Trie ) {
0 commit comments