Skip to content

Commit f2e79e1

Browse files
committed
Fix differentiating nil and empty subvalues
1 parent e36334b commit f2e79e1

File tree

3 files changed

+77
-3
lines changed

3 files changed

+77
-3
lines changed

internal/trie/node/subvalue.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2022 ChainSafe Systems (ON)
2+
// SPDX-License-Identifier: LGPL-3.0-only
3+
4+
package node
5+
6+
import "bytes"
7+
8+
// SubValueEqual returns true if the node subvalue is equal to the
9+
// subvalue given as argument. In particular, it returns false
10+
// if one subvalue is nil and the other subvalue is the empty slice.
11+
func (n Node) SubValueEqual(subValue []byte) (equal bool) {
12+
if len(subValue) == 0 && len(n.SubValue) == 0 {
13+
return (subValue == nil && n.SubValue == nil) ||
14+
(subValue != nil && n.SubValue != nil)
15+
}
16+
return bytes.Equal(n.SubValue, subValue)
17+
}

internal/trie/node/subvalue_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright 2022 ChainSafe Systems (ON)
2+
// SPDX-License-Identifier: LGPL-3.0-only
3+
4+
package node
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func Test_Node_SubValueEqual(t *testing.T) {
13+
t.Parallel()
14+
15+
testCases := map[string]struct {
16+
node Node
17+
subValue []byte
18+
equal bool
19+
}{
20+
"nil node subvalue and nil subvalue": {
21+
equal: true,
22+
},
23+
"empty node subvalue and empty subvalue": {
24+
node: Node{SubValue: []byte{}},
25+
subValue: []byte{},
26+
equal: true,
27+
},
28+
"nil node subvalue and empty subvalue": {
29+
subValue: []byte{},
30+
},
31+
"empty node subvalue and nil subvalue": {
32+
node: Node{SubValue: []byte{}},
33+
},
34+
"equal non empty values": {
35+
node: Node{SubValue: []byte{1, 2}},
36+
subValue: []byte{1, 2},
37+
equal: true,
38+
},
39+
"not equal non empty values": {
40+
node: Node{SubValue: []byte{1, 2}},
41+
subValue: []byte{1, 3},
42+
},
43+
}
44+
45+
for name, testCase := range testCases {
46+
testCase := testCase
47+
t.Run(name, func(t *testing.T) {
48+
t.Parallel()
49+
50+
node := testCase.node
51+
52+
equal := node.SubValueEqual(testCase.subValue)
53+
54+
assert.Equal(t, testCase.equal, equal)
55+
})
56+
}
57+
}

lib/trie/trie.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte) (
351351
newParent *Node, mutated bool, nodesCreated uint32) {
352352
if bytes.Equal(parentLeaf.Key, key) {
353353
nodesCreated = 0
354-
if bytes.Equal(value, parentLeaf.SubValue) {
354+
if parentLeaf.SubValueEqual(value) {
355355
const mutated = false
356356
return parentLeaf, mutated, nodesCreated
357357
}
@@ -431,7 +431,7 @@ func (t *Trie) insertInBranch(parentBranch *Node, key, value []byte) (
431431
copySettings := node.DefaultCopySettings
432432

433433
if bytes.Equal(key, parentBranch.Key) {
434-
if bytes.Equal(parentBranch.SubValue, value) {
434+
if parentBranch.SubValueEqual(value) {
435435
const mutated = false
436436
return parentBranch, mutated, 0
437437
}
@@ -463,7 +463,7 @@ func (t *Trie) insertInBranch(parentBranch *Node, key, value []byte) (
463463
return parentBranch, mutated, nodesCreated
464464
}
465465

466-
child, mutated, nodesCreated := t.insert(child, remainingKey, value)
466+
child, mutated, nodesCreated = t.insert(child, remainingKey, value)
467467
if !mutated {
468468
return parentBranch, mutated, 0
469469
}

0 commit comments

Comments
 (0)