You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

273 lines
5.9 KiB

  1. package asmtree
  2. import (
  3. "bytes"
  4. "crypto/rand"
  5. "fmt"
  6. "testing"
  7. "time"
  8. )
  9. func TestTree(t *testing.T) {
  10. censusSize := 1000
  11. storage := t.TempDir()
  12. tr1 := &Tree{}
  13. err := tr1.Init("test1", storage)
  14. if err != nil {
  15. t.Fatal(err)
  16. }
  17. for i := 0; i < censusSize; i++ {
  18. if err = tr1.Add([]byte(fmt.Sprintf("number %d", i)),
  19. []byte(fmt.Sprintf("number %d value", i))); err != nil {
  20. t.Fatal(err)
  21. }
  22. }
  23. root1 := tr1.Root()
  24. data, err := tr1.Dump(root1)
  25. if err != nil {
  26. t.Fatal(err)
  27. }
  28. t.Logf("dumped data size is: %d bytes", len(data))
  29. tr2 := &Tree{}
  30. err = tr2.Init("test2", storage)
  31. if err != nil {
  32. t.Fatal(err)
  33. }
  34. if err = tr2.ImportDump(data); err != nil {
  35. t.Fatal(err)
  36. }
  37. root2 := tr2.Root()
  38. if !bytes.Equal(root1, root2) {
  39. t.Errorf("roots are different but they should be equal (%x != %x)", root1, root2)
  40. }
  41. // Try closing the storage and creating the tree again
  42. tr2.Close()
  43. err = tr2.Init("test2", storage)
  44. if err != nil {
  45. t.Fatal(err)
  46. }
  47. // Get the size
  48. s, err := tr2.Size(nil)
  49. if err != nil {
  50. t.Errorf("cannot get te size of the tree after reopen: (%s)", err)
  51. }
  52. if s != int64(censusSize) {
  53. t.Errorf("Size is wrong (have %d, expexted %d)", s, censusSize)
  54. }
  55. // Check Root is still the same
  56. if !bytes.Equal(tr2.Root(), root2) {
  57. t.Fatalf("after closing and opening the tree, the root is different")
  58. }
  59. // Generate a proof on tr1 and check validity on snapshot and tr2
  60. proof1, err := tr1.GenProof([]byte("number 5"), []byte("number 5 value"))
  61. if err != nil {
  62. t.Error(err)
  63. }
  64. t.Logf("Proof Length: %d", len(proof1))
  65. tr1s, err := tr1.Snapshot(root1)
  66. if err != nil {
  67. t.Fatal(err)
  68. }
  69. valid, err := tr1s.CheckProof([]byte("number 5"), []byte("number 5 value"), root1, proof1)
  70. if err != nil {
  71. t.Error(err)
  72. }
  73. if !valid {
  74. t.Errorf("proof is invalid on snapshot")
  75. }
  76. valid, err = tr2.CheckProof([]byte("number 5"), []byte("number 5 value"), nil, proof1)
  77. if err != nil {
  78. t.Error(err)
  79. }
  80. if !valid {
  81. t.Errorf("proof is invalid on tree2")
  82. }
  83. }
  84. func TestProofs(t *testing.T) {
  85. censusSize := 10000
  86. storage := t.TempDir()
  87. tr1 := &Tree{}
  88. err := tr1.Init("test1", storage)
  89. if err != nil {
  90. t.Fatal(err)
  91. }
  92. var keys, values [][]byte
  93. for i := 0; i < censusSize; i++ {
  94. keys = append(keys, RandomBytes(32))
  95. values = append(values, RandomBytes(32))
  96. }
  97. i := 0
  98. for i < censusSize-200 {
  99. if fail, err := tr1.AddBatch(keys[i:i+200], values[i:i+200]); err != nil {
  100. t.Fatal(err)
  101. } else if len(fail) > 0 {
  102. t.Fatalf("some keys failed to add on addBatch: %v", fail)
  103. }
  104. i += 200
  105. }
  106. // Add remaining claims (if size%200 != 0)
  107. if i < censusSize {
  108. if fail, err := tr1.AddBatch(keys[i:], values[i:]); err != nil {
  109. t.Fatal(err)
  110. } else if len(fail) > 0 {
  111. t.Fatalf("some keys failed to add on addBatch: %v", fail)
  112. }
  113. }
  114. root1 := tr1.Root()
  115. data, err := tr1.Dump(root1)
  116. if err != nil {
  117. t.Fatal(err)
  118. }
  119. t.Logf("dumped data size is: %d bytes", len(data))
  120. // Get the size
  121. s, err := tr1.Size(nil)
  122. if err != nil {
  123. t.Errorf("cannot get te size: %v", err)
  124. }
  125. if s != int64(censusSize) {
  126. t.Errorf("size is wrong (have %d, expexted %d)", s, censusSize)
  127. }
  128. // Generate a proofs
  129. time.Sleep(5 * time.Second)
  130. proofs := [][]byte{}
  131. for i := 0; i < censusSize; i++ {
  132. p, err := tr1.GenProof(keys[i], values[i])
  133. if err != nil {
  134. t.Fatal(err)
  135. }
  136. if len(p) == 0 {
  137. t.Fatal("proof not generated")
  138. }
  139. proofs = append(proofs, p)
  140. }
  141. // Check proofs
  142. for i := 0; i < censusSize; i++ {
  143. valid, err := tr1.CheckProof(keys[i], values[i], root1, proofs[i])
  144. if err != nil {
  145. t.Fatal(err)
  146. }
  147. if !valid {
  148. t.Errorf("proof %d is invalid", i)
  149. }
  150. }
  151. }
  152. // go test -v -run=- -bench=Tree -benchtime=30s .
  153. func BenchmarkTree(b *testing.B) {
  154. b.ReportAllocs()
  155. b.ResetTimer()
  156. b.RunParallel(func(pb *testing.PB) {
  157. // Create websocket client
  158. for pb.Next() {
  159. benchProofs(b, 100000)
  160. }
  161. })
  162. }
  163. func benchProofs(b *testing.B, censusSize int) {
  164. totalTimer := time.Now()
  165. storage := b.TempDir()
  166. tr1 := &Tree{}
  167. err := tr1.Init("test1", storage)
  168. if err != nil {
  169. b.Fatal(err)
  170. }
  171. var keys, values [][]byte
  172. for i := 0; i < censusSize; i++ {
  173. keys = append(keys, RandomBytes(32))
  174. values = append(values, RandomBytes(32))
  175. }
  176. timer := time.Now()
  177. i := 0
  178. for i < censusSize-200 {
  179. if fail, err := tr1.AddBatch(keys[i:i+200], values[i:i+200]); err != nil {
  180. b.Fatal(err)
  181. } else if len(fail) > 0 {
  182. b.Fatalf("some keys failed to add on addBatch: %v", fail)
  183. }
  184. i += 200
  185. }
  186. // Add remaining claims (if size%200 != 0)
  187. if i < censusSize {
  188. if fail, err := tr1.AddBatch(keys[i:], values[i:]); err != nil {
  189. b.Fatal(err)
  190. } else if len(fail) > 0 {
  191. b.Fatalf("some keys failed to add on addBatch: %v", fail)
  192. }
  193. }
  194. b.Logf("addBatch took %d ms", time.Since(timer).Milliseconds())
  195. timer = time.Now()
  196. root1 := tr1.Root()
  197. data, err := tr1.Dump(root1)
  198. if err != nil {
  199. b.Fatal(err)
  200. }
  201. b.Logf("dumped data size is: %d bytes", len(data))
  202. b.Logf("dump took %d ms", time.Since(timer).Milliseconds())
  203. // Get the size
  204. s, err := tr1.Size(nil)
  205. if err != nil {
  206. b.Errorf("cannot get te size: %v", err)
  207. }
  208. if s != int64(censusSize) {
  209. b.Errorf("size is wrong (have %d, expexted %d)", s, censusSize)
  210. }
  211. // Generate a proofs
  212. timer = time.Now()
  213. time.Sleep(5 * time.Second)
  214. proofs := [][]byte{}
  215. for i := 0; i < censusSize; i++ {
  216. p, err := tr1.GenProof(keys[i], values[i])
  217. if err != nil {
  218. b.Fatal(err)
  219. }
  220. if len(p) == 0 {
  221. b.Fatal("proof not generated")
  222. }
  223. proofs = append(proofs, p)
  224. }
  225. b.Logf("gen proofs took %d ms", time.Since(timer).Milliseconds())
  226. // Check proofs
  227. timer = time.Now()
  228. for i := 0; i < censusSize; i++ {
  229. valid, err := tr1.CheckProof(keys[i], values[i], root1, proofs[i])
  230. if err != nil {
  231. b.Fatal(err)
  232. }
  233. if !valid {
  234. b.Errorf("proof %d is invalid", i)
  235. }
  236. }
  237. b.Logf("check proofs took %d ms", time.Since(timer).Milliseconds())
  238. b.Logf("[finished] %d ms", time.Since(totalTimer).Milliseconds())
  239. }
  240. func RandomBytes(n int) []byte {
  241. b := make([]byte, n)
  242. _, err := rand.Read(b)
  243. if err != nil {
  244. panic(err)
  245. }
  246. return b
  247. }