batch merkle tree creation

This commit is contained in:
Alexey 2019-07-11 17:04:36 +03:00
parent 65fd0202c5
commit ea51af1512
3 changed files with 77 additions and 12 deletions

View File

@ -91,6 +91,51 @@ contract('MerkleTreeWithHistory', async accounts => {
// console.log(root)
assert.equal(root, calculated_root)
})
it('creation odd elements count', async () => {
const elements = [12, 13, 14, 15, 16, 17, 18, 19, 20]
for(const [i, el] of Object.entries(elements)) {
await tree.update(i, el)
}
const storage = new JsStorage()
hasher = new MimcHacher()
const batchTree = new MerkleTree(
prefix,
storage,
hasher,
levels,
zeroValue,
elements
);
for(const [i, el] of Object.entries(elements)) {
const pathViaConstructor = await batchTree.path(i)
const pathViaUpdate = await tree.path(i)
pathViaConstructor.should.be.deep.equal(pathViaUpdate)
}
})
it('creation even elements count', async () => {
const elements = [12, 13, 14, 15, 16, 17]
for(const [i, el] of Object.entries(elements)) {
await tree.update(i, el)
}
const storage = new JsStorage()
hasher = new MimcHacher()
const batchTree = new MerkleTree(
prefix,
storage,
hasher,
levels,
zeroValue,
elements
);
for(const [i, el] of Object.entries(elements)) {
const pathViaConstructor = await batchTree.path(i)
const pathViaUpdate = await tree.path(i)
pathViaConstructor.should.be.deep.equal(pathViaUpdate)
}
})
})
describe('#insert', async () => {

View File

@ -1,9 +1,7 @@
// const AwaitLock = require('await-lock');
class MerkleTree {
constructor(prefix, storage, hasher, n_levels, zero_value) {
constructor(prefix, storage, hasher, n_levels, zero_value, defaultElements) {
this.prefix = prefix;
this.storage = storage;
this.hasher = hasher;
@ -18,7 +16,28 @@ class MerkleTree {
current_zero_value.toString(),
);
}
// this.lock = new AwaitLock();
if (defaultElements) {
let level = 0
defaultElements.forEach((element, i) => {
this.storage.put(MerkleTree.element_to_key(prefix, element), i.toString())
this.storage.put(MerkleTree.index_to_key(prefix, level, i), element)
})
level++
let numberOfElementInRow = Math.ceil(defaultElements.length / 2)
for (level; level <= this.n_levels; level++) {
for(let i = 0; i < numberOfElementInRow; i++) {
const leftKey = MerkleTree.index_to_key(prefix, level - 1, 2 * i)
const rightKey = MerkleTree.index_to_key(prefix, level - 1, 2 * i + 1)
const left = this.storage.get(leftKey)
const right = this.storage.get_or_element(rightKey, this.zero_values[level - 1])
const subRoot = this.hasher.hash(null, left, right);
this.storage.put(MerkleTree.index_to_key(prefix, level, i), subRoot)
}
numberOfElementInRow = Math.max(Math.ceil(numberOfElementInRow / 2), 1)
}
}
}
static index_to_key(prefix, level, index) {
@ -121,7 +140,6 @@ class MerkleTree {
}
async update(index, element, update_log_index) {
// await this.lock.acquireAsync();
try {
//console.log(`updating ${index}, ${element}`);
class UpdateTraverser {
@ -198,8 +216,8 @@ class MerkleTree {
const root = await this.root();
//console.log(`updated root ${root}`);
} finally {
// this.lock.release();
} catch(e) {
console.error(e)
}
}
@ -218,7 +236,6 @@ class MerkleTree {
}
async rollback(updates) {
// await this.lock.acquireAsync();
try {
const update_log_key = MerkleTree.update_log_to_key(this.prefix);
const update_log_index = await this.storage.get(update_log_key);
@ -228,8 +245,8 @@ class MerkleTree {
await this.update(update_element_log.index, update_element_log.old_element, update_log_index - i - 1);
}
} finally {
// this.lock.release();
} catch (e) {
console.error(e)
}
}
@ -252,8 +269,8 @@ class MerkleTree {
if (await this.root() != root) {
throw new Error(`could not rollback to root ${root}`);
}
} finally {
// this.lock.release();
} catch (e) {
console.log(e)
}
}

View File

@ -19,6 +19,9 @@ class JsStorage {
}
put(key, value) {
if (key === undefined || value === undefined) {
throw Error('key or value is undefined')
}
this.db[key] = value;
}