An empty root represents the root of a tree with no leaves. It is obtained using the EmptyRoot() method of the Hasher type. However, the root generated by this method may not be consistent, even when the hasher is configured identically.
Below, this inconsistency is shown by an example:
nIDSzie := 1
ignoreMaxNS := true
nIDList := []byte{1, 2, 3, 4}
// Create an nmt using the above configs
tree := New(sha256.New(), NamespaceIDSize(nIDSzie), IgnoreMaxNamespace(ignoreMaxNS))
for i, nid := range nIDList {
namespace := bytes.Repeat([]byte{nid}, nIDSzie)
d := append(namespace, []byte(fmt.Sprintf("leaf_%d", i))...)
if err := tree.Push(d); err != nil {
panic(fmt.Sprintf("unexpected error: %v", err))
}
}
// Calculate the empty root by accessing the `Hasher` field of the tree
expectedEmptyRoot := tree.treeHasher.EmptyRoot()
// Create a hasher identical to the one used for the tree
hasher := NewNmtHasher(sha256.New(), namespace.IDSize(nIDSzie), ignoreMaxNS)
gotEmptyRoot := hasher.EmptyRoot()
assert.True(t, bytes.Equal(gotEmptyRoot, expectedEmptyRoot)) // it panics, they are not equal
Problem
An empty root represents the root of a tree with no leaves. It is obtained using the EmptyRoot() method of the Hasher type. However, the root generated by this method may not be consistent, even when the hasher is configured identically. Below, this inconsistency is shown by an example: