UNPKG

merkle-tree

Version:

A Merkle Tree skeleton, written in IcedCoffeeScript

958 lines (908 loc) 32.6 kB
// 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);