merkle-tree
Version:
A Merkle Tree skeleton, written in IcedCoffeeScript
958 lines (908 loc) • 32.6 kB
JavaScript
// Generated by IcedCoffeeScript 108.0.11
(function() {
var Base, Config, JSS, Lock, SortedMap, chain_err, deq, format_hex, hex_cmp, hex_len, iced, is_hex, iutils, json_stringify_sorted, log_16, make_esc, map, my_cmp, node_types, strcmp, __iced_k, __iced_k_noop, _ref;
iced = require('iced-runtime');
__iced_k = __iced_k_noop = function() {};
iutils = require('iced-utils');
Lock = iutils.lock.Lock;
json_stringify_sorted = iutils.util.json_stringify_sorted;
_ref = require('iced-error'), chain_err = _ref.chain_err, make_esc = _ref.make_esc;
deq = require('deep-equal');
exports.node_types = node_types = {
NONE: 0,
INODE: 1,
LEAF: 2
};
log_16 = function(y) {
var ret;
ret = 0;
while (y > 1) {
y = y >> 4;
ret++;
}
return ret;
};
JSS = function(x) {
var inner, pr;
inner = function(y) {
return json_stringify_sorted(y, {
sort_fn: hex_cmp
});
};
pr = x.prev_root != null ? '"prev_root":"' + x.prev_root + '",' : "";
return "{" + pr + "\"tab\":" + (inner(x.tab)) + ",\"type\":" + (inner(x.type)) + "}";
};
format_hex = function(i, len) {
var buf;
buf = Buffer.alloc(4);
buf.writeUInt32BE(i, 0);
return buf.toString('hex').slice(8 - len);
};
hex_len = function(a) {
var c, ret, _i, _len;
ret = a.length;
for (_i = 0, _len = a.length; _i < _len; _i++) {
c = a[_i];
if (c === '0') {
ret--;
} else {
break;
}
}
return ret;
};
map = {
0: 0,
1: 1,
2: 2,
3: 3,
4: 4,
5: 5,
6: 6,
7: 7,
8: 8,
9: 9,
a: 10,
b: 11,
c: 12,
d: 13,
e: 14,
f: 15
};
is_hex = function(x) {
return x.match(/^[a-fA-F0-9]+$/);
};
strcmp = function(x, y) {
if (x === y) {
return 0;
} else if (x < y) {
return -1;
} else {
return 1;
}
};
exports.my_cmp = my_cmp = function(a, b) {
if (is_hex(a) && is_hex(b)) {
return hex_cmp(a, b);
} else {
return strcmp(a, b);
}
};
exports.hex_cmp = hex_cmp = function(a, b) {
var a_len, b_len, c, d, i, ret, tmp;
a_len = hex_len(a);
b_len = hex_len(b);
ret = (function() {
var _i, _len;
if (a_len > b_len) {
return 1;
} else if (a_len < b_len) {
return -1;
} else {
tmp = 0;
for (i = _i = 0, _len = a.length; _i < _len; i = ++_i) {
c = a[i];
d = b[i];
if (map[c] > map[d]) {
tmp = 1;
} else if (map[c] < map[d]) {
tmp = -1;
}
if (tmp !== 0) {
break;
}
}
return tmp;
}
})();
return ret;
};
exports.SortedMap = SortedMap = (function() {
function SortedMap(_arg) {
var i, j, k, key, list, node, obj, sorted, sorted_list, v, val, _i, _ref1;
node = _arg.node, obj = _arg.obj, list = _arg.list, sorted_list = _arg.sorted_list, key = _arg.key, val = _arg.val;
if (node != null) {
obj = node.tab;
this._type = node.type;
}
if (obj != null) {
list = (function() {
var _results;
_results = [];
for (k in obj) {
v = obj[k];
_results.push([k, v]);
}
return _results;
})();
} else if (sorted_list != null) {
this._list = sorted_list;
}
if ((key != null) && (val != null)) {
this._list = [[key, val]];
}
if ((list != null) && (this._list == null)) {
sorted = true;
for (i = _i = 0, _ref1 = list.length; 0 <= _ref1 ? _i < _ref1 : _i > _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
j = i + 1;
if ((j < list.length) && (hex_cmp(list[i][0], list[j][0])) > 0) {
sorted = false;
break;
}
}
if (!sorted) {
list.sort(function(a, b) {
return hex_cmp(a[0], b[0]);
});
}
this._list = list;
}
if (this._list == null) {
this._list = [];
}
}
SortedMap.prototype.slice = function(a, b) {
return new SortedMap({
sorted_list: this._list.slice(a, b)
});
};
SortedMap.prototype.len = function() {
return this._list.length;
};
SortedMap.prototype.at = function(i) {
return this._list[i];
};
SortedMap.prototype.push = function(_arg) {
var key, val;
key = _arg.key, val = _arg.val;
return this._list.push([key, val]);
};
SortedMap.prototype.to_hash = function(_arg) {
var JS, hasher, k, key, level, obj, obj_s, parts, pr, prev_root, tab, tab_s, type, v, _i, _len, _ref1, _ref2;
hasher = _arg.hasher, type = _arg.type, prev_root = _arg.prev_root, level = _arg.level;
JS = JSON.stringify;
type || (type = this._type);
parts = [];
tab = {};
_ref1 = this._list;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
_ref2 = _ref1[_i], k = _ref2[0], v = _ref2[1];
parts.push([JS(k), JS(v)].join(":"));
tab[k] = v;
}
tab_s = "{" + parts.join(",") + "}";
pr = prev_root != null ? '"prev_root":"' + prev_root + '",' : "";
obj_s = "{" + pr + "\"tab\":" + tab_s + ",\"type\":" + type + "}";
obj = {};
if ((prev_root != null) && (level != null) && level === 0) {
obj.prev_root;
}
obj.tab = tab;
obj.type = type;
key = hasher(obj_s);
return {
key: key,
obj: obj,
obj_s: obj_s
};
};
SortedMap.prototype.binary_search = function(_arg) {
var beg, c, end, eq, key, mid, ret;
key = _arg.key;
beg = 0;
end = this._list.length - 1;
while (beg < end) {
mid = (end + beg) >> 1;
c = hex_cmp(key, this._list[mid][0]);
if (c > 0) {
beg = mid + 1;
} else {
end = mid;
}
}
c = hex_cmp(key, this._list[beg][0]);
eq = 0;
ret = c > 0 ? beg + 1 : c === 0 ? (eq = 1, beg) : beg;
return [ret, eq];
};
SortedMap.prototype.replace = function(_arg) {
var eq, index, key, val, _ref1;
key = _arg.key, val = _arg.val;
if (this._list.length) {
_ref1 = this.binary_search({
key: key
}), index = _ref1[0], eq = _ref1[1];
this._list = this._list.slice(0, index).concat([[key, val]]).concat(this._list.slice(index + eq));
} else {
this._list = [[key, val]];
}
return this;
};
return SortedMap;
})();
exports.Config = Config = (function() {
function Config(_arg) {
var M, N;
M = _arg.M, N = _arg.N;
this.M = M || 256;
this.N = N || 256;
this.C = log_16(this.M);
}
Config.prototype.obj_to_key = function(o) {
return o[0];
};
Config.prototype.prefix_at_level = function(_arg) {
var key, level, obj;
level = _arg.level, key = _arg.key, obj = _arg.obj;
key || (key = this.obj_to_key(obj));
return key.slice(level * this.C, (level + 1) * this.C);
};
Config.prototype.prefix_through_level = function(_arg) {
var key, level, obj;
level = _arg.level, key = _arg.key, obj = _arg.obj;
key || (key = this.obj_to_key(obj));
return key.slice(0, (level + 1) * this.C);
};
return Config;
})();
exports.Base = Base = (function() {
function Base(_arg) {
var config;
config = _arg.config;
this.config = config || (new Config({}));
this._lock = new Lock;
this.hasher = this.hash_fn.bind(this);
}
Base.prototype.unimplemented = function() {
return new Error("unimplemented");
};
Base.prototype.hash_fn = function(s) {
return cb(this.unimplemented());
};
Base.prototype.store_node = function(_arg, cb) {
var key, obj, obj_s;
key = _arg.key, obj = _arg.obj, obj_s = _arg.obj_s;
return cb(this.unimplemented());
};
Base.prototype.commit_root = function(_arg, cb) {
var key, prev_root, txinfo;
key = _arg.key, txinfo = _arg.txinfo, prev_root = _arg.prev_root;
return cb(this.unimplemented());
};
Base.prototype.lookup_node = function(_arg, cb) {
var key;
key = _arg.key;
return cb(this.unimplemented());
};
Base.prototype.lookup_root = function(_arg, cb) {
var txinfo;
txinfo = _arg.txinfo;
return cb(this.unimplemented());
};
Base.prototype.unlock = function(cb) {
this._lock.release();
return cb(null);
};
Base.prototype.upsert = function(_arg, cb) {
var curr, esc, h, key, last, level, nxt, obj, obj_s, p, path, prev_root, ret, root, sm, sorted_map, tmp, txinfo, v2, val, ___iced_passed_deferral, __iced_deferrals, __iced_k;
__iced_k = __iced_k_noop;
___iced_passed_deferral = iced.findDeferral(arguments);
key = _arg.key, val = _arg.val, txinfo = _arg.txinfo;
cb = chain_err(cb, this.unlock.bind(this));
esc = make_esc(cb, "upsert");
(function(_this) {
return (function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.upsert"
});
_this._lock.acquire(__iced_deferrals.defer({
lineno: 265
}));
__iced_deferrals._fulfill();
});
})(this)((function(_this) {
return function() {
(function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.upsert"
});
_this.lookup_root({
txinfo: txinfo
}, esc(__iced_deferrals.defer({
assign_fn: (function() {
return function() {
return root = arguments[0];
};
})(),
lineno: 268
})));
__iced_deferrals._fulfill();
})(function() {
prev_root = root;
curr = null;
(function(__iced_k) {
if (typeof root !== "undefined" && root !== null) {
(function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.upsert"
});
_this.lookup_node({
key: root
}, esc(__iced_deferrals.defer({
assign_fn: (function() {
return function() {
return curr = arguments[0];
};
})(),
lineno: 272
})));
__iced_deferrals._fulfill();
})(__iced_k);
} else {
return __iced_k();
}
})(function() {
last = null;
path = [];
level = 0;
(function(__iced_k) {
var _while;
_while = function(__iced_k) {
var _break, _continue, _next;
_break = __iced_k;
_continue = function() {
return iced.trampoline(function() {
return _while(__iced_k);
});
};
_next = _continue;
if (curr == null) {
return _break();
} else {
p = _this.config.prefix_through_level({
key: key,
level: level
});
path.push([p, curr, level++]);
last = curr;
(function(__iced_k) {
if ((nxt = curr.tab[p]) != null) {
(function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.upsert"
});
_this.lookup_node({
key: nxt
}, esc(__iced_deferrals.defer({
assign_fn: (function() {
return function() {
return curr = arguments[0];
};
})(),
lineno: 285
})));
__iced_deferrals._fulfill();
})(__iced_k);
} else {
return __iced_k(curr = null);
}
})(_next);
}
};
_while(__iced_k);
})(function() {
var _ref1;
ret = null;
_ref1 = (last == null) || (last.type === node_types.INODE) ? [
new SortedMap({
key: key,
val: val
}), 0
] : !((v2 = last.tab[key]) != null) || !(deq(val, v2)) ? [
(new SortedMap({
obj: last.tab
})).replace({
key: key,
val: val
}), path.length - 1
] : [null, 0], sorted_map = _ref1[0], level = _ref1[1];
(function(__iced_k) {
if (sorted_map != null) {
(function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.upsert"
});
_this.hash_tree_r({
level: level,
sorted_map: sorted_map,
prev_root: prev_root
}, esc(__iced_deferrals.defer({
assign_fn: (function() {
return function() {
return tmp = arguments[0];
};
})(),
lineno: 300
})));
__iced_deferrals._fulfill();
})(function() {
h = tmp;
path.reverse();
(function(__iced_k) {
var _i, _len, _ref2, _results, _while;
_ref2 = path;
_len = _ref2.length;
_i = 0;
_while = function(__iced_k) {
var _break, _continue, _next, _ref3, _ref4;
_break = __iced_k;
_continue = function() {
return iced.trampoline(function() {
++_i;
return _while(__iced_k);
});
};
_next = _continue;
if (!(_i < _len)) {
return _break();
} else {
_ref3 = _ref2[_i], p = _ref3[0], curr = _ref3[1], level = _ref3[2];
if (curr.type === node_types.INODE) {
sm = (new SortedMap({
node: curr
})).replace({
key: p,
val: h
});
_ref4 = sm.to_hash({
hasher: _this.hasher,
prev_root: prev_root,
level: level
}), key = _ref4.key, obj = _ref4.obj, obj_s = _ref4.obj_s;
h = key;
(function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.upsert"
});
_this.store_node({
key: key,
obj: obj,
obj_s: obj_s
}, esc(__iced_deferrals.defer({
lineno: 312
})));
__iced_deferrals._fulfill();
})(_next);
} else {
return _continue();
}
}
};
_while(__iced_k);
})(function() {
(function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.upsert"
});
_this.commit_root({
key: h,
txinfo: txinfo,
prev_root: prev_root
}, esc(__iced_deferrals.defer({
lineno: 315
})));
__iced_deferrals._fulfill();
})(function() {
return __iced_k(ret = h);
});
});
});
} else {
return __iced_k();
}
})(function() {
return cb(null, ret, prev_root);
});
});
});
});
};
})(this));
};
Base.prototype.verify_node = function(_arg, cb) {
var err, h, key, node;
key = _arg.key, node = _arg.node;
h = this.hasher(JSS(node));
err = null;
if (key !== h) {
err = new Error("Node hash failed: " + key + " != " + h);
}
return cb(err);
};
Base.prototype.find = function(_arg, cb) {
var curr, esc, key, level, node, p, root_obj, skip_verify, val, ___iced_passed_deferral, __iced_deferrals, __iced_k;
__iced_k = __iced_k_noop;
___iced_passed_deferral = iced.findDeferral(arguments);
key = _arg.key, skip_verify = _arg.skip_verify;
esc = make_esc(cb, "find");
val = null;
(function(_this) {
return (function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.find"
});
_this.lookup_root({}, esc(__iced_deferrals.defer({
assign_fn: (function() {
return function() {
curr = arguments[0];
return root_obj = arguments[1];
};
})(),
lineno: 334
})));
__iced_deferrals._fulfill();
});
})(this)((function(_this) {
return function() {
level = 0;
(function(__iced_k) {
var _while;
_while = function(__iced_k) {
var _break, _continue, _next;
_break = __iced_k;
_continue = function() {
return iced.trampoline(function() {
return _while(__iced_k);
});
};
_next = _continue;
if (typeof curr === "undefined" || curr === null) {
return _break();
} else {
(function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.find"
});
_this.lookup_node({
key: curr
}, esc(__iced_deferrals.defer({
assign_fn: (function() {
return function() {
return node = arguments[0];
};
})(),
lineno: 337
})));
__iced_deferrals._fulfill();
})(function() {
(function(__iced_k) {
if (!skip_verify) {
(function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.find"
});
_this.verify_node({
key: curr,
node: node
}, esc(__iced_deferrals.defer({
lineno: 339
})));
__iced_deferrals._fulfill();
})(__iced_k);
} else {
return __iced_k();
}
})(function() {
if (node.type === node_types.LEAF) {
val = node.tab[key];
curr = null;
} else {
p = _this.config.prefix_through_level({
key: key,
level: level
});
curr = node.tab[p];
}
return _next(level++);
});
});
}
};
_while(__iced_k);
})(function() {
return cb(null, val, root_obj);
});
};
})(this));
};
Base.prototype.build = function(_arg, cb) {
var esc, h, prev_root, sorted_map, txinfo, ___iced_passed_deferral, __iced_deferrals, __iced_k;
__iced_k = __iced_k_noop;
___iced_passed_deferral = iced.findDeferral(arguments);
sorted_map = _arg.sorted_map, txinfo = _arg.txinfo;
cb = chain_err(cb, this.unlock.bind(this));
esc = make_esc(cb, "full_build");
(function(_this) {
return (function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.build"
});
_this._lock.acquire(__iced_deferrals.defer({
lineno: 356
}));
__iced_deferrals._fulfill();
});
})(this)((function(_this) {
return function() {
(function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.build"
});
_this.lookup_root({
txinfo: txinfo
}, esc(__iced_deferrals.defer({
assign_fn: (function() {
return function() {
return prev_root = arguments[0];
};
})(),
lineno: 357
})));
__iced_deferrals._fulfill();
})(function() {
(function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.build"
});
_this.hash_tree_r({
level: 0,
sorted_map: sorted_map,
prev_root: prev_root
}, esc(__iced_deferrals.defer({
assign_fn: (function() {
return function() {
return h = arguments[0];
};
})(),
lineno: 358
})));
__iced_deferrals._fulfill();
})(function() {
(function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.build"
});
_this.commit_root({
key: h,
prev: prev_root,
txinfo: txinfo
}, esc(__iced_deferrals.defer({
lineno: 359
})));
__iced_deferrals._fulfill();
})(function() {
return cb(null, h);
});
});
});
};
})(this));
};
Base.prototype.hash_tree_r = function(_arg, cb) {
var C, M, end, err, h, i, j, key, level, new_sorted_map, obj, obj_s, prefix, prev_root, sorted_map, start, sublist, ___iced_passed_deferral, __iced_deferrals, __iced_k;
__iced_k = __iced_k_noop;
___iced_passed_deferral = iced.findDeferral(arguments);
level = _arg.level, sorted_map = _arg.sorted_map, prev_root = _arg.prev_root;
err = null;
key = null;
(function(_this) {
return (function(__iced_k) {
var _ref1;
if (sorted_map.len() <= _this.config.N) {
_ref1 = sorted_map.to_hash({
prev_root: prev_root,
hasher: _this.hasher,
level: level,
type: node_types.LEAF
}), key = _ref1.key, obj = _ref1.obj, obj_s = _ref1.obj_s;
(function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.hash_tree_r"
});
_this.store_node({
key: key,
obj: obj,
obj_s: obj_s
}, __iced_deferrals.defer({
assign_fn: (function() {
return function() {
return err = arguments[0];
};
})(),
lineno: 370
}));
__iced_deferrals._fulfill();
})(__iced_k);
} else {
M = _this.config.M;
C = _this.config.C;
j = 0;
new_sorted_map = new SortedMap({});
(function(__iced_k) {
var _begin, _end, _i, _positive, _results, _step, _while;
i = 0;
_begin = 0;
_end = M;
if (_end > _begin) {
_step = 1;
} else {
_step = -1;
}
_positive = _end > _begin;
_while = function(__iced_k) {
var _break, _continue, _next;
_break = __iced_k;
_continue = function() {
return iced.trampoline(function() {
i += _step;
return _while(__iced_k);
});
};
_next = _continue;
if (!!((_positive === true && i >= M) || (_positive === false && i <= M))) {
return _break();
} else {
prefix = format_hex(i, C);
start = j;
while (j < sorted_map.len() && (_this.config.prefix_at_level({
level: level,
obj: sorted_map.at(j)
}) === prefix)) {
j++;
}
end = j;
(function(__iced_k) {
if (end > start) {
sublist = sorted_map.slice(start, end);
(function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.hash_tree_r"
});
_this.hash_tree_r({
level: level + 1,
sorted_map: sublist
}, __iced_deferrals.defer({
assign_fn: (function() {
return function() {
err = arguments[0];
return h = arguments[1];
};
})(),
lineno: 384
}));
__iced_deferrals._fulfill();
})(function() {
(function(__iced_k) {
if (err != null) {
(function(__iced_k) {
_break()
})(__iced_k);
} else {
return __iced_k();
}
})(function() {
prefix = _this.config.prefix_through_level({
level: level,
obj: sublist.at(0)
});
return __iced_k(new_sorted_map.push({
key: prefix,
val: h
}));
});
});
} else {
return __iced_k();
}
})(_next);
}
};
_while(__iced_k);
})(function() {
(function(__iced_k) {
var _ref2;
if (err == null) {
_ref2 = new_sorted_map.to_hash({
prev_root: prev_root,
hasher: _this.hasher,
level: level,
type: node_types.INODE
}), key = _ref2.key, obj = _ref2.obj, obj_s = _ref2.obj_s;
(function(__iced_k) {
__iced_deferrals = new iced.Deferrals(__iced_k, {
parent: ___iced_passed_deferral,
filename: "/Users/max/src/keybase/node-merkle-tree/src/tree.iced",
funcname: "Base.hash_tree_r"
});
_this.store_node({
key: key,
obj: obj,
obj_s: obj_s
}, __iced_deferrals.defer({
assign_fn: (function() {
return function() {
return err = arguments[0];
};
})(),
lineno: 390
}));
__iced_deferrals._fulfill();
})(__iced_k);
} else {
return __iced_k();
}
})(__iced_k);
});
}
});
})(this)((function(_this) {
return function() {
return cb(err, key);
};
})(this));
};
return Base;
})();
}).call(this);