arnaucube
arnaucube/circomlibPublic Self-hosted repository
circomlib/test/smtjs.js
test/smtjs.jsRaw
  1const chai = require("chai");
  2const snarkjs = require("snarkjs");
  3
  4const smt = require("../src/smt.js");
  5
  6const assert = chai.assert;
  7
  8const bigInt = snarkjs.bigInt;
  9
 10
 11function stringifyBigInts(o) {
 12    if ((typeof(o) == "bigint") || (o instanceof bigInt))  {
 13        return o.toString(10);
 14    } else if (Array.isArray(o)) {
 15        return o.map(stringifyBigInts);
 16    } else if (typeof o == "object") {
 17        const res = {};
 18        for (let k in o) {
 19            res[k] = stringifyBigInts(o[k]);
 20        }
 21        return res;
 22    } else {
 23        return o;
 24    }
 25}
 26
 27describe("SMT Javascript test", function () {
 28    this.timeout(100000);
 29    before( async () => {
 30    });
 31
 32    it("Should insert 2 elements and empty them", async () => {
 33        const tree = await smt.newMemEmptyTrie();
 34        const key1 = bigInt(111);
 35        const value1 = bigInt(222);
 36        const key2 = bigInt(333);
 37        const value2 = bigInt(444);
 38
 39        await tree.insert(key1,value1);
 40        await tree.insert(key2,value2);
 41        await tree.delete(key2);
 42        await tree.delete(key1);
 43
 44        assert(tree.root.isZero());
 45    });
 46
 47    it("Should insert 3 elements in dferent order and should be the same", async () => {
 48        const keys = [bigInt(8), bigInt(9), bigInt(32)];
 49        const values = [bigInt(88), bigInt(99), bigInt(3232)];
 50        const tree1 = await smt.newMemEmptyTrie();
 51        const tree2 = await smt.newMemEmptyTrie();
 52        const tree3 = await smt.newMemEmptyTrie();
 53        const tree4 = await smt.newMemEmptyTrie();
 54        const tree5 = await smt.newMemEmptyTrie();
 55        const tree6 = await smt.newMemEmptyTrie();
 56
 57        await tree1.insert(keys[0],values[0]);
 58        await tree1.insert(keys[1],values[1]);
 59        await tree1.insert(keys[2],values[2]);
 60
 61        await tree2.insert(keys[0],values[0]);
 62        await tree2.insert(keys[2],values[2]);
 63        await tree2.insert(keys[1],values[1]);
 64
 65        await tree3.insert(keys[1],values[1]);
 66        await tree3.insert(keys[0],values[0]);
 67        await tree3.insert(keys[2],values[2]);
 68
 69        await tree4.insert(keys[1],values[1]);
 70        await tree4.insert(keys[2],values[2]);
 71        await tree4.insert(keys[0],values[0]);
 72
 73        await tree5.insert(keys[2],values[2]);
 74        await tree5.insert(keys[0],values[0]);
 75        await tree5.insert(keys[1],values[1]);
 76
 77        await tree6.insert(keys[2],values[2]);
 78        await tree6.insert(keys[1],values[1]);
 79        await tree6.insert(keys[0],values[0]);
 80
 81        assert(tree1.root.equals(tree2.root));
 82        assert(tree2.root.equals(tree3.root));
 83        assert(tree3.root.equals(tree4.root));
 84        assert(tree4.root.equals(tree5.root));
 85        assert(tree5.root.equals(tree6.root));
 86
 87        assert.equal(Object.keys(tree1.db.nodes).length,  Object.keys(tree2.db.nodes).length);
 88        assert.equal(Object.keys(tree2.db.nodes).length,  Object.keys(tree3.db.nodes).length);
 89        assert.equal(Object.keys(tree3.db.nodes).length,  Object.keys(tree4.db.nodes).length);
 90        assert.equal(Object.keys(tree4.db.nodes).length,  Object.keys(tree5.db.nodes).length);
 91        assert.equal(Object.keys(tree5.db.nodes).length,  Object.keys(tree6.db.nodes).length);
 92
 93        await tree1.delete(keys[0]);
 94        await tree1.delete(keys[1]);
 95        await tree2.delete(keys[1]);
 96        await tree2.delete(keys[0]);
 97        assert(tree1.root.equals(tree2.root));
 98
 99        await tree3.delete(keys[0]);
100        await tree3.delete(keys[2]);
101        await tree4.delete(keys[2]);
102        await tree4.delete(keys[0]);
103        assert(tree3.root.equals(tree4.root));
104
105        await tree5.delete(keys[1]);
106        await tree5.delete(keys[2]);
107        await tree6.delete(keys[2]);
108        await tree6.delete(keys[1]);
109        assert(tree5.root.equals(tree6.root));
110
111        await tree1.delete(keys[2]);
112        await tree2.delete(keys[2]);
113        await tree3.delete(keys[1]);
114        await tree4.delete(keys[1]);
115        await tree5.delete(keys[0]);
116        await tree6.delete(keys[0]);
117
118        assert(tree1.root.isZero());
119        assert(tree2.root.isZero());
120        assert(tree3.root.isZero());
121        assert(tree4.root.isZero());
122        assert(tree5.root.isZero());
123        assert(tree6.root.isZero());
124
125        assert.equal(Object.keys(tree1.db.nodes).length, 0);
126        assert.equal(Object.keys(tree2.db.nodes).length, 0);
127        assert.equal(Object.keys(tree3.db.nodes).length, 0);
128        assert.equal(Object.keys(tree4.db.nodes).length, 0);
129        assert.equal(Object.keys(tree5.db.nodes).length, 0);
130        assert.equal(Object.keys(tree6.db.nodes).length, 0);
131    });
132
133    it("Insert and remove 100 numbers randomly", async () => {
134        function perm(a) {
135            const arr = a.slice();
136            const rArr = [];
137            for (let i=0; i<arr.length; i++) {
138                let rIdx = Math.floor(Math.random() * (arr.length - i));
139                rArr.push(arr[rIdx]);
140                arr[rIdx] = arr[arr.length - i - 1];
141            }
142            return rArr;
143        }
144        const tree = await smt.newMemEmptyTrie();
145        const arr = [];
146        const N = 100;
147        for (let i=0; i<N; i++) {
148            arr.push(bigInt(i));
149        }
150        const insArr = perm(arr);
151        for (let i=0; i<N; i++) {
152            await tree.insert(insArr[i], i);
153        }
154        const delArr = perm(insArr);
155        for (let i=0; i<N; i++) {
156            await tree.delete(delArr[i]);
157        }
158
159        assert(tree.root.isZero());
160        assert.equal(Object.keys(tree.db.nodes).length, 0);
161    });
162
163});