Skip to content

Commit 72a08ec

Browse files
authored
fix(trie): equality differentiate nil and empty storage values (#2969)
1 parent bdb0eea commit 72a08ec

File tree

3 files changed

+76
-2
lines changed

3 files changed

+76
-2
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+
// StorageValueEqual returns true if the node storage value is equal to the
9+
// storage value given as argument. In particular, it returns false
10+
// if one storage value is nil and the other storage value is the empty slice.
11+
func (n Node) StorageValueEqual(stoageValue []byte) (equal bool) {
12+
if len(stoageValue) == 0 && len(n.StorageValue) == 0 {
13+
return (stoageValue == nil && n.StorageValue == nil) ||
14+
(stoageValue != nil && n.StorageValue != nil)
15+
}
16+
return bytes.Equal(n.StorageValue, stoageValue)
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_StorageValueEqual(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{StorageValue: []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{StorageValue: []byte{}},
33+
},
34+
"equal non empty values": {
35+
node: Node{StorageValue: []byte{1, 2}},
36+
subValue: []byte{1, 2},
37+
equal: true,
38+
},
39+
"not equal non empty values": {
40+
node: Node{StorageValue: []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.StorageValueEqual(testCase.subValue)
53+
54+
assert.Equal(t, testCase.equal, equal)
55+
})
56+
}
57+
}

lib/trie/trie.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte,
370370
newParent *Node, mutated bool, nodesCreated uint32) {
371371
if bytes.Equal(parentLeaf.PartialKey, key) {
372372
nodesCreated = 0
373-
if bytes.Equal(parentLeaf.StorageValue, value) {
373+
if parentLeaf.StorageValueEqual(value) {
374374
mutated = false
375375
return parentLeaf, mutated, nodesCreated
376376
}
@@ -451,7 +451,7 @@ func (t *Trie) insertInBranch(parentBranch *Node, key, value []byte,
451451
copySettings := node.DefaultCopySettings
452452

453453
if bytes.Equal(key, parentBranch.PartialKey) {
454-
if bytes.Equal(parentBranch.StorageValue, value) {
454+
if parentBranch.StorageValueEqual(value) {
455455
mutated = false
456456
return parentBranch, mutated, 0
457457
}

0 commit comments

Comments
 (0)