exonum-client-cis
Version:
Light Client for Exonum CIS Blockchain
125 lines (96 loc) • 3.28 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.verifyTable = verifyTable;
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _crypto = require("../crypto");
var _primitive = require("../types/primitive");
var _hexadecimal = require("../types/hexadecimal");
var _merklePatricia = require("./merkle-patricia");
var IndexCoordinates = {
/**
* Serialization index coordinates
* @param {Object} data
* @returns {Array}
*/
serialize: function serialize(data) {
var buffer = [];
_primitive.Uint16.serialize(data.origin_label, buffer, buffer.length, true);
_primitive.Uint32.serialize(data.local_schema_id, buffer, buffer.length, true);
_primitive.Uint16.serialize(data.index_id, buffer, buffer.length, true);
return buffer;
},
hash: function hash(data) {
return (0, _crypto.hash)(this.serialize(data));
}
};
Object.compare = function (obj1, obj2) {
// loop through properties in object 1
for (var p in obj1) {
// check property exists on both objects
if (obj1.hasOwnProperty(p) !== obj2.hasOwnProperty(p)) return false;
switch ((0, _typeof2["default"])(obj1[p])) {
// deep compare objects
case 'object':
if (!Object.compare(obj1[p], obj2[p])) return false;
break;
// compare function code
case 'function':
if (typeof obj2[p] === 'undefined' || p !== 'compare' && obj1[p].toString() !== obj2[p].toString()) return false;
break;
// compare values
default:
if (obj1[p] !== obj2[p]) return false;
}
} // check object 2 for any extra properties
for (var _p in obj2) {
if (typeof obj1[_p] === 'undefined') return false;
}
return true;
};
/**
* Validate path from tree root to some table
* @param {Object} proof
* @param {string} stateHash
* @param {Object} key
* @returns {string}
*/
function verifyTable(proof, stateHash, key) {
// validate proof of table existence in root tree
var tableProof = new _merklePatricia.MapProof(proof, IndexCoordinates, _hexadecimal.Hash);
if (tableProof.merkleRoot !== stateHash) {
throw new Error('Table proof is corrupted');
}
var rootHash; // get root hash of the table
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = tableProof.entries.keys()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var k = _step.value;
// use `Object.compare` for 'deep' key comparison, because keys may be objects
if (Object.compare(k, key)) {
rootHash = tableProof.entries.get(k);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator["return"] != null) {
_iterator["return"]();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
if (typeof rootHash === 'undefined') {
throw new Error('Table not found in the root tree');
}
return rootHash;
}