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.

1206 lines
32 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. /*
  2. Package arbo implements a Merkle Tree compatible with the circomlib
  3. implementation of the MerkleTree, following the specification from
  4. https://docs.iden3.io/publications/pdfs/Merkle-Tree.pdf and
  5. https://eprint.iacr.org/2018/955.
  6. Allows to define which hash function to use. So for example, when working with
  7. zkSnarks the Poseidon hash function can be used, but when not, it can be used
  8. the Blake2b hash function, which has much faster computation time.
  9. */
  10. package arbo
  11. import (
  12. "bytes"
  13. "encoding/binary"
  14. "encoding/hex"
  15. "fmt"
  16. "io"
  17. "math"
  18. "sync"
  19. "go.vocdoni.io/dvote/db"
  20. )
  21. const (
  22. // PrefixValueLen defines the bytes-prefix length used for the Value
  23. // bytes representation stored in the db
  24. PrefixValueLen = 2
  25. // PrefixValueEmpty is used for the first byte of a Value to indicate
  26. // that is an Empty value
  27. PrefixValueEmpty = 0
  28. // PrefixValueLeaf is used for the first byte of a Value to indicate
  29. // that is a Leaf value
  30. PrefixValueLeaf = 1
  31. // PrefixValueIntermediate is used for the first byte of a Value to
  32. // indicate that is a Intermediate value
  33. PrefixValueIntermediate = 2
  34. // nChars is used to crop the Graphviz nodes labels
  35. nChars = 4
  36. )
  37. var (
  38. dbKeyRoot = []byte("root")
  39. dbKeyNLeafs = []byte("nleafs")
  40. emptyValue = []byte{0}
  41. // ErrKeyNotFound is used when a key is not found in the db neither in
  42. // the current db Batch.
  43. ErrKeyNotFound = fmt.Errorf("key not found")
  44. // ErrKeyAlreadyExists is used when trying to add a key as leaf to the
  45. // tree that already exists.
  46. ErrKeyAlreadyExists = fmt.Errorf("key already exists")
  47. // ErrInvalidValuePrefix is used when going down into the tree, a value
  48. // is read from the db and has an unrecognized prefix.
  49. ErrInvalidValuePrefix = fmt.Errorf("invalid value prefix")
  50. // ErrDBNoTx is used when trying to use Tree.dbPut but Tree.dbBatch==nil
  51. ErrDBNoTx = fmt.Errorf("dbPut error: no db Batch")
  52. // ErrMaxLevel indicates when going down into the tree, the max level is
  53. // reached
  54. ErrMaxLevel = fmt.Errorf("max level reached")
  55. // ErrMaxVirtualLevel indicates when going down into the tree, the max
  56. // virtual level is reached
  57. ErrMaxVirtualLevel = fmt.Errorf("max virtual level reached")
  58. // ErrSnapshotNotEditable indicates when the tree is a non writable
  59. // snapshot, thus can not be modified
  60. ErrSnapshotNotEditable = fmt.Errorf("snapshot tree can not be edited")
  61. // ErrTreeNotEmpty indicates when the tree was expected to be empty and
  62. // it is not
  63. ErrTreeNotEmpty = fmt.Errorf("tree is not empty")
  64. )
  65. // Tree defines the struct that implements the MerkleTree functionalities
  66. type Tree struct {
  67. sync.Mutex
  68. db db.Database
  69. maxLevels int
  70. snapshotRoot []byte
  71. hashFunction HashFunction
  72. // TODO in the methods that use it, check if emptyHash param is len>0
  73. // (check if it has been initialized)
  74. emptyHash []byte
  75. dbg *dbgStats
  76. }
  77. // NewTree returns a new Tree, if there is a Tree still in the given database, it
  78. // will load it.
  79. func NewTree(database db.Database, maxLevels int, hash HashFunction) (*Tree, error) {
  80. wTx := database.WriteTx()
  81. defer wTx.Discard()
  82. t, err := NewTreeWithTx(wTx, database, maxLevels, hash)
  83. if err != nil {
  84. return nil, err
  85. }
  86. if err = wTx.Commit(); err != nil {
  87. return nil, err
  88. }
  89. return t, nil
  90. }
  91. // NewTreeWithTx returns a new Tree using the given db.WriteTx, which will not
  92. // be ccommited inside this method, if there is a Tree still in the given
  93. // database, it will load it.
  94. func NewTreeWithTx(wTx db.WriteTx, database db.Database,
  95. maxLevels int, hash HashFunction) (*Tree, error) {
  96. t := Tree{db: database, maxLevels: maxLevels, hashFunction: hash}
  97. t.emptyHash = make([]byte, t.hashFunction.Len()) // empty
  98. _, err := wTx.Get(dbKeyRoot)
  99. if err == db.ErrKeyNotFound {
  100. // store new root 0 (empty)
  101. if err = wTx.Set(dbKeyRoot, t.emptyHash); err != nil {
  102. return nil, err
  103. }
  104. if err = t.setNLeafs(wTx, 0); err != nil {
  105. return nil, err
  106. }
  107. return &t, nil
  108. } else if err != nil {
  109. return nil, err
  110. }
  111. return &t, nil
  112. }
  113. // Root returns the root of the Tree
  114. func (t *Tree) Root() ([]byte, error) {
  115. rTx := t.db.ReadTx()
  116. defer rTx.Discard()
  117. return t.RootWithTx(rTx)
  118. }
  119. // RootWithTx returns the root of the Tree using the given db.ReadTx
  120. func (t *Tree) RootWithTx(rTx db.ReadTx) ([]byte, error) {
  121. // if snapshotRoot is defined, means that the tree is a snapshot, and
  122. // the root is not obtained from the db, but from the snapshotRoot
  123. // parameter
  124. if t.snapshotRoot != nil {
  125. return t.snapshotRoot, nil
  126. }
  127. // get db root
  128. return rTx.Get(dbKeyRoot)
  129. }
  130. func (t *Tree) setRoot(wTx db.WriteTx, root []byte) error {
  131. return wTx.Set(dbKeyRoot, root)
  132. }
  133. // HashFunction returns Tree.hashFunction
  134. func (t *Tree) HashFunction() HashFunction {
  135. return t.hashFunction
  136. }
  137. // editable returns true if the tree is editable, and false when is not
  138. // editable (because is a snapshot tree)
  139. func (t *Tree) editable() bool {
  140. return t.snapshotRoot == nil
  141. }
  142. // AddBatch adds a batch of key-values to the Tree. Returns an array containing
  143. // the indexes of the keys failed to add. Supports empty values as input
  144. // parameters, which is equivalent to 0 valued byte array.
  145. func (t *Tree) AddBatch(keys, values [][]byte) ([]int, error) {
  146. wTx := t.db.WriteTx()
  147. defer wTx.Discard()
  148. invalids, err := t.AddBatchWithTx(wTx, keys, values)
  149. if err != nil {
  150. return invalids, err
  151. }
  152. return invalids, wTx.Commit()
  153. }
  154. // AddBatchWithTx does the same than the AddBatch method, but allowing to pass
  155. // the db.WriteTx that is used. The db.WriteTx will not be committed inside
  156. // this method.
  157. func (t *Tree) AddBatchWithTx(wTx db.WriteTx, keys, values [][]byte) ([]int, error) {
  158. t.Lock()
  159. defer t.Unlock()
  160. if !t.editable() {
  161. return nil, ErrSnapshotNotEditable
  162. }
  163. vt, err := t.loadVT(wTx)
  164. if err != nil {
  165. return nil, err
  166. }
  167. e := []byte{}
  168. // equal the number of keys & values
  169. if len(keys) > len(values) {
  170. // add missing values
  171. for i := len(values); i < len(keys); i++ {
  172. values = append(values, e)
  173. }
  174. } else if len(keys) < len(values) {
  175. // crop extra values
  176. values = values[:len(keys)]
  177. }
  178. invalids, err := vt.addBatch(keys, values)
  179. if err != nil {
  180. return nil, err
  181. }
  182. // once the VirtualTree is build, compute the hashes
  183. pairs, err := vt.computeHashes()
  184. if err != nil {
  185. // currently invalids in computeHashes are not counted,
  186. // but should not be needed, as if there is an error there is
  187. // nothing stored in the db and the error is returned
  188. return nil, err
  189. }
  190. // store pairs in db
  191. for i := 0; i < len(pairs); i++ {
  192. if err := wTx.Set(pairs[i][0], pairs[i][1]); err != nil {
  193. return nil, err
  194. }
  195. }
  196. // store root (from the vt) to db
  197. if err := wTx.Set(dbKeyRoot, vt.root.h); err != nil {
  198. return nil, err
  199. }
  200. // update nLeafs
  201. if err := t.incNLeafs(wTx, len(keys)-len(invalids)); err != nil {
  202. return nil, err
  203. }
  204. return invalids, nil
  205. }
  206. // loadVT loads a new virtual tree (vt) from the current Tree, which contains
  207. // the same leafs.
  208. func (t *Tree) loadVT(rTx db.ReadTx) (vt, error) {
  209. vt := newVT(t.maxLevels, t.hashFunction)
  210. vt.params.dbg = t.dbg
  211. err := t.IterateWithTx(rTx, nil, func(k, v []byte) {
  212. if v[0] != PrefixValueLeaf {
  213. return
  214. }
  215. leafK, leafV := ReadLeafValue(v)
  216. if err := vt.add(0, leafK, leafV); err != nil {
  217. // TODO instead of panic, return this error
  218. panic(err)
  219. }
  220. })
  221. return vt, err
  222. }
  223. // Add inserts the key-value into the Tree. If the inputs come from a
  224. // *big.Int, is expected that are represented by a Little-Endian byte array
  225. // (for circom compatibility).
  226. func (t *Tree) Add(k, v []byte) error {
  227. wTx := t.db.WriteTx()
  228. defer wTx.Discard()
  229. if err := t.AddWithTx(wTx, k, v); err != nil {
  230. return err
  231. }
  232. return wTx.Commit()
  233. }
  234. // AddWithTx does the same than the Add method, but allowing to pass the
  235. // db.WriteTx that is used. The db.WriteTx will not be committed inside this
  236. // method.
  237. func (t *Tree) AddWithTx(wTx db.WriteTx, k, v []byte) error {
  238. t.Lock()
  239. defer t.Unlock()
  240. if !t.editable() {
  241. return ErrSnapshotNotEditable
  242. }
  243. root, err := t.RootWithTx(wTx)
  244. if err != nil {
  245. return err
  246. }
  247. root, err = t.add(wTx, root, 0, k, v) // add from level 0
  248. if err != nil {
  249. return err
  250. }
  251. // store root to db
  252. if err := t.setRoot(wTx, root); err != nil {
  253. return err
  254. }
  255. // update nLeafs
  256. if err = t.incNLeafs(wTx, 1); err != nil {
  257. return err
  258. }
  259. return nil
  260. }
  261. func (t *Tree) add(wTx db.WriteTx, root []byte, fromLvl int, k, v []byte) ([]byte, error) {
  262. keyPath := make([]byte, t.hashFunction.Len())
  263. copy(keyPath[:], k)
  264. path := getPath(t.maxLevels, keyPath)
  265. // go down to the leaf
  266. var siblings [][]byte
  267. _, _, siblings, err := t.down(wTx, k, root, siblings, path, fromLvl, false)
  268. if err != nil {
  269. return nil, err
  270. }
  271. leafKey, leafValue, err := t.newLeafValue(k, v)
  272. if err != nil {
  273. return nil, err
  274. }
  275. if err := wTx.Set(leafKey, leafValue); err != nil {
  276. return nil, err
  277. }
  278. // go up to the root
  279. if len(siblings) == 0 {
  280. // return the leafKey as root
  281. return leafKey, nil
  282. }
  283. root, err = t.up(wTx, leafKey, siblings, path, len(siblings)-1, fromLvl)
  284. if err != nil {
  285. return nil, err
  286. }
  287. return root, nil
  288. }
  289. // down goes down to the leaf recursively
  290. func (t *Tree) down(rTx db.ReadTx, newKey, currKey []byte, siblings [][]byte,
  291. path []bool, currLvl int, getLeaf bool) (
  292. []byte, []byte, [][]byte, error) {
  293. if currLvl > t.maxLevels {
  294. return nil, nil, nil, ErrMaxLevel
  295. }
  296. var err error
  297. var currValue []byte
  298. if bytes.Equal(currKey, t.emptyHash) {
  299. // empty value
  300. return currKey, emptyValue, siblings, nil
  301. }
  302. currValue, err = rTx.Get(currKey)
  303. if err != nil {
  304. return nil, nil, nil, err
  305. }
  306. switch currValue[0] {
  307. case PrefixValueEmpty: // empty
  308. fmt.Printf("newKey: %s, currKey: %s, currLvl: %d, currValue: %s\n",
  309. hex.EncodeToString(newKey), hex.EncodeToString(currKey),
  310. currLvl, hex.EncodeToString(currValue))
  311. panic("This point should not be reached, as the 'if' above" +
  312. " should avoid reaching this point. This panic is temporary" +
  313. " for reporting purposes, will be deleted in future versions." +
  314. " Please paste this log (including the previous lines) in a" +
  315. " new issue: https://github.com/vocdoni/arbo/issues/new") // TMP
  316. case PrefixValueLeaf: // leaf
  317. if !bytes.Equal(currValue, emptyValue) {
  318. if getLeaf {
  319. return currKey, currValue, siblings, nil
  320. }
  321. oldLeafKey, _ := ReadLeafValue(currValue)
  322. if bytes.Equal(newKey, oldLeafKey) {
  323. return nil, nil, nil, ErrKeyAlreadyExists
  324. }
  325. oldLeafKeyFull := make([]byte, t.hashFunction.Len())
  326. copy(oldLeafKeyFull[:], oldLeafKey)
  327. // if currKey is already used, go down until paths diverge
  328. oldPath := getPath(t.maxLevels, oldLeafKeyFull)
  329. siblings, err = t.downVirtually(siblings, currKey, newKey, oldPath, path, currLvl)
  330. if err != nil {
  331. return nil, nil, nil, err
  332. }
  333. }
  334. return currKey, currValue, siblings, nil
  335. case PrefixValueIntermediate: // intermediate
  336. if len(currValue) != PrefixValueLen+t.hashFunction.Len()*2 {
  337. return nil, nil, nil,
  338. fmt.Errorf("intermediate value invalid length (expected: %d, actual: %d)",
  339. PrefixValueLen+t.hashFunction.Len()*2, len(currValue))
  340. }
  341. // collect siblings while going down
  342. if path[currLvl] {
  343. // right
  344. lChild, rChild := ReadIntermediateChilds(currValue)
  345. siblings = append(siblings, lChild)
  346. return t.down(rTx, newKey, rChild, siblings, path, currLvl+1, getLeaf)
  347. }
  348. // left
  349. lChild, rChild := ReadIntermediateChilds(currValue)
  350. siblings = append(siblings, rChild)
  351. return t.down(rTx, newKey, lChild, siblings, path, currLvl+1, getLeaf)
  352. default:
  353. return nil, nil, nil, ErrInvalidValuePrefix
  354. }
  355. }
  356. // downVirtually is used when in a leaf already exists, and a new leaf which
  357. // shares the path until the existing leaf is being added
  358. func (t *Tree) downVirtually(siblings [][]byte, oldKey, newKey []byte, oldPath,
  359. newPath []bool, currLvl int) ([][]byte, error) {
  360. var err error
  361. if currLvl > t.maxLevels-1 {
  362. return nil, ErrMaxVirtualLevel
  363. }
  364. if oldPath[currLvl] == newPath[currLvl] {
  365. siblings = append(siblings, t.emptyHash)
  366. siblings, err = t.downVirtually(siblings, oldKey, newKey, oldPath, newPath, currLvl+1)
  367. if err != nil {
  368. return nil, err
  369. }
  370. return siblings, nil
  371. }
  372. // reached the divergence
  373. siblings = append(siblings, oldKey)
  374. return siblings, nil
  375. }
  376. // up goes up recursively updating the intermediate nodes
  377. func (t *Tree) up(wTx db.WriteTx, key []byte, siblings [][]byte, path []bool,
  378. currLvl, toLvl int) ([]byte, error) {
  379. var k, v []byte
  380. var err error
  381. if path[currLvl+toLvl] {
  382. k, v, err = t.newIntermediate(siblings[currLvl], key)
  383. if err != nil {
  384. return nil, err
  385. }
  386. } else {
  387. k, v, err = t.newIntermediate(key, siblings[currLvl])
  388. if err != nil {
  389. return nil, err
  390. }
  391. }
  392. // store k-v to db
  393. if err = wTx.Set(k, v); err != nil {
  394. return nil, err
  395. }
  396. if currLvl == 0 {
  397. // reached the root
  398. return k, nil
  399. }
  400. return t.up(wTx, k, siblings, path, currLvl-1, toLvl)
  401. }
  402. func (t *Tree) newLeafValue(k, v []byte) ([]byte, []byte, error) {
  403. t.dbg.incHash()
  404. return newLeafValue(t.hashFunction, k, v)
  405. }
  406. // newLeafValue takes a key & value from a leaf, and computes the leaf hash,
  407. // which is used as the leaf key. And the value is the concatenation of the
  408. // inputed key & value. The output of this function is used as key-value to
  409. // store the leaf in the DB.
  410. // [ 1 byte | 1 byte | N bytes | M bytes ]
  411. // [ type of node | length of key | key | value ]
  412. func newLeafValue(hashFunc HashFunction, k, v []byte) ([]byte, []byte, error) {
  413. leafKey, err := hashFunc.Hash(k, v, []byte{1})
  414. if err != nil {
  415. return nil, nil, err
  416. }
  417. var leafValue []byte
  418. leafValue = append(leafValue, byte(PrefixValueLeaf))
  419. leafValue = append(leafValue, byte(len(k)))
  420. leafValue = append(leafValue, k...)
  421. leafValue = append(leafValue, v...)
  422. return leafKey, leafValue, nil
  423. }
  424. // ReadLeafValue reads from a byte array the leaf key & value
  425. func ReadLeafValue(b []byte) ([]byte, []byte) {
  426. if len(b) < PrefixValueLen {
  427. return []byte{}, []byte{}
  428. }
  429. kLen := b[1]
  430. if len(b) < PrefixValueLen+int(kLen) {
  431. return []byte{}, []byte{}
  432. }
  433. k := b[PrefixValueLen : PrefixValueLen+kLen]
  434. v := b[PrefixValueLen+kLen:]
  435. return k, v
  436. }
  437. func (t *Tree) newIntermediate(l, r []byte) ([]byte, []byte, error) {
  438. t.dbg.incHash()
  439. return newIntermediate(t.hashFunction, l, r)
  440. }
  441. // newIntermediate takes the left & right keys of a intermediate node, and
  442. // computes its hash. Returns the hash of the node, which is the node key, and a
  443. // byte array that contains the value (which contains the left & right child
  444. // keys) to store in the DB.
  445. // [ 1 byte | 1 byte | N bytes | N bytes ]
  446. // [ type of node | length of left key | left key | right key ]
  447. func newIntermediate(hashFunc HashFunction, l, r []byte) ([]byte, []byte, error) {
  448. b := make([]byte, PrefixValueLen+hashFunc.Len()*2)
  449. b[0] = PrefixValueIntermediate
  450. b[1] = byte(len(l))
  451. copy(b[PrefixValueLen:PrefixValueLen+hashFunc.Len()], l)
  452. copy(b[PrefixValueLen+hashFunc.Len():], r)
  453. key, err := hashFunc.Hash(l, r)
  454. if err != nil {
  455. return nil, nil, err
  456. }
  457. return key, b, nil
  458. }
  459. // ReadIntermediateChilds reads from a byte array the two childs keys
  460. func ReadIntermediateChilds(b []byte) ([]byte, []byte) {
  461. if len(b) < PrefixValueLen {
  462. return []byte{}, []byte{}
  463. }
  464. lLen := b[1]
  465. if len(b) < PrefixValueLen+int(lLen) {
  466. return []byte{}, []byte{}
  467. }
  468. l := b[PrefixValueLen : PrefixValueLen+lLen]
  469. r := b[PrefixValueLen+lLen:]
  470. return l, r
  471. }
  472. func getPath(numLevels int, k []byte) []bool {
  473. path := make([]bool, numLevels)
  474. for n := 0; n < numLevels; n++ {
  475. path[n] = k[n/8]&(1<<(n%8)) != 0
  476. }
  477. return path
  478. }
  479. // Update updates the value for a given existing key. If the given key does not
  480. // exist, returns an error.
  481. func (t *Tree) Update(k, v []byte) error {
  482. wTx := t.db.WriteTx()
  483. defer wTx.Discard()
  484. if err := t.UpdateWithTx(wTx, k, v); err != nil {
  485. return err
  486. }
  487. return wTx.Commit()
  488. }
  489. // UpdateWithTx does the same than the Update method, but allowing to pass the
  490. // db.WriteTx that is used. The db.WriteTx will not be committed inside this
  491. // method.
  492. func (t *Tree) UpdateWithTx(wTx db.WriteTx, k, v []byte) error {
  493. t.Lock()
  494. defer t.Unlock()
  495. if !t.editable() {
  496. return ErrSnapshotNotEditable
  497. }
  498. var err error
  499. keyPath := make([]byte, t.hashFunction.Len())
  500. copy(keyPath[:], k)
  501. path := getPath(t.maxLevels, keyPath)
  502. root, err := t.RootWithTx(wTx)
  503. if err != nil {
  504. return err
  505. }
  506. var siblings [][]byte
  507. _, valueAtBottom, siblings, err := t.down(wTx, k, root, siblings, path, 0, true)
  508. if err != nil {
  509. return err
  510. }
  511. oldKey, _ := ReadLeafValue(valueAtBottom)
  512. if !bytes.Equal(oldKey, k) {
  513. return ErrKeyNotFound
  514. }
  515. leafKey, leafValue, err := t.newLeafValue(k, v)
  516. if err != nil {
  517. return err
  518. }
  519. if err := wTx.Set(leafKey, leafValue); err != nil {
  520. return err
  521. }
  522. // go up to the root
  523. if len(siblings) == 0 {
  524. return t.setRoot(wTx, leafKey)
  525. }
  526. root, err = t.up(wTx, leafKey, siblings, path, len(siblings)-1, 0)
  527. if err != nil {
  528. return err
  529. }
  530. // store root to db
  531. if err := t.setRoot(wTx, root); err != nil {
  532. return err
  533. }
  534. return nil
  535. }
  536. // GenProof generates a MerkleTree proof for the given key. The leaf value is
  537. // returned, together with the packed siblings of the proof, and a boolean
  538. // parameter that indicates if the proof is of existence (true) or not (false).
  539. func (t *Tree) GenProof(k []byte) ([]byte, []byte, []byte, bool, error) {
  540. rTx := t.db.ReadTx()
  541. defer rTx.Discard()
  542. return t.GenProofWithTx(rTx, k)
  543. }
  544. // GenProofWithTx does the same than the GenProof method, but allowing to pass
  545. // the db.ReadTx that is used.
  546. func (t *Tree) GenProofWithTx(rTx db.ReadTx, k []byte) ([]byte, []byte, []byte, bool, error) {
  547. keyPath := make([]byte, t.hashFunction.Len())
  548. copy(keyPath[:], k)
  549. root, err := t.RootWithTx(rTx)
  550. if err != nil {
  551. return nil, nil, nil, false, err
  552. }
  553. path := getPath(t.maxLevels, keyPath)
  554. // go down to the leaf
  555. var siblings [][]byte
  556. _, value, siblings, err := t.down(rTx, k, root, siblings, path, 0, true)
  557. if err != nil {
  558. return nil, nil, nil, false, err
  559. }
  560. s := PackSiblings(t.hashFunction, siblings)
  561. leafK, leafV := ReadLeafValue(value)
  562. if !bytes.Equal(k, leafK) {
  563. // key not in tree, proof of non-existence
  564. return leafK, leafV, s, false, nil
  565. }
  566. return leafK, leafV, s, true, nil
  567. }
  568. // PackSiblings packs the siblings into a byte array.
  569. // [ 2 byte | 2 byte | L bytes | S * N bytes ]
  570. // [ full length | bitmap length (L) | bitmap | N non-zero siblings ]
  571. // Where the bitmap indicates if the sibling is 0 or a value from the siblings
  572. // array. And S is the size of the output of the hash function used for the
  573. // Tree. The 2 2-byte that define the full length and bitmap length, are
  574. // encoded in little-endian.
  575. func PackSiblings(hashFunc HashFunction, siblings [][]byte) []byte {
  576. var b []byte
  577. var bitmap []bool
  578. emptySibling := make([]byte, hashFunc.Len())
  579. for i := 0; i < len(siblings); i++ {
  580. if bytes.Equal(siblings[i], emptySibling) {
  581. bitmap = append(bitmap, false)
  582. } else {
  583. bitmap = append(bitmap, true)
  584. b = append(b, siblings[i]...)
  585. }
  586. }
  587. bitmapBytes := bitmapToBytes(bitmap)
  588. l := len(bitmapBytes)
  589. fullLen := 4 + l + len(b) //nolint:gomnd
  590. res := make([]byte, fullLen)
  591. binary.LittleEndian.PutUint16(res[0:2], uint16(fullLen)) // set full length
  592. binary.LittleEndian.PutUint16(res[2:4], uint16(l)) // set the bitmapBytes length
  593. copy(res[4:4+l], bitmapBytes)
  594. copy(res[4+l:], b)
  595. return res
  596. }
  597. // UnpackSiblings unpacks the siblings from a byte array.
  598. func UnpackSiblings(hashFunc HashFunction, b []byte) ([][]byte, error) {
  599. fullLen := binary.LittleEndian.Uint16(b[0:2])
  600. l := binary.LittleEndian.Uint16(b[2:4]) // bitmap bytes length
  601. if len(b) != int(fullLen) {
  602. return nil,
  603. fmt.Errorf("error unpacking siblings. Expected len: %d, current len: %d",
  604. fullLen, len(b))
  605. }
  606. bitmapBytes := b[4 : 4+l]
  607. bitmap := bytesToBitmap(bitmapBytes)
  608. siblingsBytes := b[4+l:]
  609. iSibl := 0
  610. emptySibl := make([]byte, hashFunc.Len())
  611. var siblings [][]byte
  612. for i := 0; i < len(bitmap); i++ {
  613. if iSibl >= len(siblingsBytes) {
  614. break
  615. }
  616. if bitmap[i] {
  617. siblings = append(siblings, siblingsBytes[iSibl:iSibl+hashFunc.Len()])
  618. iSibl += hashFunc.Len()
  619. } else {
  620. siblings = append(siblings, emptySibl)
  621. }
  622. }
  623. return siblings, nil
  624. }
  625. func bitmapToBytes(bitmap []bool) []byte {
  626. bitmapBytesLen := int(math.Ceil(float64(len(bitmap)) / 8)) //nolint:gomnd
  627. b := make([]byte, bitmapBytesLen)
  628. for i := 0; i < len(bitmap); i++ {
  629. if bitmap[i] {
  630. b[i/8] |= 1 << (i % 8)
  631. }
  632. }
  633. return b
  634. }
  635. func bytesToBitmap(b []byte) []bool {
  636. var bitmap []bool
  637. for i := 0; i < len(b); i++ {
  638. for j := 0; j < 8; j++ {
  639. bitmap = append(bitmap, b[i]&(1<<j) > 0)
  640. }
  641. }
  642. return bitmap
  643. }
  644. // Get returns the value in the Tree for a given key. If the key is not found,
  645. // will return the error ErrKeyNotFound, and in the leafK & leafV parameters
  646. // will be placed the data found in the tree in the leaf that was on the path
  647. // going to the input key.
  648. func (t *Tree) Get(k []byte) ([]byte, []byte, error) {
  649. rTx := t.db.ReadTx()
  650. defer rTx.Discard()
  651. return t.GetWithTx(rTx, k)
  652. }
  653. // GetWithTx does the same than the Get method, but allowing to pass the
  654. // db.ReadTx that is used. If the key is not found, will return the error
  655. // ErrKeyNotFound, and in the leafK & leafV parameters will be placed the data
  656. // found in the tree in the leaf that was on the path going to the input key.
  657. func (t *Tree) GetWithTx(rTx db.ReadTx, k []byte) ([]byte, []byte, error) {
  658. keyPath := make([]byte, t.hashFunction.Len())
  659. copy(keyPath[:], k)
  660. root, err := t.RootWithTx(rTx)
  661. if err != nil {
  662. return nil, nil, err
  663. }
  664. path := getPath(t.maxLevels, keyPath)
  665. // go down to the leaf
  666. var siblings [][]byte
  667. _, value, _, err := t.down(rTx, k, root, siblings, path, 0, true)
  668. if err != nil {
  669. return nil, nil, err
  670. }
  671. leafK, leafV := ReadLeafValue(value)
  672. if !bytes.Equal(k, leafK) {
  673. return leafK, leafV, ErrKeyNotFound
  674. }
  675. return leafK, leafV, nil
  676. }
  677. // CheckProof verifies the given proof. The proof verification depends on the
  678. // HashFunction passed as parameter.
  679. func CheckProof(hashFunc HashFunction, k, v, root, packedSiblings []byte) (bool, error) {
  680. siblings, err := UnpackSiblings(hashFunc, packedSiblings)
  681. if err != nil {
  682. return false, err
  683. }
  684. keyPath := make([]byte, hashFunc.Len())
  685. copy(keyPath[:], k)
  686. key, _, err := newLeafValue(hashFunc, k, v)
  687. if err != nil {
  688. return false, err
  689. }
  690. path := getPath(len(siblings), keyPath)
  691. for i := len(siblings) - 1; i >= 0; i-- {
  692. if path[i] {
  693. key, _, err = newIntermediate(hashFunc, siblings[i], key)
  694. if err != nil {
  695. return false, err
  696. }
  697. } else {
  698. key, _, err = newIntermediate(hashFunc, key, siblings[i])
  699. if err != nil {
  700. return false, err
  701. }
  702. }
  703. }
  704. if bytes.Equal(key[:], root) {
  705. return true, nil
  706. }
  707. return false, nil
  708. }
  709. func (t *Tree) incNLeafs(wTx db.WriteTx, nLeafs int) error {
  710. oldNLeafs, err := t.GetNLeafsWithTx(wTx)
  711. if err != nil {
  712. return err
  713. }
  714. newNLeafs := oldNLeafs + nLeafs
  715. return t.setNLeafs(wTx, newNLeafs)
  716. }
  717. func (t *Tree) setNLeafs(wTx db.WriteTx, nLeafs int) error {
  718. b := make([]byte, 8)
  719. binary.LittleEndian.PutUint64(b, uint64(nLeafs))
  720. if err := wTx.Set(dbKeyNLeafs, b); err != nil {
  721. return err
  722. }
  723. return nil
  724. }
  725. // GetNLeafs returns the number of Leafs of the Tree.
  726. func (t *Tree) GetNLeafs() (int, error) {
  727. rTx := t.db.ReadTx()
  728. defer rTx.Discard()
  729. return t.GetNLeafsWithTx(rTx)
  730. }
  731. // GetNLeafsWithTx does the same than the GetNLeafs method, but allowing to
  732. // pass the db.ReadTx that is used.
  733. func (t *Tree) GetNLeafsWithTx(rTx db.ReadTx) (int, error) {
  734. b, err := rTx.Get(dbKeyNLeafs)
  735. if err != nil {
  736. return 0, err
  737. }
  738. nLeafs := binary.LittleEndian.Uint64(b)
  739. return int(nLeafs), nil
  740. }
  741. // SetRoot sets the root to the given root
  742. func (t *Tree) SetRoot(root []byte) error {
  743. wTx := t.db.WriteTx()
  744. defer wTx.Discard()
  745. if err := t.SetRootWithTx(wTx, root); err != nil {
  746. return err
  747. }
  748. return wTx.Commit()
  749. }
  750. // SetRootWithTx sets the root to the given root using the given db.WriteTx
  751. func (t *Tree) SetRootWithTx(wTx db.WriteTx, root []byte) error {
  752. if !t.editable() {
  753. return ErrSnapshotNotEditable
  754. }
  755. if root == nil {
  756. return fmt.Errorf("can not SetRoot with nil root")
  757. }
  758. // check that the root exists in the db
  759. if !bytes.Equal(root, t.emptyHash) {
  760. if _, err := wTx.Get(root); err == ErrKeyNotFound {
  761. return fmt.Errorf("can not SetRoot with root %x, as it does not exist in the db", root)
  762. } else if err != nil {
  763. return err
  764. }
  765. }
  766. return wTx.Set(dbKeyRoot, root)
  767. }
  768. // Snapshot returns a read-only copy of the Tree from the given root
  769. func (t *Tree) Snapshot(fromRoot []byte) (*Tree, error) {
  770. // allow to define which root to use
  771. if fromRoot == nil {
  772. var err error
  773. fromRoot, err = t.Root()
  774. if err != nil {
  775. return nil, err
  776. }
  777. }
  778. rTx := t.db.ReadTx()
  779. defer rTx.Discard()
  780. // check that the root exists in the db
  781. if !bytes.Equal(fromRoot, t.emptyHash) {
  782. if _, err := rTx.Get(fromRoot); err == ErrKeyNotFound {
  783. return nil,
  784. fmt.Errorf("can not do a Snapshot with root %x, as it does not exist in the db",
  785. fromRoot)
  786. } else if err != nil {
  787. return nil, err
  788. }
  789. }
  790. return &Tree{
  791. db: t.db,
  792. maxLevels: t.maxLevels,
  793. snapshotRoot: fromRoot,
  794. emptyHash: t.emptyHash,
  795. hashFunction: t.hashFunction,
  796. dbg: t.dbg,
  797. }, nil
  798. }
  799. // Iterate iterates through the full Tree, executing the given function on each
  800. // node of the Tree.
  801. func (t *Tree) Iterate(fromRoot []byte, f func([]byte, []byte)) error {
  802. rTx := t.db.ReadTx()
  803. defer rTx.Discard()
  804. return t.IterateWithTx(rTx, fromRoot, f)
  805. }
  806. // IterateWithTx does the same than the Iterate method, but allowing to pass
  807. // the db.ReadTx that is used.
  808. func (t *Tree) IterateWithTx(rTx db.ReadTx, fromRoot []byte, f func([]byte, []byte)) error {
  809. // allow to define which root to use
  810. if fromRoot == nil {
  811. var err error
  812. fromRoot, err = t.RootWithTx(rTx)
  813. if err != nil {
  814. return err
  815. }
  816. }
  817. return t.iter(rTx, fromRoot, f)
  818. }
  819. // IterateWithStop does the same than Iterate, but with int for the current
  820. // level, and a boolean parameter used by the passed function, is to indicate to
  821. // stop iterating on the branch when the method returns 'true'.
  822. func (t *Tree) IterateWithStop(fromRoot []byte, f func(int, []byte, []byte) bool) error {
  823. rTx := t.db.ReadTx()
  824. defer rTx.Discard()
  825. // allow to define which root to use
  826. if fromRoot == nil {
  827. var err error
  828. fromRoot, err = t.RootWithTx(rTx)
  829. if err != nil {
  830. return err
  831. }
  832. }
  833. return t.iterWithStop(rTx, fromRoot, 0, f)
  834. }
  835. // IterateWithStopWithTx does the same than the IterateWithStop method, but
  836. // allowing to pass the db.ReadTx that is used.
  837. func (t *Tree) IterateWithStopWithTx(rTx db.ReadTx, fromRoot []byte,
  838. f func(int, []byte, []byte) bool) error {
  839. // allow to define which root to use
  840. if fromRoot == nil {
  841. var err error
  842. fromRoot, err = t.RootWithTx(rTx)
  843. if err != nil {
  844. return err
  845. }
  846. }
  847. return t.iterWithStop(rTx, fromRoot, 0, f)
  848. }
  849. func (t *Tree) iterWithStop(rTx db.ReadTx, k []byte, currLevel int,
  850. f func(int, []byte, []byte) bool) error {
  851. var v []byte
  852. var err error
  853. if bytes.Equal(k, t.emptyHash) {
  854. v = t.emptyHash
  855. } else {
  856. v, err = rTx.Get(k)
  857. if err != nil {
  858. return err
  859. }
  860. }
  861. currLevel++
  862. switch v[0] {
  863. case PrefixValueEmpty:
  864. f(currLevel, k, v)
  865. case PrefixValueLeaf:
  866. f(currLevel, k, v)
  867. case PrefixValueIntermediate:
  868. stop := f(currLevel, k, v)
  869. if stop {
  870. return nil
  871. }
  872. l, r := ReadIntermediateChilds(v)
  873. if err = t.iterWithStop(rTx, l, currLevel, f); err != nil {
  874. return err
  875. }
  876. if err = t.iterWithStop(rTx, r, currLevel, f); err != nil {
  877. return err
  878. }
  879. default:
  880. return ErrInvalidValuePrefix
  881. }
  882. return nil
  883. }
  884. func (t *Tree) iter(rTx db.ReadTx, k []byte, f func([]byte, []byte)) error {
  885. f2 := func(currLvl int, k, v []byte) bool {
  886. f(k, v)
  887. return false
  888. }
  889. return t.iterWithStop(rTx, k, 0, f2)
  890. }
  891. // Dump exports all the Tree leafs in a byte array of length:
  892. // [ N * (2+len(k+v)) ]. Where N is the number of key-values, and for each k+v:
  893. // [ 1 byte | 1 byte | S bytes | len(v) bytes ]
  894. // [ len(k) | len(v) | key | value ]
  895. // Where S is the size of the output of the hash function used for the Tree.
  896. func (t *Tree) Dump(fromRoot []byte) ([]byte, error) {
  897. // allow to define which root to use
  898. if fromRoot == nil {
  899. var err error
  900. fromRoot, err = t.Root()
  901. if err != nil {
  902. return nil, err
  903. }
  904. }
  905. // WARNING current encoding only supports key & values of 255 bytes each
  906. // (due using only 1 byte for the length headers).
  907. var b []byte
  908. err := t.Iterate(fromRoot, func(k, v []byte) {
  909. if v[0] != PrefixValueLeaf {
  910. return
  911. }
  912. leafK, leafV := ReadLeafValue(v)
  913. kv := make([]byte, 2+len(leafK)+len(leafV))
  914. kv[0] = byte(len(leafK))
  915. kv[1] = byte(len(leafV))
  916. copy(kv[2:2+len(leafK)], leafK)
  917. copy(kv[2+len(leafK):], leafV)
  918. b = append(b, kv...)
  919. })
  920. return b, err
  921. }
  922. // ImportDump imports the leafs (that have been exported with the Dump method)
  923. // in the Tree.
  924. func (t *Tree) ImportDump(b []byte) error {
  925. if !t.editable() {
  926. return ErrSnapshotNotEditable
  927. }
  928. root, err := t.Root()
  929. if err != nil {
  930. return err
  931. }
  932. if !bytes.Equal(root, t.emptyHash) {
  933. return ErrTreeNotEmpty
  934. }
  935. r := bytes.NewReader(b)
  936. var keys, values [][]byte
  937. for {
  938. l := make([]byte, 2)
  939. _, err = io.ReadFull(r, l)
  940. if err == io.EOF {
  941. break
  942. } else if err != nil {
  943. return err
  944. }
  945. k := make([]byte, l[0])
  946. _, err = io.ReadFull(r, k)
  947. if err != nil {
  948. return err
  949. }
  950. v := make([]byte, l[1])
  951. _, err = io.ReadFull(r, v)
  952. if err != nil {
  953. return err
  954. }
  955. keys = append(keys, k)
  956. values = append(values, v)
  957. }
  958. if _, err = t.AddBatch(keys, values); err != nil {
  959. return err
  960. }
  961. return nil
  962. }
  963. // Graphviz iterates across the full tree to generate a string Graphviz
  964. // representation of the tree and writes it to w
  965. func (t *Tree) Graphviz(w io.Writer, fromRoot []byte) error {
  966. return t.GraphvizFirstNLevels(w, fromRoot, t.maxLevels)
  967. }
  968. // GraphvizFirstNLevels iterates across the first NLevels of the tree to
  969. // generate a string Graphviz representation of the first NLevels of the tree
  970. // and writes it to w
  971. func (t *Tree) GraphvizFirstNLevels(w io.Writer, fromRoot []byte, untilLvl int) error {
  972. fmt.Fprintf(w, `digraph hierarchy {
  973. node [fontname=Monospace,fontsize=10,shape=box]
  974. `)
  975. rTx := t.db.ReadTx()
  976. defer rTx.Discard()
  977. if fromRoot == nil {
  978. var err error
  979. fromRoot, err = t.RootWithTx(rTx)
  980. if err != nil {
  981. return err
  982. }
  983. }
  984. nEmpties := 0
  985. err := t.iterWithStop(rTx, fromRoot, 0, func(currLvl int, k, v []byte) bool {
  986. if currLvl == untilLvl {
  987. return true // to stop the iter from going down
  988. }
  989. switch v[0] {
  990. case PrefixValueEmpty:
  991. case PrefixValueLeaf:
  992. fmt.Fprintf(w, "\"%v\" [style=filled];\n", hex.EncodeToString(k[:nChars]))
  993. // key & value from the leaf
  994. kB, vB := ReadLeafValue(v)
  995. fmt.Fprintf(w, "\"%v\" -> {\"k:%v\\nv:%v\"}\n",
  996. hex.EncodeToString(k[:nChars]), hex.EncodeToString(kB[:nChars]),
  997. hex.EncodeToString(vB[:nChars]))
  998. fmt.Fprintf(w, "\"k:%v\\nv:%v\" [style=dashed]\n",
  999. hex.EncodeToString(kB[:nChars]), hex.EncodeToString(vB[:nChars]))
  1000. case PrefixValueIntermediate:
  1001. l, r := ReadIntermediateChilds(v)
  1002. lStr := hex.EncodeToString(l[:nChars])
  1003. rStr := hex.EncodeToString(r[:nChars])
  1004. eStr := ""
  1005. if bytes.Equal(l, t.emptyHash) {
  1006. lStr = fmt.Sprintf("empty%v", nEmpties)
  1007. eStr += fmt.Sprintf("\"%v\" [style=dashed,label=0];\n",
  1008. lStr)
  1009. nEmpties++
  1010. }
  1011. if bytes.Equal(r, t.emptyHash) {
  1012. rStr = fmt.Sprintf("empty%v", nEmpties)
  1013. eStr += fmt.Sprintf("\"%v\" [style=dashed,label=0];\n",
  1014. rStr)
  1015. nEmpties++
  1016. }
  1017. fmt.Fprintf(w, "\"%v\" -> {\"%v\" \"%v\"}\n", hex.EncodeToString(k[:nChars]),
  1018. lStr, rStr)
  1019. fmt.Fprint(w, eStr)
  1020. default:
  1021. }
  1022. return false
  1023. })
  1024. fmt.Fprintf(w, "}\n")
  1025. return err
  1026. }
  1027. // PrintGraphviz prints the output of Tree.Graphviz
  1028. func (t *Tree) PrintGraphviz(fromRoot []byte) error {
  1029. if fromRoot == nil {
  1030. var err error
  1031. fromRoot, err = t.Root()
  1032. if err != nil {
  1033. return err
  1034. }
  1035. }
  1036. return t.PrintGraphvizFirstNLevels(fromRoot, t.maxLevels)
  1037. }
  1038. // PrintGraphvizFirstNLevels prints the output of Tree.GraphvizFirstNLevels
  1039. func (t *Tree) PrintGraphvizFirstNLevels(fromRoot []byte, untilLvl int) error {
  1040. if fromRoot == nil {
  1041. var err error
  1042. fromRoot, err = t.Root()
  1043. if err != nil {
  1044. return err
  1045. }
  1046. }
  1047. w := bytes.NewBufferString("")
  1048. fmt.Fprintf(w,
  1049. "--------\nGraphviz of the Tree with Root "+hex.EncodeToString(fromRoot)+":\n")
  1050. err := t.GraphvizFirstNLevels(w, fromRoot, untilLvl)
  1051. if err != nil {
  1052. fmt.Println(w)
  1053. return err
  1054. }
  1055. fmt.Fprintf(w,
  1056. "End of Graphviz of the Tree with Root "+hex.EncodeToString(fromRoot)+"\n--------\n")
  1057. fmt.Println(w)
  1058. return nil
  1059. }
  1060. // TODO circom proofs
  1061. // TODO data structure for proofs (including root, key, value, siblings,
  1062. // hashFunction) + method to verify that data structure