@@ -57,7 +57,10 @@ func hashNode(n node, digestBuffer io.Writer) (err error) {
57
57
// if length of encoded leaf is less than 32 bytes, do not hash
58
58
if encodingBuffer .Len () < 32 {
59
59
_ , err = digestBuffer .Write (encodingBuffer .Bytes ())
60
- return err
60
+ if err != nil {
61
+ return fmt .Errorf ("cannot write encoded node to buffer: %w" , err )
62
+ }
63
+ return nil
61
64
}
62
65
63
66
// otherwise, hash encoded node
@@ -72,16 +75,26 @@ func hashNode(n node, digestBuffer io.Writer) (err error) {
72
75
}
73
76
74
77
_ , err = digestBuffer .Write (hasher .Sum (nil ))
75
- return err
78
+ if err != nil {
79
+ return fmt .Errorf ("cannot write hash sum of node to buffer: %w" , err )
80
+ }
81
+ return nil
76
82
}
77
83
78
84
var ErrNodeTypeUnsupported = errors .New ("node type is not supported" )
79
85
86
+ type bytesBuffer interface {
87
+ // note: cannot compose with io.Writer for mock generation
88
+ Write (p []byte ) (n int , err error )
89
+ Len () int
90
+ Bytes () []byte
91
+ }
92
+
80
93
// encodeNode writes the encoding of the node to the buffer given.
81
94
// It is the high-level function wrapping the encoding for different
82
95
// node types. The encoding has the following format:
83
96
// NodeHeader | Extra partial key length | Partial Key | Value
84
- func encodeNode (n node , buffer * bytes. Buffer , parallel bool ) (err error ) {
97
+ func encodeNode (n node , buffer bytesBuffer , parallel bool ) (err error ) {
85
98
switch n := n .(type ) {
86
99
case * branch :
87
100
err := encodeBranch (n , buffer , parallel )
@@ -104,70 +117,58 @@ func encodeNode(n node, buffer *bytes.Buffer, parallel bool) (err error) {
104
117
copy (n .encoding , buffer .Bytes ())
105
118
return nil
106
119
case nil :
107
- buffer .Write ([]byte {0 })
120
+ _ , err := buffer .Write ([]byte {0 })
121
+ if err != nil {
122
+ return fmt .Errorf ("cannot encode nil node: %w" , err )
123
+ }
108
124
return nil
109
125
default :
110
126
return fmt .Errorf ("%w: %T" , ErrNodeTypeUnsupported , n )
111
127
}
112
128
}
113
129
114
- func encodeAndHash (n node ) ([]byte , error ) {
115
- buffer := digestBufferPool .Get ().(* bytes.Buffer )
116
- buffer .Reset ()
117
- defer digestBufferPool .Put (buffer )
118
-
119
- err := hashNode (n , buffer )
120
- if err != nil {
121
- return nil , err
122
- }
123
-
124
- scEncChild , err := scale .Marshal (buffer .Bytes ())
125
- if err != nil {
126
- return nil , err
127
- }
128
- return scEncChild , nil
129
- }
130
-
131
130
// encodeBranch encodes a branch with the encoding specified at the top of this package
132
131
// to the buffer given.
133
132
func encodeBranch (b * branch , buffer io.Writer , parallel bool ) (err error ) {
134
133
if ! b .dirty && b .encoding != nil {
135
134
_ , err = buffer .Write (b .encoding )
136
135
if err != nil {
137
- return fmt .Errorf ("cannot write stored encoded branch to buffer: %w" , err )
136
+ return fmt .Errorf ("cannot write stored encoding to buffer: %w" , err )
138
137
}
139
138
return nil
140
139
}
141
140
142
- encoding , err := b .header ()
141
+ encodedHeader , err := b .header ()
143
142
if err != nil {
144
- return fmt .Errorf ("cannot encode branch header: %w" , err )
143
+ return fmt .Errorf ("cannot encode header: %w" , err )
145
144
}
146
145
147
- _ , err = buffer .Write (encoding )
146
+ _ , err = buffer .Write (encodedHeader )
148
147
if err != nil {
149
- return fmt .Errorf ("cannot write encoded branch header to buffer: %w" , err )
148
+ return fmt .Errorf ("cannot write encoded header to buffer: %w" , err )
150
149
}
151
150
152
- _ , err = buffer .Write (nibblesToKeyLE (b .key ))
151
+ keyLE := nibblesToKeyLE (b .key )
152
+ _ , err = buffer .Write (keyLE )
153
153
if err != nil {
154
- return fmt .Errorf ("cannot write encoded branch key to buffer: %w" , err )
154
+ return fmt .Errorf ("cannot write encoded key to buffer: %w" , err )
155
155
}
156
156
157
- _ , err = buffer .Write (common .Uint16ToBytes (b .childrenBitmap ()))
157
+ childrenBitmap := common .Uint16ToBytes (b .childrenBitmap ())
158
+ _ , err = buffer .Write (childrenBitmap )
158
159
if err != nil {
159
- return fmt .Errorf ("cannot write branch children bitmap to buffer: %w" , err )
160
+ return fmt .Errorf ("cannot write children bitmap to buffer: %w" , err )
160
161
}
161
162
162
163
if b .value != nil {
163
164
bytes , err := scale .Marshal (b .value )
164
165
if err != nil {
165
- return fmt .Errorf ("cannot scale encode branch value: %w" , err )
166
+ return fmt .Errorf ("cannot scale encode value: %w" , err )
166
167
}
167
168
168
169
_ , err = buffer .Write (bytes )
169
170
if err != nil {
170
- return fmt .Errorf ("cannot write encoded branch value to buffer: %w" , err )
171
+ return fmt .Errorf ("cannot write encoded value to buffer: %w" , err )
171
172
}
172
173
}
173
174
@@ -222,10 +223,15 @@ func encodeChildrenInParallel(children [16]node, buffer io.Writer) (err error) {
222
223
// write as many completed buffers to the result buffer.
223
224
for currentIndex < len (children ) &&
224
225
resultBuffers [currentIndex ] != nil {
225
- // note buffer.Write copies the byte slice given as argument
226
- _ , writeErr := buffer .Write (resultBuffers [currentIndex ].Bytes ())
227
- if writeErr != nil && err == nil {
228
- err = writeErr
226
+ bufferSlice := resultBuffers [currentIndex ].Bytes ()
227
+ if len (bufferSlice ) > 0 {
228
+ // note buffer.Write copies the byte slice given as argument
229
+ _ , writeErr := buffer .Write (bufferSlice )
230
+ if writeErr != nil && err == nil {
231
+ err = fmt .Errorf (
232
+ "cannot write encoding of child at index %d: %w" ,
233
+ currentIndex , writeErr )
234
+ }
229
235
}
230
236
231
237
encodingBufferPool .Put (resultBuffers [currentIndex ])
@@ -246,17 +252,26 @@ func encodeChildrenInParallel(children [16]node, buffer io.Writer) (err error) {
246
252
}
247
253
248
254
func encodeChildrenSequentially (children [16 ]node , buffer io.Writer ) (err error ) {
249
- for _ , child := range children {
255
+ for i , child := range children {
250
256
err = encodeChild (child , buffer )
251
257
if err != nil {
252
- return err
258
+ return fmt . Errorf ( "cannot encode child at index %d: %w" , i , err )
253
259
}
254
260
}
255
261
return nil
256
262
}
257
263
258
264
func encodeChild (child node , buffer io.Writer ) (err error ) {
259
- if child == nil {
265
+ var isNil bool
266
+ switch impl := child .(type ) {
267
+ case * branch :
268
+ isNil = impl == nil
269
+ case * leaf :
270
+ isNil = impl == nil
271
+ default :
272
+ isNil = child == nil
273
+ }
274
+ if isNil {
260
275
return nil
261
276
}
262
277
@@ -273,6 +288,23 @@ func encodeChild(child node, buffer io.Writer) (err error) {
273
288
return nil
274
289
}
275
290
291
+ func encodeAndHash (n node ) (b []byte , err error ) {
292
+ buffer := digestBufferPool .Get ().(* bytes.Buffer )
293
+ buffer .Reset ()
294
+ defer digestBufferPool .Put (buffer )
295
+
296
+ err = hashNode (n , buffer )
297
+ if err != nil {
298
+ return nil , fmt .Errorf ("cannot hash node: %w" , err )
299
+ }
300
+
301
+ scEncChild , err := scale .Marshal (buffer .Bytes ())
302
+ if err != nil {
303
+ return nil , fmt .Errorf ("cannot scale encode hashed node: %w" , err )
304
+ }
305
+ return scEncChild , nil
306
+ }
307
+
276
308
// encodeLeaf encodes a leaf to the buffer given, with the encoding
277
309
// specified at the top of this package.
278
310
func encodeLeaf (l * leaf , buffer io.Writer ) (err error ) {
@@ -286,27 +318,28 @@ func encodeLeaf(l *leaf, buffer io.Writer) (err error) {
286
318
return nil
287
319
}
288
320
289
- encoding , err := l .header ()
321
+ encodedHeader , err := l .header ()
290
322
if err != nil {
291
323
return fmt .Errorf ("cannot encode header: %w" , err )
292
324
}
293
325
294
- _ , err = buffer .Write (encoding )
326
+ _ , err = buffer .Write (encodedHeader )
295
327
if err != nil {
296
328
return fmt .Errorf ("cannot write encoded header to buffer: %w" , err )
297
329
}
298
330
299
- _ , err = buffer .Write (nibblesToKeyLE (l .key ))
331
+ keyLE := nibblesToKeyLE (l .key )
332
+ _ , err = buffer .Write (keyLE )
300
333
if err != nil {
301
334
return fmt .Errorf ("cannot write LE key to buffer: %w" , err )
302
335
}
303
336
304
- bytes , err := scale .Marshal (l .value ) // TODO scale encoder to write to buffer
337
+ encodedValue , err := scale .Marshal (l .value ) // TODO scale encoder to write to buffer
305
338
if err != nil {
306
- return err
339
+ return fmt . Errorf ( "cannot scale marshal value: %w" , err )
307
340
}
308
341
309
- _ , err = buffer .Write (bytes )
342
+ _ , err = buffer .Write (encodedValue )
310
343
if err != nil {
311
344
return fmt .Errorf ("cannot write scale encoded value to buffer: %w" , err )
312
345
}
0 commit comments