'use strict'; require('./lib/BuildKBucket') (function(GLOBAL) { var kBucket = GLOBAL.kBucket = {} var SNKB, SNCO; function decodeID(floID) { let k = bitjs.Base58.decode(floID) k.shift() k.splice(-4, 4) const decodedId = Crypto.util.bytesToHex(k); const nodeIdBigInt = new BigInteger(decodedId, 16); const nodeIdBytes = nodeIdBigInt.toByteArrayUnsigned(); const nodeIdNewInt8Array = new Uint8Array(nodeIdBytes); return nodeIdNewInt8Array; } function distanceOf(floID) { let decodedId = decodeID(floID); return SNKB.distance(SNKB.localNodeId, decodedId); } function constructKB(list, refID) { let KB = new BuildKBucket({ localNodeId: decodeID(refID) }); list.forEach(id => KB.add({ id: decodeID(id), floID: floID })); return KB; } kBucket.launch = function() { return new Promise((resolve, reject) => { try { let superNodeList = Object.keys(floGlobals.supernodes); let masterID = floGlobals.SNStorageID; SNKB = constructKB(superNodeList, masterID); SNCO = superNodeList.map(sn => [distanceOf(sn), sn]) .sort((a, b) => a[0] - b[0]) .map(a => a[1]) resolve('SuperNode KBucket formed'); } catch (error) { reject(error); } }); } kBucket.innerNodes = function(id1, id2) { if (!SNCO.includes(id1) || !SNCO.includes(id2)) throw Error('Given nodes are not supernode'); let iNodes = [] for (let i = SNCO.indexOf(id1) + 1; SNCO[i] != id2; i++) { if (i < SNCO.length) iNodes.push(SNCO[i]) else i = -1 } return iNodes } kBucket.outterNodes = function(id1, id2) { if (!SNCO.includes(id1) || !SNCO.includes(id2)) throw Error('Given nodes are not supernode'); let oNodes = [] for (let i = SNCO.indexOf(id2) + 1; SNCO[i] != id1; i++) { if (i < SNCO.length) oNodes.push(SNCO[i]) else i = -1 } return oNodes } kBucket.prevNode = function(id, N = 1) { let n = N || SNCO.length; if (!SNCO.includes(id)) throw Error('Given node is not supernode'); let pNodes = [] for (let i = 0, j = SNCO.indexOf(id) - 1; i < n; j--) { if (j == SNCO.indexOf(id)) break; else if (j > -1) pNodes[i++] = SNCO[j] else j = SNCO.length } return (N == 1 ? pNodes[0] : pNodes) } kBucket.nextNode = function(id, N = 1) { let n = N || SNCO.length; if (!SNCO.includes(id)) throw Error('Given node is not supernode'); let nNodes = [] for (let i = 0, j = SNCO.indexOf(id) + 1; i < n; j++) { if (j == SNCO.indexOf(id)) break; else if (j < SNCO.length) nNodes[i++] = SNCO[j] else j = -1 } return (N == 1 ? nNodes[0] : nNodes) } kBucket.closestNode = function(id, N = 1) { let decodedId = decodeID(id); let n = N || SNCO.length; let cNodes = SNKB.closest(decodedId, n) .map(k => k.floID) return (N == 1 ? cNodes[0] : cNodes) } })(typeof global !== "undefined" ? global : window)