UNPKG

o2-client

Version:

Light Client for O2 Blockchain

93 lines (70 loc) 3.14 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.verifyBlock = verifyBlock; var _primitive = require('../types/primitive'); var primitive = _interopRequireWildcard(_primitive); var _message = require('../types/message'); var _hexadecimal = require('../types/hexadecimal'); var _generic = require('../types/generic'); var _convert = require('../types/convert'); var _crypto = require('../crypto'); var _helpers = require('../helpers'); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } var Block = (0, _generic.newType)({ fields: [{ name: 'proposer_id', type: primitive.Uint16 }, { name: 'height', type: primitive.Uint64 }, { name: 'tx_count', type: primitive.Uint32 }, { name: 'prev_hash', type: _hexadecimal.Hash }, { name: 'tx_hash', type: _hexadecimal.Hash }, { name: 'state_hash', type: _hexadecimal.Hash }] }); var SystemTime = (0, _generic.newType)({ fields: [{ name: 'secs', type: primitive.Uint64 }, { name: 'nanos', type: primitive.Uint32 }] }); /** * Validate block and each precommit in block * @param {Object} data * @param {Array} validators * @return {boolean} */ function verifyBlock(data, validators) { var blockHash = void 0; try { blockHash = (0, _crypto.hash)(data.block, Block); } catch (error) { return false; } for (var i = 0; i < data.precommits.length; i++) { var precommit = data.precommits[i]; var buffer = (0, _convert.hexadecimalToUint8Array)(precommit.message); if (precommit.payload.height !== data.block.height) { // height of block is not match return false; } if (precommit.payload.block_hash !== blockHash) { // hash of block is not match return false; } var publicKey = validators[precommit.payload.validator]; if ((0, _convert.uint8ArrayToHexadecimal)(buffer.slice(0, _hexadecimal.PUBLIC_KEY_LENGTH)) !== publicKey) { // public key is not match return false; } var Precommit = (0, _message.newPrecommit)({ author: publicKey, fields: [{ name: 'validator', type: primitive.Uint16 }, { name: 'height', type: primitive.Uint64 }, { name: 'round', type: primitive.Uint32 }, { name: 'propose_hash', type: _hexadecimal.Hash }, { name: 'block_hash', type: _hexadecimal.Hash }, { name: 'time', type: SystemTime }] }); var precommitBody = buffer.slice(0, buffer.length - _message.SIGNATURE_LENGTH); if (!(0, _helpers.compareUint8Arrays)(Precommit.serialize(precommit.payload), precommitBody)) { // payload is not match return false; } var signature = (0, _convert.uint8ArrayToHexadecimal)(buffer.slice(buffer.length - _message.SIGNATURE_LENGTH, buffer.length)); try { if (!(0, _crypto.verifySignature)(signature, publicKey, precommitBody)) { // signature is not match return false; } } catch (error) { return false; } } return true; }