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.

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