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.

814 lines
23 KiB

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"
  5. "math/big"
  6. "runtime"
  7. "testing"
  8. "time"
  9. qt "github.com/frankban/quicktest"
  10. "go.vocdoni.io/dvote/db"
  11. "go.vocdoni.io/dvote/db/badgerdb"
  12. "go.vocdoni.io/dvote/db/pebbledb"
  13. )
  14. func checkRootBIString(c *qt.C, tree *Tree, expected string) {
  15. root, err := tree.Root()
  16. c.Assert(err, qt.IsNil)
  17. rootBI := BytesToBigInt(root)
  18. c.Check(rootBI.String(), qt.Equals, expected)
  19. }
  20. func TestDBTx(t *testing.T) {
  21. c := qt.New(t)
  22. dbBadger, err := badgerdb.New(db.Options{Path: c.TempDir()})
  23. c.Assert(err, qt.IsNil)
  24. testDBTx(c, dbBadger)
  25. dbPebble, err := pebbledb.New(db.Options{Path: c.TempDir()})
  26. c.Assert(err, qt.IsNil)
  27. testDBTx(c, dbPebble)
  28. }
  29. func testDBTx(c *qt.C, database db.Database) {
  30. wTx := database.WriteTx()
  31. defer wTx.Discard()
  32. _, err := wTx.Get([]byte("a"))
  33. c.Assert(err, qt.Equals, db.ErrKeyNotFound)
  34. err = wTx.Set([]byte("a"), []byte("b"))
  35. c.Assert(err, qt.IsNil)
  36. v, err := wTx.Get([]byte("a"))
  37. c.Assert(err, qt.IsNil)
  38. c.Assert(v, qt.DeepEquals, []byte("b"))
  39. }
  40. func TestAddTestVectors(t *testing.T) {
  41. c := qt.New(t)
  42. // Poseidon test vectors generated using https://github.com/iden3/circomlib smt.js
  43. testVectorsPoseidon := []string{
  44. "0000000000000000000000000000000000000000000000000000000000000000",
  45. "13578938674299138072471463694055224830892726234048532520316387704878000008795",
  46. "5412393676474193513566895793055462193090331607895808993925969873307089394741",
  47. "14204494359367183802864593755198662203838502594566452929175967972147978322084",
  48. }
  49. testAdd(c, HashFunctionPoseidon, testVectorsPoseidon)
  50. testVectorsSha256 := []string{
  51. "0000000000000000000000000000000000000000000000000000000000000000",
  52. "46910109172468462938850740851377282682950237270676610513794735904325820156367",
  53. "59481735341404520835410489183267411392292882901306595567679529387376287440550",
  54. "20573794434149960984975763118181266662429997821552560184909083010514790081771",
  55. }
  56. testAdd(c, HashFunctionSha256, testVectorsSha256)
  57. }
  58. func testAdd(c *qt.C, hashFunc HashFunction, testVectors []string) {
  59. database, err := badgerdb.New(db.Options{Path: c.TempDir()})
  60. c.Assert(err, qt.IsNil)
  61. tree, err := NewTree(database, 256, hashFunc)
  62. c.Assert(err, qt.IsNil)
  63. defer tree.db.Close() //nolint:errcheck
  64. root, err := tree.Root()
  65. c.Assert(err, qt.IsNil)
  66. c.Check(hex.EncodeToString(root), qt.Equals, testVectors[0])
  67. bLen := 32
  68. err = tree.Add(
  69. BigIntToBytes(bLen, big.NewInt(1)),
  70. BigIntToBytes(bLen, big.NewInt(2)))
  71. c.Assert(err, qt.IsNil)
  72. checkRootBIString(c, tree, testVectors[1])
  73. err = tree.Add(
  74. BigIntToBytes(bLen, big.NewInt(33)),
  75. BigIntToBytes(bLen, big.NewInt(44)))
  76. c.Assert(err, qt.IsNil)
  77. checkRootBIString(c, tree, testVectors[2])
  78. err = tree.Add(
  79. BigIntToBytes(bLen, big.NewInt(1234)),
  80. BigIntToBytes(bLen, big.NewInt(9876)))
  81. c.Assert(err, qt.IsNil)
  82. checkRootBIString(c, tree, testVectors[3])
  83. }
  84. func TestAddBatch(t *testing.T) {
  85. c := qt.New(t)
  86. database, err := badgerdb.New(db.Options{Path: c.TempDir()})
  87. c.Assert(err, qt.IsNil)
  88. tree, err := NewTree(database, 256, HashFunctionPoseidon)
  89. c.Assert(err, qt.IsNil)
  90. defer tree.db.Close() //nolint:errcheck
  91. bLen := 32
  92. for i := 0; i < 1000; i++ {
  93. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  94. v := BigIntToBytes(bLen, big.NewInt(0))
  95. if err := tree.Add(k, v); err != nil {
  96. t.Fatal(err)
  97. }
  98. }
  99. checkRootBIString(c, tree,
  100. "296519252211642170490407814696803112091039265640052570497930797516015811235")
  101. database, err = badgerdb.New(db.Options{Path: c.TempDir()})
  102. c.Assert(err, qt.IsNil)
  103. tree2, err := NewTree(database, 256, HashFunctionPoseidon)
  104. c.Assert(err, qt.IsNil)
  105. defer tree2.db.Close() //nolint:errcheck
  106. var keys, values [][]byte
  107. for i := 0; i < 1000; i++ {
  108. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  109. v := BigIntToBytes(bLen, big.NewInt(0))
  110. keys = append(keys, k)
  111. values = append(values, v)
  112. }
  113. indexes, err := tree2.AddBatch(keys, values)
  114. c.Assert(err, qt.IsNil)
  115. c.Check(len(indexes), qt.Equals, 0)
  116. checkRootBIString(c, tree2,
  117. "296519252211642170490407814696803112091039265640052570497930797516015811235")
  118. }
  119. func TestAddDifferentOrder(t *testing.T) {
  120. c := qt.New(t)
  121. database1, err := badgerdb.New(db.Options{Path: c.TempDir()})
  122. c.Assert(err, qt.IsNil)
  123. tree1, err := NewTree(database1, 256, HashFunctionPoseidon)
  124. c.Assert(err, qt.IsNil)
  125. defer tree1.db.Close() //nolint:errcheck
  126. bLen := 32
  127. for i := 0; i < 16; i++ {
  128. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  129. v := BigIntToBytes(bLen, big.NewInt(0))
  130. if err := tree1.Add(k, v); err != nil {
  131. t.Fatal(err)
  132. }
  133. }
  134. database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
  135. c.Assert(err, qt.IsNil)
  136. tree2, err := NewTree(database2, 256, HashFunctionPoseidon)
  137. c.Assert(err, qt.IsNil)
  138. defer tree2.db.Close() //nolint:errcheck
  139. for i := 16 - 1; i >= 0; i-- {
  140. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  141. v := BigIntToBytes(bLen, big.NewInt(0))
  142. if err := tree2.Add(k, v); err != nil {
  143. t.Fatal(err)
  144. }
  145. }
  146. root1, err := tree1.Root()
  147. c.Assert(err, qt.IsNil)
  148. root2, err := tree2.Root()
  149. c.Assert(err, qt.IsNil)
  150. c.Check(hex.EncodeToString(root2), qt.Equals, hex.EncodeToString(root1))
  151. c.Check(hex.EncodeToString(root1), qt.Equals,
  152. "3b89100bec24da9275c87bc188740389e1d5accfc7d88ba5688d7fa96a00d82f")
  153. }
  154. func TestAddRepeatedIndex(t *testing.T) {
  155. c := qt.New(t)
  156. database, err := badgerdb.New(db.Options{Path: c.TempDir()})
  157. c.Assert(err, qt.IsNil)
  158. tree, err := NewTree(database, 256, HashFunctionPoseidon)
  159. c.Assert(err, qt.IsNil)
  160. defer tree.db.Close() //nolint:errcheck
  161. bLen := 32
  162. k := BigIntToBytes(bLen, big.NewInt(int64(3)))
  163. v := BigIntToBytes(bLen, big.NewInt(int64(12)))
  164. err = tree.Add(k, v)
  165. c.Assert(err, qt.IsNil)
  166. err = tree.Add(k, v) // repeating same key-value
  167. c.Check(err, qt.Equals, ErrKeyAlreadyExists)
  168. }
  169. func TestUpdate(t *testing.T) {
  170. c := qt.New(t)
  171. database, err := badgerdb.New(db.Options{Path: c.TempDir()})
  172. c.Assert(err, qt.IsNil)
  173. tree, err := NewTree(database, 256, HashFunctionPoseidon)
  174. c.Assert(err, qt.IsNil)
  175. defer tree.db.Close() //nolint:errcheck
  176. bLen := 32
  177. k := BigIntToBytes(bLen, big.NewInt(int64(20)))
  178. v := BigIntToBytes(bLen, big.NewInt(int64(12)))
  179. if err := tree.Add(k, v); err != nil {
  180. t.Fatal(err)
  181. }
  182. v = BigIntToBytes(bLen, big.NewInt(int64(11)))
  183. err = tree.Update(k, v)
  184. c.Assert(err, qt.IsNil)
  185. gettedKey, gettedValue, err := tree.Get(k)
  186. c.Assert(err, qt.IsNil)
  187. c.Check(gettedKey, qt.DeepEquals, k)
  188. c.Check(gettedValue, qt.DeepEquals, v)
  189. // add more leafs to the tree to do another test
  190. for i := 0; i < 16; i++ {
  191. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  192. v := BigIntToBytes(bLen, big.NewInt(int64(i*2)))
  193. if err := tree.Add(k, v); err != nil {
  194. t.Fatal(err)
  195. }
  196. }
  197. k = BigIntToBytes(bLen, big.NewInt(int64(3)))
  198. v = BigIntToBytes(bLen, big.NewInt(int64(11)))
  199. // check that before the Update, value for 3 is !=11
  200. gettedKey, gettedValue, err = tree.Get(k)
  201. c.Assert(err, qt.IsNil)
  202. c.Check(gettedKey, qt.DeepEquals, k)
  203. c.Check(gettedValue, qt.Not(qt.DeepEquals), v)
  204. c.Check(gettedValue, qt.DeepEquals, BigIntToBytes(bLen, big.NewInt(6)))
  205. err = tree.Update(k, v)
  206. c.Assert(err, qt.IsNil)
  207. // check that after Update, the value for 3 is ==11
  208. gettedKey, gettedValue, err = tree.Get(k)
  209. c.Assert(err, qt.IsNil)
  210. c.Check(gettedKey, qt.DeepEquals, k)
  211. c.Check(gettedValue, qt.DeepEquals, v)
  212. c.Check(gettedValue, qt.DeepEquals, BigIntToBytes(bLen, big.NewInt(11)))
  213. }
  214. func TestAux(t *testing.T) { // TODO split in proper tests
  215. c := qt.New(t)
  216. database, err := badgerdb.New(db.Options{Path: c.TempDir()})
  217. c.Assert(err, qt.IsNil)
  218. tree, err := NewTree(database, 256, HashFunctionPoseidon)
  219. c.Assert(err, qt.IsNil)
  220. defer tree.db.Close() //nolint:errcheck
  221. bLen := 32
  222. k := BigIntToBytes(bLen, big.NewInt(int64(1)))
  223. v := BigIntToBytes(bLen, big.NewInt(int64(0)))
  224. err = tree.Add(k, v)
  225. c.Assert(err, qt.IsNil)
  226. k = BigIntToBytes(bLen, big.NewInt(int64(256)))
  227. err = tree.Add(k, v)
  228. c.Assert(err, qt.IsNil)
  229. k = BigIntToBytes(bLen, big.NewInt(int64(257)))
  230. err = tree.Add(k, v)
  231. c.Assert(err, qt.IsNil)
  232. k = BigIntToBytes(bLen, big.NewInt(int64(515)))
  233. err = tree.Add(k, v)
  234. c.Assert(err, qt.IsNil)
  235. k = BigIntToBytes(bLen, big.NewInt(int64(770)))
  236. err = tree.Add(k, v)
  237. c.Assert(err, qt.IsNil)
  238. k = BigIntToBytes(bLen, big.NewInt(int64(388)))
  239. err = tree.Add(k, v)
  240. c.Assert(err, qt.IsNil)
  241. k = BigIntToBytes(bLen, big.NewInt(int64(900)))
  242. err = tree.Add(k, v)
  243. c.Assert(err, qt.IsNil)
  244. //
  245. // err = tree.PrintGraphviz(nil)
  246. // c.Assert(err, qt.IsNil)
  247. }
  248. func TestGet(t *testing.T) {
  249. c := qt.New(t)
  250. database, err := badgerdb.New(db.Options{Path: c.TempDir()})
  251. c.Assert(err, qt.IsNil)
  252. tree, err := NewTree(database, 256, HashFunctionPoseidon)
  253. c.Assert(err, qt.IsNil)
  254. defer tree.db.Close() //nolint:errcheck
  255. bLen := 32
  256. for i := 0; i < 10; i++ {
  257. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  258. v := BigIntToBytes(bLen, big.NewInt(int64(i*2)))
  259. if err := tree.Add(k, v); err != nil {
  260. t.Fatal(err)
  261. }
  262. }
  263. k := BigIntToBytes(bLen, big.NewInt(int64(7)))
  264. gettedKey, gettedValue, err := tree.Get(k)
  265. c.Assert(err, qt.IsNil)
  266. c.Check(gettedKey, qt.DeepEquals, k)
  267. c.Check(gettedValue, qt.DeepEquals, BigIntToBytes(bLen, big.NewInt(int64(7*2))))
  268. }
  269. func TestGenProofAndVerify(t *testing.T) {
  270. c := qt.New(t)
  271. database, err := badgerdb.New(db.Options{Path: c.TempDir()})
  272. c.Assert(err, qt.IsNil)
  273. tree, err := NewTree(database, 256, HashFunctionPoseidon)
  274. c.Assert(err, qt.IsNil)
  275. defer tree.db.Close() //nolint:errcheck
  276. bLen := 32
  277. for i := 0; i < 10; i++ {
  278. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  279. v := BigIntToBytes(bLen, big.NewInt(int64(i*2)))
  280. if err := tree.Add(k, v); err != nil {
  281. t.Fatal(err)
  282. }
  283. }
  284. k := BigIntToBytes(bLen, big.NewInt(int64(7)))
  285. v := BigIntToBytes(bLen, big.NewInt(int64(14)))
  286. kAux, proofV, siblings, existence, err := tree.GenProof(k)
  287. c.Assert(err, qt.IsNil)
  288. c.Assert(proofV, qt.DeepEquals, v)
  289. c.Assert(k, qt.DeepEquals, kAux)
  290. c.Assert(existence, qt.IsTrue)
  291. root, err := tree.Root()
  292. c.Assert(err, qt.IsNil)
  293. verif, err := CheckProof(tree.hashFunction, k, v, root, siblings)
  294. c.Assert(err, qt.IsNil)
  295. c.Check(verif, qt.IsTrue)
  296. }
  297. func TestDumpAndImportDump(t *testing.T) {
  298. c := qt.New(t)
  299. database1, err := badgerdb.New(db.Options{Path: c.TempDir()})
  300. c.Assert(err, qt.IsNil)
  301. tree1, err := NewTree(database1, 256, HashFunctionPoseidon)
  302. c.Assert(err, qt.IsNil)
  303. defer tree1.db.Close() //nolint:errcheck
  304. bLen := 32
  305. for i := 0; i < 16; i++ {
  306. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  307. v := BigIntToBytes(bLen, big.NewInt(int64(i*2)))
  308. if err := tree1.Add(k, v); err != nil {
  309. t.Fatal(err)
  310. }
  311. }
  312. e, err := tree1.Dump(nil)
  313. c.Assert(err, qt.IsNil)
  314. database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
  315. c.Assert(err, qt.IsNil)
  316. tree2, err := NewTree(database2, 256, HashFunctionPoseidon)
  317. c.Assert(err, qt.IsNil)
  318. defer tree2.db.Close() //nolint:errcheck
  319. err = tree2.ImportDump(e)
  320. c.Assert(err, qt.IsNil)
  321. root1, err := tree1.Root()
  322. c.Assert(err, qt.IsNil)
  323. root2, err := tree2.Root()
  324. c.Assert(err, qt.IsNil)
  325. c.Check(root2, qt.DeepEquals, root1)
  326. c.Check(hex.EncodeToString(root2), qt.Equals,
  327. "0d93aaa3362b2f999f15e15728f123087c2eee716f01c01f56e23aae07f09f08")
  328. }
  329. func TestRWMutex(t *testing.T) {
  330. c := qt.New(t)
  331. database, err := badgerdb.New(db.Options{Path: c.TempDir()})
  332. c.Assert(err, qt.IsNil)
  333. tree, err := NewTree(database, 256, HashFunctionPoseidon)
  334. c.Assert(err, qt.IsNil)
  335. defer tree.db.Close() //nolint:errcheck
  336. bLen := 32
  337. var keys, values [][]byte
  338. for i := 0; i < 1000; i++ {
  339. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  340. v := BigIntToBytes(bLen, big.NewInt(0))
  341. keys = append(keys, k)
  342. values = append(values, v)
  343. }
  344. go func() {
  345. _, err = tree.AddBatch(keys, values)
  346. if err != nil {
  347. panic(err)
  348. }
  349. }()
  350. time.Sleep(500 * time.Millisecond)
  351. k := BigIntToBytes(bLen, big.NewInt(int64(99999)))
  352. v := BigIntToBytes(bLen, big.NewInt(int64(99999)))
  353. if err := tree.Add(k, v); err != nil {
  354. t.Fatal(err)
  355. }
  356. }
  357. // TODO UPDATE
  358. // func TestSetGetNLeafs(t *testing.T) {
  359. // c := qt.New(t)
  360. // database, err := badgerdb.New(db.Options{Path: c.TempDir()})
  361. // c.Assert(err, qt.IsNil)
  362. // tree, err := NewTree(database, 100, HashFunctionPoseidon)
  363. // c.Assert(err, qt.IsNil)
  364. //
  365. // // 0
  366. // tree.dbBatch = tree.db.NewBatch()
  367. //
  368. // err = tree.setNLeafs(0)
  369. // c.Assert(err, qt.IsNil)
  370. //
  371. // err = tree.dbBatch.Write()
  372. // c.Assert(err, qt.IsNil)
  373. //
  374. // n, err := tree.GetNLeafs()
  375. // c.Assert(err, qt.IsNil)
  376. // c.Assert(n, qt.Equals, 0)
  377. //
  378. // // 1024
  379. // tree.dbBatch = tree.db.NewBatch()
  380. //
  381. // err = tree.setNLeafs(1024)
  382. // c.Assert(err, qt.IsNil)
  383. //
  384. // err = tree.dbBatch.Write()
  385. // c.Assert(err, qt.IsNil)
  386. //
  387. // n, err = tree.GetNLeafs()
  388. // c.Assert(err, qt.IsNil)
  389. // c.Assert(n, qt.Equals, 1024)
  390. //
  391. // // 2**64 -1
  392. // tree.dbBatch = tree.db.NewBatch()
  393. //
  394. // maxUint := ^uint(0)
  395. // maxInt := int(maxUint >> 1)
  396. //
  397. // err = tree.setNLeafs(maxInt)
  398. // c.Assert(err, qt.IsNil)
  399. //
  400. // err = tree.dbBatch.Write()
  401. // c.Assert(err, qt.IsNil)
  402. //
  403. // n, err = tree.GetNLeafs()
  404. // c.Assert(err, qt.IsNil)
  405. // c.Assert(n, qt.Equals, maxInt)
  406. // }
  407. func TestAddBatchFullyUsed(t *testing.T) {
  408. c := qt.New(t)
  409. database1, err := badgerdb.New(db.Options{Path: c.TempDir()})
  410. c.Assert(err, qt.IsNil)
  411. tree1, err := NewTree(database1, 4, HashFunctionPoseidon)
  412. c.Assert(err, qt.IsNil)
  413. database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
  414. c.Assert(err, qt.IsNil)
  415. tree2, err := NewTree(database2, 4, HashFunctionPoseidon)
  416. c.Assert(err, qt.IsNil)
  417. var keys, values [][]byte
  418. for i := 0; i < 16; i++ {
  419. k := BigIntToBytes(1, big.NewInt(int64(i)))
  420. v := k
  421. keys = append(keys, k)
  422. values = append(values, v)
  423. // add one by one expecting no error
  424. err := tree1.Add(k, v)
  425. c.Assert(err, qt.IsNil)
  426. }
  427. invalids, err := tree2.AddBatch(keys, values)
  428. c.Assert(err, qt.IsNil)
  429. c.Assert(0, qt.Equals, len(invalids))
  430. root1, err := tree1.Root()
  431. c.Assert(err, qt.IsNil)
  432. root2, err := tree2.Root()
  433. c.Assert(err, qt.IsNil)
  434. c.Assert(root1, qt.DeepEquals, root2)
  435. // get all key-values and check that are equal between both trees
  436. for i := 0; i < 16; i++ {
  437. auxK1, auxV1, err := tree1.Get(BigIntToBytes(1, big.NewInt(int64(i))))
  438. c.Assert(err, qt.IsNil)
  439. auxK2, auxV2, err := tree2.Get(BigIntToBytes(1, big.NewInt(int64(i))))
  440. c.Assert(err, qt.IsNil)
  441. c.Assert(auxK1, qt.DeepEquals, auxK2)
  442. c.Assert(auxV1, qt.DeepEquals, auxV2)
  443. }
  444. // try adding one more key to both trees (through Add & AddBatch) and
  445. // expect not being added due the tree is already full
  446. k := BigIntToBytes(1, big.NewInt(int64(16)))
  447. v := k
  448. err = tree1.Add(k, v)
  449. c.Assert(err, qt.Equals, ErrMaxVirtualLevel)
  450. invalids, err = tree2.AddBatch([][]byte{k}, [][]byte{v})
  451. c.Assert(err, qt.IsNil)
  452. c.Assert(1, qt.Equals, len(invalids))
  453. }
  454. func TestSetRoot(t *testing.T) {
  455. c := qt.New(t)
  456. database, err := badgerdb.New(db.Options{Path: c.TempDir()})
  457. c.Assert(err, qt.IsNil)
  458. tree, err := NewTree(database, 256, HashFunctionPoseidon)
  459. c.Assert(err, qt.IsNil)
  460. expectedRoot := "13742386369878513332697380582061714160370929283209286127733983161245560237407"
  461. // fill the tree
  462. bLen := 32
  463. var keys, values [][]byte
  464. for i := 0; i < 1000; i++ {
  465. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  466. v := BigIntToBytes(bLen, big.NewInt(int64(i)))
  467. keys = append(keys, k)
  468. values = append(values, v)
  469. }
  470. indexes, err := tree.AddBatch(keys, values)
  471. c.Assert(err, qt.IsNil)
  472. c.Check(len(indexes), qt.Equals, 0)
  473. checkRootBIString(c, tree,
  474. expectedRoot)
  475. // add one more k-v
  476. k := BigIntToBytes(bLen, big.NewInt(1000))
  477. v := BigIntToBytes(bLen, big.NewInt(1000))
  478. err = tree.Add(k, v)
  479. c.Assert(err, qt.IsNil)
  480. checkRootBIString(c, tree,
  481. "10747149055773881257049574592162159501044114324358186833013814735296193179713")
  482. // do a SetRoot, and expect the same root than the original tree
  483. pastRootBI, ok := new(big.Int).SetString(expectedRoot, 10)
  484. c.Assert(ok, qt.IsTrue)
  485. pastRoot := BigIntToBytes(32, pastRootBI)
  486. err = tree.SetRoot(pastRoot)
  487. c.Assert(err, qt.IsNil)
  488. checkRootBIString(c, tree, expectedRoot)
  489. // check that the tree can be updated
  490. err = tree.Add([]byte("test"), []byte("test"))
  491. c.Assert(err, qt.IsNil)
  492. err = tree.Update([]byte("test"), []byte("test"))
  493. c.Assert(err, qt.IsNil)
  494. // check that the k-v '1000' does not exist in the new tree
  495. _, _, err = tree.Get(k)
  496. c.Assert(err, qt.Equals, ErrKeyNotFound)
  497. // check that can be set an empty root
  498. err = tree.SetRoot(tree.emptyHash)
  499. c.Assert(err, qt.IsNil)
  500. }
  501. func TestSnapshot(t *testing.T) {
  502. c := qt.New(t)
  503. database, err := badgerdb.New(db.Options{Path: c.TempDir()})
  504. c.Assert(err, qt.IsNil)
  505. tree, err := NewTree(database, 256, HashFunctionPoseidon)
  506. c.Assert(err, qt.IsNil)
  507. // fill the tree
  508. bLen := 32
  509. var keys, values [][]byte
  510. for i := 0; i < 1000; i++ {
  511. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  512. v := BigIntToBytes(bLen, big.NewInt(int64(i)))
  513. keys = append(keys, k)
  514. values = append(values, v)
  515. }
  516. indexes, err := tree.AddBatch(keys, values)
  517. c.Assert(err, qt.IsNil)
  518. c.Check(len(indexes), qt.Equals, 0)
  519. checkRootBIString(c, tree,
  520. "13742386369878513332697380582061714160370929283209286127733983161245560237407")
  521. // do a snapshot, and expect the same root than the original tree
  522. snapshotTree, err := tree.Snapshot(nil)
  523. c.Assert(err, qt.IsNil)
  524. checkRootBIString(c, snapshotTree,
  525. "13742386369878513332697380582061714160370929283209286127733983161245560237407")
  526. // check that the snapshotTree can not be updated
  527. _, err = snapshotTree.AddBatch(keys, values)
  528. c.Assert(err, qt.Equals, ErrSnapshotNotEditable)
  529. err = snapshotTree.Add([]byte("test"), []byte("test"))
  530. c.Assert(err, qt.Equals, ErrSnapshotNotEditable)
  531. err = snapshotTree.Update([]byte("test"), []byte("test"))
  532. c.Assert(err, qt.Equals, ErrSnapshotNotEditable)
  533. err = snapshotTree.ImportDump(nil)
  534. c.Assert(err, qt.Equals, ErrSnapshotNotEditable)
  535. // update the original tree by adding a new key-value, and check that
  536. // snapshotTree still has the old root, but the original tree has a new
  537. // root
  538. err = tree.Add([]byte("test"), []byte("test"))
  539. c.Assert(err, qt.IsNil)
  540. checkRootBIString(c, snapshotTree,
  541. "13742386369878513332697380582061714160370929283209286127733983161245560237407")
  542. checkRootBIString(c, tree,
  543. "1025190963769001718196479367844646783678188389989148142691917685159698888868")
  544. }
  545. func TestGetFromSnapshotExpectArboErrKeyNotFound(t *testing.T) {
  546. c := qt.New(t)
  547. database, err := badgerdb.New(db.Options{Path: c.TempDir()})
  548. c.Assert(err, qt.IsNil)
  549. tree, err := NewTree(database, 256, HashFunctionPoseidon)
  550. c.Assert(err, qt.IsNil)
  551. defer tree.db.Close() //nolint:errcheck
  552. bLen := 32
  553. k := BigIntToBytes(bLen, big.NewInt(int64(3)))
  554. root, err := tree.Root()
  555. c.Assert(err, qt.IsNil)
  556. tree, err = tree.Snapshot(root)
  557. c.Assert(err, qt.IsNil)
  558. _, _, err = tree.Get(k)
  559. c.Assert(err, qt.Equals, ErrKeyNotFound) // and not equal to db.ErrKeyNotFound
  560. }
  561. func TestKeyLen(t *testing.T) {
  562. c := qt.New(t)
  563. database, err := badgerdb.New(db.Options{Path: c.TempDir()})
  564. c.Assert(err, qt.IsNil)
  565. // maxLevels is 100, keyPath length = ceil(maxLevels/8) = 13
  566. maxLevels := 100
  567. tree, err := NewTree(database, maxLevels, HashFunctionBlake2b)
  568. c.Assert(err, qt.IsNil)
  569. // expect no errors when adding a key of only 4 bytes (when the
  570. // required length of keyPath for 100 levels would be 13 bytes)
  571. bLen := 4
  572. k := BigIntToBytes(bLen, big.NewInt(1))
  573. v := BigIntToBytes(bLen, big.NewInt(1))
  574. err = tree.Add(k, v)
  575. c.Assert(err, qt.IsNil)
  576. err = tree.Update(k, v)
  577. c.Assert(err, qt.IsNil)
  578. _, _, _, _, err = tree.GenProof(k)
  579. c.Assert(err, qt.IsNil)
  580. _, _, err = tree.Get(k)
  581. c.Assert(err, qt.IsNil)
  582. k = BigIntToBytes(bLen, big.NewInt(2))
  583. v = BigIntToBytes(bLen, big.NewInt(2))
  584. invalids, err := tree.AddBatch([][]byte{k}, [][]byte{v})
  585. c.Assert(err, qt.IsNil)
  586. c.Assert(len(invalids), qt.Equals, 0)
  587. // expect errors when adding a key bigger than maximum capacity of the
  588. // tree: ceil(maxLevels/8)
  589. maxLevels = 32
  590. database, err = badgerdb.New(db.Options{Path: c.TempDir()})
  591. c.Assert(err, qt.IsNil)
  592. tree, err = NewTree(database, maxLevels, HashFunctionBlake2b)
  593. c.Assert(err, qt.IsNil)
  594. maxKeyLen := int(math.Ceil(float64(maxLevels) / float64(8))) //nolint:gomnd
  595. k = BigIntToBytes(maxKeyLen+1, big.NewInt(1))
  596. v = BigIntToBytes(maxKeyLen+1, big.NewInt(1))
  597. expectedErrMsg := "len(k) can not be bigger than ceil(maxLevels/8)," +
  598. " where len(k): 5, maxLevels: 32, max key len=ceil(maxLevels/8): 4." +
  599. " Might need a bigger tree depth (maxLevels>=40) in order to input" +
  600. " keys of length 5"
  601. err = tree.Add(k, v)
  602. c.Assert(err.Error(), qt.Equals, expectedErrMsg)
  603. err = tree.Update(k, v)
  604. c.Assert(err.Error(), qt.Equals, expectedErrMsg)
  605. _, _, _, _, err = tree.GenProof(k)
  606. c.Assert(err.Error(), qt.Equals, expectedErrMsg)
  607. _, _, err = tree.Get(k)
  608. c.Assert(err.Error(), qt.Equals, expectedErrMsg)
  609. // check AddBatch with few key-values
  610. invalids, err = tree.AddBatch([][]byte{k}, [][]byte{v})
  611. c.Assert(err, qt.IsNil)
  612. c.Assert(len(invalids), qt.Equals, 1)
  613. // check AddBatch with many key-values
  614. nCPU := flp2(runtime.NumCPU())
  615. nKVs := nCPU + 1
  616. var ks, vs [][]byte
  617. for i := 0; i < nKVs; i++ {
  618. ks = append(ks, BigIntToBytes(maxKeyLen+1, big.NewInt(1)))
  619. vs = append(vs, BigIntToBytes(maxKeyLen+1, big.NewInt(1)))
  620. }
  621. invalids, err = tree.AddBatch(ks, vs)
  622. c.Assert(err, qt.IsNil)
  623. c.Assert(len(invalids), qt.Equals, nKVs)
  624. // check that with maxKeyLen it can be added
  625. k = BigIntToBytes(maxKeyLen, big.NewInt(1))
  626. err = tree.Add(k, v)
  627. c.Assert(err, qt.IsNil)
  628. // check CheckProof check with key longer
  629. kAux, vAux, packedSiblings, existence, err := tree.GenProof(k)
  630. c.Assert(err, qt.IsNil)
  631. c.Assert(existence, qt.IsTrue)
  632. root, err := tree.Root()
  633. c.Assert(err, qt.IsNil)
  634. verif, err := CheckProof(tree.HashFunction(), kAux, vAux, root, packedSiblings)
  635. c.Assert(err, qt.IsNil)
  636. c.Assert(verif, qt.IsTrue)
  637. // use a similar key but with one zero, expect that CheckProof fails on
  638. // the verification
  639. kAux = append(kAux, 0)
  640. verif, err = CheckProof(tree.HashFunction(), kAux, vAux, root, packedSiblings)
  641. c.Assert(err, qt.IsNil)
  642. c.Assert(verif, qt.IsFalse)
  643. }
  644. func TestKeyLenBiggerThan32(t *testing.T) {
  645. c := qt.New(t)
  646. maxLevels := 264
  647. database, err := badgerdb.New(db.Options{Path: c.TempDir()})
  648. c.Assert(err, qt.IsNil)
  649. tree, err := NewTree(database, maxLevels, HashFunctionBlake2b)
  650. c.Assert(err, qt.IsNil)
  651. bLen := 33
  652. err = tree.Add(
  653. randomBytes(bLen),
  654. randomBytes(bLen))
  655. c.Assert(err, qt.IsNil)
  656. // 2nd key that we add, will find a node with len(key)==32 (due the
  657. // hash output size, expect that next Add does not give any error, as
  658. // internally it will use a keyPath of size corresponent to the
  659. // maxLevels size of the tree
  660. err = tree.Add(
  661. randomBytes(bLen),
  662. randomBytes(bLen))
  663. c.Assert(err, qt.IsNil)
  664. }
  665. func BenchmarkAdd(b *testing.B) {
  666. bLen := 32 // for both Poseidon & Sha256
  667. // prepare inputs
  668. var ks, vs [][]byte
  669. for i := 0; i < 1000; i++ {
  670. k := BigIntToBytes(bLen, big.NewInt(int64(i)))
  671. v := BigIntToBytes(bLen, big.NewInt(int64(i)))
  672. ks = append(ks, k)
  673. vs = append(vs, v)
  674. }
  675. b.Run("Poseidon", func(b *testing.B) {
  676. benchmarkAdd(b, HashFunctionPoseidon, ks, vs)
  677. })
  678. b.Run("Sha256", func(b *testing.B) {
  679. benchmarkAdd(b, HashFunctionSha256, ks, vs)
  680. })
  681. }
  682. func benchmarkAdd(b *testing.B, hashFunc HashFunction, ks, vs [][]byte) {
  683. c := qt.New(b)
  684. database, err := badgerdb.New(db.Options{Path: c.TempDir()})
  685. c.Assert(err, qt.IsNil)
  686. tree, err := NewTree(database, 140, hashFunc)
  687. c.Assert(err, qt.IsNil)
  688. defer tree.db.Close() //nolint:errcheck
  689. for i := 0; i < len(ks); i++ {
  690. if err := tree.Add(ks[i], vs[i]); err != nil {
  691. b.Fatal(err)
  692. }
  693. }
  694. }