Skip to content

Commit

Permalink
fix(trie): do not create buffer for nil child (#2928)
Browse files Browse the repository at this point in the history
  • Loading branch information
qdm12 authored Jan 10, 2023
1 parent df46e65 commit d70af4f
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 13 deletions.
39 changes: 27 additions & 12 deletions internal/trie/node/branch_encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@ func encodeChildrenOpportunisticParallel(children []*Node, buffer io.Writer) (er
resultsCh := make(chan encodingAsyncResult, ChildrenCapacity)

for i, child := range children {
if child == nil || child.Kind() == Leaf {
if child == nil {
resultsCh <- encodingAsyncResult{index: i}
continue
}

if child.Kind() == Leaf {
runEncodeChild(child, i, resultsCh, nil)
continue
}
Expand All @@ -69,19 +74,31 @@ func encodeChildrenOpportunisticParallel(children []*Node, buffer io.Writer) (er
}

currentIndex := 0
resultBuffers := make([]*bytes.Buffer, ChildrenCapacity)
indexToBuffer := make(map[int]*bytes.Buffer, ChildrenCapacity)
for range children {
result := <-resultsCh
if result.err != nil && err == nil { // only set the first error we get
err = result.err
}

resultBuffers[result.index] = result.buffer
indexToBuffer[result.index] = result.buffer

// write as many completed buffers to the result buffer.
for currentIndex < ChildrenCapacity &&
resultBuffers[currentIndex] != nil {
bufferSlice := resultBuffers[currentIndex].Bytes()
for currentIndex < ChildrenCapacity {
resultBuffer, done := indexToBuffer[currentIndex]
if !done {
break
}

delete(indexToBuffer, currentIndex)

nilChildNode := resultBuffer == nil
if nilChildNode {
currentIndex++
continue
}

bufferSlice := resultBuffer.Bytes()
if err == nil && len(bufferSlice) > 0 {
// note buffer.Write copies the byte slice given as argument
_, writeErr := buffer.Write(bufferSlice)
Expand All @@ -92,8 +109,6 @@ func encodeChildrenOpportunisticParallel(children []*Node, buffer io.Writer) (er
}
}

resultBuffers[currentIndex] = nil

currentIndex++
}
}
Expand All @@ -103,6 +118,10 @@ func encodeChildrenOpportunisticParallel(children []*Node, buffer io.Writer) (er

func encodeChildrenSequentially(children []*Node, buffer io.Writer) (err error) {
for i, child := range children {
if child == nil {
continue
}

err = encodeChild(child, buffer)
if err != nil {
return fmt.Errorf("encoding child at index %d: %w", i, err)
Expand All @@ -114,10 +133,6 @@ func encodeChildrenSequentially(children []*Node, buffer io.Writer) (err error)
// encodeChild computes the Merkle value of the node
// and then SCALE encodes it to the given buffer.
func encodeChild(child *Node, buffer io.Writer) (err error) {
if child == nil {
return nil
}

merkleValue, err := child.CalculateMerkleValue()
if err != nil {
return fmt.Errorf("computing %s Merkle value: %w", child.Kind(), err)
Expand Down
1 change: 0 additions & 1 deletion internal/trie/node/branch_encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,6 @@ func Test_encodeChild(t *testing.T) {
wrappedErr error
errMessage string
}{
"nil node": {},
"empty branch child": {
child: &Node{
Children: make([]*Node, ChildrenCapacity),
Expand Down

0 comments on commit d70af4f

Please sign in to comment.