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.

426 lines
12 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. package arbo
  2. import (
  3. "encoding/hex"
  4. "math/big"
  5. "testing"
  6. "time"
  7. qt "github.com/frankban/quicktest"
  8. "github.com/iden3/go-merkletree/db/memory"
  9. )
  10. func TestAddTestVectors(t *testing.T) {
  11. c := qt.New(t)
  12. // Poseidon test vectors generated using https://github.com/iden3/circomlib smt.js
  13. testVectorsPoseidon := []string{
  14. "0000000000000000000000000000000000000000000000000000000000000000",
  15. "13578938674299138072471463694055224830892726234048532520316387704878000008795",
  16. "5412393676474193513566895793055462193090331607895808993925969873307089394741",
  17. "14204494359367183802864593755198662203838502594566452929175967972147978322084",
  18. }
  19. testAdd(c, HashFunctionPoseidon, testVectorsPoseidon)
  20. testVectorsSha256 := []string{
  21. "0000000000000000000000000000000000000000000000000000000000000000",
  22. "46910109172468462938850740851377282682950237270676610513794735904325820156367",
  23. "59481735341404520835410489183267411392292882901306595567679529387376287440550",
  24. "20573794434149960984975763118181266662429997821552560184909083010514790081771",
  25. }
  26. testAdd(c, HashFunctionSha256, testVectorsSha256)
  27. }
  28. func testAdd(c *qt.C, hashFunc HashFunction, testVectors []string) {
  29. tree, err := NewTree(memory.NewMemoryStorage(), 10, hashFunc)
  30. c.Assert(err, qt.IsNil)
  31. defer tree.db.Close()
  32. c.Check(hex.EncodeToString(tree.Root()), qt.Equals, testVectors[0])
  33. bLen := hashFunc.Len()
  34. err = tree.Add(
  35. BigIntToBytes(bLen, big.NewInt(1)),
  36. BigIntToBytes(bLen, big.NewInt(2)))
  37. c.Assert(err, qt.IsNil)
  38. rootBI := BytesToBigInt(tree.Root())
  39. c.Check(rootBI.String(), qt.Equals, testVectors[1])
  40. err = tree.Add(
  41. BigIntToBytes(bLen, big.NewInt(33)),
  42. BigIntToBytes(bLen, big.NewInt(44)))
  43. c.Assert(err, qt.IsNil)
  44. rootBI = BytesToBigInt(tree.Root())
  45. c.Check(rootBI.String(), qt.Equals, testVectors[2])
  46. err = tree.Add(
  47. BigIntToBytes(bLen, big.NewInt(1234)),
  48. BigIntToBytes(bLen, big.NewInt(9876)))
  49. c.Assert(err, qt.IsNil)
  50. rootBI = BytesToBigInt(tree.Root())
  51. c.Check(rootBI.String(), qt.Equals, testVectors[3])
  52. }
  53. func TestAddBatch(t *testing.T) {
  54. c := qt.New(t)
  55. tree, err := NewTree(memory.NewMemoryStorage(), 100, HashFunctionPoseidon)
  56. c.Assert(err, qt.IsNil)
  57. defer tree.db.Close()
  58. bLen := tree.HashFunction().Len()
  59. for i := 0; i < 1000; i++ {
  60. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  61. v := BigIntToBytes(bLen, big.NewInt(0))
  62. if err := tree.Add(k, v); err != nil {
  63. t.Fatal(err)
  64. }
  65. }
  66. rootBI := BytesToBigInt(tree.Root())
  67. c.Check(rootBI.String(), qt.Equals,
  68. "296519252211642170490407814696803112091039265640052570497930797516015811235")
  69. tree2, err := NewTree(memory.NewMemoryStorage(), 100, HashFunctionPoseidon)
  70. c.Assert(err, qt.IsNil)
  71. defer tree2.db.Close()
  72. var keys, values [][]byte
  73. for i := 0; i < 1000; i++ {
  74. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  75. v := BigIntToBytes(bLen, big.NewInt(0))
  76. keys = append(keys, k)
  77. values = append(values, v)
  78. }
  79. indexes, err := tree2.AddBatch(keys, values)
  80. c.Assert(err, qt.IsNil)
  81. c.Check(len(indexes), qt.Equals, 0)
  82. rootBI = BytesToBigInt(tree2.Root())
  83. c.Check(rootBI.String(), qt.Equals,
  84. "296519252211642170490407814696803112091039265640052570497930797516015811235")
  85. }
  86. func TestAddDifferentOrder(t *testing.T) {
  87. c := qt.New(t)
  88. tree1, err := NewTree(memory.NewMemoryStorage(), 100, HashFunctionPoseidon)
  89. c.Assert(err, qt.IsNil)
  90. defer tree1.db.Close()
  91. bLen := tree1.HashFunction().Len()
  92. for i := 0; i < 16; i++ {
  93. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  94. v := BigIntToBytes(bLen, big.NewInt(0))
  95. if err := tree1.Add(k, v); err != nil {
  96. t.Fatal(err)
  97. }
  98. }
  99. tree2, err := NewTree(memory.NewMemoryStorage(), 100, HashFunctionPoseidon)
  100. c.Assert(err, qt.IsNil)
  101. defer tree2.db.Close()
  102. for i := 16 - 1; i >= 0; i-- {
  103. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  104. v := BigIntToBytes(bLen, big.NewInt(0))
  105. if err := tree2.Add(k, v); err != nil {
  106. t.Fatal(err)
  107. }
  108. }
  109. c.Check(hex.EncodeToString(tree2.Root()), qt.Equals, hex.EncodeToString(tree1.Root()))
  110. c.Check(hex.EncodeToString(tree1.Root()), qt.Equals,
  111. "3b89100bec24da9275c87bc188740389e1d5accfc7d88ba5688d7fa96a00d82f")
  112. }
  113. func TestAddRepeatedIndex(t *testing.T) {
  114. c := qt.New(t)
  115. tree, err := NewTree(memory.NewMemoryStorage(), 100, HashFunctionPoseidon)
  116. c.Assert(err, qt.IsNil)
  117. defer tree.db.Close()
  118. bLen := tree.HashFunction().Len()
  119. k := BigIntToBytes(bLen, big.NewInt(int64(3)))
  120. v := BigIntToBytes(bLen, big.NewInt(int64(12)))
  121. if err := tree.Add(k, v); err != nil {
  122. t.Fatal(err)
  123. }
  124. err = tree.Add(k, v)
  125. c.Assert(err, qt.Not(qt.IsNil))
  126. c.Check(err, qt.Equals, ErrMaxVirtualLevel)
  127. }
  128. func TestUpdate(t *testing.T) {
  129. c := qt.New(t)
  130. tree, err := NewTree(memory.NewMemoryStorage(), 100, HashFunctionPoseidon)
  131. c.Assert(err, qt.IsNil)
  132. defer tree.db.Close()
  133. bLen := tree.HashFunction().Len()
  134. k := BigIntToBytes(bLen, big.NewInt(int64(20)))
  135. v := BigIntToBytes(bLen, big.NewInt(int64(12)))
  136. if err := tree.Add(k, v); err != nil {
  137. t.Fatal(err)
  138. }
  139. v = BigIntToBytes(bLen, big.NewInt(int64(11)))
  140. err = tree.Update(k, v)
  141. c.Assert(err, qt.IsNil)
  142. gettedKey, gettedValue, err := tree.Get(k)
  143. c.Assert(err, qt.IsNil)
  144. c.Check(gettedKey, qt.DeepEquals, k)
  145. c.Check(gettedValue, qt.DeepEquals, v)
  146. // add more leafs to the tree to do another test
  147. for i := 0; i < 16; i++ {
  148. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  149. v := BigIntToBytes(bLen, big.NewInt(int64(i*2)))
  150. if err := tree.Add(k, v); err != nil {
  151. t.Fatal(err)
  152. }
  153. }
  154. k = BigIntToBytes(bLen, big.NewInt(int64(3)))
  155. v = BigIntToBytes(bLen, big.NewInt(int64(11)))
  156. // check that before the Update, value for 3 is !=11
  157. gettedKey, gettedValue, err = tree.Get(k)
  158. c.Assert(err, qt.IsNil)
  159. c.Check(gettedKey, qt.DeepEquals, k)
  160. c.Check(gettedValue, qt.Not(qt.DeepEquals), v)
  161. c.Check(gettedValue, qt.DeepEquals, BigIntToBytes(bLen, big.NewInt(6)))
  162. err = tree.Update(k, v)
  163. c.Assert(err, qt.IsNil)
  164. // check that after Update, the value for 3 is ==11
  165. gettedKey, gettedValue, err = tree.Get(k)
  166. c.Assert(err, qt.IsNil)
  167. c.Check(gettedKey, qt.DeepEquals, k)
  168. c.Check(gettedValue, qt.DeepEquals, v)
  169. c.Check(gettedValue, qt.DeepEquals, BigIntToBytes(bLen, big.NewInt(11)))
  170. }
  171. func TestAux(t *testing.T) { // TODO split in proper tests
  172. c := qt.New(t)
  173. tree, err := NewTree(memory.NewMemoryStorage(), 100, HashFunctionPoseidon)
  174. c.Assert(err, qt.IsNil)
  175. defer tree.db.Close()
  176. bLen := tree.HashFunction().Len()
  177. k := BigIntToBytes(bLen, big.NewInt(int64(1)))
  178. v := BigIntToBytes(bLen, big.NewInt(int64(0)))
  179. err = tree.Add(k, v)
  180. c.Assert(err, qt.IsNil)
  181. k = BigIntToBytes(bLen, big.NewInt(int64(256)))
  182. err = tree.Add(k, v)
  183. c.Assert(err, qt.IsNil)
  184. k = BigIntToBytes(bLen, big.NewInt(int64(257)))
  185. err = tree.Add(k, v)
  186. c.Assert(err, qt.IsNil)
  187. k = BigIntToBytes(bLen, big.NewInt(int64(515)))
  188. err = tree.Add(k, v)
  189. c.Assert(err, qt.IsNil)
  190. k = BigIntToBytes(bLen, big.NewInt(int64(770)))
  191. err = tree.Add(k, v)
  192. c.Assert(err, qt.IsNil)
  193. k = BigIntToBytes(bLen, big.NewInt(int64(388)))
  194. err = tree.Add(k, v)
  195. c.Assert(err, qt.IsNil)
  196. k = BigIntToBytes(bLen, big.NewInt(int64(900)))
  197. err = tree.Add(k, v)
  198. c.Assert(err, qt.IsNil)
  199. //
  200. // err = tree.PrintGraphviz(nil)
  201. // c.Assert(err, qt.IsNil)
  202. }
  203. func TestGet(t *testing.T) {
  204. c := qt.New(t)
  205. tree, err := NewTree(memory.NewMemoryStorage(), 100, HashFunctionPoseidon)
  206. c.Assert(err, qt.IsNil)
  207. defer tree.db.Close()
  208. bLen := tree.HashFunction().Len()
  209. for i := 0; i < 10; i++ {
  210. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  211. v := BigIntToBytes(bLen, big.NewInt(int64(i*2)))
  212. if err := tree.Add(k, v); err != nil {
  213. t.Fatal(err)
  214. }
  215. }
  216. k := BigIntToBytes(bLen, big.NewInt(int64(7)))
  217. gettedKey, gettedValue, err := tree.Get(k)
  218. c.Assert(err, qt.IsNil)
  219. c.Check(gettedKey, qt.DeepEquals, k)
  220. c.Check(gettedValue, qt.DeepEquals, BigIntToBytes(bLen, big.NewInt(int64(7*2))))
  221. }
  222. func TestGenProofAndVerify(t *testing.T) {
  223. c := qt.New(t)
  224. tree, err := NewTree(memory.NewMemoryStorage(), 100, HashFunctionPoseidon)
  225. c.Assert(err, qt.IsNil)
  226. defer tree.db.Close()
  227. bLen := tree.HashFunction().Len()
  228. for i := 0; i < 10; i++ {
  229. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  230. v := BigIntToBytes(bLen, big.NewInt(int64(i*2)))
  231. if err := tree.Add(k, v); err != nil {
  232. t.Fatal(err)
  233. }
  234. }
  235. k := BigIntToBytes(bLen, big.NewInt(int64(7)))
  236. v := BigIntToBytes(bLen, big.NewInt(int64(14)))
  237. proofV, siblings, err := tree.GenProof(k)
  238. c.Assert(err, qt.IsNil)
  239. c.Assert(proofV, qt.DeepEquals, v)
  240. verif, err := CheckProof(tree.hashFunction, k, v, tree.Root(), siblings)
  241. c.Assert(err, qt.IsNil)
  242. c.Check(verif, qt.IsTrue)
  243. }
  244. func TestDumpAndImportDump(t *testing.T) {
  245. c := qt.New(t)
  246. tree1, err := NewTree(memory.NewMemoryStorage(), 100, HashFunctionPoseidon)
  247. c.Assert(err, qt.IsNil)
  248. defer tree1.db.Close()
  249. bLen := tree1.HashFunction().Len()
  250. for i := 0; i < 16; i++ {
  251. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  252. v := BigIntToBytes(bLen, big.NewInt(int64(i*2)))
  253. if err := tree1.Add(k, v); err != nil {
  254. t.Fatal(err)
  255. }
  256. }
  257. e, err := tree1.Dump(nil)
  258. c.Assert(err, qt.IsNil)
  259. tree2, err := NewTree(memory.NewMemoryStorage(), 100, HashFunctionPoseidon)
  260. c.Assert(err, qt.IsNil)
  261. defer tree2.db.Close()
  262. err = tree2.ImportDump(e)
  263. c.Assert(err, qt.IsNil)
  264. c.Check(tree2.Root(), qt.DeepEquals, tree1.Root())
  265. c.Check(hex.EncodeToString(tree2.Root()), qt.Equals,
  266. "0d93aaa3362b2f999f15e15728f123087c2eee716f01c01f56e23aae07f09f08")
  267. }
  268. func TestRWMutex(t *testing.T) {
  269. c := qt.New(t)
  270. tree, err := NewTree(memory.NewMemoryStorage(), 100, HashFunctionPoseidon)
  271. c.Assert(err, qt.IsNil)
  272. defer tree.db.Close()
  273. bLen := tree.HashFunction().Len()
  274. var keys, values [][]byte
  275. for i := 0; i < 1000; i++ {
  276. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  277. v := BigIntToBytes(bLen, big.NewInt(0))
  278. keys = append(keys, k)
  279. values = append(values, v)
  280. }
  281. go func() {
  282. _, err = tree.AddBatch(keys, values)
  283. if err != nil {
  284. panic(err)
  285. }
  286. }()
  287. time.Sleep(500 * time.Millisecond)
  288. k := BigIntToBytes(bLen, big.NewInt(int64(99999)))
  289. v := BigIntToBytes(bLen, big.NewInt(int64(99999)))
  290. if err := tree.Add(k, v); err != nil {
  291. t.Fatal(err)
  292. }
  293. }
  294. func TestSetGetNLeafs(t *testing.T) {
  295. c := qt.New(t)
  296. tree, err := NewTree(memory.NewMemoryStorage(), 100, HashFunctionPoseidon)
  297. c.Assert(err, qt.IsNil)
  298. // 0
  299. tree.tx, err = tree.db.NewTx()
  300. c.Assert(err, qt.IsNil)
  301. err = tree.setNLeafs(0)
  302. c.Assert(err, qt.IsNil)
  303. err = tree.tx.Commit()
  304. c.Assert(err, qt.IsNil)
  305. n, err := tree.GetNLeafs()
  306. c.Assert(err, qt.IsNil)
  307. c.Assert(n, qt.Equals, 0)
  308. // 1024
  309. tree.tx, err = tree.db.NewTx()
  310. c.Assert(err, qt.IsNil)
  311. err = tree.setNLeafs(1024)
  312. c.Assert(err, qt.IsNil)
  313. err = tree.tx.Commit()
  314. c.Assert(err, qt.IsNil)
  315. n, err = tree.GetNLeafs()
  316. c.Assert(err, qt.IsNil)
  317. c.Assert(n, qt.Equals, 1024)
  318. // 2**64 -1
  319. tree.tx, err = tree.db.NewTx()
  320. c.Assert(err, qt.IsNil)
  321. maxUint := ^uint(0)
  322. maxInt := int(maxUint >> 1)
  323. err = tree.setNLeafs(maxInt)
  324. c.Assert(err, qt.IsNil)
  325. err = tree.tx.Commit()
  326. c.Assert(err, qt.IsNil)
  327. n, err = tree.GetNLeafs()
  328. c.Assert(err, qt.IsNil)
  329. c.Assert(n, qt.Equals, maxInt)
  330. }
  331. func BenchmarkAdd(b *testing.B) {
  332. bLen := 32 // for both Poseidon & Sha256
  333. // prepare inputs
  334. var ks, vs [][]byte
  335. for i := 0; i < 1000; i++ {
  336. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  337. v := BigIntToBytes(bLen, big.NewInt(int64(i)))
  338. ks = append(ks, k)
  339. vs = append(vs, v)
  340. }
  341. b.Run("Poseidon", func(b *testing.B) {
  342. benchmarkAdd(b, HashFunctionPoseidon, ks, vs)
  343. })
  344. b.Run("Sha256", func(b *testing.B) {
  345. benchmarkAdd(b, HashFunctionSha256, ks, vs)
  346. })
  347. }
  348. func benchmarkAdd(b *testing.B, hashFunc HashFunction, ks, vs [][]byte) {
  349. c := qt.New(b)
  350. tree, err := NewTree(memory.NewMemoryStorage(), 140, hashFunc)
  351. c.Assert(err, qt.IsNil)
  352. defer tree.db.Close()
  353. for i := 0; i < len(ks); i++ {
  354. if err := tree.Add(ks[i], vs[i]); err != nil {
  355. b.Fatal(err)
  356. }
  357. }
  358. }