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.

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