Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/trie/node/branch_encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func encodeChild(child *Node, buffer io.Writer) (err error) {
return nil
}

_, merkleValue, err := child.EncodeAndHash()
merkleValue, err := child.CalculateMerkleValue()
if err != nil {
return fmt.Errorf("computing %s Merkle value: %w", child.Kind(), err)
}
Expand Down
77 changes: 0 additions & 77 deletions lib/trie/buffer_mock_test.go

This file was deleted.

9 changes: 0 additions & 9 deletions lib/trie/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package trie

import (
"errors"
"math/rand"
"testing"
"time"
Expand All @@ -13,14 +12,6 @@ import (
"github.com/stretchr/testify/require"
)

type writeCall struct {
written []byte
n int
err error
}

var errTest = errors.New("test error")

type keyValues struct {
key []byte
value []byte
Expand Down
27 changes: 9 additions & 18 deletions lib/trie/trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

// EmptyHash is the empty trie hash.
var EmptyHash, _ = NewEmptyTrie().Hash()
var EmptyHash = common.MustBlake2bHash([]byte{0})

// Trie is a base 16 modified Merkle Patricia trie.
type Trie struct {
Expand Down Expand Up @@ -170,18 +170,6 @@ func (t *Trie) RootNode() *Node {
return t.root.Copy(copySettings)
}

// encodeRoot writes the encoding of the root node to the buffer.
func encodeRoot(root *Node, buffer node.Buffer) (err error) {
if root == nil {
_, err = buffer.Write([]byte{0})
if err != nil {
return fmt.Errorf("cannot write nil root node to buffer: %w", err)
}
return nil
}
return root.Encode(buffer)
}

// MustHash returns the hashed root of the trie.
// It panics if it fails to hash the root node.
func (t *Trie) MustHash() common.Hash {
Expand All @@ -195,13 +183,16 @@ func (t *Trie) MustHash() common.Hash {

// Hash returns the hashed root of the trie.
func (t *Trie) Hash() (rootHash common.Hash, err error) {
buffer := bytes.NewBuffer(nil)
err = encodeRoot(t.root, buffer)
if err != nil {
return [32]byte{}, err
if t.root == nil {
return EmptyHash, nil
}

return common.Blake2bHash(buffer.Bytes()) // TODO optimisation: use hashers sync pools
merkleValue, err := t.root.CalculateRootMerkleValue()
if err != nil {
return rootHash, err
}
copy(rootHash[:], merkleValue)
return rootHash, nil
}

// Entries returns all the key-value pairs in the trie as a map of keys to values
Expand Down
123 changes: 26 additions & 97 deletions lib/trie/trie_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,22 @@ import (

"github.com/ChainSafe/gossamer/internal/trie/node"
"github.com/ChainSafe/gossamer/lib/common"
gomock "github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

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

expected := common.Hash{
0x3, 0x17, 0xa, 0x2e, 0x75, 0x97, 0xb7, 0xb7,
0xe3, 0xd8, 0x4c, 0x5, 0x39, 0x1d, 0x13, 0x9a,
0x62, 0xb1, 0x57, 0xe7, 0x87, 0x86, 0xd8, 0xc0,
0x82, 0xf2, 0x9d, 0xcf, 0x4c, 0x11, 0x13, 0x14,
}
Comment thread
qdm12 marked this conversation as resolved.
assert.Equal(t, expected, EmptyHash)
}

func Test_NewEmptyTrie(t *testing.T) {
expectedTrie := &Trie{
childTries: make(map[common.Hash]*Trie),
Expand Down Expand Up @@ -290,100 +301,6 @@ func Test_Trie_RootNode(t *testing.T) {
assert.Equal(t, expectedRoot, root)
}

//go:generate mockgen -destination=buffer_mock_test.go -package $GOPACKAGE github.com/ChainSafe/gossamer/internal/trie/node Buffer

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

testCases := map[string]struct {
root *Node
writeCalls []writeCall
errWrapped error
errMessage string
expectedRoot *Node
}{
"nil root and no error": {
writeCalls: []writeCall{
{written: []byte{0}},
},
},
"nil root and write error": {
writeCalls: []writeCall{
{
written: []byte{0},
err: errTest,
},
},
errWrapped: errTest,
errMessage: "cannot write nil root node to buffer: test error",
},
"root encoding error": {
root: &Node{
Key: []byte{1, 2},
SubValue: []byte{1},
},
writeCalls: []writeCall{
{
written: []byte{66},
err: errTest,
},
},
errWrapped: errTest,
errMessage: "cannot encode header: test error",
expectedRoot: &Node{
Key: []byte{1, 2},
SubValue: []byte{1},
},
},
"root encoding success": {
root: &Node{
Key: []byte{1, 2},
SubValue: []byte{1},
},
writeCalls: []writeCall{
{written: []byte{66}},
{written: []byte{18}},
{written: []byte{4}},
{written: []byte{1}},
},
expectedRoot: &Node{
Key: []byte{1, 2},
SubValue: []byte{1},
},
},
}

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

buffer := NewMockBuffer(ctrl)

var previousCall *gomock.Call
for _, write := range testCase.writeCalls {
call := buffer.EXPECT().
Write(write.written).
Return(write.n, write.err)

if previousCall != nil {
call.After(previousCall)
}
previousCall = call
}

err := encodeRoot(testCase.root, buffer)

assert.ErrorIs(t, err, testCase.errWrapped)
if testCase.errWrapped != nil {
assert.EqualError(t, err, testCase.errMessage)
}
assert.Equal(t, testCase.expectedRoot, testCase.root)
})
}
}

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

Expand Down Expand Up @@ -436,6 +353,12 @@ func Test_Trie_Hash(t *testing.T) {
root: &Node{
Key: []byte{1, 2, 3},
SubValue: []byte{1},
MerkleValue: []byte{
0xa8, 0x13, 0x7c, 0xee, 0xb4, 0xad, 0xea, 0xac,
0x9e, 0x5b, 0x37, 0xe2, 0x8e, 0x7d, 0x64, 0x78,
0xac, 0xba, 0xb0, 0x6e, 0x90, 0x76, 0xe4, 0x67,
0xa1, 0xd8, 0xa2, 0x29, 0x4e, 0x4a, 0xd9, 0xa3,
},
Comment thread
qdm12 marked this conversation as resolved.
},
},
},
Expand All @@ -457,8 +380,14 @@ func Test_Trie_Hash(t *testing.T) {
0xf0, 0xe, 0xd3, 0x39, 0x48, 0x21, 0xe3, 0xdd},
expectedTrie: Trie{
root: &Node{
Key: []byte{1, 2, 3},
SubValue: []byte("branch"),
Key: []byte{1, 2, 3},
SubValue: []byte("branch"),
MerkleValue: []byte{
0xaa, 0x7e, 0x57, 0x48, 0xb0, 0x27, 0x4d, 0x18,
0xf5, 0x1c, 0xfd, 0x36, 0x4c, 0x4b, 0x56, 0x4a,
0xf5, 0x37, 0x9d, 0xd7, 0xcb, 0xf5, 0x80, 0x15,
0xf0, 0x0e, 0xd3, 0x39, 0x48, 0x21, 0xe3, 0xdd,
},
Descendants: 1,
Children: padRightChildren([]*Node{
{
Expand Down