|
1 | 1 | package merkle
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "encoding/hex" |
4 | 5 | "fmt"
|
| 6 | + "runtime" |
5 | 7 | "testing"
|
6 | 8 |
|
7 | 9 | "github.com/stretchr/testify/assert"
|
@@ -65,3 +67,87 @@ func TestHashZero(t *testing.T) {
|
65 | 67 | valid, _ := VerifyProof(root, 0, nil, nil)
|
66 | 68 | assert.False(t, valid)
|
67 | 69 | }
|
| 70 | + |
| 71 | +func generateInputs(dst string, N int) [][]byte { |
| 72 | + var res [][]byte |
| 73 | + for i := 0; i < N; i++ { |
| 74 | + res = append(res, []byte(dst+fmt.Sprintf("%09d", i))) |
| 75 | + } |
| 76 | + return res |
| 77 | +} |
| 78 | + |
| 79 | +func TestHashBatch(t *testing.T) { |
| 80 | + for N := 1; N < 300; { |
| 81 | + inputs := generateInputs(fmt.Sprintf("batch-%d", N), N) |
| 82 | + expected := make([]Digest, 0, N-1) |
| 83 | + |
| 84 | + for i := 0; i < N; i++ { |
| 85 | + expected = append(expected, Tree(inputs[0:i+1])) |
| 86 | + } |
| 87 | + |
| 88 | + batchRes := BatchTree(inputs) |
| 89 | + require.Equal(t, expected, batchRes, "failed at size %d", N) |
| 90 | + if N < 32 { |
| 91 | + N++ |
| 92 | + } else { |
| 93 | + N += 13 |
| 94 | + } |
| 95 | + } |
| 96 | +} |
| 97 | + |
| 98 | +func TestHashTreeGolden(t *testing.T) { |
| 99 | + expectedHex := []string{ |
| 100 | + "3d4395573ce4d2acbce4fe8a4be67ca5e7cdfb8ee2e85b2f6733c16b24c3b175", |
| 101 | + "91b7c899421ca7f3228e10265c6970a03bc2ccba44367b1d44a9d8597b20a32e", |
| 102 | + "69abe78dc2390b4666b60d0582e1799e73e48766f6e502c515e79d6cd2ae3c45", |
| 103 | + "bc4ce8dbf993eb2e87c02bbf19cd4faeb3a0672188bc6be6c8d867cef9b08917", |
| 104 | + "538cfd0c1f6b7ab4c3d20466d4e01b438972212fe5257eae213ae0a040da977f", |
| 105 | + "e28aa108b0263820dfe2c7f051ddc8794ab48ebd3c1813db28bf9f06bedc52f3", |
| 106 | + "875cb1d5027522b344b8adc62cd6bd110d97eaedd40a35bcb2fe142a9cb4612b", |
| 107 | + "63804e8b6cb16993d5d43d9d7faf17ba967365dac141a4afbce1d794157a1b8e", |
| 108 | + "07105bd8716bebc90036c8ebfe23a92bd775c09664b076ffa1d9a29d30647f91", |
| 109 | + "960b7eb6440789f76f5d53965e8b208e34777bc4aab78edf6827d71c7eea4933", |
| 110 | + "d55e07222c786722e1ad1b5bcc2ebaf04b2b4e92c07f3f7b61b0fbf0fd78fb9b", |
| 111 | + "ee5a34dfae748e088a1b99386274158266f44ceeb2c5190f4e9bbc39cd8a4d26", |
| 112 | + "15def4fc077ccfb0e48b32bc07ea3b91acecc5b73ed9caf13b10adf17052c371", |
| 113 | + "07cfe4ec2efa9075763f921e9f29794ec6b945694e41cc19911101270d8b1087", |
| 114 | + "84cdf541cbb3b9b3f26dbdeb9ca3a2721d15447a8b47074c3b08b560f79e5d85", |
| 115 | + "af8e9fc2f15aaedadb96da1afb339b93e3174661327dcc6aad70ea67e183369d", |
| 116 | + } |
| 117 | + var results []string |
| 118 | + N := 16 |
| 119 | + for i := 0; i < N; i++ { |
| 120 | + inputs := generateInputs("golden", i+1) |
| 121 | + res := Tree(inputs) |
| 122 | + resHex := hex.EncodeToString(res[:]) |
| 123 | + assert.Equal(t, expectedHex[i], resHex) |
| 124 | + results = append(results, resHex) |
| 125 | + } |
| 126 | + t.Logf("results: %#v", results) |
| 127 | + |
| 128 | + batchRes := BatchTree(generateInputs("golden", N)) |
| 129 | + batchResHash := make([]string, N) |
| 130 | + for i := 0; i < N; i++ { |
| 131 | + batchResHash[i] = hex.EncodeToString(batchRes[i][:]) |
| 132 | + } |
| 133 | + assert.Equal(t, expectedHex, batchResHash) |
| 134 | +} |
| 135 | + |
| 136 | +func BenchmarkPrefixes(b *testing.B) { |
| 137 | + K := 128 |
| 138 | + inputs := generateInputs("golden", K) |
| 139 | + b.Run("IndividualPrefix", func(b *testing.B) { |
| 140 | + b.ReportAllocs() |
| 141 | + for range b.N { |
| 142 | + for i := range len(inputs) { |
| 143 | + runtime.KeepAlive(Tree(inputs[:i+1])) |
| 144 | + } |
| 145 | + } |
| 146 | + }) |
| 147 | + b.Run("BatchPrefix", func(b *testing.B) { |
| 148 | + b.ReportAllocs() |
| 149 | + for range b.N { |
| 150 | + runtime.KeepAlive(BatchTree(inputs)) |
| 151 | + } |
| 152 | + }) |
| 153 | +} |
0 commit comments