github.com/spacemeshos/merkle-tree@v0.2.2/merkle_test.go (about)

     1  package merkle_test
     2  
     3  import (
     4  	"encoding/binary"
     5  	"encoding/hex"
     6  	"fmt"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/spacemeshos/merkle-tree"
    13  	"github.com/spacemeshos/merkle-tree/cache"
    14  )
    15  
    16  var (
    17  	NewTree                                 = merkle.NewTree
    18  	NewTreeBuilder                          = merkle.NewTreeBuilder
    19  	NewProvingTree                          = merkle.NewProvingTree
    20  	NewCachingTree                          = merkle.NewCachingTree
    21  	GenerateProof                           = merkle.GenerateProof
    22  	ValidatePartialTree                     = merkle.ValidatePartialTree
    23  	ValidatePartialTreeWithParkingSnapshots = merkle.ValidatePartialTreeWithParkingSnapshots
    24  	GetSha256Parent                         = merkle.GetSha256Parent
    25  	GetNode                                 = merkle.GetNode
    26  	setOf                                   = merkle.SetOf
    27  	newSparseBoolStack                      = merkle.NewSparseBoolStack
    28  	emptyNode                               = merkle.EmptyNode
    29  	NodeSize                                = merkle.NodeSize
    30  )
    31  
    32  type (
    33  	set          = merkle.Set
    34  	position     = merkle.Position
    35  	validator    = merkle.Validator
    36  	leafIterator = merkle.LeafIterator
    37  	CacheReader  = cache.CacheReader
    38  )
    39  
    40  /*
    41  
    42  	8-leaf tree (1st 2 bytes of each node):
    43  
    44  	+--------------------------------------------------+
    45  	|                       89a0                       |
    46  	|           ba94                    633b           |
    47  	|     cb59        0094        bd50        fa67     |
    48  	|  0000  0100  0200  0300  0400  0500  0600  0700  |
    49  	+--------------------------------------------------+
    50  
    51  */
    52  
    53  func TestNewTree(t *testing.T) {
    54  	r := require.New(t)
    55  	tree, err := NewTree()
    56  	r.NoError(err)
    57  	for i := uint64(0); i < 8; i++ {
    58  		err := tree.AddLeaf(NewNodeFromUint64(i))
    59  		r.NoError(err)
    60  	}
    61  	expectedRoot, _ := NewNodeFromHex("89a0f1577268cc19b0a39c7a69f804fd140640c699585eb635ebb03c06154cce")
    62  	root := tree.Root()
    63  	r.Equal(expectedRoot, root)
    64  }
    65  
    66  func concatLeaves(_, lChild, rChild []byte) []byte {
    67  	if len(lChild) == NodeSize {
    68  		lChild = lChild[:1]
    69  	}
    70  	if len(rChild) == NodeSize {
    71  		rChild = rChild[:1]
    72  	}
    73  	return append(lChild, rChild...)
    74  }
    75  
    76  func TestNewTreeWithMinHeightEqual(t *testing.T) {
    77  	r := require.New(t)
    78  	tree, err := NewTreeBuilder().WithHashFunc(concatLeaves).WithMinHeight(3).Build()
    79  	r.NoError(err)
    80  	for i := uint64(0); i < 8; i++ {
    81  		err := tree.AddLeaf(NewNodeFromUint64(i))
    82  		r.NoError(err)
    83  	}
    84  	expectedRoot, _ := NewNodeFromHex("0001020304050607")
    85  	root := tree.Root()
    86  	r.Equal(expectedRoot, root)
    87  }
    88  
    89  func TestNewTreeWithMinHeightGreater(t *testing.T) {
    90  	r := require.New(t)
    91  	tree, err := NewTreeBuilder().WithHashFunc(concatLeaves).WithMinHeight(4).Build()
    92  	r.NoError(err)
    93  	for i := uint64(0); i < 8; i++ {
    94  		err := tree.AddLeaf(NewNodeFromUint64(i))
    95  		r.NoError(err)
    96  	}
    97  	// An 8-leaf tree is 3 layers high, so setting a minHeight of 4 means we need to add a "padding node" to the root.
    98  	expectedRoot, _ := NewNodeFromHex("000102030405060700")
    99  	root := tree.Root()
   100  	r.Equal(expectedRoot, root)
   101  }
   102  
   103  func TestNewTreeWithMinHeightGreater2(t *testing.T) {
   104  	r := require.New(t)
   105  	tree, err := NewTreeBuilder().WithHashFunc(concatLeaves).WithMinHeight(5).Build()
   106  	r.NoError(err)
   107  	for i := uint64(0); i < 8; i++ {
   108  		err := tree.AddLeaf(NewNodeFromUint64(i))
   109  		r.NoError(err)
   110  	}
   111  	// An 8-leaf tree is 3 layers high, so setting a minHeight of 5 means we need to add two "padding nodes" to the root.
   112  	expectedRoot, _ := NewNodeFromHex("00010203040506070000")
   113  	root := tree.Root()
   114  	r.Equal(expectedRoot, root)
   115  }
   116  
   117  func TestNewTreeUnbalanced(t *testing.T) {
   118  	r := require.New(t)
   119  	tree, err := NewTree()
   120  	r.NoError(err)
   121  	for i := uint64(0); i < 9; i++ {
   122  		err := tree.AddLeaf(NewNodeFromUint64(i))
   123  		r.NoError(err)
   124  	}
   125  	expectedRoot, _ := NewNodeFromHex("cb71c80ee780788eedb819ec125a41e0cde57bd0955cdd3157ca363193ab5ff1")
   126  	root := tree.Root()
   127  	r.Equal(expectedRoot, root)
   128  }
   129  
   130  func TestNewTreeUnbalanced2(t *testing.T) {
   131  	r := require.New(t)
   132  	tree, err := NewTree()
   133  	r.NoError(err)
   134  	for i := uint64(0); i < 10; i++ {
   135  		err := tree.AddLeaf(NewNodeFromUint64(i))
   136  		r.NoError(err)
   137  	}
   138  	expectedRoot, _ := NewNodeFromHex("59f32a43534fe4c4c0966421aef624267cdf65bd11f74998c60f27c7caccb12d")
   139  	root := tree.Root()
   140  	r.Equal(expectedRoot, root)
   141  }
   142  
   143  func TestNewTreeUnbalanced3(t *testing.T) {
   144  	r := require.New(t)
   145  	tree, err := NewTree()
   146  	r.NoError(err)
   147  	for i := uint64(0); i < 15; i++ {
   148  		err := tree.AddLeaf(NewNodeFromUint64(i))
   149  		r.NoError(err)
   150  	}
   151  	expectedRoot, _ := NewNodeFromHex("b9746fb884ed07041c5cbb3bb5526e1383928e832a8385e08db995966889b5a8")
   152  	root := tree.Root()
   153  	r.Equal(expectedRoot, root)
   154  }
   155  
   156  func TestNewTreeUnbalancedProof(t *testing.T) {
   157  	r := require.New(t)
   158  
   159  	leavesToProve := setOf(0, 4, 7)
   160  
   161  	cacheWriter := cache.NewWriter(cache.MinHeightPolicy(0), cache.MakeSliceReadWriterFactory())
   162  
   163  	tree, err := NewTreeBuilder().
   164  		WithLeavesToProve(leavesToProve).
   165  		WithCacheWriter(cacheWriter).
   166  		Build()
   167  	r.NoError(err)
   168  	for i := uint64(0); i < 10; i++ {
   169  		err := tree.AddLeaf(NewNodeFromUint64(i))
   170  		r.NoError(err)
   171  	}
   172  	expectedRoot, _ := NewNodeFromHex("59f32a43534fe4c4c0966421aef624267cdf65bd11f74998c60f27c7caccb12d")
   173  	root := tree.Root()
   174  	r.Equal(expectedRoot, root)
   175  
   176  	cacheReader, err := cacheWriter.GetReader()
   177  	r.NoError(err)
   178  
   179  	assertWidth(r, 10, cacheReader.GetLayerReader(0))
   180  	assertWidth(r, 5, cacheReader.GetLayerReader(1))
   181  	assertWidth(r, 2, cacheReader.GetLayerReader(2))
   182  	assertWidth(r, 1, cacheReader.GetLayerReader(3))
   183  
   184  	cacheRoot, err := cacheReader.GetLayerReader(3).ReadNext()
   185  	r.NoError(err)
   186  	r.NotEqual(cacheRoot, expectedRoot)
   187  
   188  	expectedProof := make([][]byte, 5)
   189  	expectedProof[0], _ = NewNodeFromHex("0100000000000000000000000000000000000000000000000000000000000000")
   190  	expectedProof[1], _ = NewNodeFromHex("0094579cfc7b716038d416a311465309bea202baa922b224a7b08f01599642fb")
   191  	expectedProof[2], _ = NewNodeFromHex("0500000000000000000000000000000000000000000000000000000000000000")
   192  	expectedProof[3], _ = NewNodeFromHex("0600000000000000000000000000000000000000000000000000000000000000")
   193  	expectedProof[4], _ = NewNodeFromHex("bc68417a8495de6e22d95b980fca5a1183f29eff0e2a9b7ddde91ed5bcbea952")
   194  
   195  	proof := tree.Proof()
   196  	r.EqualValues(expectedProof, proof)
   197  }
   198  
   199  func assertWidth(r *require.Assertions, expectedWidth int, layerReader cache.LayerReader) {
   200  	r.NotNil(layerReader)
   201  	width, err := layerReader.Width()
   202  	r.NoError(err)
   203  	r.Equal(uint64(expectedWidth), width)
   204  }
   205  
   206  func BenchmarkNewTree(b *testing.B) {
   207  	var size uint64 = 1 << 28
   208  	tree, _ := NewTree()
   209  	for i := uint64(0); i < size; i++ {
   210  		_ = tree.AddLeaf(NewNodeFromUint64(i))
   211  	}
   212  	/*
   213  		goos: darwin
   214  		goarch: amd64
   215  		pkg: github.com/spacemeshos/merkle-tree
   216  		BenchmarkNewTree-8   	       1	125055682774 ns/op
   217  		PASS
   218  	*/
   219  }
   220  
   221  func BenchmarkNewTreeSmall(b *testing.B) {
   222  	var size uint64 = 1 << 23
   223  	start := time.Now()
   224  	tree, _ := NewTree()
   225  	for i := uint64(0); i < size; i++ {
   226  		_ = tree.AddLeaf(NewNodeFromUint64(i))
   227  	}
   228  	b.Log(time.Since(start))
   229  	/*
   230  	   merkle_test.go:72: 3.700763631s
   231  	*/
   232  }
   233  
   234  func BenchmarkNewTreeNoHashing(b *testing.B) {
   235  	var size uint64 = 1 << 28
   236  	tree, _ := NewTree()
   237  	for i := uint64(0); i < size; i++ {
   238  		_ = tree.AddLeaf(NewNodeFromUint64(i))
   239  	}
   240  	/*
   241  		goos: darwin
   242  		goarch: amd64
   243  		pkg: github.com/spacemeshos/merkle-tree
   244  		BenchmarkNewTreeNoHashing-8   	       1	14668889972 ns/op
   245  		BenchmarkNewTreeNoHashing-8   	       1	15791579912 ns/op
   246  		PASS
   247  	*/
   248  }
   249  
   250  /*
   251  	28 layer tree takes 125 seconds to construct. Overhead (no hashing) is 15.5 seconds. Net: 109.5 seconds.
   252  	(8.5GB @ 32b leaves) => x30 256GB => 55 minutes for hashing, 8 minutes overhead.
   253  
   254  	Reading 256GB from a magnetic disk should take ~30 minutes.
   255  */
   256  
   257  // Proving tree tests
   258  
   259  func TestNewProvingTree(t *testing.T) {
   260  	r := require.New(t)
   261  	tree, err := NewProvingTree(setOf(4))
   262  	r.NoError(err)
   263  	for i := uint64(0); i < 8; i++ {
   264  		err := tree.AddLeaf(NewNodeFromUint64(i))
   265  		r.NoError(err)
   266  	}
   267  	expectedRoot, _ := NewNodeFromHex("89a0f1577268cc19b0a39c7a69f804fd140640c699585eb635ebb03c06154cce")
   268  	root := tree.Root()
   269  	r.Equal(expectedRoot, root)
   270  
   271  	expectedProof := make([][]byte, 3)
   272  	expectedProof[0], _ = NewNodeFromHex("0500000000000000000000000000000000000000000000000000000000000000")
   273  	expectedProof[1], _ = NewNodeFromHex("fa670379e5c2212ed93ff09769622f81f98a91e1ec8fb114d607dd25220b9088")
   274  	expectedProof[2], _ = NewNodeFromHex("ba94ffe7edabf26ef12736f8eb5ce74d15bedb6af61444ae2906e926b1a95084")
   275  
   276  	proof := tree.Proof()
   277  	r.EqualValues(expectedProof, proof)
   278  
   279  	/***************************************************
   280  	|                       89a0                       |
   281  	|          .ba94.                   633b           |
   282  	|     cb59        0094        bd50       .fa67.    |
   283  	|  0000  0100  0200  0300 =0400=.0500. 0600  0700  |
   284  	***************************************************/
   285  }
   286  
   287  func TestNewProvingTreeMultiProof(t *testing.T) {
   288  	r := require.New(t)
   289  	tree, err := NewProvingTree(setOf(1, 4))
   290  	r.NoError(err)
   291  	for i := uint64(0); i < 8; i++ {
   292  		err := tree.AddLeaf(NewNodeFromUint64(i))
   293  		r.NoError(err)
   294  	}
   295  	expectedRoot, _ := NewNodeFromHex("89a0f1577268cc19b0a39c7a69f804fd140640c699585eb635ebb03c06154cce")
   296  	root := tree.Root()
   297  	r.Equal(expectedRoot, root)
   298  
   299  	expectedProof := make([][]byte, 4)
   300  	expectedProof[0], _ = NewNodeFromHex("0000000000000000000000000000000000000000000000000000000000000000")
   301  	expectedProof[1], _ = NewNodeFromHex("0094579cfc7b716038d416a311465309bea202baa922b224a7b08f01599642fb")
   302  	expectedProof[2], _ = NewNodeFromHex("0500000000000000000000000000000000000000000000000000000000000000")
   303  	expectedProof[3], _ = NewNodeFromHex("fa670379e5c2212ed93ff09769622f81f98a91e1ec8fb114d607dd25220b9088")
   304  
   305  	proof := tree.Proof()
   306  	r.EqualValues(expectedProof, proof)
   307  
   308  	/***************************************************
   309  	|                       89a0                       |
   310  	|           ba94                    633b           |
   311  	|     cb59       .0094.       bd50       .fa67.    |
   312  	| .0000.=0100= 0200  0300 =0400=.0500. 0600  0700  |
   313  	***************************************************/
   314  }
   315  
   316  // TestNewProvingTreeMultiProofReuseLeafBytes verifies if the user of Tree
   317  // can safely reuse the memory passed into Tree::AddLeaf.
   318  func TestNewProvingTreeMultiProofReuseLeafBytes(t *testing.T) {
   319  	r := require.New(t)
   320  	tree, err := NewProvingTree(setOf(1, 4))
   321  	r.NoError(err)
   322  	var leaf [32]byte
   323  	for i := uint64(0); i < 8; i++ {
   324  		binary.LittleEndian.PutUint64(leaf[:], i)
   325  		r.NoError(tree.AddLeaf(leaf[:]))
   326  	}
   327  	expectedRoot, _ := NewNodeFromHex("89a0f1577268cc19b0a39c7a69f804fd140640c699585eb635ebb03c06154cce")
   328  	root := tree.Root()
   329  	r.Equal(expectedRoot, root)
   330  
   331  	expectedProof := make([][]byte, 4)
   332  	expectedProof[0], _ = NewNodeFromHex("0000000000000000000000000000000000000000000000000000000000000000")
   333  	expectedProof[1], _ = NewNodeFromHex("0094579cfc7b716038d416a311465309bea202baa922b224a7b08f01599642fb")
   334  	expectedProof[2], _ = NewNodeFromHex("0500000000000000000000000000000000000000000000000000000000000000")
   335  	expectedProof[3], _ = NewNodeFromHex("fa670379e5c2212ed93ff09769622f81f98a91e1ec8fb114d607dd25220b9088")
   336  
   337  	proof := tree.Proof()
   338  	r.EqualValues(expectedProof, proof)
   339  
   340  	/***************************************************
   341  	|                       89a0                       |
   342  	|           ba94                    633b           |
   343  	|     cb59       .0094.       bd50       .fa67.    |
   344  	| .0000.=0100= 0200  0300 =0400=.0500. 0600  0700  |
   345  	***************************************************/
   346  }
   347  
   348  func TestNewProvingTreeMultiProof2(t *testing.T) {
   349  	r := require.New(t)
   350  	tree, err := NewProvingTree(setOf(0, 1, 4))
   351  	r.NoError(err)
   352  	for i := uint64(0); i < 8; i++ {
   353  		err := tree.AddLeaf(NewNodeFromUint64(i))
   354  		r.NoError(err)
   355  	}
   356  	expectedRoot, _ := NewNodeFromHex("89a0f1577268cc19b0a39c7a69f804fd140640c699585eb635ebb03c06154cce")
   357  	root := tree.Root()
   358  	r.Equal(expectedRoot, root)
   359  
   360  	expectedProof := make([][]byte, 3)
   361  	expectedProof[0], _ = NewNodeFromHex("0094579cfc7b716038d416a311465309bea202baa922b224a7b08f01599642fb")
   362  	expectedProof[1], _ = NewNodeFromHex("0500000000000000000000000000000000000000000000000000000000000000")
   363  	expectedProof[2], _ = NewNodeFromHex("fa670379e5c2212ed93ff09769622f81f98a91e1ec8fb114d607dd25220b9088")
   364  
   365  	proof := tree.Proof()
   366  	r.EqualValues(expectedProof, proof)
   367  
   368  	/***************************************************
   369  	|                       89a0                       |
   370  	|           ba94                    633b           |
   371  	|     cb59       .0094.       bd50       .fa67.    |
   372  	| =0000==0100= 0200  0300 =0400=.0500. 0600  0700  |
   373  	***************************************************/
   374  }
   375  
   376  func NewNodeFromUint64(i uint64) []byte {
   377  	b := make([]byte, NodeSize)
   378  	binary.LittleEndian.PutUint64(b, i)
   379  	return b
   380  }
   381  
   382  func NewNodeFromHex(s string) ([]byte, error) {
   383  	return hex.DecodeString(s)
   384  }
   385  
   386  // Caching tests:
   387  
   388  func TestNewCachingTree(t *testing.T) {
   389  	r := require.New(t)
   390  	cacheWriter := cache.NewWriter(cache.MinHeightPolicy(0), cache.MakeSliceReadWriterFactory())
   391  	tree, err := NewCachingTree(cacheWriter)
   392  	r.NoError(err)
   393  	for i := uint64(0); i < 8; i++ {
   394  		err := tree.AddLeaf(NewNodeFromUint64(i))
   395  		r.NoError(err)
   396  	}
   397  	expectedRoot, _ := NewNodeFromHex("89a0f1577268cc19b0a39c7a69f804fd140640c699585eb635ebb03c06154cce")
   398  	root := tree.Root()
   399  	r.Equal(expectedRoot, root)
   400  
   401  	cacheReader, err := cacheWriter.GetReader()
   402  	r.NoError(err)
   403  
   404  	assertWidth(r, 8, cacheReader.GetLayerReader(0))
   405  	assertWidth(r, 4, cacheReader.GetLayerReader(1))
   406  	assertWidth(r, 2, cacheReader.GetLayerReader(2))
   407  	assertWidth(r, 1, cacheReader.GetLayerReader(3))
   408  	cacheRoot, err := cacheReader.GetLayerReader(3).ReadNext()
   409  	r.NoError(err)
   410  	r.Equal(cacheRoot, expectedRoot)
   411  
   412  	// cacheWriter.Print(0 , 3)
   413  }
   414  
   415  func BenchmarkNewCachingTreeSmall(b *testing.B) {
   416  	var size uint64 = 1 << 23
   417  	cacheWriter := cache.NewWriter(cache.MinHeightPolicy(7), cache.MakeSliceReadWriterFactory())
   418  	start := time.Now()
   419  	tree, _ := NewCachingTree(cacheWriter)
   420  	for i := uint64(0); i < size; i++ {
   421  		_ = tree.AddLeaf(NewNodeFromUint64(i))
   422  	}
   423  	b.Log(time.Since(start))
   424  	/*
   425  	   merkle_test.go:242: 3.054842184s
   426  	*/
   427  }
   428  
   429  func TestSparseBoolStack(t *testing.T) {
   430  	r := require.New(t)
   431  
   432  	allFalse := newSparseBoolStack(make(set))
   433  	for i := 0; i < 1000; i++ {
   434  		r.False(allFalse.Pop())
   435  	}
   436  
   437  	allTrue := newSparseBoolStack(setOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))
   438  	for i := 0; i < 10; i++ {
   439  		r.True(allTrue.Pop())
   440  	}
   441  
   442  	rounds := make(set)
   443  	for i := uint64(0); i < 1000; i += 10 {
   444  		rounds[i] = true
   445  	}
   446  	roundsTrue := newSparseBoolStack(rounds)
   447  	for i := 0; i < 1000; i++ {
   448  		if i%10 == 0 {
   449  			r.True(roundsTrue.Pop())
   450  		} else {
   451  			r.False(roundsTrue.Pop())
   452  		}
   453  	}
   454  }
   455  
   456  func TestEmptyNode(t *testing.T) {
   457  	r := require.New(t)
   458  
   459  	r.True(emptyNode.IsEmpty())
   460  	r.False(emptyNode.OnProvenPath)
   461  }
   462  
   463  func TestTree_GetParkedNodes(t *testing.T) {
   464  	r := require.New(t)
   465  
   466  	tree, err := NewTreeBuilder().Build()
   467  	r.NoError(err)
   468  
   469  	r.NoError(tree.AddLeaf([]byte{0}))
   470  	r.EqualValues(
   471  		[][]byte{{0}},
   472  		tree.GetParkedNodes(nil))
   473  
   474  	r.NoError(tree.AddLeaf([]byte{1}))
   475  	r.EqualValues(
   476  		[][]byte{{}, decode(r, "b413f47d13ee2fe6c845b2ee141af81de858df4ec549a58b7970bb96645bc8d2")},
   477  		tree.GetParkedNodes(nil))
   478  
   479  	r.NoError(tree.AddLeaf([]byte{2}))
   480  	r.EqualValues(
   481  		[][]byte{{2}, decode(r, "b413f47d13ee2fe6c845b2ee141af81de858df4ec549a58b7970bb96645bc8d2")},
   482  		tree.GetParkedNodes(nil))
   483  
   484  	r.NoError(tree.AddLeaf([]byte{3}))
   485  	r.EqualValues(
   486  		[][]byte{{}, {}, decode(r, "7699a4fdd6b8b6908a344f73b8f05c8e1400f7253f544602c442ff5c65504b24")},
   487  		tree.GetParkedNodes(nil))
   488  }
   489  
   490  func TestTree_SetParkedNodes(t *testing.T) {
   491  	r := require.New(t)
   492  
   493  	tree, err := NewTreeBuilder().Build()
   494  	r.NoError(err)
   495  	r.NoError(tree.SetParkedNodes([][]byte{{0}}))
   496  	r.NoError(tree.AddLeaf([]byte{1}))
   497  	parkedNodes := [][]byte{{}, decode(r, "b413f47d13ee2fe6c845b2ee141af81de858df4ec549a58b7970bb96645bc8d2")}
   498  	r.EqualValues(parkedNodes, tree.GetParkedNodes(nil))
   499  
   500  	tree, err = NewTreeBuilder().Build()
   501  	r.NoError(err)
   502  	r.NoError(tree.SetParkedNodes(parkedNodes))
   503  	r.NoError(tree.AddLeaf([]byte{2}))
   504  	parkedNodes = [][]byte{{2}, decode(r, "b413f47d13ee2fe6c845b2ee141af81de858df4ec549a58b7970bb96645bc8d2")}
   505  	r.EqualValues(parkedNodes, tree.GetParkedNodes(nil))
   506  
   507  	tree, err = NewTreeBuilder().Build()
   508  	r.NoError(err)
   509  	r.NoError(tree.SetParkedNodes(parkedNodes))
   510  	r.NoError(tree.AddLeaf([]byte{3}))
   511  	parkedNodes = [][]byte{{}, {}, decode(r, "7699a4fdd6b8b6908a344f73b8f05c8e1400f7253f544602c442ff5c65504b24")}
   512  	r.EqualValues(parkedNodes, tree.GetParkedNodes(nil))
   513  }
   514  
   515  func decode(r *require.Assertions, hexString string) []byte {
   516  	hash, err := hex.DecodeString(hexString)
   517  	r.NoError(err)
   518  	return hash
   519  }
   520  
   521  // Annotated example explaining how to use this package
   522  func ExampleTree() {
   523  	// First, we create a cache writer with caching policy and layer read-writer factory:
   524  	cacheWriter := cache.NewWriter(cache.MinHeightPolicy(0), cache.MakeSliceReadWriterFactory())
   525  
   526  	// We then initialize the tree:
   527  	tree, err := NewTreeBuilder().WithCacheWriter(cacheWriter).Build()
   528  	if err != nil {
   529  		fmt.Println("Error while building the tree:", err.Error())
   530  		return
   531  	}
   532  
   533  	// We add the leaves one-by-one:
   534  	for i := uint64(0); i < 8; i++ {
   535  		err := tree.AddLeaf(NewNodeFromUint64(i))
   536  		if err != nil {
   537  			fmt.Println("Error while adding a leaf:", err.Error())
   538  			return
   539  		}
   540  	}
   541  
   542  	// After adding some leaves we can access the root of the tree:
   543  	fmt.Println(tree.Root()) // 89a0f1577268cc19b0a39c7a69f804fd140640c699585eb635ebb03c06154cce
   544  
   545  	// If we need to generate a proof, we could derive the proven leaves from the root. Here we create a static set:
   546  	leavesToProve := setOf(0, 4, 7)
   547  
   548  	// We get a cache reader from the cache writer:
   549  	cacheReader, err := cacheWriter.GetReader()
   550  	if err != nil {
   551  		fmt.Println("Error while getting cache reader:", err.Error())
   552  		return
   553  	}
   554  
   555  	// We pass the cache into GenerateProof along with the set of leaves to prove:
   556  	sortedProvenLeafIndices, provenLeaves, proof, err := GenerateProof(leavesToProve, cacheReader)
   557  	if err != nil {
   558  		fmt.Println("Error while getting generating proof:", err.Error())
   559  		return
   560  	}
   561  
   562  	// We now have access to a sorted list of proven leaves, the values of those leaves and the Merkle proof for them:
   563  	fmt.Println(sortedProvenLeafIndices) // 0 4 7
   564  	fmt.Println(nodes(provenLeaves))     // 0000 0400 0700
   565  	fmt.Println(nodes(proof))            // 0100 0094 0500 0600
   566  
   567  	// We can validate these values using ValidatePartialTree:
   568  	valid, err := ValidatePartialTree(sortedProvenLeafIndices, provenLeaves, proof, tree.Root(), GetSha256Parent)
   569  	if err != nil {
   570  		fmt.Println("Error while validating proof:", err.Error())
   571  		return
   572  	}
   573  	fmt.Println(valid) // true
   574  
   575  	/***************************************************
   576  	|                       89a0                       |
   577  	|           ba94                    633b           |
   578  	|     cb59       .0094.       bd50        fa67     |
   579  	| =0000=.0100. 0200  0300 =0400=.0500..0600.=0700= |
   580  	***************************************************/
   581  }