Skip to content

Commit

Permalink
fix(trie): equality differentiate nil and empty storage values (#2969)
Browse files Browse the repository at this point in the history
  • Loading branch information
qdm12 committed Nov 23, 2022
1 parent bdb0eea commit 72a08ec
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 2 deletions.
17 changes: 17 additions & 0 deletions internal/trie/node/subvalue.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2022 ChainSafe Systems (ON)
// SPDX-License-Identifier: LGPL-3.0-only

package node

import "bytes"

// StorageValueEqual returns true if the node storage value is equal to the
// storage value given as argument. In particular, it returns false
// if one storage value is nil and the other storage value is the empty slice.
func (n Node) StorageValueEqual(stoageValue []byte) (equal bool) {
if len(stoageValue) == 0 && len(n.StorageValue) == 0 {
return (stoageValue == nil && n.StorageValue == nil) ||
(stoageValue != nil && n.StorageValue != nil)
}
return bytes.Equal(n.StorageValue, stoageValue)
}
57 changes: 57 additions & 0 deletions internal/trie/node/subvalue_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2022 ChainSafe Systems (ON)
// SPDX-License-Identifier: LGPL-3.0-only

package node

import (
"testing"

"github.com/stretchr/testify/assert"
)

func Test_Node_StorageValueEqual(t *testing.T) {
t.Parallel()

testCases := map[string]struct {
node Node
subValue []byte
equal bool
}{
"nil node subvalue and nil subvalue": {
equal: true,
},
"empty node subvalue and empty subvalue": {
node: Node{StorageValue: []byte{}},
subValue: []byte{},
equal: true,
},
"nil node subvalue and empty subvalue": {
subValue: []byte{},
},
"empty node subvalue and nil subvalue": {
node: Node{StorageValue: []byte{}},
},
"equal non empty values": {
node: Node{StorageValue: []byte{1, 2}},
subValue: []byte{1, 2},
equal: true,
},
"not equal non empty values": {
node: Node{StorageValue: []byte{1, 2}},
subValue: []byte{1, 3},
},
}

for name, testCase := range testCases {
testCase := testCase
t.Run(name, func(t *testing.T) {
t.Parallel()

node := testCase.node

equal := node.StorageValueEqual(testCase.subValue)

assert.Equal(t, testCase.equal, equal)
})
}
}
4 changes: 2 additions & 2 deletions lib/trie/trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ func (t *Trie) insertInLeaf(parentLeaf *Node, key, value []byte,
newParent *Node, mutated bool, nodesCreated uint32) {
if bytes.Equal(parentLeaf.PartialKey, key) {
nodesCreated = 0
if bytes.Equal(parentLeaf.StorageValue, value) {
if parentLeaf.StorageValueEqual(value) {
mutated = false
return parentLeaf, mutated, nodesCreated
}
Expand Down Expand Up @@ -451,7 +451,7 @@ func (t *Trie) insertInBranch(parentBranch *Node, key, value []byte,
copySettings := node.DefaultCopySettings

if bytes.Equal(key, parentBranch.PartialKey) {
if bytes.Equal(parentBranch.StorageValue, value) {
if parentBranch.StorageValueEqual(value) {
mutated = false
return parentBranch, mutated, 0
}
Expand Down

0 comments on commit 72a08ec

Please sign in to comment.