diff --git a/dot/state/offline_pruner.go b/dot/state/offline_pruner.go index 72d400260b9..62ceb7b86cf 100644 --- a/dot/state/offline_pruner.go +++ b/dot/state/offline_pruner.go @@ -121,7 +121,7 @@ func (p *OfflinePruner) SetBloomFilter() (err error) { return err } - trie.PopulateMerkleValues(tr.RootNode(), merkleValues) + trie.PopulateNodeHashes(tr.RootNode(), merkleValues) // get parent header of current block header, err = p.blockState.GetHeader(header.ParentHash) diff --git a/lib/trie/database.go b/lib/trie/database.go index 3018b8872ac..78120867a08 100644 --- a/lib/trie/database.go +++ b/lib/trie/database.go @@ -185,20 +185,25 @@ func (t *Trie) loadNode(db Database, n *Node) error { return nil } -// PopulateMerkleValues writes the Merkle values of the node given and of -// all its descendant nodes as keys to the merkleValues map. +// PopulateNodeHashes writes the node hash values of the node given and of +// all its descendant nodes as keys to the nodeHashes map. // It is assumed the node and its descendant nodes have their Merkle value already // computed. -func PopulateMerkleValues(n *Node, merkleValues map[string]struct{}) { +func PopulateNodeHashes(n *Node, nodeHashes map[string]struct{}) { if n == nil { return } - if len(n.MerkleValue) == 0 { + switch { + case len(n.MerkleValue) == 0: panic(fmt.Sprintf("node with key 0x%x has no Merkle value computed", n.Key)) + case len(n.MerkleValue) < 32: + // Inlined node where its Merkle value is its + // encoding and not the encoding hash digest. + return } - merkleValues[string(n.MerkleValue)] = struct{}{} + nodeHashes[string(n.MerkleValue)] = struct{}{} if n.Kind() == node.Leaf { return @@ -206,7 +211,7 @@ func PopulateMerkleValues(n *Node, merkleValues map[string]struct{}) { branch := n for _, child := range branch.Children { - PopulateMerkleValues(child, merkleValues) + PopulateNodeHashes(child, nodeHashes) } } diff --git a/lib/trie/database_test.go b/lib/trie/database_test.go index 63a2883d1a9..341eaa2e885 100644 --- a/lib/trie/database_test.go +++ b/lib/trie/database_test.go @@ -158,57 +158,77 @@ func Test_Trie_WriteDirty_ClearPrefix(t *testing.T) { assert.Equal(t, trie.String(), trieFromDB.String()) } -func Test_PopulateMerkleValues(t *testing.T) { +func Test_PopulateNodeHashes(t *testing.T) { t.Parallel() + const ( + merkleValue32Zeroes = "00000000000000000000000000000000" + merkleValue32Ones = "11111111111111111111111111111111" + merkleValue32Twos = "22222222222222222222222222222222" + merkleValue32Threes = "33333333333333333333333333333333" + ) + testCases := map[string]struct { - node *Node - merkleValues map[string]struct{} - panicValue interface{} + node *Node + nodeHashes map[string]struct{} + panicValue interface{} }{ "nil node": { - merkleValues: map[string]struct{}{}, + nodeHashes: map[string]struct{}{}, + }, + "inlined leaf node": { + node: &Node{MerkleValue: []byte("a")}, + nodeHashes: map[string]struct{}{}, }, "leaf node": { - node: &Node{MerkleValue: []byte("a")}, - merkleValues: map[string]struct{}{ - "a": {}, + node: &Node{MerkleValue: []byte(merkleValue32Zeroes)}, + nodeHashes: map[string]struct{}{ + merkleValue32Zeroes: {}, }, }, "leaf node without Merkle value": { node: &Node{Key: []byte{1}, SubValue: []byte{2}}, panicValue: "node with key 0x01 has no Merkle value computed", }, - "branch node": { + "inlined branch node": { node: &Node{ MerkleValue: []byte("a"), Children: padRightChildren([]*Node{ {MerkleValue: []byte("b")}, }), }, - merkleValues: map[string]struct{}{ - "a": {}, - "b": {}, + nodeHashes: map[string]struct{}{}, + }, + "branch node": { + node: &Node{ + MerkleValue: []byte(merkleValue32Zeroes), + Children: padRightChildren([]*Node{ + {MerkleValue: []byte(merkleValue32Ones)}, + }), + }, + nodeHashes: map[string]struct{}{ + merkleValue32Zeroes: {}, + merkleValue32Ones: {}, }, }, "nested branch node": { node: &Node{ - MerkleValue: []byte("a"), + MerkleValue: []byte(merkleValue32Zeroes), Children: padRightChildren([]*Node{ - {MerkleValue: []byte("b")}, + {MerkleValue: []byte(merkleValue32Ones)}, { - MerkleValue: []byte("c"), + MerkleValue: []byte(merkleValue32Twos), Children: padRightChildren([]*Node{ - {MerkleValue: []byte("d")}, + {MerkleValue: []byte(merkleValue32Threes)}, }), }, }), }, - merkleValues: map[string]struct{}{ - "a": {}, - "b": {}, - "c": {}, - "d": {}, + nodeHashes: map[string]struct{}{ + merkleValue32Zeroes: {}, + merkleValue32Ones: {}, + merkleValue32Twos: {}, + merkleValue32Threes: {}, }, }, } @@ -218,18 +238,18 @@ func Test_PopulateMerkleValues(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - merkleValues := make(map[string]struct{}) + nodeHashes := make(map[string]struct{}) if testCase.panicValue != nil { assert.PanicsWithValue(t, testCase.panicValue, func() { - PopulateMerkleValues(testCase.node, merkleValues) + PopulateNodeHashes(testCase.node, nodeHashes) }) return } - PopulateMerkleValues(testCase.node, merkleValues) + PopulateNodeHashes(testCase.node, nodeHashes) - assert.Equal(t, testCase.merkleValues, merkleValues) + assert.Equal(t, testCase.nodeHashes, nodeHashes) }) } }