From e4b7eb57892b3b58091922b7ffbb02f152092050 Mon Sep 17 00:00:00 2001 From: SergNikolaev Date: Wed, 13 Sep 2017 14:58:06 +0300 Subject: [PATCH] code style - standard (reformat commit) --- .babelrc | 18 +- .editorconfig | 2 +- .eslintrc.json | 24 +- Gruntfile.js | 108 +- README.md | 3 + package.json | 9 +- src/blockchain/block.js | 210 ++-- src/blockchain/index.js | 6 +- src/blockchain/merkle-patricia.js | 567 +++++---- src/blockchain/merkle.js | 288 ++--- src/crypto/index.js | 180 +-- src/helpers.js | 4 +- src/index.js | 6 +- src/types/convert.js | 200 +-- src/types/generic.js | 90 +- src/types/index.js | 8 +- src/types/message.js | 104 +- src/types/primitive.js | 386 +++--- src/types/serialization.js | 88 +- src/types/validate.js | 110 +- test/blockchain.js | 737 ++++++----- test/convertors.js | 181 ++- test/cryptography.js | 1423 +++++++++++---------- test/merkle-patricia-proof.js | 1379 ++++++++++---------- test/merkle-proof.js | 627 +++++---- test/readme.js | 117 +- test/serialization.js | 291 +++-- test/types.js | 1957 ++++++++++++++--------------- 28 files changed, 4542 insertions(+), 4581 deletions(-) diff --git a/.babelrc b/.babelrc index 1f84844..26abaf8 100644 --- a/.babelrc +++ b/.babelrc @@ -1,12 +1,12 @@ { - "presets": [ - "es2015" - ], - "env": { - "test": { - "plugins": [ - "istanbul" - ] - } + "presets": [ + "es2015" + ], + "env": { + "test": { + "plugins": [ + "istanbul" + ] } + } } diff --git a/.editorconfig b/.editorconfig index d3341a7..34fcd17 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,7 +8,7 @@ root = true # change these settings to your own preference indent_style = space -indent_size = 4 +indent_size = 2 # we recommend you to keep these unchanged end_of_line = lf diff --git a/.eslintrc.json b/.eslintrc.json index 9c780c8..1d1b40e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,15 +1,13 @@ { - "env": { - "node": true, - "es6": true - }, - "extends": "eslint:recommended", - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "module" - }, - "rules": { - "quotes": ["error", "single"], - "indent": ["error", 4] - } + "env": { + "node": true, + "es6": true + }, + "extends": "standard", + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module" + }, + "rules": { + } } diff --git a/Gruntfile.js b/Gruntfile.js index 0aaf40f..92b7426 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,58 +1,58 @@ module.exports = function (grunt) { - require('load-grunt-tasks')(grunt); + require('load-grunt-tasks')(grunt) - grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), - eslint: { - dist: { - src: ['./src/**/*.js'] - }, - tests: { - src: ['./test/**/*.js'] - } + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + eslint: { + dist: { + src: ['./src/**/*.js'] + }, + tests: { + src: ['./test/**/*.js'] + } + }, + clean: { + dist: { + src: ['./dist', './lib'] + } + }, + babel: { + options: { + presets: ['babel-preset-es2015'] + }, + dist: { + expand: true, + cwd: './src/', + src: ['**/*.js'], + dest: './lib/' + } + }, + browserify: { + dist: { + options: { + browserifyOptions: {debug: false, standalone: 'Exonum'}, + transform: [['babelify', {'presets': ['es2015']}]] }, - clean: { - dist: { - src: ['./dist', './lib'] - } - }, - babel: { - options: { - presets: ['babel-preset-es2015'] - }, - dist: { - expand: true, - cwd: './src/', - src: ['**/*.js'], - dest: './lib/' - } - }, - browserify: { - dist: { - options: { - browserifyOptions: {debug: false, standalone: 'Exonum'}, - transform: [["babelify", {"presets": ["es2015"]}]] - }, - src: './src/index.js', - dest: './dist/<%= pkg.name %>.js' - } - }, - uglify: { - dist: { - src: './dist/<%= pkg.name %>.js', - dest: './dist/<%= pkg.name %>.min.js' - } - }, - mochaTest: { - options: { - reporter: 'spec', - require: ['babel-register'] - }, - src: ['./test/**/*.js'] - } - }); + src: './src/index.js', + dest: './dist/<%= pkg.name %>.js' + } + }, + uglify: { + dist: { + src: './dist/<%= pkg.name %>.js', + dest: './dist/<%= pkg.name %>.min.js' + } + }, + mochaTest: { + options: { + reporter: 'spec', + require: ['babel-register'] + }, + src: ['./test/**/*.js'] + } + }) - grunt.registerTask('compile', ['eslint', 'clean', 'babel', 'browserify', 'uglify']); - grunt.registerTask('test', ['eslint:tests', 'mochaTest']); - grunt.registerTask('default', ['compile', 'test']); -}; + grunt.registerTask('compile', ['eslint', 'clean', 'babel', 'browserify', 'uglify']) + grunt.registerTask('test', ['eslint:tests', 'mochaTest']) + grunt.registerTask('default', ['compile', 'test']) +} diff --git a/README.md b/README.md index 262e598..17e71fc 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,15 @@ [![Build status][travis-image]][travis-url] [![Coverage Status][coveralls-image]][coveralls-url] +[![js-standard-style][codestyle-image]][codestyle-url] [![License][license-image]][license-url] [travis-image]: https://img.shields.io/travis/exonum/exonum-client/master.svg [travis-url]: https://travis-ci.org/exonum/exonum-client [coveralls-image]: https://coveralls.io/repos/github/exonum/exonum-client/badge.svg?branch=master [coveralls-url]: https://coveralls.io/github/exonum/exonum-client?branch=master +[codestyle-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg +[codestyle-url]: http://standardjs.com [license-image]: https://img.shields.io/github/license/exonum/exonum-client.svg?style=flat-square [license-url]: https://opensource.org/licenses/Apache-2.0 diff --git a/package.json b/package.json index af4fae7..a826ae9 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,11 @@ "chai": "^3.5.0", "coveralls": "^2.13.1", "cross-env": "^5.0.5", + "eslint-config-standard": "^10.2.1", + "eslint-plugin-import": "^2.7.0", + "eslint-plugin-node": "^5.1.1", + "eslint-plugin-promise": "^3.5.0", + "eslint-plugin-standard": "^3.0.1", "grunt": "^1.0.1", "grunt-babel": "^6.0.0", "grunt-browserify": "^5.0.0", @@ -44,7 +49,9 @@ "scripts": { "test": "grunt test", "coveralls": "cross-env NODE_ENV=test nyc mocha && cat ./coverage/lcov.info | coveralls", - "prepare": "grunt compile" + "prepare": "grunt compile", + "lint": "node_modules/.bin/eslint ./src ./test", + "lint:fix": "npm run lint -- --fix" }, "repository": { "type": "git", diff --git a/src/blockchain/block.js b/src/blockchain/block.js index 746d36d..77b3c1b 100644 --- a/src/blockchain/block.js +++ b/src/blockchain/block.js @@ -1,32 +1,32 @@ -import {isObject} from '../helpers'; -import * as primitive from '../types/primitive'; -import {newType} from '../types/generic'; -import {newMessage} from '../types/message'; -import {validateHexadecimal} from '../types/validate'; -import {hash, verifySignature} from '../crypto'; - -const PROTOCOL_VERSION = 0; -const CORE_SERVICE_ID = 0; -const PRECOMMIT_MESSAGE_ID = 4; +import {isObject} from '../helpers' +import * as primitive from '../types/primitive' +import {newType} from '../types/generic' +import {newMessage} from '../types/message' +import {validateHexadecimal} from '../types/validate' +import {hash, verifySignature} from '../crypto' + +const PROTOCOL_VERSION = 0 +const CORE_SERVICE_ID = 0 +const PRECOMMIT_MESSAGE_ID = 4 const Block = newType({ - size: 112, - fields: { - schema_version: {type: primitive.Uint16, size: 2, from: 0, to: 2}, - proposer_id: {type: primitive.Uint16, size: 2, from: 2, to: 4}, - height: {type: primitive.Uint64, size: 8, from: 4, to: 12}, - tx_count: {type: primitive.Uint32, size: 4, from: 12, to: 16}, - prev_hash: {type: primitive.Hash, size: 32, from: 16, to: 48}, - tx_hash: {type: primitive.Hash, size: 32, from: 48, to: 80}, - state_hash: {type: primitive.Hash, size: 32, from: 80, to: 112} - } -}); + size: 112, + fields: { + schema_version: {type: primitive.Uint16, size: 2, from: 0, to: 2}, + proposer_id: {type: primitive.Uint16, size: 2, from: 2, to: 4}, + height: {type: primitive.Uint64, size: 8, from: 4, to: 12}, + tx_count: {type: primitive.Uint32, size: 4, from: 12, to: 16}, + prev_hash: {type: primitive.Hash, size: 32, from: 16, to: 48}, + tx_hash: {type: primitive.Hash, size: 32, from: 48, to: 80}, + state_hash: {type: primitive.Hash, size: 32, from: 80, to: 112} + } +}) const SystemTime = newType({ - size: 12, - fields: { - secs: {type: primitive.Uint64, size: 8, from: 0, to: 8}, - nanos: {type: primitive.Uint32, size: 4, from: 8, to: 12} - } -}); + size: 12, + fields: { + secs: {type: primitive.Uint64, size: 8, from: 0, to: 8}, + nanos: {type: primitive.Uint32, size: 4, from: 8, to: 12} + } +}) /** * Validate block and each precommit in block @@ -35,106 +35,106 @@ const SystemTime = newType({ * @param {number} networkId * @return {boolean} */ -export function verifyBlock(data, validators, networkId) { - if (isObject(data) === false) { - return false; - } else if (isObject(data.block) === false) { - return false; - } else if (Array.isArray(data.precommits) === false) { - return false; - } else if (Array.isArray(validators) === false) { - return false; +export function verifyBlock (data, validators, networkId) { + if (isObject(data) === false) { + return false + } else if (isObject(data.block) === false) { + return false + } else if (Array.isArray(data.precommits) === false) { + return false + } else if (Array.isArray(validators) === false) { + return false + } + + for (var i = 0; i < validators.length; i++) { + if (!validateHexadecimal(validators[i])) { + return false } - - for (var i = 0; i < validators.length; i++) { - if (!validateHexadecimal(validators[i])) { - return false; - } + } + + try { + var blockHash = hash(data.block, Block) + } catch (error) { + return false + } + + if (typeof networkId !== 'number' || networkId < 0 || networkId > 255) { + return false + } + + var Precommit = newMessage({ + size: 90, + network_id: networkId, + protocol_version: PROTOCOL_VERSION, + message_id: PRECOMMIT_MESSAGE_ID, + service_id: CORE_SERVICE_ID, + fields: { + validator: {type: primitive.Uint16, size: 2, from: 0, to: 2}, + height: {type: primitive.Uint64, size: 8, from: 2, to: 10}, + round: {type: primitive.Uint32, size: 4, from: 10, to: 14}, + propose_hash: {type: primitive.Hash, size: 32, from: 14, to: 46}, + block_hash: {type: primitive.Hash, size: 32, from: 46, to: 78}, + time: {type: SystemTime, size: 12, from: 78, to: 90} } + }) + + var validatorsTotalNumber = validators.length + var uniqueValidators = [] + var round - try { - var blockHash = hash(data.block, Block); - } catch (error) { - return false; + for (i = 0; i < data.precommits.length; i++) { + var precommit = data.precommits[i] + + if (isObject(precommit.body) === false) { + return false } - if (typeof networkId !== 'number' || networkId < 0 || networkId > 255) { - return false; + if (!validateHexadecimal(precommit.signature, 64)) { + return false } - var Precommit = newMessage({ - size: 90, - network_id: networkId, - protocol_version: PROTOCOL_VERSION, - message_id: PRECOMMIT_MESSAGE_ID, - service_id: CORE_SERVICE_ID, - fields: { - validator: {type: primitive.Uint16, size: 2, from: 0, to: 2}, - height: {type: primitive.Uint64, size: 8, from: 2, to: 10}, - round: {type: primitive.Uint32, size: 4, from: 10, to: 14}, - propose_hash: {type: primitive.Hash, size: 32, from: 14, to: 46}, - block_hash: {type: primitive.Hash, size: 32, from: 46, to: 78}, - time: {type: SystemTime, size: 12, from: 78, to: 90} - } - }); - - var validatorsTotalNumber = validators.length; - var uniqueValidators = []; - var round; - - for (i = 0; i < data.precommits.length; i++) { - var precommit = data.precommits[i]; - - if (isObject(precommit.body) === false) { - return false; - } - - if (!validateHexadecimal(precommit.signature, 64)) { - return false; - } - - if (precommit.body.validator >= validatorsTotalNumber) { + if (precommit.body.validator >= validatorsTotalNumber) { // validator does not exist - return false; - } + return false + } - if (uniqueValidators.indexOf(precommit.body.validator) === -1) { - uniqueValidators.push(precommit.body.validator); - } + if (uniqueValidators.indexOf(precommit.body.validator) === -1) { + uniqueValidators.push(precommit.body.validator) + } - if (precommit.network_id !== networkId || + if (precommit.network_id !== networkId || precommit.protocol_version !== PROTOCOL_VERSION || precommit.service_id !== CORE_SERVICE_ID || precommit.message_id !== PRECOMMIT_MESSAGE_ID) { - return false; - } + return false + } - if (precommit.body.height !== data.block.height) { + if (precommit.body.height !== data.block.height) { // wrong height of block in precommit - return false; - } else if (precommit.body.block_hash !== blockHash) { + return false + } else if (precommit.body.block_hash !== blockHash) { // wrong hash of block in precommit - return false; - } + return false + } - if (round === undefined) { - round = precommit.body.round; - } else if (precommit.body.round !== round) { + if (round === undefined) { + round = precommit.body.round + } else if (precommit.body.round !== round) { // wrong round in precommit - return false; - } + return false + } - var publicKey = validators[precommit.body.validator]; + var publicKey = validators[precommit.body.validator] - if (!verifySignature(precommit.signature, publicKey, precommit.body, Precommit)) { - return false; - } + if (!verifySignature(precommit.signature, publicKey, precommit.body, Precommit)) { + return false } + } - if (uniqueValidators.length <= validatorsTotalNumber * 2 / 3) { + if (uniqueValidators.length <= validatorsTotalNumber * 2 / 3) { // not enough precommits from unique validators - return false; - } + return false + } - return true; + return true } diff --git a/src/blockchain/index.js b/src/blockchain/index.js index 4f1c309..886a10d 100644 --- a/src/blockchain/index.js +++ b/src/blockchain/index.js @@ -1,3 +1,3 @@ -export * from './merkle'; -export * from './merkle-patricia'; -export * from './block'; +export * from './merkle' +export * from './merkle-patricia' +export * from './block' diff --git a/src/blockchain/merkle-patricia.js b/src/blockchain/merkle-patricia.js index d6835bb..bc1635e 100644 --- a/src/blockchain/merkle-patricia.js +++ b/src/blockchain/merkle-patricia.js @@ -1,11 +1,11 @@ -import {isObject} from '../helpers'; -import * as primitive from '../types/primitive'; -import {newType} from '../types/generic'; -import * as validate from '../types/validate'; -import * as convert from '../types/convert'; -import {hash} from '../crypto'; +import {isObject} from '../helpers' +import * as primitive from '../types/primitive' +import {newType} from '../types/generic' +import * as validate from '../types/validate' +import * as convert from '../types/convert' +import {hash} from '../crypto' -const MERKLE_PATRICIA_KEY_LENGTH = 32; +const MERKLE_PATRICIA_KEY_LENGTH = 32 /** * Check Merkle Patricia tree proof and return element @@ -15,67 +15,67 @@ const MERKLE_PATRICIA_KEY_LENGTH = 32; * @param {NewType} [type] - optional * @return {Object} */ -export function merklePatriciaProof(rootHash, proofNode, key, type) { - var DBKey = newType({ - size: 34, - fields: { - variant: {type: primitive.Uint8, size: 1, from: 0, to: 1}, - key: {type: primitive.Hash, size: 32, from: 1, to: 33}, - length: {type: primitive.Uint8, size: 1, from: 33, to: 34} - } - }); - var Branch = newType({ - size: 132, - fields: { - left_hash: {type: primitive.Hash, size: 32, from: 0, to: 32}, - right_hash: {type: primitive.Hash, size: 32, from: 32, to: 64}, - left_key: {type: DBKey, size: 34, from: 64, to: 98}, - right_key: {type: DBKey, size: 34, from: 98, to: 132} - } - }); - var RootBranch = newType({ - size: 66, - fields: { - key: {type: DBKey, size: 34, from: 0, to: 34}, - hash: {type: primitive.Hash, size: 32, from: 34, to: 66} - } - }); +export function merklePatriciaProof (rootHash, proofNode, key, type) { + var DBKey = newType({ + size: 34, + fields: { + variant: {type: primitive.Uint8, size: 1, from: 0, to: 1}, + key: {type: primitive.Hash, size: 32, from: 1, to: 33}, + length: {type: primitive.Uint8, size: 1, from: 33, to: 34} + } + }) + var Branch = newType({ + size: 132, + fields: { + left_hash: {type: primitive.Hash, size: 32, from: 0, to: 32}, + right_hash: {type: primitive.Hash, size: 32, from: 32, to: 64}, + left_key: {type: DBKey, size: 34, from: 64, to: 98}, + right_key: {type: DBKey, size: 34, from: 98, to: 132} + } + }) + var RootBranch = newType({ + size: 66, + fields: { + key: {type: DBKey, size: 34, from: 0, to: 34}, + hash: {type: primitive.Hash, size: 32, from: 34, to: 66} + } + }) /** * Get element from node * @param data * @returns {string} or {Array} or {Object} */ - function getElement(data) { - if (typeof data === 'string') { - if (!validate.validateHexadecimal(data)) { - throw new TypeError('Element of wrong type is passed. Hexadecimal expected.'); - } - return data; - } else if (Array.isArray(data)) { - if (!validate.validateBytesArray(data)) { - throw new TypeError('Element of wrong type is passed. Bytes array expected.'); - } - return data.slice(0); // clone array of 8-bit integers - } else if (isObject(data)) { - return JSON.parse(JSON.stringify(data)); // deep clone - } + function getElement (data) { + if (typeof data === 'string') { + if (!validate.validateHexadecimal(data)) { + throw new TypeError('Element of wrong type is passed. Hexadecimal expected.') + } + return data + } else if (Array.isArray(data)) { + if (!validate.validateBytesArray(data)) { + throw new TypeError('Element of wrong type is passed. Bytes array expected.') + } + return data.slice(0) // clone array of 8-bit integers + } else if (isObject(data)) { + return JSON.parse(JSON.stringify(data)) // deep clone } + } /** * Get hash of element * @param element * @returns {string} */ - function getHash(element) { - if (typeof element === 'string') { - return element; - } else if (Array.isArray(element)) { - return hash(element); - } else if (isObject(element)) { - return hash(element, type); - } + function getHash (element) { + if (typeof element === 'string') { + return element + } else if (Array.isArray(element)) { + return hash(element) + } else if (isObject(element)) { + return hash(element, type) } + } /** * Check either suffix is a part of search key @@ -83,28 +83,28 @@ export function merklePatriciaProof(rootHash, proofNode, key, type) { * @param {string} suffix * @returns {boolean} */ - function isPartOfSearchKey(prefix, suffix) { + function isPartOfSearchKey (prefix, suffix) { // remove prefix from searched binary key - var diff = keyBinary.substr(prefix.length); - return diff.indexOf(suffix) === 0; - } + var diff = keyBinary.substr(prefix.length) + return diff.indexOf(suffix) === 0 + } /** * Order left and right nodes in a tree * @param {Array} nodes * @returns {Array} or {null} */ - function orderNodes(nodes) { - var child1 = nodes[0]; - var child2 = nodes[1]; - var len = Math.min(child1.suffix.length, child2.suffix.length); - for (var i = 0; i < len; i++) { - if (child1.suffix[i] !== child2.suffix[i]) { - return child1.suffix[i] === '0' ? [child1, child2] : [child2, child1]; - } - } - return null; + function orderNodes (nodes) { + var child1 = nodes[0] + var child2 = nodes[1] + var len = Math.min(child1.suffix.length, child2.suffix.length) + for (var i = 0; i < len; i++) { + if (child1.suffix[i] !== child2.suffix[i]) { + return child1.suffix[i] === '0' ? [child1, child2] : [child2, child1] + } } + return null + } /** * Recursive tree traversal function @@ -112,256 +112,255 @@ export function merklePatriciaProof(rootHash, proofNode, key, type) { * @param {string} keyPrefix * @returns {string} */ - function recursive(node, keyPrefix) { - if (Object.keys(node).length !== 2) { - throw new Error('Invalid number of children in the tree node.'); - } + function recursive (node, keyPrefix) { + if (Object.keys(node).length !== 2) { + throw new Error('Invalid number of children in the tree node.') + } - var nodes = []; - var fullKey; + var nodes = [] + var fullKey - for (var keySuffix in node) { - if (!node.hasOwnProperty(keySuffix)) { - continue; - } else if (keySuffix.length === 0) { - throw new TypeError('Empty key suffix is passed.'); - } + for (var keySuffix in node) { + if (!node.hasOwnProperty(keySuffix)) { + continue + } else if (keySuffix.length === 0) { + throw new TypeError('Empty key suffix is passed.') + } // validate key - if (!validate.validateBinaryString(keySuffix)) { - throw new TypeError('Key suffix of wrong type is passed. Binary string expected.'); - } - - var branchValueHash; - var nodeValue = node[keySuffix]; - var branchType; - var branchKey; - var branchKeyHash; - - fullKey = keyPrefix + keySuffix; - - if (fullKey.length === MERKLE_PATRICIA_KEY_LENGTH * 8) { - if (typeof nodeValue === 'string') { - if (!validate.validateHexadecimal(nodeValue)) { - throw new TypeError('Tree node of wrong type is passed. Hexadecimal expected.'); - } - - branchValueHash = nodeValue; - branchType = 'hash'; - } else if (isObject(nodeValue)) { - if (nodeValue.val === undefined) { - throw new TypeError('Leaf tree contains invalid data.'); - } else if (element !== undefined) { - throw new Error('Tree can not contains more than one node with value.'); - } - - element = getElement(nodeValue.val); - branchValueHash = getHash(element); - - branchType = 'value'; - } else { - throw new TypeError('Invalid type of node in tree leaf.'); - } - - branchKeyHash = convert.binaryStringToHexadecimal(fullKey); - - branchKey = { - variant: 1, - key: branchKeyHash, - length: 0 - }; - } else if (fullKey.length < MERKLE_PATRICIA_KEY_LENGTH * 8) { // node is branch - if (typeof nodeValue === 'string') { - if (!validate.validateHexadecimal(nodeValue)) { - throw new TypeError('Tree node of wrong type is passed. Hexadecimal expected.'); - } - - branchValueHash = nodeValue; - branchType = 'hash'; - } else if (isObject(nodeValue)) { - if (nodeValue.val !== undefined) { - throw new Error('Node with value is at non-leaf position in tree.'); - } - - branchValueHash = recursive(nodeValue, fullKey); - - branchType = 'branch'; - } else { - throw new TypeError('Invalid type of node in tree.'); - } - - var binaryKeyLength = fullKey.length; - var binaryKey = fullKey; - - for (var j = 0; j < (MERKLE_PATRICIA_KEY_LENGTH * 8 - fullKey.length); j++) { - binaryKey += '0'; - } - - branchKeyHash = convert.binaryStringToHexadecimal(binaryKey); - - branchKey = { - variant: 0, - key: branchKeyHash, - length: binaryKeyLength - }; - } else { - throw new Error('Invalid length of key in tree.'); - } - - nodes.push({ - hash: branchValueHash, - key: branchKey, - type: branchType, - suffix: keySuffix, - size: fullKey.length - }); + if (!validate.validateBinaryString(keySuffix)) { + throw new TypeError('Key suffix of wrong type is passed. Binary string expected.') + } + + var branchValueHash + var nodeValue = node[keySuffix] + var branchType + var branchKey + var branchKeyHash + + fullKey = keyPrefix + keySuffix + + if (fullKey.length === MERKLE_PATRICIA_KEY_LENGTH * 8) { + if (typeof nodeValue === 'string') { + if (!validate.validateHexadecimal(nodeValue)) { + throw new TypeError('Tree node of wrong type is passed. Hexadecimal expected.') + } + + branchValueHash = nodeValue + branchType = 'hash' + } else if (isObject(nodeValue)) { + if (nodeValue.val === undefined) { + throw new TypeError('Leaf tree contains invalid data.') + } else if (element !== undefined) { + throw new Error('Tree can not contains more than one node with value.') + } + + element = getElement(nodeValue.val) + branchValueHash = getHash(element) + + branchType = 'value' + } else { + throw new TypeError('Invalid type of node in tree leaf.') } - if (nodes[0].suffix[0] === nodes[1].suffix[0] && keyPrefix.length > 0) { - throw new Error('Nodes with common-prefix keys are located on non-zero level of the tree.'); + branchKeyHash = convert.binaryStringToHexadecimal(fullKey) + + branchKey = { + variant: 1, + key: branchKeyHash, + length: 0 + } + } else if (fullKey.length < MERKLE_PATRICIA_KEY_LENGTH * 8) { // node is branch + if (typeof nodeValue === 'string') { + if (!validate.validateHexadecimal(nodeValue)) { + throw new TypeError('Tree node of wrong type is passed. Hexadecimal expected.') + } + + branchValueHash = nodeValue + branchType = 'hash' + } else if (isObject(nodeValue)) { + if (nodeValue.val !== undefined) { + throw new Error('Node with value is at non-leaf position in tree.') + } + + branchValueHash = recursive(nodeValue, fullKey) + + branchType = 'branch' + } else { + throw new TypeError('Invalid type of node in tree.') } - var orderedNodes = orderNodes(nodes); + var binaryKeyLength = fullKey.length + var binaryKey = fullKey - if (!orderedNodes) { - throw new Error('Impossible to determine left and right nodes.'); + for (var j = 0; j < (MERKLE_PATRICIA_KEY_LENGTH * 8 - fullKey.length); j++) { + binaryKey += '0' } - var left = orderedNodes[0]; - var right = orderedNodes[1]; + branchKeyHash = convert.binaryStringToHexadecimal(binaryKey) - if ( + branchKey = { + variant: 0, + key: branchKeyHash, + length: binaryKeyLength + } + } else { + throw new Error('Invalid length of key in tree.') + } + + nodes.push({ + hash: branchValueHash, + key: branchKey, + type: branchType, + suffix: keySuffix, + size: fullKey.length + }) + } + + if (nodes[0].suffix[0] === nodes[1].suffix[0] && keyPrefix.length > 0) { + throw new Error('Nodes with common-prefix keys are located on non-zero level of the tree.') + } + + var orderedNodes = orderNodes(nodes) + + if (!orderedNodes) { + throw new Error('Impossible to determine left and right nodes.') + } + + var left = orderedNodes[0] + var right = orderedNodes[1] + + if ( left.type === 'hash' && right.type === 'hash' && fullKey.length < MERKLE_PATRICIA_KEY_LENGTH * 8 ) { - if (isPartOfSearchKey(keyPrefix, left.suffix)) { - throw new Error('Tree is invalid. Left key is a part of search key but its branch is not expanded.'); - } else if (isPartOfSearchKey(keyPrefix, right.suffix)) { - throw new Error('Tree is invalid. Right key is a part of search key but its branch is not expanded.'); - } - } - - return hash({ - left_hash: left.hash, - right_hash: right.hash, - left_key: left.key, - right_key: right.key - }, Branch); + if (isPartOfSearchKey(keyPrefix, left.suffix)) { + throw new Error('Tree is invalid. Left key is a part of search key but its branch is not expanded.') + } else if (isPartOfSearchKey(keyPrefix, right.suffix)) { + throw new Error('Tree is invalid. Right key is a part of search key but its branch is not expanded.') + } } - var element; + return hash({ + left_hash: left.hash, + right_hash: right.hash, + left_key: left.key, + right_key: right.key + }, Branch) + } + + var element // validate rootHash - if (!validate.validateHexadecimal(rootHash)) { - throw new TypeError('Root hash of wrong type is passed. Hexadecimal expected.'); - } + if (!validate.validateHexadecimal(rootHash)) { + throw new TypeError('Root hash of wrong type is passed. Hexadecimal expected.') + } - rootHash = rootHash.toLowerCase(); + rootHash = rootHash.toLowerCase() // validate proofNode parameter - if (isObject(proofNode) === false) { - throw new TypeError('Invalid type of proofNode parameter. Object expected.'); - } + if (isObject(proofNode) === false) { + throw new TypeError('Invalid type of proofNode parameter. Object expected.') + } // validate key parameter - if (Array.isArray(key)) { - if (!validate.validateBytesArray(key, MERKLE_PATRICIA_KEY_LENGTH)) { - throw new TypeError('Key parameter of wrong type is passed. Bytes array expected.'); - } + if (Array.isArray(key)) { + if (!validate.validateBytesArray(key, MERKLE_PATRICIA_KEY_LENGTH)) { + throw new TypeError('Key parameter of wrong type is passed. Bytes array expected.') + } - key = convert.uint8ArrayToHexadecimal(key); - } else if (typeof key === 'string') { - if (!validate.validateHexadecimal(key, MERKLE_PATRICIA_KEY_LENGTH)) { - throw new TypeError('Key parameter of wrong type is passed. Hexadecimal expected.'); - } + key = convert.uint8ArrayToHexadecimal(key) + } else if (typeof key === 'string') { + if (!validate.validateHexadecimal(key, MERKLE_PATRICIA_KEY_LENGTH)) { + throw new TypeError('Key parameter of wrong type is passed. Hexadecimal expected.') + } + } else { + throw new TypeError('Invalid type of key parameter. Array of 8-bit integers or hexadecimal string is expected.') + } + + var keyBinary = convert.hexadecimalToBinaryString(key) + + var proofNodeRootNumberOfNodes = Object.keys(proofNode).length + if (proofNodeRootNumberOfNodes === 0) { + if (rootHash === (new Uint8Array(MERKLE_PATRICIA_KEY_LENGTH * 2)).join('')) { + return null } else { - throw new TypeError('Invalid type of key parameter. Array of 8-bit integers or hexadecimal string is expected.'); + throw new Error('Invalid rootHash parameter of empty tree.') } + } else if (proofNodeRootNumberOfNodes === 1) { + for (var i in proofNode) { + if (!proofNode.hasOwnProperty(i)) { + continue + } - var keyBinary = convert.hexadecimalToBinaryString(key); + if (!validate.validateBinaryString(i, 256)) { + throw new TypeError('Tree key of wrong type is passed. Binary string expected.') + } - var proofNodeRootNumberOfNodes = Object.keys(proofNode).length; - if (proofNodeRootNumberOfNodes === 0) { - if (rootHash === (new Uint8Array(MERKLE_PATRICIA_KEY_LENGTH * 2)).join('')) { - return null; - } else { - throw new Error('Invalid rootHash parameter of empty tree.'); - } - } else if (proofNodeRootNumberOfNodes === 1) { - for (var i in proofNode) { - if (!proofNode.hasOwnProperty(i)) { - continue; - } - - if (!validate.validateBinaryString(i, 256)) { - throw new TypeError('Tree key of wrong type is passed. Binary string expected.'); - } - - var data = proofNode[i]; - var nodeHash; - - var nodeKeyBuffer = convert.binaryStringToUint8Array(i); - var nodeKey = convert.uint8ArrayToHexadecimal(nodeKeyBuffer); - - if (typeof data === 'string') { - if (!validate.validateHexadecimal(data)) { - throw new TypeError('Tree element of wrong type is passed. Hexadecimal expected.'); - } - - nodeHash = hash({ - key: { - variant: 1, - key: nodeKey, - length: 0 - }, - hash: data - }, RootBranch); - - if (rootHash === nodeHash) { - if (key !== nodeKey) { - return null; // no element with data in tree - } else { - throw new Error('Invalid key with hash is in the root of proofNode parameter.'); - } - } else { - throw new Error('rootHash parameter is not equal to actual hash.'); - } - } else if (isObject(data)) { - element = getElement(data.val); - - nodeHash = hash({ - key: { - variant: 1, - key: nodeKey, - length: 0 - }, - hash: getHash(element) - }, RootBranch); - - if (rootHash === nodeHash) { - if (key === nodeKey) { - return element; - } else { - throw new Error('Invalid key with value is in the root of proofNode parameter.'); - } - } else { - throw new Error('rootHash parameter is not equal to actual hash.'); - } - } else { - throw new Error('Invalid type of value in the root of proofNode parameter.'); - } + var data = proofNode[i] + var nodeHash + + var nodeKeyBuffer = convert.binaryStringToUint8Array(i) + var nodeKey = convert.uint8ArrayToHexadecimal(nodeKeyBuffer) + if (typeof data === 'string') { + if (!validate.validateHexadecimal(data)) { + throw new TypeError('Tree element of wrong type is passed. Hexadecimal expected.') } - } else { - var actualHash = recursive(proofNode, ''); - if (rootHash !== actualHash) { - throw new Error('rootHash parameter is not equal to actual hash.'); - } else if (element === undefined) { - return null; // no element with data in tree + nodeHash = hash({ + key: { + variant: 1, + key: nodeKey, + length: 0 + }, + hash: data + }, RootBranch) + + if (rootHash === nodeHash) { + if (key !== nodeKey) { + return null // no element with data in tree + } else { + throw new Error('Invalid key with hash is in the root of proofNode parameter.') + } + } else { + throw new Error('rootHash parameter is not equal to actual hash.') + } + } else if (isObject(data)) { + element = getElement(data.val) + + nodeHash = hash({ + key: { + variant: 1, + key: nodeKey, + length: 0 + }, + hash: getHash(element) + }, RootBranch) + + if (rootHash === nodeHash) { + if (key === nodeKey) { + return element + } else { + throw new Error('Invalid key with value is in the root of proofNode parameter.') + } + } else { + throw new Error('rootHash parameter is not equal to actual hash.') } + } else { + throw new Error('Invalid type of value in the root of proofNode parameter.') + } + } + } else { + var actualHash = recursive(proofNode, '') - return element; + if (rootHash !== actualHash) { + throw new Error('rootHash parameter is not equal to actual hash.') + } else if (element === undefined) { + return null // no element with data in tree } + + return element + } } diff --git a/src/blockchain/merkle.js b/src/blockchain/merkle.js index 6df284a..91f42e1 100644 --- a/src/blockchain/merkle.js +++ b/src/blockchain/merkle.js @@ -1,21 +1,21 @@ -import bigInt from 'big-integer'; -import {isObject} from '../helpers'; -import {isInstanceofOfNewType} from '../types/generic'; -import {validateHexadecimal, validateBytesArray} from '../types/validate'; -import {hexadecimalToUint8Array} from '../types/convert'; -import {hash} from '../crypto'; +import bigInt from 'big-integer' +import {isObject} from '../helpers' +import {isInstanceofOfNewType} from '../types/generic' +import {validateHexadecimal, validateBytesArray} from '../types/validate' +import {hexadecimalToUint8Array} from '../types/convert' +import {hash} from '../crypto' /** * Calculate height of merkle tree * @param {bigInt} count * @return {number} */ -function calcHeight(count) { - var i = 0; - while (bigInt(2).pow(i).lt(count)) { - i++; - } - return i; +function calcHeight (count) { + var i = 0 + while (bigInt(2).pow(i).lt(count)) { + i++ + } + return i } /** @@ -27,9 +27,9 @@ function calcHeight(count) { * @param {NewType} [type] - optional * @return {Array} */ -export function merkleProof(rootHash, count, proofNode, range, type) { - var elements = []; - var rootBranch = 'left'; +export function merkleProof (rootHash, count, proofNode, range, type) { + var elements = [] + var rootBranch = 'left' /** * Get value from node, insert into elements array and return its hash @@ -38,45 +38,45 @@ export function merkleProof(rootHash, count, proofNode, range, type) { * @param {number} index * @returns {string} */ - function getHash(data, depth, index) { - var element; - var elementsHash; - - if (depth !== 0 && (depth + 1) !== height) { - throw new Error('Value node is on wrong height in tree.'); - } else if (start.gt(index) || end.lt(index)) { - throw new Error('Wrong index of value node.'); - } else if (start.plus(elements.length).neq(index)) { - throw new Error('Value node is on wrong position in tree.'); - } - - if (typeof data === 'string') { - if (!validateHexadecimal(data)) { - throw new TypeError('Tree element of wrong type is passed. Hexadecimal expected.'); - } - element = data; - elementsHash = element; - } else if (Array.isArray(data)) { - if (!validateBytesArray(data)) { - throw new TypeError('Tree element of wrong type is passed. Bytes array expected.'); - } - element = data.slice(0); // clone array of 8-bit integers - elementsHash = hash(element); - } else if (isObject(data)) { - if (isInstanceofOfNewType(type)) { - element = data; - elementsHash = hash(element, type); - } else { - throw new TypeError('Invalid type of type parameter.'); - } - } else { - throw new TypeError('Invalid value of data parameter.'); - } + function getHash (data, depth, index) { + var element + var elementsHash + + if (depth !== 0 && (depth + 1) !== height) { + throw new Error('Value node is on wrong height in tree.') + } else if (start.gt(index) || end.lt(index)) { + throw new Error('Wrong index of value node.') + } else if (start.plus(elements.length).neq(index)) { + throw new Error('Value node is on wrong position in tree.') + } - elements.push(element); - return elementsHash; + if (typeof data === 'string') { + if (!validateHexadecimal(data)) { + throw new TypeError('Tree element of wrong type is passed. Hexadecimal expected.') + } + element = data + elementsHash = element + } else if (Array.isArray(data)) { + if (!validateBytesArray(data)) { + throw new TypeError('Tree element of wrong type is passed. Bytes array expected.') + } + element = data.slice(0) // clone array of 8-bit integers + elementsHash = hash(element) + } else if (isObject(data)) { + if (isInstanceofOfNewType(type)) { + element = data + elementsHash = hash(element, type) + } else { + throw new TypeError('Invalid type of type parameter.') + } + } else { + throw new TypeError('Invalid value of data parameter.') } + elements.push(element) + return elementsHash + } + /** * Recursive tree traversal function * @param {Object} node @@ -84,121 +84,121 @@ export function merkleProof(rootHash, count, proofNode, range, type) { * @param {number} index * @returns {string} */ - function recursive(node, depth, index) { - var hashLeft; - var hashRight; - var summingBuffer; + function recursive (node, depth, index) { + var hashLeft + var hashRight + var summingBuffer // case with single node in tree - if (depth === 0 && node.val !== undefined) { - return getHash(node.val, depth, index * 2); - } + if (depth === 0 && node.val !== undefined) { + return getHash(node.val, depth, index * 2) + } - if (node.left !== undefined) { - if (typeof node.left === 'string') { - if (!validateHexadecimal(node.left)) { - throw new TypeError('Tree element of wrong type is passed. Hexadecimal expected.'); - } - hashLeft = node.left; - } else if (isObject(node.left)) { - if (node.left.val !== undefined) { - hashLeft = getHash(node.left.val, depth, index * 2); - } else { - hashLeft = recursive(node.left, depth + 1, index * 2); - } - } else { - throw new TypeError('Invalid type of left node.'); - } + if (node.left !== undefined) { + if (typeof node.left === 'string') { + if (!validateHexadecimal(node.left)) { + throw new TypeError('Tree element of wrong type is passed. Hexadecimal expected.') + } + hashLeft = node.left + } else if (isObject(node.left)) { + if (node.left.val !== undefined) { + hashLeft = getHash(node.left.val, depth, index * 2) } else { - throw new Error('Left node is missed.'); + hashLeft = recursive(node.left, depth + 1, index * 2) } + } else { + throw new TypeError('Invalid type of left node.') + } + } else { + throw new Error('Left node is missed.') + } - if (depth === 0) { - rootBranch = 'right'; - } + if (depth === 0) { + rootBranch = 'right' + } - if (node.right !== undefined) { - if (typeof node.right === 'string') { - if (!validateHexadecimal(node.right)) { - throw new TypeError('Tree element of wrong type is passed. Hexadecimal expected.'); - } - hashRight = node.right; - } else if (isObject(node.right)) { - if (node.right.val !== undefined) { - hashRight = getHash(node.right.val, depth, index * 2 + 1); - } else { - hashRight = recursive(node.right, depth + 1, index * 2 + 1); - } - } else { - throw new TypeError('Invalid type of right node.'); - } - - summingBuffer = new Uint8Array(64); - summingBuffer.set(hexadecimalToUint8Array(hashLeft)); - summingBuffer.set(hexadecimalToUint8Array(hashRight), 32); - } else if (depth === 0 || rootBranch === 'left') { - throw new Error('Right leaf is missed in left branch of tree.'); + if (node.right !== undefined) { + if (typeof node.right === 'string') { + if (!validateHexadecimal(node.right)) { + throw new TypeError('Tree element of wrong type is passed. Hexadecimal expected.') + } + hashRight = node.right + } else if (isObject(node.right)) { + if (node.right.val !== undefined) { + hashRight = getHash(node.right.val, depth, index * 2 + 1) } else { - summingBuffer = hexadecimalToUint8Array(hashLeft); + hashRight = recursive(node.right, depth + 1, index * 2 + 1) } - - return hash(summingBuffer); + } else { + throw new TypeError('Invalid type of right node.') + } + + summingBuffer = new Uint8Array(64) + summingBuffer.set(hexadecimalToUint8Array(hashLeft)) + summingBuffer.set(hexadecimalToUint8Array(hashRight), 32) + } else if (depth === 0 || rootBranch === 'left') { + throw new Error('Right leaf is missed in left branch of tree.') + } else { + summingBuffer = hexadecimalToUint8Array(hashLeft) } + return hash(summingBuffer) + } + // validate rootHash - if (!validateHexadecimal(rootHash)) { - throw new TypeError('Root hash of wrong type is passed. Hexadecimal expected.'); - } + if (!validateHexadecimal(rootHash)) { + throw new TypeError('Root hash of wrong type is passed. Hexadecimal expected.') + } // validate count - if (!(typeof count === 'number' || typeof count === 'string')) { - throw new TypeError('Invalid value is passed as count parameter. Number or string is expected.'); - } + if (!(typeof count === 'number' || typeof count === 'string')) { + throw new TypeError('Invalid value is passed as count parameter. Number or string is expected.') + } - count = bigInt(count); + count = bigInt(count) - if (count.lt(0)) { - throw new RangeError('Invalid count parameter. Count can\'t be below zero.'); - } + if (count.lt(0)) { + throw new RangeError('Invalid count parameter. Count can\'t be below zero.') + } // validate range - if (Array.isArray(range) === false || range.length !== 2) { - throw new TypeError('Invalid type of range parameter. Array of two elements expected.'); - } else if (!(typeof range[0] === 'number' || typeof range[0] === 'string')) { - throw new TypeError('Invalid value is passed as start of range parameter.'); - } else if (!(typeof range[1] === 'number' || typeof range[1] === 'string')) { - throw new TypeError('Invalid value is passed as end of range parameter.'); - } - - var rangeStart = bigInt(range[0]); - var rangeEnd = bigInt(range[1]); - - if (rangeStart.gt(rangeEnd)) { - throw new RangeError('Invalid range parameter. Start index can\'t be out of range.'); - } else if (rangeStart.lt(0)) { - throw new RangeError('Invalid range parameter. Start index can\'t be below zero.'); - } else if (rangeEnd.lt(0)) { - throw new RangeError('Invalid range parameter. End index can\'t be below zero.'); - } else if (rangeStart.gt(count.minus(1))) { - return []; - } + if (Array.isArray(range) === false || range.length !== 2) { + throw new TypeError('Invalid type of range parameter. Array of two elements expected.') + } else if (!(typeof range[0] === 'number' || typeof range[0] === 'string')) { + throw new TypeError('Invalid value is passed as start of range parameter.') + } else if (!(typeof range[1] === 'number' || typeof range[1] === 'string')) { + throw new TypeError('Invalid value is passed as end of range parameter.') + } + + var rangeStart = bigInt(range[0]) + var rangeEnd = bigInt(range[1]) + + if (rangeStart.gt(rangeEnd)) { + throw new RangeError('Invalid range parameter. Start index can\'t be out of range.') + } else if (rangeStart.lt(0)) { + throw new RangeError('Invalid range parameter. Start index can\'t be below zero.') + } else if (rangeEnd.lt(0)) { + throw new RangeError('Invalid range parameter. End index can\'t be below zero.') + } else if (rangeStart.gt(count.minus(1))) { + return [] + } // validate proofNode - if (isObject(proofNode) === false) { - throw new TypeError('Invalid type of proofNode parameter. Object expected.'); - } + if (isObject(proofNode) === false) { + throw new TypeError('Invalid type of proofNode parameter. Object expected.') + } - var height = calcHeight(count); - var start = rangeStart; - var end = rangeEnd.lt(count) ? rangeEnd : count.minus(1); + var height = calcHeight(count) + var start = rangeStart + var end = rangeEnd.lt(count) ? rangeEnd : count.minus(1) - var actualHash = recursive(proofNode, 0, 0); + var actualHash = recursive(proofNode, 0, 0) - if (rootHash.toLowerCase() !== actualHash) { - throw new Error('rootHash parameter is not equal to actual hash.'); - } else if (bigInt(elements.length).neq(end.eq(start) ? 1 : end.minus(start).plus(1))) { - throw new Error('Actual elements in tree amount is not equal to requested.'); - } + if (rootHash.toLowerCase() !== actualHash) { + throw new Error('rootHash parameter is not equal to actual hash.') + } else if (bigInt(elements.length).neq(end.eq(start) ? 1 : end.minus(start).plus(1))) { + throw new Error('Actual elements in tree amount is not equal to requested.') + } - return elements; + return elements } diff --git a/src/crypto/index.js b/src/crypto/index.js index b43471e..59ad189 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -1,10 +1,10 @@ -import bigInt from 'big-integer'; -import sha from 'sha.js'; -import nacl from 'tweetnacl'; -import {isInstanceofOfNewType} from '../types/generic'; -import {isInstanceofOfNewMessage} from '../types/message'; -import * as validate from '../types/validate'; -import * as convert from '../types/convert'; +import bigInt from 'big-integer' +import sha from 'sha.js' +import nacl from 'tweetnacl' +import {isInstanceofOfNewType} from '../types/generic' +import {isInstanceofOfNewMessage} from '../types/message' +import * as validate from '../types/validate' +import * as convert from '../types/convert' /** * Get SHA256 hash @@ -12,24 +12,24 @@ import * as convert from '../types/convert'; * @param {NewType|NewMessage} [type] - optional, used only if data of {Object} type is passed * @return {string} */ -export function hash(data, type) { - var buffer; - - if (isInstanceofOfNewType(type) || isInstanceofOfNewMessage(type)) { - buffer = type.serialize(data); - } else if (type === undefined) { - if (data instanceof Uint8Array) { - buffer = data; - } else if (Array.isArray(data)) { - buffer = new Uint8Array(data); - } else { - throw new TypeError('Invalid data parameter.'); - } +export function hash (data, type) { + var buffer + + if (isInstanceofOfNewType(type) || isInstanceofOfNewMessage(type)) { + buffer = type.serialize(data) + } else if (type === undefined) { + if (data instanceof Uint8Array) { + buffer = data + } else if (Array.isArray(data)) { + buffer = new Uint8Array(data) } else { - throw new TypeError('Wrong type of data.'); + throw new TypeError('Invalid data parameter.') } + } else { + throw new TypeError('Wrong type of data.') + } - return sha('sha256').update(buffer, 'utf8').digest('hex'); + return sha('sha256').update(buffer, 'utf8').digest('hex') } /** @@ -39,36 +39,36 @@ export function hash(data, type) { * @param {NewType|NewMessage} [type] - optional, used only if data of {Object} type is passed * @return {string} */ -export function sign(secretKey, data, type) { - var secretKeyUint8Array; - var buffer; - var signature; - - if (!validate.validateHexadecimal(secretKey, 64)) { - throw new TypeError('secretKey of wrong type is passed. Hexadecimal expected.'); - } - - secretKeyUint8Array = convert.hexadecimalToUint8Array(secretKey); - - if (isInstanceofOfNewType(type)) { - buffer = new Uint8Array(type.serialize(data)); - } else if (isInstanceofOfNewMessage(type)) { - buffer = new Uint8Array(type.serialize(data, true)); - } else if (type === undefined) { - if (data instanceof Uint8Array) { - buffer = data; - } else if (Array.isArray(data)) { - buffer = new Uint8Array(data); - } else { - throw new TypeError('Invalid data parameter.'); - } +export function sign (secretKey, data, type) { + var secretKeyUint8Array + var buffer + var signature + + if (!validate.validateHexadecimal(secretKey, 64)) { + throw new TypeError('secretKey of wrong type is passed. Hexadecimal expected.') + } + + secretKeyUint8Array = convert.hexadecimalToUint8Array(secretKey) + + if (isInstanceofOfNewType(type)) { + buffer = new Uint8Array(type.serialize(data)) + } else if (isInstanceofOfNewMessage(type)) { + buffer = new Uint8Array(type.serialize(data, true)) + } else if (type === undefined) { + if (data instanceof Uint8Array) { + buffer = data + } else if (Array.isArray(data)) { + buffer = new Uint8Array(data) } else { - throw new TypeError('Wrong type of data.'); + throw new TypeError('Invalid data parameter.') } + } else { + throw new TypeError('Wrong type of data.') + } - signature = nacl.sign.detached(buffer, secretKeyUint8Array); + signature = nacl.sign.detached(buffer, secretKeyUint8Array) - return convert.uint8ArrayToHexadecimal(signature); + return convert.uint8ArrayToHexadecimal(signature) } /** @@ -79,38 +79,38 @@ export function sign(secretKey, data, type) { * @param {NewType|NewMessage} [type] - optional, used only if data of {Object} type is passed * @return {boolean} */ -export function verifySignature(signature, publicKey, data, type) { - var signatureUint8Array; - var publicKeyUint8Array; - var buffer; - - if (!validate.validateHexadecimal(signature, 64)) { - throw new TypeError('Signature of wrong type is passed. Hexadecimal expected.'); - } - - signatureUint8Array = convert.hexadecimalToUint8Array(signature); - - if (!validate.validateHexadecimal(publicKey)) { - throw new TypeError('publicKey of wrong type is passed. Hexadecimal expected.'); - } - - publicKeyUint8Array = convert.hexadecimalToUint8Array(publicKey); - - if (isInstanceofOfNewType(type)) { - buffer = new Uint8Array(type.serialize(data)); - } else if (isInstanceofOfNewMessage(type)) { - buffer = new Uint8Array(type.serialize(data, true)); - } else if (type === undefined) { - if (data instanceof Uint8Array) { - buffer = data; - } else if (Array.isArray(data)) { - buffer = new Uint8Array(data); - } - } else { - throw new TypeError('Wrong type of data.'); +export function verifySignature (signature, publicKey, data, type) { + var signatureUint8Array + var publicKeyUint8Array + var buffer + + if (!validate.validateHexadecimal(signature, 64)) { + throw new TypeError('Signature of wrong type is passed. Hexadecimal expected.') + } + + signatureUint8Array = convert.hexadecimalToUint8Array(signature) + + if (!validate.validateHexadecimal(publicKey)) { + throw new TypeError('publicKey of wrong type is passed. Hexadecimal expected.') + } + + publicKeyUint8Array = convert.hexadecimalToUint8Array(publicKey) + + if (isInstanceofOfNewType(type)) { + buffer = new Uint8Array(type.serialize(data)) + } else if (isInstanceofOfNewMessage(type)) { + buffer = new Uint8Array(type.serialize(data, true)) + } else if (type === undefined) { + if (data instanceof Uint8Array) { + buffer = data + } else if (Array.isArray(data)) { + buffer = new Uint8Array(data) } + } else { + throw new TypeError('Wrong type of data.') + } - return nacl.sign.detached.verify(buffer, signatureUint8Array, publicKeyUint8Array); + return nacl.sign.detached.verify(buffer, signatureUint8Array, publicKeyUint8Array) } /** @@ -119,22 +119,22 @@ export function verifySignature(signature, publicKey, data, type) { * publicKey {string} * secretKey {string} */ -export function keyPair() { - var pair = nacl.sign.keyPair(); - var publicKey = convert.uint8ArrayToHexadecimal(pair.publicKey); - var secretKey = convert.uint8ArrayToHexadecimal(pair.secretKey); - - return { - publicKey: publicKey, - secretKey: secretKey - }; +export function keyPair () { + var pair = nacl.sign.keyPair() + var publicKey = convert.uint8ArrayToHexadecimal(pair.publicKey) + var secretKey = convert.uint8ArrayToHexadecimal(pair.secretKey) + + return { + publicKey: publicKey, + secretKey: secretKey + } } /** * Get random number of cryptographic quality * @returns {string} */ -export function randomUint64() { - var buffer = nacl.randomBytes(8); - return bigInt.fromArray(Array.from(buffer), 256).toString(); +export function randomUint64 () { + var buffer = nacl.randomBytes(8) + return bigInt.fromArray(Array.from(buffer), 256).toString() } diff --git a/src/helpers.js b/src/helpers.js index 9e24eda..f13e7b6 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -3,6 +3,6 @@ * @param obj * @returns {boolean} */ -export function isObject(obj) { - return (typeof obj === 'object' && Array.isArray(obj) === false && obj !== null && !(obj instanceof Date)); +export function isObject (obj) { + return (typeof obj === 'object' && Array.isArray(obj) === false && obj !== null && !(obj instanceof Date)) } diff --git a/src/index.js b/src/index.js index 6672bdc..6ba0022 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,3 @@ -export * from './types'; -export * from './crypto'; -export * from './blockchain'; +export * from './types' +export * from './crypto' +export * from './blockchain' diff --git a/src/types/convert.js b/src/types/convert.js index c98b1f6..b3bf70b 100644 --- a/src/types/convert.js +++ b/src/types/convert.js @@ -1,26 +1,26 @@ -import * as validate from '../types/validate'; +import * as validate from '../types/validate' /** * Convert hexadecimal string into uint8Array * @param {string} str * @returns {Uint8Array} */ -export function hexadecimalToUint8Array(str) { - if (typeof str !== 'string') { - throw new TypeError('Wrong data type passed to convertor. Hexadecimal string is expected'); - } +export function hexadecimalToUint8Array (str) { + if (typeof str !== 'string') { + throw new TypeError('Wrong data type passed to convertor. Hexadecimal string is expected') + } - if (!validate.validateHexadecimal(str, str.length / 2)) { - throw new TypeError('String of wrong type is passed. Hexadecimal expected.'); - } + if (!validate.validateHexadecimal(str, str.length / 2)) { + throw new TypeError('String of wrong type is passed. Hexadecimal expected.') + } - var uint8arr = new Uint8Array(str.length / 2); + var uint8arr = new Uint8Array(str.length / 2) - for (var i = 0, j = 0; i < str.length; i += 2, j++) { - uint8arr[j] = parseInt(str.substr(i, 2), 16); - } + for (var i = 0, j = 0; i < str.length; i += 2, j++) { + uint8arr[j] = parseInt(str.substr(i, 2), 16) + } - return uint8arr; + return uint8arr } /** @@ -28,26 +28,26 @@ export function hexadecimalToUint8Array(str) { * @param {string} str * @returns {string} */ -export function hexadecimalToBinaryString(str) { - var binaryStr = ''; +export function hexadecimalToBinaryString (str) { + var binaryStr = '' - if (typeof str !== 'string') { - throw new TypeError('Wrong data type passed to convertor. Hexadecimal string is expected'); - } + if (typeof str !== 'string') { + throw new TypeError('Wrong data type passed to convertor. Hexadecimal string is expected') + } - if (!validate.validateHexadecimal(str, Math.ceil(str.length / 2))) { - throw new TypeError('String of wrong type is passed. Hexadecimal expected.'); - } + if (!validate.validateHexadecimal(str, Math.ceil(str.length / 2))) { + throw new TypeError('String of wrong type is passed. Hexadecimal expected.') + } - for (var i = 0; i < str.length; i++) { - var bin = parseInt(str[i], 16).toString(2); - while (bin.length < 4) { - bin = '0' + bin; - } - binaryStr += bin; + for (var i = 0; i < str.length; i++) { + var bin = parseInt(str[i], 16).toString(2) + while (bin.length < 4) { + bin = '0' + bin } + binaryStr += bin + } - return binaryStr; + return binaryStr } /** @@ -55,20 +55,20 @@ export function hexadecimalToBinaryString(str) { * @param {Uint8Array} uint8arr * @returns {string} */ -export function uint8ArrayToHexadecimal(uint8arr) { - var str = ''; +export function uint8ArrayToHexadecimal (uint8arr) { + var str = '' - if (!(uint8arr instanceof Uint8Array)) { - throw new TypeError('Wrong data type of array of 8-bit integers. Uint8Array is expected'); - } + if (!(uint8arr instanceof Uint8Array)) { + throw new TypeError('Wrong data type of array of 8-bit integers. Uint8Array is expected') + } - for (var i = 0; i < uint8arr.length; i++) { - var hex = uint8arr[i].toString(16); - hex = (hex.length === 1) ? '0' + hex : hex; - str += hex; - } + for (var i = 0; i < uint8arr.length; i++) { + var hex = uint8arr[i].toString(16) + hex = (hex.length === 1) ? '0' + hex : hex + str += hex + } - return str.toLowerCase(); + return str.toLowerCase() } /** @@ -76,22 +76,22 @@ export function uint8ArrayToHexadecimal(uint8arr) { * @param {string} binaryStr * @returns {Uint8Array} */ -export function binaryStringToUint8Array(binaryStr) { - var array = []; +export function binaryStringToUint8Array (binaryStr) { + var array = [] - if (typeof binaryStr !== 'string') { - throw new TypeError('Wrong data type passed to convertor. Binary string is expected'); - } + if (typeof binaryStr !== 'string') { + throw new TypeError('Wrong data type passed to convertor. Binary string is expected') + } - if (!validate.validateBinaryString(binaryStr)) { - throw new TypeError('String of wrong type is passed. Binary string expected.'); - } + if (!validate.validateBinaryString(binaryStr)) { + throw new TypeError('String of wrong type is passed. Binary string expected.') + } - for (var i = 0; i < binaryStr.length; i += 8) { - array.push(parseInt(binaryStr.substr(i, 8), 2)); - } + for (var i = 0; i < binaryStr.length; i += 8) { + array.push(parseInt(binaryStr.substr(i, 8), 2)) + } - return new Uint8Array(array); + return new Uint8Array(array) } /** @@ -99,24 +99,24 @@ export function binaryStringToUint8Array(binaryStr) { * @param {string} binaryStr * @returns {string} */ -export function binaryStringToHexadecimal(binaryStr) { - var str = ''; +export function binaryStringToHexadecimal (binaryStr) { + var str = '' - if (typeof binaryStr !== 'string') { - throw new TypeError('Wrong data type passed to convertor. Binary string is expected'); - } + if (typeof binaryStr !== 'string') { + throw new TypeError('Wrong data type passed to convertor. Binary string is expected') + } - if (!validate.validateBinaryString(binaryStr)) { - throw new TypeError('String of wrong type is passed. Binary string expected.'); - } + if (!validate.validateBinaryString(binaryStr)) { + throw new TypeError('String of wrong type is passed. Binary string expected.') + } - for (var i = 0; i < binaryStr.length; i += 8) { - var hex = (parseInt(binaryStr.substr(i, 8), 2)).toString(16); - hex = (hex.length === 1) ? '0' + hex : hex; - str += hex; - } + for (var i = 0; i < binaryStr.length; i += 8) { + var hex = (parseInt(binaryStr.substr(i, 8), 2)).toString(16) + hex = (hex.length === 1) ? '0' + hex : hex + str += hex + } - return str.toLowerCase(); + return str.toLowerCase() } /** @@ -125,42 +125,42 @@ export function binaryStringToHexadecimal(binaryStr) { * @param {number} [len] - optional * @returns {Uint8Array} */ -export function stringToUint8Array(str, len) { - var array; - var from = 0; - - if (typeof str !== 'string') { - throw new TypeError('Wrong data type passed to convertor. String is expected'); - } - - if (len > 0) { - array = new Array(len); - array.fill(0); +export function stringToUint8Array (str, len) { + var array + var from = 0 + + if (typeof str !== 'string') { + throw new TypeError('Wrong data type passed to convertor. String is expected') + } + + if (len > 0) { + array = new Array(len) + array.fill(0) + } else { + array = [] + } + + for (var i = 0; i < str.length; i++) { + var c = str.charCodeAt(i) + + if (c < 128) { + array[from++] = c + } else if (c < 2048) { + array[from++] = (c >> 6) | 192 + array[from++] = (c & 63) | 128 + } else if (((c & 0xFC00) === 0xD800) && (i + 1) < str.length && ((str.charCodeAt(i + 1) & 0xFC00) === 0xDC00)) { + // surrogate pair + c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF) + array[from++] = (c >> 18) | 240 + array[from++] = ((c >> 12) & 63) | 128 + array[from++] = ((c >> 6) & 63) | 128 + array[from++] = (c & 63) | 128 } else { - array = []; - } - - for (var i = 0; i < str.length; i++) { - var c = str.charCodeAt(i); - - if (c < 128) { - array[from++] = c; - } else if (c < 2048) { - array[from++] = (c >> 6) | 192; - array[from++] = (c & 63) | 128; - } else if (((c & 0xFC00) == 0xD800) && (i + 1) < str.length && ((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) { - // surrogate pair - c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF); - array[from++] = (c >> 18) | 240; - array[from++] = ((c >> 12) & 63) | 128; - array[from++] = ((c >> 6) & 63) | 128; - array[from++] = (c & 63) | 128; - } else { - array[from++] = (c >> 12) | 224; - array[from++] = ((c >> 6) & 63) | 128; - array[from++] = (c & 63) | 128; - } + array[from++] = (c >> 12) | 224 + array[from++] = ((c >> 6) & 63) | 128 + array[from++] = (c & 63) | 128 } + } - return new Uint8Array(array); + return new Uint8Array(array) } diff --git a/src/types/generic.js b/src/types/generic.js index 2023985..27e5086 100644 --- a/src/types/generic.js +++ b/src/types/generic.js @@ -1,54 +1,54 @@ -import * as serialization from './serialization'; -import * as crypto from '../crypto'; +import * as serialization from './serialization' +import * as crypto from '../crypto' /** * @constructor * @param {Object} type */ class NewType { - constructor(type) { - this.size = type.size; - this.fields = type.fields; - } + constructor (type) { + this.size = type.size + this.fields = type.fields + } - /** - * Serialize data of NewType type into array of 8-bit integers - * @param {Object} data - * @returns {Array} - */ - serialize(data) { - return serialization.serialize([], 0, data, this); - } + /** + * Serialize data of NewType type into array of 8-bit integers + * @param {Object} data + * @returns {Array} + */ + serialize (data) { + return serialization.serialize([], 0, data, this) + } - /** - * Get SHA256 hash - * @param {Object} data - * @returns {string} - */ - hash(data) { - return crypto.hash(data, this); - } + /** + * Get SHA256 hash + * @param {Object} data + * @returns {string} + */ + hash (data) { + return crypto.hash(data, this) + } - /** - * Get ED25519 signature - * @param {string} secretKey - * @param {Object} data - * @returns {string} - */ - sign(secretKey, data) { - return crypto.sign(secretKey, data, this); - } + /** + * Get ED25519 signature + * @param {string} secretKey + * @param {Object} data + * @returns {string} + */ + sign (secretKey, data) { + return crypto.sign(secretKey, data, this) + } - /** - * Verifies ED25519 signature - * @param {string} signature - * @param {string} publicKey - * @param {Object} data - * @returns {boolean} - */ - verifySignature(signature, publicKey, data) { - return crypto.verifySignature(signature, publicKey, data, this); - } + /** + * Verifies ED25519 signature + * @param {string} signature + * @param {string} publicKey + * @param {Object} data + * @returns {boolean} + */ + verifySignature (signature, publicKey, data) { + return crypto.verifySignature(signature, publicKey, data, this) + } } /** @@ -56,8 +56,8 @@ class NewType { * @param {Object} type * @returns {NewType} */ -export function newType(type) { - return new NewType(type); +export function newType (type) { + return new NewType(type) } /** @@ -65,6 +65,6 @@ export function newType(type) { * @param {Object} type * @returns {boolean} */ -export function isInstanceofOfNewType(type) { - return type instanceof NewType; +export function isInstanceofOfNewType (type) { + return type instanceof NewType } diff --git a/src/types/index.js b/src/types/index.js index c64b72a..958b72b 100644 --- a/src/types/index.js +++ b/src/types/index.js @@ -1,4 +1,4 @@ -export * from './primitive'; -export * from './generic'; -export * from './message'; -export * from './convert'; +export * from './primitive' +export * from './generic' +export * from './message' +export * from './convert' diff --git a/src/types/message.js b/src/types/message.js index 1b5d76f..6c7687a 100644 --- a/src/types/message.js +++ b/src/types/message.js @@ -1,24 +1,24 @@ -import * as primitive from './primitive'; -import {newType} from './generic'; -import * as serialization from './serialization'; -import * as crypto from '../crypto'; +import * as primitive from './primitive' +import {newType} from './generic' +import * as serialization from './serialization' +import * as crypto from '../crypto' -const SIGNATURE_LENGTH = 64; +const SIGNATURE_LENGTH = 64 /** * @constructor * @param {Object} type */ class NewMessage { - constructor(type) { - this.size = type.size; - this.network_id = type.network_id; - this.protocol_version = type.protocol_version; - this.message_id = type.message_id; - this.service_id = type.service_id; - this.signature = type.signature; - this.fields = type.fields; - } + constructor (type) { + this.size = type.size + this.network_id = type.network_id + this.protocol_version = type.protocol_version + this.message_id = type.message_id + this.service_id = type.service_id + this.signature = type.signature + this.fields = type.fields + } /** * Serialize data of NewMessage type into array of 8-bit integers @@ -26,48 +26,48 @@ class NewMessage { * @param {boolean} [cutSignature] - optional parameter used flag that signature should not be appended to serialized data * @returns {Array} */ - serialize(data, cutSignature) { - var MessageHead = newType({ - size: 10, - fields: { - network_id: {type: primitive.Uint8, size: 1, from: 0, to: 1}, - protocol_version: {type: primitive.Uint8, size: 1, from: 1, to: 2}, - message_id: {type: primitive.Uint16, size: 2, from: 2, to: 4}, - service_id: {type: primitive.Uint16, size: 2, from: 4, to: 6}, - payload: {type: primitive.Uint32, size: 4, from: 6, to: 10} - } - }); + serialize (data, cutSignature) { + var MessageHead = newType({ + size: 10, + fields: { + network_id: {type: primitive.Uint8, size: 1, from: 0, to: 1}, + protocol_version: {type: primitive.Uint8, size: 1, from: 1, to: 2}, + message_id: {type: primitive.Uint16, size: 2, from: 2, to: 4}, + service_id: {type: primitive.Uint16, size: 2, from: 4, to: 6}, + payload: {type: primitive.Uint32, size: 4, from: 6, to: 10} + } + }) - var buffer = MessageHead.serialize({ - network_id: this.network_id, - protocol_version: this.protocol_version, - message_id: this.message_id, - service_id: this.service_id, - payload: 0 // placeholder, real value will be inserted later - }); + var buffer = MessageHead.serialize({ + network_id: this.network_id, + protocol_version: this.protocol_version, + message_id: this.message_id, + service_id: this.service_id, + payload: 0 // placeholder, real value will be inserted later + }) // serialize and append message body - buffer = serialization.serialize(buffer, MessageHead.size, data, this); + buffer = serialization.serialize(buffer, MessageHead.size, data, this) // calculate payload and insert it into buffer - primitive.Uint32(buffer.length + SIGNATURE_LENGTH, buffer, MessageHead.fields.payload.from, MessageHead.fields.payload.to); + primitive.Uint32(buffer.length + SIGNATURE_LENGTH, buffer, MessageHead.fields.payload.from, MessageHead.fields.payload.to) - if (cutSignature !== true) { + if (cutSignature !== true) { // append signature - primitive.Digest(this.signature, buffer, buffer.length, buffer.length + SIGNATURE_LENGTH); - } - - return buffer; + primitive.Digest(this.signature, buffer, buffer.length, buffer.length + SIGNATURE_LENGTH) } + return buffer + } + /** * Get SHA256 hash * @param {Object} data * @returns {string} */ - hash(data) { - return crypto.hash(data, this); - } + hash (data) { + return crypto.hash(data, this) + } /** * Get ED25519 signature @@ -75,9 +75,9 @@ class NewMessage { * @param {Object} data * @returns {string} */ - sign(secretKey, data) { - return crypto.sign(secretKey, data, this); - } + sign (secretKey, data) { + return crypto.sign(secretKey, data, this) + } /** * Verifies ED25519 signature @@ -86,9 +86,9 @@ class NewMessage { * @param {Object} data * @returns {boolean} */ - verifySignature(signature, publicKey, data) { - return crypto.verifySignature(signature, publicKey, data, this); - } + verifySignature (signature, publicKey, data) { + return crypto.verifySignature(signature, publicKey, data, this) + } } /** @@ -96,8 +96,8 @@ class NewMessage { * @param {Object} type * @returns {NewMessage} */ -export function newMessage(type) { - return new NewMessage(type); +export function newMessage (type) { + return new NewMessage(type) } /** @@ -105,6 +105,6 @@ export function newMessage(type) { * @param type * @returns {boolean} */ -export function isInstanceofOfNewMessage(type) { - return type instanceof NewMessage; +export function isInstanceofOfNewMessage (type) { + return type instanceof NewMessage } diff --git a/src/types/primitive.js b/src/types/primitive.js index 60aa7c4..a841d38 100644 --- a/src/types/primitive.js +++ b/src/types/primitive.js @@ -1,18 +1,18 @@ -import bigInt from 'big-integer'; -import * as validate from './validate'; - -const MIN_INT8 = -128; -const MAX_INT8 = 127; -const MIN_INT16 = -32768; -const MAX_INT16 = 32767; -const MIN_INT32 = -2147483648; -const MAX_INT32 = 2147483647; -const MIN_INT64 = '-9223372036854775808'; -const MAX_INT64 = '9223372036854775807'; -const MAX_UINT8 = 255; -const MAX_UINT16 = 65535; -const MAX_UINT32 = 4294967295; -const MAX_UINT64 = '18446744073709551615'; +import bigInt from 'big-integer' +import * as validate from './validate' + +const MIN_INT8 = -128 +const MAX_INT8 = 127 +const MIN_INT16 = -32768 +const MAX_INT16 = 32767 +const MIN_INT32 = -2147483648 +const MAX_INT32 = 2147483647 +const MIN_INT64 = '-9223372036854775808' +const MAX_INT64 = '9223372036854775807' +const MAX_UINT8 = 255 +const MAX_UINT16 = 65535 +const MAX_UINT32 = 4294967295 +const MAX_UINT64 = '18446744073709551615' /** * @param {string} str @@ -20,15 +20,15 @@ const MAX_UINT64 = '18446744073709551615'; * @param {number} from * @param {number} to */ -function insertHexadecimalToByteArray(str, buffer, from, to) { - for (var i = 0; i < str.length; i += 2) { - buffer[from] = parseInt(str.substr(i, 2), 16); - from++; - - if (from > to) { - break; - } +function insertHexadecimalToByteArray (str, buffer, from, to) { + for (var i = 0; i < str.length; i += 2) { + buffer[from] = parseInt(str.substr(i, 2), 16) + from++ + + if (from > to) { + break } + } } /** @@ -39,14 +39,14 @@ function insertHexadecimalToByteArray(str, buffer, from, to) { * @param {number} to * @returns {boolean} */ -function insertIntegerToByteArray(number, buffer, from, to) { - var value = bigInt(number); // convert a number-like object into a big integer - - for (var pos = from; pos < to; pos++) { - var divmod = value.divmod(256); - buffer[pos] = divmod.remainder.value; - value = divmod.quotient; - } +function insertIntegerToByteArray (number, buffer, from, to) { + var value = bigInt(number) // convert a number-like object into a big integer + + for (var pos = from; pos < to; pos++) { + var divmod = value.divmod(256) + buffer[pos] = divmod.remainder.value + value = divmod.quotient + } } /** @@ -55,15 +55,15 @@ function insertIntegerToByteArray(number, buffer, from, to) { * @param {number} from * @param {number} to */ -function insertByteArrayToByteArray(arr, buffer, from, to) { - for (var i = 0; i < arr.length; i++) { - buffer[from] = arr[i]; - from++; - - if (from > to) { - break; - } +function insertByteArrayToByteArray (arr, buffer, from, to) { + for (var i = 0; i < arr.length; i++) { + buffer[from] = arr[i] + from++ + + if (from > to) { + break } + } } /** @@ -71,28 +71,28 @@ function insertByteArrayToByteArray(arr, buffer, from, to) { * @param {Array} buffer * @param {number} from */ -function insertStringToByteArray(str, buffer, from) { - for (var i = 0; i < str.length; i++) { - var c = str.charCodeAt(i); - - if (c < 128) { - buffer[from++] = c; - } else if (c < 2048) { - buffer[from++] = (c >> 6) | 192; - buffer[from++] = (c & 63) | 128; - } else if (((c & 0xFC00) == 0xD800) && (i + 1) < str.length && ((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) { - // surrogate pair - c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF); - buffer[from++] = (c >> 18) | 240; - buffer[from++] = ((c >> 12) & 63) | 128; - buffer[from++] = ((c >> 6) & 63) | 128; - buffer[from++] = (c & 63) | 128; - } else { - buffer[from++] = (c >> 12) | 224; - buffer[from++] = ((c >> 6) & 63) | 128; - buffer[from++] = (c & 63) | 128; - } +function insertStringToByteArray (str, buffer, from) { + for (var i = 0; i < str.length; i++) { + var c = str.charCodeAt(i) + + if (c < 128) { + buffer[from++] = c + } else if (c < 2048) { + buffer[from++] = (c >> 6) | 192 + buffer[from++] = (c & 63) | 128 + } else if (((c & 0xFC00) === 0xD800) && (i + 1) < str.length && ((str.charCodeAt(i + 1) & 0xFC00) === 0xDC00)) { + // surrogate pair + c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF) + buffer[from++] = (c >> 18) | 240 + buffer[from++] = ((c >> 12) & 63) | 128 + buffer[from++] = ((c >> 6) & 63) | 128 + buffer[from++] = (c & 63) | 128 + } else { + buffer[from++] = (c >> 12) | 224 + buffer[from++] = ((c >> 6) & 63) | 128 + buffer[from++] = (c & 63) | 128 } + } } /** @@ -102,18 +102,18 @@ function insertStringToByteArray(str, buffer, from) { * @param {number} to * @returns {Array} */ -export function Int8(value, buffer, from, to) { - if (!validate.validateInteger(value, MIN_INT8, MAX_INT8, from, to, 1)) { - throw new TypeError('Int8 of wrong type is passed: ' + value); - } +export function Int8 (value, buffer, from, to) { + if (!validate.validateInteger(value, MIN_INT8, MAX_INT8, from, to, 1)) { + throw new TypeError('Int8 of wrong type is passed: ' + value) + } - if (value < 0) { - value = MAX_UINT8 + value + 1; - } + if (value < 0) { + value = MAX_UINT8 + value + 1 + } - insertIntegerToByteArray(value, buffer, from, to); + insertIntegerToByteArray(value, buffer, from, to) - return buffer; + return buffer } /** @@ -123,18 +123,18 @@ export function Int8(value, buffer, from, to) { * @param {number} to * @returns {Array} */ -export function Int16(value, buffer, from, to) { - if (!validate.validateInteger(value, MIN_INT16, MAX_INT16, from, to, 2)) { - throw new TypeError('Int16 of wrong type is passed: ' + value); - } +export function Int16 (value, buffer, from, to) { + if (!validate.validateInteger(value, MIN_INT16, MAX_INT16, from, to, 2)) { + throw new TypeError('Int16 of wrong type is passed: ' + value) + } - if (value < 0) { - value = MAX_UINT16 + value + 1; - } + if (value < 0) { + value = MAX_UINT16 + value + 1 + } - insertIntegerToByteArray(value, buffer, from, to); + insertIntegerToByteArray(value, buffer, from, to) - return buffer; + return buffer } /** @@ -144,18 +144,18 @@ export function Int16(value, buffer, from, to) { * @param {number} to * @returns {Array} */ -export function Int32(value, buffer, from, to) { - if (!validate.validateInteger(value, MIN_INT32, MAX_INT32, from, to, 4)) { - throw new TypeError('Int32 of wrong type is passed: ' + value); - } +export function Int32 (value, buffer, from, to) { + if (!validate.validateInteger(value, MIN_INT32, MAX_INT32, from, to, 4)) { + throw new TypeError('Int32 of wrong type is passed: ' + value) + } - if (value < 0) { - value = MAX_UINT32 + value + 1; - } + if (value < 0) { + value = MAX_UINT32 + value + 1 + } - insertIntegerToByteArray(value, buffer, from, to); + insertIntegerToByteArray(value, buffer, from, to) - return buffer; + return buffer } /** @@ -165,20 +165,20 @@ export function Int32(value, buffer, from, to) { * @param {number} to * @returns {Array} */ -export function Int64(value, buffer, from, to) { - if (!validate.validateBigInteger(value, MIN_INT64, MAX_INT64, from, to, 8)) { - throw new TypeError('Int64 of wrong type is passed: ' + value); - } +export function Int64 (value, buffer, from, to) { + if (!validate.validateBigInteger(value, MIN_INT64, MAX_INT64, from, to, 8)) { + throw new TypeError('Int64 of wrong type is passed: ' + value) + } - var val = bigInt(value); + var val = bigInt(value) - if (val.isNegative()) { - val = bigInt(MAX_UINT64).plus(1).plus(val); - } + if (val.isNegative()) { + val = bigInt(MAX_UINT64).plus(1).plus(val) + } - insertIntegerToByteArray(val, buffer, from, to); + insertIntegerToByteArray(val, buffer, from, to) - return buffer; + return buffer } /** @@ -188,14 +188,14 @@ export function Int64(value, buffer, from, to) { * @param {number} to * @returns {Array} */ -export function Uint8(value, buffer, from, to) { - if (!validate.validateInteger(value, 0, MAX_UINT8, from, to, 1)) { - throw new TypeError('Uint8 of wrong type is passed: ' + value); - } +export function Uint8 (value, buffer, from, to) { + if (!validate.validateInteger(value, 0, MAX_UINT8, from, to, 1)) { + throw new TypeError('Uint8 of wrong type is passed: ' + value) + } - insertIntegerToByteArray(value, buffer, from, to); + insertIntegerToByteArray(value, buffer, from, to) - return buffer; + return buffer } /** @@ -205,14 +205,14 @@ export function Uint8(value, buffer, from, to) { * @param {number} to * @returns {Array} */ -export function Uint16(value, buffer, from, to) { - if (!validate.validateInteger(value, 0, MAX_UINT16, from, to, 2)) { - throw new TypeError('Uint16 of wrong type is passed: ' + value); - } +export function Uint16 (value, buffer, from, to) { + if (!validate.validateInteger(value, 0, MAX_UINT16, from, to, 2)) { + throw new TypeError('Uint16 of wrong type is passed: ' + value) + } - insertIntegerToByteArray(value, buffer, from, to); + insertIntegerToByteArray(value, buffer, from, to) - return buffer; + return buffer } /** @@ -222,14 +222,14 @@ export function Uint16(value, buffer, from, to) { * @param {number} to * @returns {Array} */ -export function Uint32(value, buffer, from, to) { - if (!validate.validateInteger(value, 0, MAX_UINT32, from, to, 4)) { - throw new TypeError('Uint32 of wrong type is passed: ' + value); - } +export function Uint32 (value, buffer, from, to) { + if (!validate.validateInteger(value, 0, MAX_UINT32, from, to, 4)) { + throw new TypeError('Uint32 of wrong type is passed: ' + value) + } - insertIntegerToByteArray(value, buffer, from, to); + insertIntegerToByteArray(value, buffer, from, to) - return buffer; + return buffer } /** @@ -239,16 +239,16 @@ export function Uint32(value, buffer, from, to) { * @param {number} to * @returns {Array} */ -export function Uint64(value, buffer, from, to) { - if (!validate.validateBigInteger(value, 0, MAX_UINT64, from, to, 8)) { - throw new TypeError('Uint64 of wrong type is passed: ' + value); - } +export function Uint64 (value, buffer, from, to) { + if (!validate.validateBigInteger(value, 0, MAX_UINT64, from, to, 8)) { + throw new TypeError('Uint64 of wrong type is passed: ' + value) + } - var val = bigInt(value); + var val = bigInt(value) - insertIntegerToByteArray(val, buffer, from, to); + insertIntegerToByteArray(val, buffer, from, to) - return buffer; + return buffer } /** @@ -258,19 +258,19 @@ export function Uint64(value, buffer, from, to) { * @param {number} to * @returns {Array} */ -export function String(string, buffer, from, to) { - if (typeof string !== 'string') { - throw new TypeError('Wrong data type is passed as String. String is required'); - } else if ((to - from) !== 8) { - throw new Error('String segment is of wrong length. 8 bytes long is required to store transmitted value.'); - } - - var bufferLength = buffer.length; - Uint32(bufferLength, buffer, from, from + 4); // index where string content starts in buffer - insertStringToByteArray(string, buffer, bufferLength); // string content - Uint32(buffer.length - bufferLength, buffer, from + 4, from + 8); // string length - - return buffer; +export function String (string, buffer, from, to) { + if (typeof string !== 'string') { + throw new TypeError('Wrong data type is passed as String. String is required') + } else if ((to - from) !== 8) { + throw new Error('String segment is of wrong length. 8 bytes long is required to store transmitted value.') + } + + var bufferLength = buffer.length + Uint32(bufferLength, buffer, from, from + 4) // index where string content starts in buffer + insertStringToByteArray(string, buffer, bufferLength) // string content + Uint32(buffer.length - bufferLength, buffer, from + 4, from + 8) // string length + + return buffer } /** @@ -280,18 +280,18 @@ export function String(string, buffer, from, to) { * @param {number} to * @returns {Array} */ -export function Hash(hash, buffer, from, to) { - if (!validate.validateHexadecimal(hash)) { - throw new TypeError('Hash of wrong type is passed: ' + hash); - } +export function Hash (hash, buffer, from, to) { + if (!validate.validateHexadecimal(hash)) { + throw new TypeError('Hash of wrong type is passed: ' + hash) + } - if ((to - from) !== 32) { - throw new Error('Hash segment is of wrong length. 32 bytes long is required to store transmitted value.'); - } + if ((to - from) !== 32) { + throw new Error('Hash segment is of wrong length. 32 bytes long is required to store transmitted value.') + } - insertHexadecimalToByteArray(hash, buffer, from, to); + insertHexadecimalToByteArray(hash, buffer, from, to) - return buffer; + return buffer } /** @@ -301,18 +301,18 @@ export function Hash(hash, buffer, from, to) { * @param {number} to * @returns {Array} */ -export function Digest(digest, buffer, from, to) { - if (!validate.validateHexadecimal(digest, 64)) { - throw new TypeError('Digest of wrong type is passed: ' + digest); - } +export function Digest (digest, buffer, from, to) { + if (!validate.validateHexadecimal(digest, 64)) { + throw new TypeError('Digest of wrong type is passed: ' + digest) + } - if ((to - from) !== 64) { - throw new Error('Digest segment is of wrong length. 64 bytes long is required to store transmitted value.'); - } + if ((to - from) !== 64) { + throw new Error('Digest segment is of wrong length. 64 bytes long is required to store transmitted value.') + } - insertHexadecimalToByteArray(digest, buffer, from, to); + insertHexadecimalToByteArray(digest, buffer, from, to) - return buffer; + return buffer } /** @@ -322,18 +322,18 @@ export function Digest(digest, buffer, from, to) { * @param {number} to * @returns {Array} */ -export function PublicKey(publicKey, buffer, from, to) { - if (!validate.validateHexadecimal(publicKey)) { - throw new TypeError('PublicKey of wrong type is passed: ' + publicKey); - } +export function PublicKey (publicKey, buffer, from, to) { + if (!validate.validateHexadecimal(publicKey)) { + throw new TypeError('PublicKey of wrong type is passed: ' + publicKey) + } - if ((to - from) !== 32) { - throw new Error('PublicKey segment is of wrong length. 32 bytes long is required to store transmitted value.'); - } + if ((to - from) !== 32) { + throw new Error('PublicKey segment is of wrong length. 32 bytes long is required to store transmitted value.') + } - insertHexadecimalToByteArray(publicKey, buffer, from, to); + insertHexadecimalToByteArray(publicKey, buffer, from, to) - return buffer; + return buffer } /** @@ -343,16 +343,16 @@ export function PublicKey(publicKey, buffer, from, to) { * @param {number} to * @returns {Array} */ -export function Bool(value, buffer, from, to) { - if (typeof value !== 'boolean') { - throw new TypeError('Wrong data type is passed as Boolean. Boolean is required'); - } else if ((to - from) !== 1) { - throw new Error('Bool segment is of wrong length. 1 bytes long is required to store transmitted value.'); - } +export function Bool (value, buffer, from, to) { + if (typeof value !== 'boolean') { + throw new TypeError('Wrong data type is passed as Boolean. Boolean is required') + } else if ((to - from) !== 1) { + throw new Error('Bool segment is of wrong length. 1 bytes long is required to store transmitted value.') + } - insertIntegerToByteArray(value ? 1 : 0, buffer, from, to); + insertIntegerToByteArray(value ? 1 : 0, buffer, from, to) - return buffer; + return buffer } /** @@ -362,16 +362,16 @@ export function Bool(value, buffer, from, to) { * @param {number} to * @returns {Array} */ -export function Timespec(nanoseconds, buffer, from, to) { - if (!validate.validateBigInteger(nanoseconds, 0, MAX_UINT64, from, to, 8)) { - throw new TypeError('Timespec of wrong type is passed: ' + nanoseconds); - } +export function Timespec (nanoseconds, buffer, from, to) { + if (!validate.validateBigInteger(nanoseconds, 0, MAX_UINT64, from, to, 8)) { + throw new TypeError('Timespec of wrong type is passed: ' + nanoseconds) + } - var val = bigInt(nanoseconds); + var val = bigInt(nanoseconds) - insertIntegerToByteArray(val, buffer, from, to); + insertIntegerToByteArray(val, buffer, from, to) - return buffer; + return buffer } /** @@ -381,20 +381,20 @@ export function Timespec(nanoseconds, buffer, from, to) { * @param {number} to * @returns {Array} */ -export function FixedBuffer(value, buffer, from, to) { - var size = to - from; - - if (size < 0) { - throw new Error('FixedBuffer segment is of wrong length.'); - } - - if (typeof value === 'string' && validate.validateHexadecimal(value, size)) { - insertHexadecimalToByteArray(value, buffer, from, to); - } else if (validate.validateBytesArray(value) && size === value.length) { - insertByteArrayToByteArray(value, buffer, from, to); - } else { - throw new TypeError('FixedBuffer of wrong type is passed: ' + value); - } - - return buffer; +export function FixedBuffer (value, buffer, from, to) { + var size = to - from + + if (size < 0) { + throw new Error('FixedBuffer segment is of wrong length.') + } + + if (typeof value === 'string' && validate.validateHexadecimal(value, size)) { + insertHexadecimalToByteArray(value, buffer, from, to) + } else if (validate.validateBytesArray(value) && size === value.length) { + insertByteArrayToByteArray(value, buffer, from, to) + } else { + throw new TypeError('FixedBuffer of wrong type is passed: ' + value) + } + + return buffer } diff --git a/src/types/serialization.js b/src/types/serialization.js index 39be95c..176f201 100644 --- a/src/types/serialization.js +++ b/src/types/serialization.js @@ -1,5 +1,5 @@ -import {isInstanceofOfNewType} from './generic'; -import {Uint32} from './primitive'; +import { isInstanceofOfNewType } from './generic' +import { Uint32 } from './primitive' /** * Serialize data into array of 8-bit integers and insert into buffer @@ -9,55 +9,55 @@ import {Uint32} from './primitive'; * @param type - can be {NewType} or one of built-in types * @returns {Array} */ -export function serialize(buffer, shift, data, type) { - function isFixed(fields) { - for (var fieldName in fields) { - if (!fields.hasOwnProperty(fieldName)) { - continue; - } - - if (isInstanceofOfNewType(fields[fieldName].type)) { - if (!isFixed(fields[fieldName].type.fields)) { - return false; - } - } else if (fields[fieldName].type === String) { - return false; - } +export function serialize (buffer, shift, data, type) { + function isFixed (fields) { + for (const fieldName in fields) { + if (!fields.hasOwnProperty(fieldName)) { + continue + } + + if (isInstanceofOfNewType(fields[fieldName].type)) { + if (!isFixed(fields[fieldName].type.fields)) { + return false } - return true; + } else if (fields[fieldName].type === String) { + return false + } } + return true + } - for (var i = 0; i < type.size; i++) { - buffer[shift + i] = 0; - } + for (let i = 0; i < type.size; i++) { + buffer[shift + i] = 0 + } - for (var fieldName in type.fields) { - if (!type.fields.hasOwnProperty(fieldName)) { - continue; - } + for (const fieldName in type.fields) { + if (!type.fields.hasOwnProperty(fieldName)) { + continue + } - var fieldData = data[fieldName]; + const fieldData = data[fieldName] - if (fieldData === undefined) { - throw new TypeError('Field ' + fieldName + ' is not defined.'); - } + if (fieldData === undefined) { + throw new TypeError('Field ' + fieldName + ' is not defined.') + } - var fieldType = type.fields[fieldName]; - var from = shift + fieldType.from; - - if (isInstanceofOfNewType(fieldType.type)) { - if (isFixed(fieldType.type.fields)) { - buffer = serialize(buffer, from, fieldData, fieldType.type); - } else { - var end = buffer.length; - Uint32(end, buffer, from, from + 4); - buffer = serialize(buffer, end, fieldData, fieldType.type); - Uint32(buffer.length - end, buffer, from + 4, from + 8); - } - } else { - buffer = fieldType.type(fieldData, buffer, from, shift + fieldType.to); - } + const fieldType = type.fields[fieldName] + const from = shift + fieldType.from + + if (isInstanceofOfNewType(fieldType.type)) { + if (isFixed(fieldType.type.fields)) { + buffer = serialize(buffer, from, fieldData, fieldType.type) + } else { + const end = buffer.length + Uint32(end, buffer, from, from + 4) + buffer = serialize(buffer, end, fieldData, fieldType.type) + Uint32(buffer.length - end, buffer, from + 4, from + 8) + } + } else { + buffer = fieldType.type(fieldData, buffer, from, shift + fieldType.to) } + } - return buffer; + return buffer } diff --git a/src/types/validate.js b/src/types/validate.js index d5ae550..eab57fd 100644 --- a/src/types/validate.js +++ b/src/types/validate.js @@ -1,4 +1,4 @@ -import bigInt from 'big-integer'; +import bigInt from 'big-integer' /** * @param {number} value @@ -9,15 +9,15 @@ import bigInt from 'big-integer'; * @param {number} length * @returns {boolean} */ -export function validateInteger(value, min, max, from, to, length) { - if (typeof value !== 'number' || value < min || value > max) { - return false; - } else if ((to - from) !== length) { +export function validateInteger (value, min, max, from, to, length) { + if (typeof value !== 'number' || value < min || value > max) { + return false + } else if ((to - from) !== length) { // segment is of wrong length - return false; - } + return false + } - return true; + return true } /** @@ -29,25 +29,25 @@ export function validateInteger(value, min, max, from, to, length) { * @param {number} length * @returns {*} */ -export function validateBigInteger(value, min, max, from, to, length) { - if (!(typeof value === 'number' || typeof value === 'string')) { - return false; - } else if ((to - from) !== length) { +export function validateBigInteger (value, min, max, from, to, length) { + if (!(typeof value === 'number' || typeof value === 'string')) { + return false + } else if ((to - from) !== length) { // segment is of wrong length - return false; - } + return false + } - try { - var val = bigInt(value); - } catch (error) { - return false; - } + try { + var val = bigInt(value) + } catch (error) { + return false + } - if (val.lt(min) || val.gt(max)) { - return false; - } + if (val.lt(min) || val.gt(max)) { + return false + } - return true; + return true } /** @@ -55,24 +55,24 @@ export function validateBigInteger(value, min, max, from, to, length) { * @param {number} [bytes=32] - optional * @returns {boolean} */ -export function validateHexadecimal(hash, bytes) { - bytes = bytes || 32; +export function validateHexadecimal (hash, bytes) { + bytes = bytes || 32 - if (typeof hash !== 'string') { - return false; - } else if (hash.length !== bytes * 2) { + if (typeof hash !== 'string') { + return false + } else if (hash.length !== bytes * 2) { // 'hexadecimal string is of wrong length - return false; - } + return false + } - for (var i = 0; i < hash.length; i++) { - if (isNaN(parseInt(hash[i], 16))) { + for (var i = 0; i < hash.length; i++) { + if (isNaN(parseInt(hash[i], 16))) { // invalid symbol in hexadecimal string - return false; - } + return false } + } - return true; + return true } /** @@ -80,21 +80,21 @@ export function validateHexadecimal(hash, bytes) { * @param {number} [bytes] - optional * @returns {boolean} */ -export function validateBytesArray(arr, bytes) { - if (Array.isArray(arr) === false && !(arr instanceof Uint8Array)) { - return false; - } if (bytes && arr.length !== bytes) { +export function validateBytesArray (arr, bytes) { + if (Array.isArray(arr) === false && !(arr instanceof Uint8Array)) { + return false + } if (bytes && arr.length !== bytes) { // array is of wrong length - return false; - } + return false + } - for (var i = 0; i < arr.length; i++) { - if (typeof arr[i] !== 'number' || arr[i] < 0 || arr[i] > 255) { - return false; - } + for (var i = 0; i < arr.length; i++) { + if (typeof arr[i] !== 'number' || arr[i] < 0 || arr[i] > 255) { + return false } + } - return true; + return true } /** @@ -102,17 +102,17 @@ export function validateBytesArray(arr, bytes) { * @param {number} [bits] - optional * @returns {*} */ -export function validateBinaryString(str, bits) { - if (bits !== undefined && str.length !== bits) { - return false; - } +export function validateBinaryString (str, bits) { + if (bits !== undefined && str.length !== bits) { + return false + } - for (var i = 0; i < str.length; i++) { - if (str[i] !== '0' && str[i] !== '1') { + for (var i = 0; i < str.length; i++) { + if (str[i] !== '0' && str[i] !== '1') { // wrong bit - return false; - } + return false } + } - return true; + return true } diff --git a/test/blockchain.js b/test/blockchain.js index cc39c4a..46f3130 100644 --- a/test/blockchain.js +++ b/test/blockchain.js @@ -1,399 +1,398 @@ /* eslint-env node, mocha */ +/* eslint-disable no-unused-expressions */ -var expect = require('chai').expect; -var Exonum = require('../src'); +var expect = require('chai').expect +var Exonum = require('../src') -describe('Verify block of precommits', function() { +describe('Verify block of precommits', function () { + var validators = [ + '0b513ad9b4924015ca0902ed079044d3ac5dbec2306f06948c10da8eb6e39f2d', + '91a28a0b74381593a4d9469579208926afc8ad82c8839b7644359b9eba9a4b3a', + '5c9c6df261c9cb840475776aaefcd944b405328fab28f9b3a95ef40490d3de84', + '66cd608b928b88e50e0efeaa33faf1c43cefe07294b0b87e9fe0aba6a3cf7633' + ] + var networkId = 0 - var validators = [ - '0b513ad9b4924015ca0902ed079044d3ac5dbec2306f06948c10da8eb6e39f2d', - '91a28a0b74381593a4d9469579208926afc8ad82c8839b7644359b9eba9a4b3a', - '5c9c6df261c9cb840475776aaefcd944b405328fab28f9b3a95ef40490d3de84', - '66cd608b928b88e50e0efeaa33faf1c43cefe07294b0b87e9fe0aba6a3cf7633' - ]; - var networkId = 0; + it('should return true when valid block with precommits', function () { + var data = require('./common_data/block-with-precommits/valid-block-with-precommits.json') + expect(Exonum.verifyBlock(data, validators, networkId)).to.be.true + }) - it('should return true when valid block with precommits', function() { - var data = require('./common_data/block-with-precommits/valid-block-with-precommits.json'); - expect(Exonum.verifyBlock(data, validators, networkId)).to.be.true; - }); + it('should return false when data of wrong type', function () { + [null, undefined, 42, 'Hello world', [], {}, new Date()].forEach(function (data) { + expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false + }) + }) - it('should return false when data of wrong type', function() { - [null, undefined, 42, 'Hello world', [], {}, new Date()].forEach(function(data) { - expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false; - }); - }); + it('should return false when block info of wrong type', function () { + [null, undefined, 42, 'Hello world', [], new Date()].forEach(function (data) { + expect(Exonum.verifyBlock({block: data}, validators, networkId)).to.be.false + }) + }) - it('should return false when block info of wrong type', function() { - [null, undefined, 42, 'Hello world', [], new Date()].forEach(function(data) { - expect(Exonum.verifyBlock({block: data}, validators, networkId)).to.be.false; - }); - }); + it('should return false when precommits info of wrong type', function () { + [null, undefined, 42, 'Hello world', [], new Date()].forEach(function (precommits) { + expect(Exonum.verifyBlock({block: {}, precommits: precommits}, validators, networkId)).to.be.false + }) + }) - it('should return false when precommits info of wrong type', function() { - [null, undefined, 42, 'Hello world', [], new Date()].forEach(function(precommits) { - expect(Exonum.verifyBlock({block: {}, precommits: precommits}, validators, networkId)).to.be.false; - }); - }); + it('should return false when network_id is of wrong type', function () { + [null, undefined, -5, 260, 'Hello world', [], new Date()].forEach(function (_id) { + expect(Exonum.verifyBlock({block: {}}, validators, _id)).to.be.false + }) + }) - it('should return false when network_id is of wrong type', function() { - [null, undefined, -5, 260, 'Hello world', [], new Date()].forEach(function(_id) { - expect(Exonum.verifyBlock({block: {}}, validators, _id)).to.be.false; - }); - }); + it('should return false when body field of wrong type in precommit', function () { + [null, 42, 'Hello world', [], new Date()].forEach(function (body) { + expect(Exonum.verifyBlock({block: {}, precommits: [{body: body}]}, validators, networkId)).to.be.false + }) + }) - it('should return false when body field of wrong type in precommit', function() { - [null, 42, 'Hello world', [], new Date()].forEach(function(body) { - expect(Exonum.verifyBlock({block: {}, precommits: [{body: body}]}, validators, networkId)).to.be.false; - }); - }); + it('should return false when signature field of wrong type in precommit', function () { + [null, undefined, 42, [], {}, new Date()].forEach(function (signature) { + var data = { + block: {}, + precommits: [{ + body: {}, + signature: signature + }] + } - it('should return false when signature field of wrong type in precommit', function() { - [null, undefined, 42, [], {}, new Date()].forEach(function(signature) { - var data = { - block: {}, - precommits: [{ - body: {}, - signature: signature - }] - }; + expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false + }) + }) - expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false; - }); - }); + it('should return false when invalid signature field in precommit', function () { + var args = [ + '22635e36303ff3ef4c86b855e57356f41483e6637136d1d2ec46ba2ec8f69fb9', + '22635e36303ff3ef4c86b855e57356f41483e6637136d1d2ec46ba2ec8f69fb922635e36303ff3ef4c86b855e57356f41483e6637136d1d2ec46ba2ec8f69fbz' + ] - it('should return false when invalid signature field in precommit', function() { - var args = [ - '22635e36303ff3ef4c86b855e57356f41483e6637136d1d2ec46ba2ec8f69fb9', - '22635e36303ff3ef4c86b855e57356f41483e6637136d1d2ec46ba2ec8f69fb922635e36303ff3ef4c86b855e57356f41483e6637136d1d2ec46ba2ec8f69fbz' - ]; + args.forEach(function (signature) { + var data = { + block: {}, + precommits: [{ + body: {}, + signature: signature + }] + } - args.forEach(function(signature) { - var data = { - block: {}, - precommits: [{ - body: {}, - signature: signature - }] - }; + expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false + }) + }) - expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false; - }); - }); + it('should return false when precommit from non existed validator', function () { + var data = { + block: {}, + precommits: [{ + body: { + validator: 999999999 + }, + signature: '63b8341b82f0eb6f32be73bf36a4b605655e3979030df9e025713c972d1da6d263b8341b82f0eb6f32be73bf36a4b605655e3979030df9e025713c972d1da6d2' + }] + } - it('should return false when precommit from non existed validator', function() { - var data = { - block: {}, - precommits: [{ - body: { - validator: 999999999 - }, - signature: '63b8341b82f0eb6f32be73bf36a4b605655e3979030df9e025713c972d1da6d263b8341b82f0eb6f32be73bf36a4b605655e3979030df9e025713c972d1da6d2' - }] - }; + expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false + }) - expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false; - }); + it('should return false when wrong height of block in precommit', function () { + var data = { + block: { + height: 1 + }, + precommits: [{ + body: { + height: 5, + validator: 0 + }, + signature: '63b8341b82f0eb6f32be73bf36a4b605655e3979030df9e025713c972d1da6d263b8341b82f0eb6f32be73bf36a4b605655e3979030df9e025713c972d1da6d2' + }] + } - it('should return false when wrong height of block in precommit', function() { - var data = { - block: { - height: 1 - }, - precommits: [{ - body: { - height: 5, - validator: 0 - }, - signature: '63b8341b82f0eb6f32be73bf36a4b605655e3979030df9e025713c972d1da6d263b8341b82f0eb6f32be73bf36a4b605655e3979030df9e025713c972d1da6d2' - }] - }; + expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false + }) - expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false; - }); + it('should return false when wrong hash of block in precommit', function () { + var data = { + 'block': { + 'height': '5', + 'propose_round': 3, + 'prev_hash': 'fe5c606da552b2a3ad0ff8ef400a7071e9e72ab3b5f5c2996416ceb86c7f2c1e', + 'tx_hash': '136c7952ed9f26b477797c23cf3d02faa46863ecc70d595b0b227027aacd0f94', + 'state_hash': 'bea2a1defd3b2ab410a1f501805d10ad94d30a5b5a1240574cade1553a60e189' + }, + 'precommits': [ + { + 'body': { + 'validator': 0, + 'height': '5', + 'round': 3, + 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', + 'block_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a' + }, + 'network_id': 0, + 'protocol_version': 0, + 'message_id': 4, + 'service_id': 0, + 'signature': '4616ef4bfac86c8ded9aa9c7e84958574e3f9df4f7aadea8b37dcdb40ebedd8ac009f8a9b54bd907bf4f43289bfec72e47e6338912f282a6b5a5ce8c558ef50b' + }, + { + 'body': { + 'validator': 2, + 'height': '5', + 'round': 3, + 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', + 'block_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a' + }, + 'network_id': 0, + 'protocol_version': 0, + 'message_id': 4, + 'service_id': 0, + 'signature': '5253cba87af1abac95c7c92f06b2b286af84353fd060ea1069f107094d97298473fe6431613c3e2d02d92624c82394b86cec047cd681e0f3fc98f0f877383a04' + }, + { + 'body': { + 'validator': 3, + 'height': '5', + 'round': 3, + 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', + 'block_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a' + }, + 'network_id': 0, + 'protocol_version': 0, + 'message_id': 4, + 'service_id': 0, + 'signature': 'e35a3cb1ca834cce77d67d5945ef1d7021488a357a35e973cd1ef17099d4db55a28123d95f9c5dcedf34c86a12c20e91cc47622612039115f2a376d7e5f7ab00' + } + ] + } - it('should return false when wrong hash of block in precommit', function() { - var data = { - 'block': { - 'height': '5', - 'propose_round': 3, - 'prev_hash': 'fe5c606da552b2a3ad0ff8ef400a7071e9e72ab3b5f5c2996416ceb86c7f2c1e', - 'tx_hash': '136c7952ed9f26b477797c23cf3d02faa46863ecc70d595b0b227027aacd0f94', - 'state_hash': 'bea2a1defd3b2ab410a1f501805d10ad94d30a5b5a1240574cade1553a60e189' - }, - 'precommits': [ - { - 'body': { - 'validator': 0, - 'height': '5', - 'round': 3, - 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', - 'block_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a' - }, - 'network_id': 0, - 'protocol_version': 0, - 'message_id': 4, - 'service_id': 0, - 'signature': '4616ef4bfac86c8ded9aa9c7e84958574e3f9df4f7aadea8b37dcdb40ebedd8ac009f8a9b54bd907bf4f43289bfec72e47e6338912f282a6b5a5ce8c558ef50b' - }, - { - 'body': { - 'validator': 2, - 'height': '5', - 'round': 3, - 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', - 'block_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a' - }, - 'network_id': 0, - 'protocol_version': 0, - 'message_id': 4, - 'service_id': 0, - 'signature': '5253cba87af1abac95c7c92f06b2b286af84353fd060ea1069f107094d97298473fe6431613c3e2d02d92624c82394b86cec047cd681e0f3fc98f0f877383a04' - }, - { - 'body': { - 'validator': 3, - 'height': '5', - 'round': 3, - 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', - 'block_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a' - }, - 'network_id': 0, - 'protocol_version': 0, - 'message_id': 4, - 'service_id': 0, - 'signature': 'e35a3cb1ca834cce77d67d5945ef1d7021488a357a35e973cd1ef17099d4db55a28123d95f9c5dcedf34c86a12c20e91cc47622612039115f2a376d7e5f7ab00' - } - ] - }; + expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false + }) - expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false; - }); + it('should return false when wrong round in precommit', function () { + var data = { + 'block': { + 'height': '5', + 'propose_round': 3, + 'prev_hash': 'fe5c606da552b2a3ad0ff8ef400a7071e9e72ab3b5f5c2996416ceb86c7f2c1e', + 'tx_hash': '136c7952ed9f26b477797c23cf3d02faa46863ecc70d595b0b227027aacd0f94', + 'state_hash': 'bea2a1defd3b2ab410a1f501805d10ad94d30a5b5a1240574cade1553a60e189' + }, + 'precommits': [ + { + 'body': { + 'validator': 0, + 'height': '5', + 'round': 3, + 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', + 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' + }, + 'network_id': 0, + 'protocol_version': 0, + 'message_id': 4, + 'service_id': 0, + 'signature': '4616ef4bfac86c8ded9aa9c7e84958574e3f9df4f7aadea8b37dcdb40ebedd8ac009f8a9b54bd907bf4f43289bfec72e47e6338912f282a6b5a5ce8c558ef50b' + }, + { + 'body': { + 'validator': 2, + 'height': '5', + 'round': 3, + 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', + 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' + }, + 'network_id': 0, + 'protocol_version': 0, + 'message_id': 4, + 'service_id': 0, + 'signature': '5253cba87af1abac95c7c92f06b2b286af84353fd060ea1069f107094d97298473fe6431613c3e2d02d92624c82394b86cec047cd681e0f3fc98f0f877383a04' + }, + { + 'body': { + 'validator': 1, + 'height': '5', + 'round': 7, + 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', + 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' + }, + 'network_id': 0, + 'protocol_version': 0, + 'message_id': 4, + 'service_id': 0, + 'signature': 'fc7d8d9150db263f03cb8a141b6a372a0bed1fa21128907b52485ad37ea19e71342ebbd8f80e76c81e42d125e3a2e4e15189212f6f78a307005c63c0eade6c06' + } + ] + } - it('should return false when wrong round in precommit', function() { - var data = { - 'block': { - 'height': '5', - 'propose_round': 3, - 'prev_hash': 'fe5c606da552b2a3ad0ff8ef400a7071e9e72ab3b5f5c2996416ceb86c7f2c1e', - 'tx_hash': '136c7952ed9f26b477797c23cf3d02faa46863ecc70d595b0b227027aacd0f94', - 'state_hash': 'bea2a1defd3b2ab410a1f501805d10ad94d30a5b5a1240574cade1553a60e189' - }, - 'precommits': [ - { - 'body': { - 'validator': 0, - 'height': '5', - 'round': 3, - 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', - 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' - }, - 'network_id': 0, - 'protocol_version': 0, - 'message_id': 4, - 'service_id': 0, - 'signature': '4616ef4bfac86c8ded9aa9c7e84958574e3f9df4f7aadea8b37dcdb40ebedd8ac009f8a9b54bd907bf4f43289bfec72e47e6338912f282a6b5a5ce8c558ef50b' - }, - { - 'body': { - 'validator': 2, - 'height': '5', - 'round': 3, - 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', - 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' - }, - 'network_id': 0, - 'protocol_version': 0, - 'message_id': 4, - 'service_id': 0, - 'signature': '5253cba87af1abac95c7c92f06b2b286af84353fd060ea1069f107094d97298473fe6431613c3e2d02d92624c82394b86cec047cd681e0f3fc98f0f877383a04' - }, - { - 'body': { - 'validator': 1, - 'height': '5', - 'round': 7, - 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', - 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' - }, - 'network_id': 0, - 'protocol_version': 0, - 'message_id': 4, - 'service_id': 0, - 'signature': 'fc7d8d9150db263f03cb8a141b6a372a0bed1fa21128907b52485ad37ea19e71342ebbd8f80e76c81e42d125e3a2e4e15189212f6f78a307005c63c0eade6c06' - } - ] - }; + expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false + }) - expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false; - }); + it('should return false when wrong signature of precommit', function () { + var data = { + 'block': { + 'height': '5', + 'propose_round': 3, + 'prev_hash': 'fe5c606da552b2a3ad0ff8ef400a7071e9e72ab3b5f5c2996416ceb86c7f2c1e', + 'tx_hash': '136c7952ed9f26b477797c23cf3d02faa46863ecc70d595b0b227027aacd0f94', + 'state_hash': 'bea2a1defd3b2ab410a1f501805d10ad94d30a5b5a1240574cade1553a60e189' + }, + 'precommits': [ + { + 'body': { + 'validator': 0, + 'height': '5', + 'round': 3, + 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', + 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' + }, + 'network_id': 0, + 'protocol_version': 0, + 'message_id': 4, + 'service_id': 0, + 'signature': '5616ef4bfac86c8ded9aa9c7e84958574e3f9df4f7aadea8b37dcdb40ebedd8ac009f8a9b54bd907bf4f43289bfec72e47e6338912f282a6b5a5ce8c558ef50b' + } + ] + } - it('should return false when wrong signature of precommit', function() { - var data = { - 'block': { - 'height': '5', - 'propose_round': 3, - 'prev_hash': 'fe5c606da552b2a3ad0ff8ef400a7071e9e72ab3b5f5c2996416ceb86c7f2c1e', - 'tx_hash': '136c7952ed9f26b477797c23cf3d02faa46863ecc70d595b0b227027aacd0f94', - 'state_hash': 'bea2a1defd3b2ab410a1f501805d10ad94d30a5b5a1240574cade1553a60e189' - }, - 'precommits': [ - { - 'body': { - 'validator': 0, - 'height': '5', - 'round': 3, - 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', - 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' - }, - 'network_id': 0, - 'protocol_version': 0, - 'message_id': 4, - 'service_id': 0, - 'signature': '5616ef4bfac86c8ded9aa9c7e84958574e3f9df4f7aadea8b37dcdb40ebedd8ac009f8a9b54bd907bf4f43289bfec72e47e6338912f282a6b5a5ce8c558ef50b' - } - ] - }; + expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false + }) - expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false; - }); + it('should return false when insufficient precommits from unique validators', function () { + var data = { + 'block': { + 'height': '5', + 'propose_round': 3, + 'prev_hash': 'fe5c606da552b2a3ad0ff8ef400a7071e9e72ab3b5f5c2996416ceb86c7f2c1e', + 'tx_hash': '136c7952ed9f26b477797c23cf3d02faa46863ecc70d595b0b227027aacd0f94', + 'state_hash': 'bea2a1defd3b2ab410a1f501805d10ad94d30a5b5a1240574cade1553a60e189' + }, + 'precommits': [ + { + 'body': { + 'validator': 0, + 'height': '5', + 'round': 3, + 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', + 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' + }, + 'network_id': 0, + 'protocol_version': 0, + 'message_id': 4, + 'service_id': 0, + 'signature': '4616ef4bfac86c8ded9aa9c7e84958574e3f9df4f7aadea8b37dcdb40ebedd8ac009f8a9b54bd907bf4f43289bfec72e47e6338912f282a6b5a5ce8c558ef50b' + } + ] + } - it('should return false when insufficient precommits from unique validators', function() { - var data = { - 'block': { - 'height': '5', - 'propose_round': 3, - 'prev_hash': 'fe5c606da552b2a3ad0ff8ef400a7071e9e72ab3b5f5c2996416ceb86c7f2c1e', - 'tx_hash': '136c7952ed9f26b477797c23cf3d02faa46863ecc70d595b0b227027aacd0f94', - 'state_hash': 'bea2a1defd3b2ab410a1f501805d10ad94d30a5b5a1240574cade1553a60e189' - }, - 'precommits': [ - { - 'body': { - 'validator': 0, - 'height': '5', - 'round': 3, - 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', - 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' - }, - 'network_id': 0, - 'protocol_version': 0, - 'message_id': 4, - 'service_id': 0, - 'signature': '4616ef4bfac86c8ded9aa9c7e84958574e3f9df4f7aadea8b37dcdb40ebedd8ac009f8a9b54bd907bf4f43289bfec72e47e6338912f282a6b5a5ce8c558ef50b' - } - ] - }; + expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false + }) - expect(Exonum.verifyBlock(data, validators, networkId)).to.be.false; - }); + it('should return false when validators of wrong type', function () { + var block = { + 'block': { + 'height': '5', + 'propose_round': 3, + 'prev_hash': 'fe5c606da552b2a3ad0ff8ef400a7071e9e72ab3b5f5c2996416ceb86c7f2c1e', + 'tx_hash': '136c7952ed9f26b477797c23cf3d02faa46863ecc70d595b0b227027aacd0f94', + 'state_hash': 'bea2a1defd3b2ab410a1f501805d10ad94d30a5b5a1240574cade1553a60e189' + }, + 'precommits': [ + { + 'body': { + 'validator': 0, + 'height': '5', + 'round': 3, + 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', + 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' + }, + 'network_id': 0, + 'protocol_version': 0, + 'message_id': 4, + 'service_id': 0, + 'signature': '4616ef4bfac86c8ded9aa9c7e84958574e3f9df4f7aadea8b37dcdb40ebedd8ac009f8a9b54bd907bf4f43289bfec72e47e6338912f282a6b5a5ce8c558ef50b' + }, + { + 'body': { + 'validator': 2, + 'height': '5', + 'round': 3, + 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', + 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' + }, + 'network_id': 0, + 'protocol_version': 0, + 'message_id': 4, + 'service_id': 0, + 'signature': '5253cba87af1abac95c7c92f06b2b286af84353fd060ea1069f107094d97298473fe6431613c3e2d02d92624c82394b86cec047cd681e0f3fc98f0f877383a04' + }, + { + 'body': { + 'validator': 3, + 'height': '5', + 'round': 3, + 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', + 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' + }, + 'network_id': 0, + 'protocol_version': 0, + 'message_id': 4, + 'service_id': 0, + 'signature': 'e35a3cb1ca834cce77d67d5945ef1d7021488a357a35e973cd1ef17099d4db55a28123d95f9c5dcedf34c86a12c20e91cc47622612039115f2a376d7e5f7ab00' + } + ] + }; - it('should return false when validators of wrong type', function() { - var block = { - 'block': { - 'height': '5', - 'propose_round': 3, - 'prev_hash': 'fe5c606da552b2a3ad0ff8ef400a7071e9e72ab3b5f5c2996416ceb86c7f2c1e', - 'tx_hash': '136c7952ed9f26b477797c23cf3d02faa46863ecc70d595b0b227027aacd0f94', - 'state_hash': 'bea2a1defd3b2ab410a1f501805d10ad94d30a5b5a1240574cade1553a60e189' - }, - 'precommits': [ - { - 'body': { - 'validator': 0, - 'height': '5', - 'round': 3, - 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', - 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' - }, - 'network_id': 0, - 'protocol_version': 0, - 'message_id': 4, - 'service_id': 0, - 'signature': '4616ef4bfac86c8ded9aa9c7e84958574e3f9df4f7aadea8b37dcdb40ebedd8ac009f8a9b54bd907bf4f43289bfec72e47e6338912f282a6b5a5ce8c558ef50b' - }, - { - 'body': { - 'validator': 2, - 'height': '5', - 'round': 3, - 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', - 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' - }, - 'network_id': 0, - 'protocol_version': 0, - 'message_id': 4, - 'service_id': 0, - 'signature': '5253cba87af1abac95c7c92f06b2b286af84353fd060ea1069f107094d97298473fe6431613c3e2d02d92624c82394b86cec047cd681e0f3fc98f0f877383a04' - }, - { - 'body': { - 'validator': 3, - 'height': '5', - 'round': 3, - 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', - 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' - }, - 'network_id': 0, - 'protocol_version': 0, - 'message_id': 4, - 'service_id': 0, - 'signature': 'e35a3cb1ca834cce77d67d5945ef1d7021488a357a35e973cd1ef17099d4db55a28123d95f9c5dcedf34c86a12c20e91cc47622612039115f2a376d7e5f7ab00' - } - ] - }; + [undefined, [true], [undefined], [null], [42], [[]], [{}], [new Date()]].forEach(function (validators) { + expect(Exonum.verifyBlock(block, validators, networkId)).to.be.false + }) + }) - [undefined, [true], [undefined], [null], [42], [[]], [{}], [new Date()]].forEach(function(validators) { - expect(Exonum.verifyBlock(block, validators, networkId)).to.be.false; - }); - }); + it('should return false when validators of wrong type', function () { + var block = { + 'block': { + 'height': '5', + 'propose_round': 3, + 'prev_hash': 'fe5c606da552b2a3ad0ff8ef400a7071e9e72ab3b5f5c2996416ceb86c7f2c1e', + 'tx_hash': '136c7952ed9f26b477797c23cf3d02faa46863ecc70d595b0b227027aacd0f94', + 'state_hash': 'bea2a1defd3b2ab410a1f501805d10ad94d30a5b5a1240574cade1553a60e189' + }, + 'precommits': [ + { + 'body': { + 'validator': 0, + 'height': '5', + 'round': 3, + 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', + 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' + }, + 'signature': '4616ef4bfac86c8ded9aa9c7e84958574e3f9df4f7aadea8b37dcdb40ebedd8ac009f8a9b54bd907bf4f43289bfec72e47e6338912f282a6b5a5ce8c558ef50b' + }, + { + 'body': { + 'validator': 2, + 'height': '5', + 'round': 3, + 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', + 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' + }, + 'signature': '5253cba87af1abac95c7c92f06b2b286af84353fd060ea1069f107094d97298473fe6431613c3e2d02d92624c82394b86cec047cd681e0f3fc98f0f877383a04' + }, + { + 'body': { + 'validator': 3, + 'height': '5', + 'round': 3, + 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', + 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' + }, + 'signature': 'e35a3cb1ca834cce77d67d5945ef1d7021488a357a35e973cd1ef17099d4db55a28123d95f9c5dcedf34c86a12c20e91cc47622612039115f2a376d7e5f7ab00' + } + ] + }; - it('should return false when validators of wrong type', function() { - var block = { - 'block': { - 'height': '5', - 'propose_round': 3, - 'prev_hash': 'fe5c606da552b2a3ad0ff8ef400a7071e9e72ab3b5f5c2996416ceb86c7f2c1e', - 'tx_hash': '136c7952ed9f26b477797c23cf3d02faa46863ecc70d595b0b227027aacd0f94', - 'state_hash': 'bea2a1defd3b2ab410a1f501805d10ad94d30a5b5a1240574cade1553a60e189' - }, - 'precommits': [ - { - 'body': { - 'validator': 0, - 'height': '5', - 'round': 3, - 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', - 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' - }, - 'signature': '4616ef4bfac86c8ded9aa9c7e84958574e3f9df4f7aadea8b37dcdb40ebedd8ac009f8a9b54bd907bf4f43289bfec72e47e6338912f282a6b5a5ce8c558ef50b' - }, - { - 'body': { - 'validator': 2, - 'height': '5', - 'round': 3, - 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', - 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' - }, - 'signature': '5253cba87af1abac95c7c92f06b2b286af84353fd060ea1069f107094d97298473fe6431613c3e2d02d92624c82394b86cec047cd681e0f3fc98f0f877383a04' - }, - { - 'body': { - 'validator': 3, - 'height': '5', - 'round': 3, - 'propose_hash': '1783d20a053b5c45b40e76358a51a7fce90eea391a409decfb9f9cbbb5a4875a', - 'block_hash': 'c2513f88478a32767c3cf7c068d60523212a005374d8d7398473c9601bf3d369' - }, - 'signature': 'e35a3cb1ca834cce77d67d5945ef1d7021488a357a35e973cd1ef17099d4db55a28123d95f9c5dcedf34c86a12c20e91cc47622612039115f2a376d7e5f7ab00' - } - ] - }; - - [['asda123'], ['eb7e3ad55f97e5d5693fe0e69f4c26bd1173077dbffb5fff5b69f213f71bee3f']].forEach(function(validators) { - expect(Exonum.verifyBlock(block, validators, networkId)).to.be.false; - }); - }); - -}); + [['asda123'], ['eb7e3ad55f97e5d5693fe0e69f4c26bd1173077dbffb5fff5b69f213f71bee3f']].forEach(function (validators) { + expect(Exonum.verifyBlock(block, validators, networkId)).to.be.false + }) + }) +}) diff --git a/test/convertors.js b/test/convertors.js index c1ea1ad..7c744ac 100644 --- a/test/convertors.js +++ b/test/convertors.js @@ -1,92 +1,91 @@ /* eslint-env node, mocha */ - -var expect = require('chai').expect; -var Exonum = require('../src'); - -describe('Convert data from one type to another', function() { - - describe('Check Exonum.hexadecimalToUint8Array', function() { - it('should convert valid hexadecimal into Uint8Array', function() { - var data = require('./data/convertors/hexadecimalToUint8Array.json'); - expect(Exonum.hexadecimalToUint8Array(data.from)).to.deep.equal(new Uint8Array(data.to)); - }); - - it('should throw error when convert invalid hexadecimal into Uint8Array', function() { - [null, false, 42, new Date(), {}, [], '0438082601f8b38ae010a621a48f4b4cd021c4e6e69219e3c2d8abab482039ez'].forEach(function(value) { - expect(() => Exonum.hexadecimalToUint8Array(value)).to.throw(TypeError); - }); - }); - }); - - describe('Check Exonum.stringToUint8Array', function() { - it('should convert valid string into Uint8Array', function() { - var data = require('./data/convertors/stringToUint8Array.json'); - expect(Exonum.stringToUint8Array(data.from)).to.deep.equal(new Uint8Array(data.to)); - }); - - it('should throw error when convert invalid string into Uint8Array', function() { - [null, false, 42, new Date(), {}, []].forEach(function(value) { - expect(() => Exonum.stringToUint8Array(value)).to.throw(TypeError); - }); - }); - }); - - describe('Check Exonum.binaryStringToUint8Array', function() { - it('should convert valid binaryString into Uint8Array', function() { - var data = require('./data/convertors/binaryStringToUint8Array.json'); - expect(Exonum.binaryStringToUint8Array(data.from)).to.deep.equal(new Uint8Array(data.to)); - }); - - it('should throw error when convert wrong binaryString into Uint8Array', function() { - [null, false, new Date(), {}, [], 42].forEach(function(value) { - expect(() => Exonum.binaryStringToUint8Array(value)).to.throw(TypeError); - }); - }); - - it('should throw error when convert invalid binaryString into Uint8Array', function() { - ['102'].forEach(function(value) { - expect(() => Exonum.binaryStringToUint8Array(value)).to.throw(TypeError); - }); - }); - }); - - describe('Check Exonum.uint8ArrayToHexadecimal', function() { - it('should convert valid Uint8Array into hexadecimal', function() { - var data = require('./data/convertors/uint8ArrayToHexadecimal.json'); - expect(Exonum.uint8ArrayToHexadecimal(new Uint8Array(data.from))).to.equal(data.to); - }); - - it('should throw error when convert invalid Uint8Array into hexadecimal', function() { - [null, false, 42, new Date(), {}, 'Hello world', [4,56]].forEach(function(value) { - expect(() => Exonum.uint8ArrayToHexadecimal(value)).to.throw(TypeError); - }); - }); - }); - - describe('Check Exonum.binaryStringToHexadecimal', function() { - it('should convert valid binaryString into hexadecimal', function() { - var data = require('./data/convertors/binaryStringToHexadecimal.json'); - expect(Exonum.binaryStringToHexadecimal(data.from)).to.deep.equal(data.to); - }); - - it('should throw error when convert binaryString of wrong type into hexadecimal', function() { - [null, false, 42, new Date(), {}, [], '102'].forEach(function(value) { - expect(() => Exonum.binaryStringToHexadecimal(value)).to.throw(TypeError); - }); - }); - }); - - describe('Check Exonum.hexadecimalToBinaryString', function() { - it('should convert valid hexadecimal into BinaryString', function() { - var data = require('./data/convertors/hexadecimalToBinaryString.json'); - expect(Exonum.hexadecimalToBinaryString(data.from)).to.equal(data.to); - }); - - it('should throw error when convert invalid hexadecimal into BinaryString', function() { - [null, false, 42, new Date(), {}, [], 'az'].forEach(function(value) { - expect(() => Exonum.hexadecimalToBinaryString(value)).to.throw(TypeError); - }); - }); - }); - -}); +/* eslint-disable no-unused-expressions */ + +var expect = require('chai').expect +var Exonum = require('../src') + +describe('Convert data from one type to another', function () { + describe('Check Exonum.hexadecimalToUint8Array', function () { + it('should convert valid hexadecimal into Uint8Array', function () { + var data = require('./data/convertors/hexadecimalToUint8Array.json') + expect(Exonum.hexadecimalToUint8Array(data.from)).to.deep.equal(new Uint8Array(data.to)) + }) + + it('should throw error when convert invalid hexadecimal into Uint8Array', function () { + [null, false, 42, new Date(), {}, [], '0438082601f8b38ae010a621a48f4b4cd021c4e6e69219e3c2d8abab482039ez'].forEach(function (value) { + expect(() => Exonum.hexadecimalToUint8Array(value)).to.throw(TypeError) + }) + }) + }) + + describe('Check Exonum.stringToUint8Array', function () { + it('should convert valid string into Uint8Array', function () { + var data = require('./data/convertors/stringToUint8Array.json') + expect(Exonum.stringToUint8Array(data.from)).to.deep.equal(new Uint8Array(data.to)) + }) + + it('should throw error when convert invalid string into Uint8Array', function () { + [null, false, 42, new Date(), {}, []].forEach(function (value) { + expect(() => Exonum.stringToUint8Array(value)).to.throw(TypeError) + }) + }) + }) + + describe('Check Exonum.binaryStringToUint8Array', function () { + it('should convert valid binaryString into Uint8Array', function () { + var data = require('./data/convertors/binaryStringToUint8Array.json') + expect(Exonum.binaryStringToUint8Array(data.from)).to.deep.equal(new Uint8Array(data.to)) + }) + + it('should throw error when convert wrong binaryString into Uint8Array', function () { + [null, false, new Date(), {}, [], 42].forEach(function (value) { + expect(() => Exonum.binaryStringToUint8Array(value)).to.throw(TypeError) + }) + }) + + it('should throw error when convert invalid binaryString into Uint8Array', function () { + ['102'].forEach(function (value) { + expect(() => Exonum.binaryStringToUint8Array(value)).to.throw(TypeError) + }) + }) + }) + + describe('Check Exonum.uint8ArrayToHexadecimal', function () { + it('should convert valid Uint8Array into hexadecimal', function () { + var data = require('./data/convertors/uint8ArrayToHexadecimal.json') + expect(Exonum.uint8ArrayToHexadecimal(new Uint8Array(data.from))).to.equal(data.to) + }) + + it('should throw error when convert invalid Uint8Array into hexadecimal', function () { + [null, false, 42, new Date(), {}, 'Hello world', [4, 56]].forEach(function (value) { + expect(() => Exonum.uint8ArrayToHexadecimal(value)).to.throw(TypeError) + }) + }) + }) + + describe('Check Exonum.binaryStringToHexadecimal', function () { + it('should convert valid binaryString into hexadecimal', function () { + var data = require('./data/convertors/binaryStringToHexadecimal.json') + expect(Exonum.binaryStringToHexadecimal(data.from)).to.deep.equal(data.to) + }) + + it('should throw error when convert binaryString of wrong type into hexadecimal', function () { + [null, false, 42, new Date(), {}, [], '102'].forEach(function (value) { + expect(() => Exonum.binaryStringToHexadecimal(value)).to.throw(TypeError) + }) + }) + }) + + describe('Check Exonum.hexadecimalToBinaryString', function () { + it('should convert valid hexadecimal into BinaryString', function () { + var data = require('./data/convertors/hexadecimalToBinaryString.json') + expect(Exonum.hexadecimalToBinaryString(data.from)).to.equal(data.to) + }) + + it('should throw error when convert invalid hexadecimal into BinaryString', function () { + [null, false, 42, new Date(), {}, [], 'az'].forEach(function (value) { + expect(() => Exonum.hexadecimalToBinaryString(value)).to.throw(TypeError) + }) + }) + }) +}) diff --git a/test/cryptography.js b/test/cryptography.js index 300cb8b..fb935c7 100644 --- a/test/cryptography.js +++ b/test/cryptography.js @@ -1,718 +1,707 @@ /* eslint-env node, mocha */ - -var expect = require('chai').expect; -var Exonum = require('../src'); - -describe('Check cryptography', function() { - - describe('Get SHA256 hash', function() { - - it('should return hash of data of newType type', function() { - var Wallet = Exonum.newType({ - size: 80, - fields: { - pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, - name: {type: Exonum.String, size: 8, from: 32, to: 40}, - balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, - history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} - } - }); - var walletData = { - pub_key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36', - name: 'Smart wallet', - balance: 359120, - history_hash: '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030' - }; - var hash = Exonum.hash(walletData, Wallet); - - expect(hash).to.equal('86b47510fbcbc83f9926d8898a57c53662518c97502625a6d131842f2003f974'); - }); - - it('should return hash of data of newType type using built-in method', function() { - var Wallet = Exonum.newType({ - size: 80, - fields: { - pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, - name: {type: Exonum.String, size: 8, from: 32, to: 40}, - balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, - history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} - } - }); - var walletData = { - pub_key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36', - name: 'Smart wallet', - balance: 359120, - history_hash: '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030' - }; - var hash = Wallet.hash(walletData); - - expect(hash).to.equal('86b47510fbcbc83f9926d8898a57c53662518c97502625a6d131842f2003f974'); - }); - - it('should return hash of data of newMessage type', function() { - var CustomMessage = Exonum.newMessage({ - size: 18, - network_id: 0, - protocol_version: 0, - service_id: 1, - message_id: 2, - fields: { - name: {type: Exonum.String, size: 8, from: 0, to: 8}, - age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, - balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, - status: {type: Exonum.Bool, size: 1, from: 17, to: 18} - }, - signature: 'dad76b4c3b067d53265534bde4d9ff59987d00f87e0e1a633613576195a4cbc1e0a43a58c67c34c98019f791812699d010655c4eccec448e46e5524471a8c401' - }); - var messageData = { - name: 'John Doe', - age: 34, - balance: 17, - status: true - }; - var hash = Exonum.hash(messageData, CustomMessage); - - expect(hash).to.equal('df2d0cf21d4fc1e2b0adf6dbff7daeb0d7292e9f51f529358c18b95b67539484'); - }); - - it('should return hash of data of newMessage type using built-in method', function() { - var CustomMessage = Exonum.newMessage({ - size: 18, - network_id: 0, - protocol_version: 0, - service_id: 1, - message_id: 2, - fields: { - name: {type: Exonum.String, size: 8, from: 0, to: 8}, - age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, - balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, - status: {type: Exonum.Bool, size: 1, from: 17, to: 18} - }, - signature: 'dad76b4c3b067d53265534bde4d9ff59987d00f87e0e1a633613576195a4cbc1e0a43a58c67c34c98019f791812699d010655c4eccec448e46e5524471a8c401' - }); - var messageData = { - name: 'John Doe', - age: 34, - balance: 17, - status: true - }; - var hash = CustomMessage.hash(messageData); - - expect(hash).to.equal('df2d0cf21d4fc1e2b0adf6dbff7daeb0d7292e9f51f529358c18b95b67539484'); - }); - - it('should return hash of the array of 8-bit integers', function() { - var Wallet = Exonum.newType({ - size: 80, - fields: { - pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, - name: {type: Exonum.String, size: 8, from: 32, to: 40}, - balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, - history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} - } - }); - var walletData = { - pub_key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36', - name: 'Smart wallet', - balance: 359120, - history_hash: '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030' - }; - var buffer = Wallet.serialize(walletData); - var hash = Exonum.hash(buffer); - - expect(hash).to.equal('86b47510fbcbc83f9926d8898a57c53662518c97502625a6d131842f2003f974'); - }); - - it('should throw error when data of invalid NewType type', function() { - var Wallet = Exonum.newType({ - size: 80, - fields: { - pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, - name: {type: Exonum.String, size: 8, from: 32, to: 40}, - balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, - history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} - } - }); - - [undefined, false, 42, new Date(), []].forEach(function(_hash) { - expect(() => Exonum.hash(_hash, Wallet)).to.throw(TypeError); - }); - }); - - it('should throw error when data of invalid NewMessage type', function() { - var CustomMessage = Exonum.newMessage({ - size: 18, - network_id: 0, - protocol_version: 0, - service_id: 1, - message_id: 2, - fields: { - name: {type: Exonum.String, size: 8, from: 0, to: 8}, - age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, - balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, - status: {type: Exonum.Bool, size: 1, from: 17, to: 18} - } - }); - - [undefined, false, 42, new Date(), []].forEach(function(_hash) { - expect(() => Exonum.hash(_hash, CustomMessage)).to.throw(TypeError); - }); - }); - - }); - - describe('Get ED25519 signature', function() { - - it('should return signature of the data of NewType type', function() { - var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - var signature = User.sign(secretKey, userData); - - expect(signature).to.equal('7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040e'); - }); - - it('should return signature of the data of NewType type using built-in method', function() { - var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - var signature = User.sign(secretKey, userData); - - expect(signature).to.equal('7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040e'); - }); - - it('should return signature of the data of NewMessage type', function() { - var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var CustomMessage = Exonum.newMessage({ - size: 18, - network_id: 0, - protocol_version: 0, - service_id: 1, - message_id: 2, - fields: { - name: {type: Exonum.String, size: 8, from: 0, to: 8}, - age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, - balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, - status: {type: Exonum.Bool, size: 1, from: 17, to: 18} - } - }); - var messageData = { - name: 'John Doe', - age: 34, - balance: 173008, - status: true - }; - var signature = Exonum.sign(secretKey, messageData, CustomMessage); - - expect(signature).to.equal('4006cef1884941850a6b97a64ed7f12d1e1053188618ef71b8c9f87438b943b1969e08011e45db8299bb738fec60c9dcd1936ab9ba44392cacc7f0385f18dd09'); - }); - - it('should return signature of the data of NewMessage type using built-in method', function() { - var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var CustomMessage = Exonum.newMessage({ - size: 18, - network_id: 0, - protocol_version: 0, - service_id: 1, - message_id: 2, - fields: { - name: {type: Exonum.String, size: 8, from: 0, to: 8}, - age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, - balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, - status: {type: Exonum.Bool, size: 1, from: 17, to: 18} - } - }); - var messageData = { - name: 'John Doe', - age: 34, - balance: 173008, - status: true - }; - var signature = CustomMessage.sign(secretKey, messageData); - - expect(signature).to.equal('4006cef1884941850a6b97a64ed7f12d1e1053188618ef71b8c9f87438b943b1969e08011e45db8299bb738fec60c9dcd1936ab9ba44392cacc7f0385f18dd09'); - }); - - it('should return signature of the array of 8-bit integers', function() { - var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - var buffer = User.serialize(userData); - var signature = Exonum.sign(secretKey, buffer); - - expect(signature).to.equal('7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040e'); - }); - - it('should throw error when the data parameter of wrong NewType type', function() { - var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - sum: 500, - hash: 'Hello world' - }; - - expect(() => Exonum.sign(secretKey, userData, User)).to.throw(TypeError); - }); - - it('should throw error when the data parameter of wrong NewMessage type', function() { - var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var CustomMessage = Exonum.newMessage({ - size: 18, - network_id: 0, - protocol_version: 0, - service_id: 1, - message_id: 2, - fields: { - name: {type: Exonum.String, size: 8, from: 0, to: 8}, - age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, - balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, - status: {type: Exonum.Bool, size: 1, from: 17, to: 18} - } - }); - var someData = { - sum: 500, - hash: 'Hello world' - }; - - expect(() => Exonum.sign(secretKey, someData, CustomMessage)).to.throw(TypeError); - }); - - it('should throw error when the type parameter of invalid type', function() { - var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var User = { - alpha: 5 - }; - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - - expect(() => Exonum.sign(secretKey, userData, User)).to.throw(TypeError); - }); - - it('should throw error when the secretKey parameter of wrong length', function() { - var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - var buffer = User.serialize(userData); - - expect(() => Exonum.sign(secretKey, buffer)).to.throw(TypeError); - }); - - it('should throw error when wrong secretKey parameter', function() { - var secretKey = '6752ZE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - var buffer = User.serialize(userData); - - expect(() => Exonum.sign(secretKey, buffer)).to.throw(TypeError); - }); - - it('should throw error when the secretKey parameter of invalid type', function() { - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - var buffer = User.serialize(userData); - - [true, null, undefined, [], {}, 51, new Date()].forEach(function(secretKey) { - expect(() => Exonum.sign(secretKey, buffer)).to.throw(TypeError); - }); - }); - - }); - - describe('Verify signature', function() { - - it('should verify signature of the data of NewType type and return true', function() { - var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var signature = '7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040e'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - - expect(User.verifySignature(signature, publicKey, userData)).to.be.true; - }); - - it('should verify signature of the data of NewType type using built-in method and return true', function() { - var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var signature = '7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040e'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - - expect(User.verifySignature(signature, publicKey, userData)).to.be.true; - }); - - it('should verify signature of the data of NewMessage type and return true', function() { - var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var signature = '4006cef1884941850a6b97a64ed7f12d1e1053188618ef71b8c9f87438b943b1969e08011e45db8299bb738fec60c9dcd1936ab9ba44392cacc7f0385f18dd09'; - var CustomMessage = Exonum.newMessage({ - size: 18, - network_id: 0, - protocol_version: 0, - service_id: 1, - message_id: 2, - fields: { - name: {type: Exonum.String, size: 8, from: 0, to: 8}, - age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, - balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, - status: {type: Exonum.Bool, size: 1, from: 17, to: 18} - } - }); - var messageData = { - name: 'John Doe', - age: 34, - balance: 173008, - status: true - }; - - expect(Exonum.verifySignature(signature, publicKey, messageData, CustomMessage)).to.be.true; - }); - - it('should verify signature of the data of NewMessage type using built-in method and return true', function() { - var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var signature = '4006cef1884941850a6b97a64ed7f12d1e1053188618ef71b8c9f87438b943b1969e08011e45db8299bb738fec60c9dcd1936ab9ba44392cacc7f0385f18dd09'; - var CustomMessage = Exonum.newMessage({ - size: 18, - network_id: 0, - protocol_version: 0, - service_id: 1, - message_id: 2, - fields: { - name: {type: Exonum.String, size: 8, from: 0, to: 8}, - age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, - balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, - status: {type: Exonum.Bool, size: 1, from: 17, to: 18} - } - }); - var messageData = { - name: 'John Doe', - age: 34, - balance: 173008, - status: true - }; - - expect(CustomMessage.verifySignature(signature, publicKey, messageData)).to.be.true; - }); - - it('should verify signature of the array of 8-bit integers', function() { - var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var signature = '7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040e'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - var buffer = User.serialize(userData); - - expect(Exonum.verifySignature(signature, publicKey, buffer)).to.be.true; - }); - - it('should verify signature of the array of 8-bit integers', function() { - var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var signature = '7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040b'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - var buffer = User.serialize(userData); - - expect(Exonum.verifySignature(signature, publicKey, buffer)).to.be.false; - }); - - it('should throw error when the data parameter is of wrong NewType type', function() { - var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var signature = '9e0f0122c2963b76ba10842951cd1b67c8197b3f964c34f8b667aa655a7b4a8d844d567698d99de30590fc5002ddb4b9b5927ec05cd73572b972cb6b034cd40b'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - sum: 500, - hash: 'Hello world' - }; - - expect(() => Exonum.verifySignature(signature, publicKey, userData, User)).to.throw(TypeError); - }); - - it('should throw error when the data parameter is of wrong NewMessage type', function() { - var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var signature = '24a5224702d670c95a78ef1f753c9e6e698da5b2a2c52dcc51b5bf9e556e717fb763b1a5e78bd39e5369a139ab68ae50dd19a129038e8da3af30985f09549500'; - var CustomMessage = Exonum.newMessage({ - size: 18, - network_id: 0, - protocol_version: 0, - service_id: 1, - message_id: 2, - fields: { - name: {type: Exonum.String, size: 8, from: 0, to: 8}, - age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, - balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, - status: {type: Exonum.Bool, size: 1, from: 17, to: 18} - } - }); - var someData = { - sum: 500, - hash: 'Hello world' - }; - - expect(() => Exonum.verifySignature(signature, publicKey, someData, CustomMessage)).to.throw(TypeError); - }); - - it('should throw error when the type parameter is of wrong type', function() { - var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var signature = '9e0f0122c2963b76ba10842951cd1b67c8197b3f964c34f8b667aa655a7b4a8d844d567698d99de30590fc5002ddb4b9b5927ec05cd73572b972cb6b034cd40b'; - var User = { - alpha: 3 - }; - var userData = { - sum: 500, - hash: 'Hello world' - }; - - expect(() => Exonum.verifySignature(signature, publicKey, userData, User)).to.throw(TypeError); - }); - - it('should throw error when the signature parameter is of wrong length', function() { - var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var signature = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - var buffer = User.serialize(userData); - - expect(() => Exonum.verifySignature(signature, publicKey, buffer)).to.throw(TypeError); - }); - - it('should throw error when the signature parameter is invalid', function() { - var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var signature = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7Z'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - var buffer = User.serialize(userData); - - expect(() => Exonum.verifySignature(signature, publicKey, buffer)).to.throw(TypeError); - }); - - it('should throw error when the signature parameter is of wrong type', function() { - var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - var buffer = User.serialize(userData); - - [true, null, undefined, [], {}, 51, new Date()].forEach(function(signature) { - expect(() => Exonum.verifySignature(signature, publicKey, buffer)).to.throw(TypeError); - }); - }); - - it('should throw error when the publicKey parameter is of wrong length', function() { - var publicKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C'; - var signature = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - var buffer = User.serialize(userData); - - expect(() => Exonum.verifySignature(signature, publicKey, buffer)).to.throw(TypeError); - }); - - it('should throw error when the publicKey parameter is invalid', function() { - var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C3Z'; - var signature = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - var buffer = User.serialize(userData); - - expect(() => Exonum.verifySignature(signature, publicKey, buffer)).to.throw(TypeError); - }); - - it('should throw error when the publicKey parameter is of wrong type', function() { - var signature = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C'; - var User = Exonum.newType({ - size: 16, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var userData = { - firstName: 'John', - lastName: 'Doe' - }; - var buffer = User.serialize(userData); - - [true, null, undefined, [], {}, 51, new Date()].forEach(function(publicKey) { - expect(() => Exonum.verifySignature(signature, publicKey, buffer)).to.throw(TypeError); - }); - }); - - }); - - describe('Generate key pair', function() { - - it('should generate random key pair of secret and public keys, serialize it and return serialized array', function() { - var Type = Exonum.newType({ - size: 96, - fields: { - publicKey: {type: Exonum.Hash, size: 32, from: 0, to: 32}, - secretKey: {type: Exonum.Digest, size: 64, from: 32, to: 96} - } - }); - var data = Exonum.keyPair(); - var buffer = Type.serialize(data); - - expect(buffer.length).to.equal(96); - }); - - }); - - describe('Generate random Uint64', function() { - - it('should generate random value of Uint64 type, serialize and return serialized array', function() { - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Uint64, size: 8, from: 0, to: 8}} - }); - var data = {balance: Exonum.randomUint64()}; - var buffer = Type.serialize(data); - - expect(buffer.length).to.equal(8); - }); - - }); - -}); +/* eslint-disable no-unused-expressions */ + +var expect = require('chai').expect +var Exonum = require('../src') + +describe('Check cryptography', function () { + describe('Get SHA256 hash', function () { + it('should return hash of data of newType type', function () { + var Wallet = Exonum.newType({ + size: 80, + fields: { + pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, + name: {type: Exonum.String, size: 8, from: 32, to: 40}, + balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, + history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} + } + }) + var walletData = { + pub_key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36', + name: 'Smart wallet', + balance: 359120, + history_hash: '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030' + } + var hash = Exonum.hash(walletData, Wallet) + + expect(hash).to.equal('86b47510fbcbc83f9926d8898a57c53662518c97502625a6d131842f2003f974') + }) + + it('should return hash of data of newType type using built-in method', function () { + var Wallet = Exonum.newType({ + size: 80, + fields: { + pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, + name: {type: Exonum.String, size: 8, from: 32, to: 40}, + balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, + history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} + } + }) + var walletData = { + pub_key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36', + name: 'Smart wallet', + balance: 359120, + history_hash: '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030' + } + var hash = Wallet.hash(walletData) + + expect(hash).to.equal('86b47510fbcbc83f9926d8898a57c53662518c97502625a6d131842f2003f974') + }) + + it('should return hash of data of newMessage type', function () { + var CustomMessage = Exonum.newMessage({ + size: 18, + network_id: 0, + protocol_version: 0, + service_id: 1, + message_id: 2, + fields: { + name: {type: Exonum.String, size: 8, from: 0, to: 8}, + age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, + balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, + status: {type: Exonum.Bool, size: 1, from: 17, to: 18} + }, + signature: 'dad76b4c3b067d53265534bde4d9ff59987d00f87e0e1a633613576195a4cbc1e0a43a58c67c34c98019f791812699d010655c4eccec448e46e5524471a8c401' + }) + var messageData = { + name: 'John Doe', + age: 34, + balance: 17, + status: true + } + var hash = Exonum.hash(messageData, CustomMessage) + + expect(hash).to.equal('df2d0cf21d4fc1e2b0adf6dbff7daeb0d7292e9f51f529358c18b95b67539484') + }) + + it('should return hash of data of newMessage type using built-in method', function () { + var CustomMessage = Exonum.newMessage({ + size: 18, + network_id: 0, + protocol_version: 0, + service_id: 1, + message_id: 2, + fields: { + name: {type: Exonum.String, size: 8, from: 0, to: 8}, + age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, + balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, + status: {type: Exonum.Bool, size: 1, from: 17, to: 18} + }, + signature: 'dad76b4c3b067d53265534bde4d9ff59987d00f87e0e1a633613576195a4cbc1e0a43a58c67c34c98019f791812699d010655c4eccec448e46e5524471a8c401' + }) + var messageData = { + name: 'John Doe', + age: 34, + balance: 17, + status: true + } + var hash = CustomMessage.hash(messageData) + + expect(hash).to.equal('df2d0cf21d4fc1e2b0adf6dbff7daeb0d7292e9f51f529358c18b95b67539484') + }) + + it('should return hash of the array of 8-bit integers', function () { + var Wallet = Exonum.newType({ + size: 80, + fields: { + pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, + name: {type: Exonum.String, size: 8, from: 32, to: 40}, + balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, + history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} + } + }) + var walletData = { + pub_key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36', + name: 'Smart wallet', + balance: 359120, + history_hash: '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030' + } + var buffer = Wallet.serialize(walletData) + var hash = Exonum.hash(buffer) + + expect(hash).to.equal('86b47510fbcbc83f9926d8898a57c53662518c97502625a6d131842f2003f974') + }) + + it('should throw error when data of invalid NewType type', function () { + var Wallet = Exonum.newType({ + size: 80, + fields: { + pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, + name: {type: Exonum.String, size: 8, from: 32, to: 40}, + balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, + history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} + } + }); + + [undefined, false, 42, new Date(), []].forEach(function (_hash) { + expect(() => Exonum.hash(_hash, Wallet)).to.throw(TypeError) + }) + }) + + it('should throw error when data of invalid NewMessage type', function () { + var CustomMessage = Exonum.newMessage({ + size: 18, + network_id: 0, + protocol_version: 0, + service_id: 1, + message_id: 2, + fields: { + name: {type: Exonum.String, size: 8, from: 0, to: 8}, + age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, + balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, + status: {type: Exonum.Bool, size: 1, from: 17, to: 18} + } + }); + + [undefined, false, 42, new Date(), []].forEach(function (_hash) { + expect(() => Exonum.hash(_hash, CustomMessage)).to.throw(TypeError) + }) + }) + }) + + describe('Get ED25519 signature', function () { + it('should return signature of the data of NewType type', function () { + var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + firstName: 'John', + lastName: 'Doe' + } + var signature = User.sign(secretKey, userData) + + expect(signature).to.equal('7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040e') + }) + + it('should return signature of the data of NewType type using built-in method', function () { + var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + firstName: 'John', + lastName: 'Doe' + } + var signature = User.sign(secretKey, userData) + + expect(signature).to.equal('7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040e') + }) + + it('should return signature of the data of NewMessage type', function () { + var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var CustomMessage = Exonum.newMessage({ + size: 18, + network_id: 0, + protocol_version: 0, + service_id: 1, + message_id: 2, + fields: { + name: {type: Exonum.String, size: 8, from: 0, to: 8}, + age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, + balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, + status: {type: Exonum.Bool, size: 1, from: 17, to: 18} + } + }) + var messageData = { + name: 'John Doe', + age: 34, + balance: 173008, + status: true + } + var signature = Exonum.sign(secretKey, messageData, CustomMessage) + + expect(signature).to.equal('4006cef1884941850a6b97a64ed7f12d1e1053188618ef71b8c9f87438b943b1969e08011e45db8299bb738fec60c9dcd1936ab9ba44392cacc7f0385f18dd09') + }) + + it('should return signature of the data of NewMessage type using built-in method', function () { + var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var CustomMessage = Exonum.newMessage({ + size: 18, + network_id: 0, + protocol_version: 0, + service_id: 1, + message_id: 2, + fields: { + name: {type: Exonum.String, size: 8, from: 0, to: 8}, + age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, + balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, + status: {type: Exonum.Bool, size: 1, from: 17, to: 18} + } + }) + var messageData = { + name: 'John Doe', + age: 34, + balance: 173008, + status: true + } + var signature = CustomMessage.sign(secretKey, messageData) + + expect(signature).to.equal('4006cef1884941850a6b97a64ed7f12d1e1053188618ef71b8c9f87438b943b1969e08011e45db8299bb738fec60c9dcd1936ab9ba44392cacc7f0385f18dd09') + }) + + it('should return signature of the array of 8-bit integers', function () { + var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + firstName: 'John', + lastName: 'Doe' + } + var buffer = User.serialize(userData) + var signature = Exonum.sign(secretKey, buffer) + + expect(signature).to.equal('7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040e') + }) + + it('should throw error when the data parameter of wrong NewType type', function () { + var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + sum: 500, + hash: 'Hello world' + } + + expect(() => Exonum.sign(secretKey, userData, User)).to.throw(TypeError) + }) + + it('should throw error when the data parameter of wrong NewMessage type', function () { + var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var CustomMessage = Exonum.newMessage({ + size: 18, + network_id: 0, + protocol_version: 0, + service_id: 1, + message_id: 2, + fields: { + name: {type: Exonum.String, size: 8, from: 0, to: 8}, + age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, + balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, + status: {type: Exonum.Bool, size: 1, from: 17, to: 18} + } + }) + var someData = { + sum: 500, + hash: 'Hello world' + } + + expect(() => Exonum.sign(secretKey, someData, CustomMessage)).to.throw(TypeError) + }) + + it('should throw error when the type parameter of invalid type', function () { + var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var User = { + alpha: 5 + } + var userData = { + firstName: 'John', + lastName: 'Doe' + } + + expect(() => Exonum.sign(secretKey, userData, User)).to.throw(TypeError) + }) + + it('should throw error when the secretKey parameter of wrong length', function () { + var secretKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + firstName: 'John', + lastName: 'Doe' + } + var buffer = User.serialize(userData) + + expect(() => Exonum.sign(secretKey, buffer)).to.throw(TypeError) + }) + + it('should throw error when wrong secretKey parameter', function () { + var secretKey = '6752ZE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + firstName: 'John', + lastName: 'Doe' + } + var buffer = User.serialize(userData) + + expect(() => Exonum.sign(secretKey, buffer)).to.throw(TypeError) + }) + + it('should throw error when the secretKey parameter of invalid type', function () { + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + firstName: 'John', + lastName: 'Doe' + } + var buffer = User.serialize(userData); + + [true, null, undefined, [], {}, 51, new Date()].forEach(function (secretKey) { + expect(() => Exonum.sign(secretKey, buffer)).to.throw(TypeError) + }) + }) + }) + + describe('Verify signature', function () { + it('should verify signature of the data of NewType type and return true', function () { + var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var signature = '7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040e' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + firstName: 'John', + lastName: 'Doe' + } + + expect(User.verifySignature(signature, publicKey, userData)).to.be.true + }) + + it('should verify signature of the data of NewType type using built-in method and return true', function () { + var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var signature = '7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040e' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + firstName: 'John', + lastName: 'Doe' + } + + expect(User.verifySignature(signature, publicKey, userData)).to.be.true + }) + + it('should verify signature of the data of NewMessage type and return true', function () { + var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var signature = '4006cef1884941850a6b97a64ed7f12d1e1053188618ef71b8c9f87438b943b1969e08011e45db8299bb738fec60c9dcd1936ab9ba44392cacc7f0385f18dd09' + var CustomMessage = Exonum.newMessage({ + size: 18, + network_id: 0, + protocol_version: 0, + service_id: 1, + message_id: 2, + fields: { + name: {type: Exonum.String, size: 8, from: 0, to: 8}, + age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, + balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, + status: {type: Exonum.Bool, size: 1, from: 17, to: 18} + } + }) + var messageData = { + name: 'John Doe', + age: 34, + balance: 173008, + status: true + } + + expect(Exonum.verifySignature(signature, publicKey, messageData, CustomMessage)).to.be.true + }) + + it('should verify signature of the data of NewMessage type using built-in method and return true', function () { + var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var signature = '4006cef1884941850a6b97a64ed7f12d1e1053188618ef71b8c9f87438b943b1969e08011e45db8299bb738fec60c9dcd1936ab9ba44392cacc7f0385f18dd09' + var CustomMessage = Exonum.newMessage({ + size: 18, + network_id: 0, + protocol_version: 0, + service_id: 1, + message_id: 2, + fields: { + name: {type: Exonum.String, size: 8, from: 0, to: 8}, + age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, + balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, + status: {type: Exonum.Bool, size: 1, from: 17, to: 18} + } + }) + var messageData = { + name: 'John Doe', + age: 34, + balance: 173008, + status: true + } + + expect(CustomMessage.verifySignature(signature, publicKey, messageData)).to.be.true + }) + + it('should verify signature of the array of 8-bit integers', function () { + var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var signature = '7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040e' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + firstName: 'John', + lastName: 'Doe' + } + var buffer = User.serialize(userData) + + expect(Exonum.verifySignature(signature, publicKey, buffer)).to.be.true + }) + + it('should verify signature of the array of 8-bit integers', function () { + var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var signature = '7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040b' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + firstName: 'John', + lastName: 'Doe' + } + var buffer = User.serialize(userData) + + expect(Exonum.verifySignature(signature, publicKey, buffer)).to.be.false + }) + + it('should throw error when the data parameter is of wrong NewType type', function () { + var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var signature = '9e0f0122c2963b76ba10842951cd1b67c8197b3f964c34f8b667aa655a7b4a8d844d567698d99de30590fc5002ddb4b9b5927ec05cd73572b972cb6b034cd40b' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + sum: 500, + hash: 'Hello world' + } + + expect(() => Exonum.verifySignature(signature, publicKey, userData, User)).to.throw(TypeError) + }) + + it('should throw error when the data parameter is of wrong NewMessage type', function () { + var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var signature = '24a5224702d670c95a78ef1f753c9e6e698da5b2a2c52dcc51b5bf9e556e717fb763b1a5e78bd39e5369a139ab68ae50dd19a129038e8da3af30985f09549500' + var CustomMessage = Exonum.newMessage({ + size: 18, + network_id: 0, + protocol_version: 0, + service_id: 1, + message_id: 2, + fields: { + name: {type: Exonum.String, size: 8, from: 0, to: 8}, + age: {type: Exonum.Uint8, size: 1, from: 8, to: 9}, + balance: {type: Exonum.Uint64, size: 8, from: 9, to: 17}, + status: {type: Exonum.Bool, size: 1, from: 17, to: 18} + } + }) + var someData = { + sum: 500, + hash: 'Hello world' + } + + expect(() => Exonum.verifySignature(signature, publicKey, someData, CustomMessage)).to.throw(TypeError) + }) + + it('should throw error when the type parameter is of wrong type', function () { + var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var signature = '9e0f0122c2963b76ba10842951cd1b67c8197b3f964c34f8b667aa655a7b4a8d844d567698d99de30590fc5002ddb4b9b5927ec05cd73572b972cb6b034cd40b' + var User = { + alpha: 3 + } + var userData = { + sum: 500, + hash: 'Hello world' + } + + expect(() => Exonum.verifySignature(signature, publicKey, userData, User)).to.throw(TypeError) + }) + + it('should throw error when the signature parameter is of wrong length', function () { + var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var signature = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + firstName: 'John', + lastName: 'Doe' + } + var buffer = User.serialize(userData) + + expect(() => Exonum.verifySignature(signature, publicKey, buffer)).to.throw(TypeError) + }) + + it('should throw error when the signature parameter is invalid', function () { + var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var signature = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7Z' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + firstName: 'John', + lastName: 'Doe' + } + var buffer = User.serialize(userData) + + expect(() => Exonum.verifySignature(signature, publicKey, buffer)).to.throw(TypeError) + }) + + it('should throw error when the signature parameter is of wrong type', function () { + var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + firstName: 'John', + lastName: 'Doe' + } + var buffer = User.serialize(userData); + + [true, null, undefined, [], {}, 51, new Date()].forEach(function (signature) { + expect(() => Exonum.verifySignature(signature, publicKey, buffer)).to.throw(TypeError) + }) + }) + + it('should throw error when the publicKey parameter is of wrong length', function () { + var publicKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C' + var signature = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + firstName: 'John', + lastName: 'Doe' + } + var buffer = User.serialize(userData) + + expect(() => Exonum.verifySignature(signature, publicKey, buffer)).to.throw(TypeError) + }) + + it('should throw error when the publicKey parameter is invalid', function () { + var publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C3Z' + var signature = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + firstName: 'John', + lastName: 'Doe' + } + var buffer = User.serialize(userData) + + expect(() => Exonum.verifySignature(signature, publicKey, buffer)).to.throw(TypeError) + }) + + it('should throw error when the publicKey parameter is of wrong type', function () { + var signature = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C' + var User = Exonum.newType({ + size: 16, + fields: { + firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, + lastName: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var userData = { + firstName: 'John', + lastName: 'Doe' + } + var buffer = User.serialize(userData); + + [true, null, undefined, [], {}, 51, new Date()].forEach(function (publicKey) { + expect(() => Exonum.verifySignature(signature, publicKey, buffer)).to.throw(TypeError) + }) + }) + }) + + describe('Generate key pair', function () { + it('should generate random key pair of secret and public keys, serialize it and return serialized array', function () { + var Type = Exonum.newType({ + size: 96, + fields: { + publicKey: {type: Exonum.Hash, size: 32, from: 0, to: 32}, + secretKey: {type: Exonum.Digest, size: 64, from: 32, to: 96} + } + }) + var data = Exonum.keyPair() + var buffer = Type.serialize(data) + + expect(buffer.length).to.equal(96) + }) + }) + + describe('Generate random Uint64', function () { + it('should generate random value of Uint64 type, serialize and return serialized array', function () { + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Uint64, size: 8, from: 0, to: 8}} + }) + var data = {balance: Exonum.randomUint64()} + var buffer = Type.serialize(data) + + expect(buffer.length).to.equal(8) + }) + }) +}) diff --git a/test/merkle-patricia-proof.js b/test/merkle-patricia-proof.js index 9134210..bcaa9ae 100644 --- a/test/merkle-patricia-proof.js +++ b/test/merkle-patricia-proof.js @@ -1,141 +1,141 @@ /* eslint-env node, mocha */ +/* eslint-disable no-unused-expressions */ -var expect = require('chai').expect; -var Exonum = require('../src'); +var expect = require('chai').expect +var Exonum = require('../src') -describe('Check proof of Merkle Patricia tree', function() { - - it('should return null when an empty tree', function() { - var data = require('./common_data/merkle-patricia-tree/valid-MPT-empty-tree.json'); - var element = Exonum.merklePatriciaProof( +describe('Check proof of Merkle Patricia tree', function () { + it('should return null when an empty tree', function () { + var data = require('./common_data/merkle-patricia-tree/valid-MPT-empty-tree.json') + var element = Exonum.merklePatriciaProof( data.root_hash, data.proof, data.searched_key - ); - expect(element).to.be.null; - }); + ) + expect(element).to.be.null + }) - it('should return null when valid tree with leaf exclusive', function() { - var data = require('./common_data/merkle-patricia-tree/valid-MPT-leaf-exclusive.json'); - var element = Exonum.merklePatriciaProof( + it('should return null when valid tree with leaf exclusive', function () { + var data = require('./common_data/merkle-patricia-tree/valid-MPT-leaf-exclusive.json') + var element = Exonum.merklePatriciaProof( data.root_hash, data.proof, data.searched_key - ); - expect(element).to.be.null; - }); + ) + expect(element).to.be.null + }) - it('should return the child of valid tree with leaf inclusive', function() { - var data = require('./common_data/merkle-patricia-tree/valid-MPT-leaf-inclusive.json'); - var element = Exonum.merklePatriciaProof( + it('should return the child of valid tree with leaf inclusive', function () { + var data = require('./common_data/merkle-patricia-tree/valid-MPT-leaf-inclusive.json') + var element = Exonum.merklePatriciaProof( data.root_hash, data.proof, data.searched_key - ); - expect(element).to.deep.equal([2]); - }); + ) + expect(element).to.deep.equal([2]) + }) - it('should return null when a tree with nested node exclusive', function() { - var data = require('./common_data/merkle-patricia-tree/valid-MPT-nested-exclusive.json'); - var element = Exonum.merklePatriciaProof( + it('should return null when a tree with nested node exclusive', function () { + var data = require('./common_data/merkle-patricia-tree/valid-MPT-nested-exclusive.json') + var element = Exonum.merklePatriciaProof( data.root_hash, data.proof, data.searched_key - ); - expect(element).to.be.null; - }); + ) + expect(element).to.be.null + }) - it('should return the child of an valid tree with nested node inclusive', function() { - var data = require('./common_data/merkle-patricia-tree/valid-MPT-nested-inclusive.json'); - var element = Exonum.merklePatriciaProof( + it('should return the child of an valid tree with nested node inclusive', function () { + var data = require('./common_data/merkle-patricia-tree/valid-MPT-nested-inclusive.json') + var element = Exonum.merklePatriciaProof( data.root_hash, data.proof, data.searched_key - ); - expect(element).to.deep.equal([36, 49, 15, 31, 163, 171, 247, 217]); - }); + ) + expect(element).to.deep.equal([36, 49, 15, 31, 163, 171, 247, 217]) + }) - it('should return the child of an valid tree with hash stored in value', function() { - var data = require('./common_data/merkle-patricia-tree/valid-MPT-hash-values.json'); - var element = Exonum.merklePatriciaProof( + it('should return the child of an valid tree with hash stored in value', function () { + var data = require('./common_data/merkle-patricia-tree/valid-MPT-hash-values.json') + var element = Exonum.merklePatriciaProof( data.root_hash, data.proof, data.searched_key - ); - expect(element).to.equal('7a6dedabca50b700a834d37f91649b0b5b42883b4e39845df36da4c24c2bc64f'); - }); + ) + expect(element).to.equal('7a6dedabca50b700a834d37f91649b0b5b42883b4e39845df36da4c24c2bc64f') + }) - it('should return the child of an valid tree with children which has common prefix', function() { - var data = require('./common_data/merkle-patricia-tree/valid-MPT-common-prefix-children.json'); - var element = Exonum.merklePatriciaProof( + it('should return the child of an valid tree with children which has common prefix', function () { + var data = require('./common_data/merkle-patricia-tree/valid-MPT-common-prefix-children.json') + var element = Exonum.merklePatriciaProof( data.root_hash, data.proof, data.searched_key - ); - expect(element).to.deep.equal([186, 86, 216, 153, 23, 168, 188, 225]); - }); - - it('should throw error when keys one key is full prefix of another', function() { - var data = require('./data/invalid-MPT-common-prefix-children.json'); - expect(() => Exonum.merklePatriciaProof(data.root_hash, data.proof, data.searched_key)).to.throw(Error, 'Impossible to determine left and right nodes.'); - }); - - it('should throw error when common-prefix keys are found on non-zero level', function() { - var data = require('./data/invalid-MPT-common-prefix-children-at-non-zero-lvl.json'); - expect(() => Exonum.merklePatriciaProof(data.root_hash, data.proof, data.searched_key)).to.throw(Error, 'Nodes with common-prefix keys are located on non-zero level of the tree.'); - }); - - it('should throw error when key suffix is of zero-length', function() { - var data = require('./data/invalid-MPT-zero-len-keys-suffix.json'); - expect(() => Exonum.merklePatriciaProof(data.root_hash, data.proof, data.searched_key)).to.throw(Error, 'Empty key suffix is passed.'); - }); - - it('should return the child of an valid tree with children which has common prefix and hashes as values', function() { - var data = require('./common_data/merkle-patricia-tree/valid-MPT-common-prefix-children-hash-values.json'); - var element = Exonum.merklePatriciaProof( + ) + expect(element).to.deep.equal([186, 86, 216, 153, 23, 168, 188, 225]) + }) + + it('should throw error when keys one key is full prefix of another', function () { + var data = require('./data/invalid-MPT-common-prefix-children.json') + expect(() => Exonum.merklePatriciaProof(data.root_hash, data.proof, data.searched_key)).to.throw(Error, 'Impossible to determine left and right nodes.') + }) + + it('should throw error when common-prefix keys are found on non-zero level', function () { + var data = require('./data/invalid-MPT-common-prefix-children-at-non-zero-lvl.json') + expect(() => Exonum.merklePatriciaProof(data.root_hash, data.proof, data.searched_key)).to.throw(Error, 'Nodes with common-prefix keys are located on non-zero level of the tree.') + }) + + it('should throw error when key suffix is of zero-length', function () { + var data = require('./data/invalid-MPT-zero-len-keys-suffix.json') + expect(() => Exonum.merklePatriciaProof(data.root_hash, data.proof, data.searched_key)).to.throw(Error, 'Empty key suffix is passed.') + }) + + it('should return the child of an valid tree with children which has common prefix and hashes as values', function () { + var data = require('./common_data/merkle-patricia-tree/valid-MPT-common-prefix-children-hash-values.json') + var element = Exonum.merklePatriciaProof( data.root_hash, data.proof, data.searched_key - ); - expect(element).to.equal('7acfd59d96d77ed99169fdc0826a6ef8a6b45d87ac00536373882dfa7ba70925'); - }); - - it('should throw error when rootHash parameter of wrong type', function() { - var args = [ - true, null, undefined, [], {}, 42, new Date() - ]; - - args.forEach(function(rootHash) { - expect(() => Exonum.merklePatriciaProof(rootHash)).to.throw(TypeError); - }); - }); - - it('should throw error when invalid rootHash parameter', function() { - var args = [ - '6z56f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13', - '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff1' - ]; - - args.forEach(function(rootHash) { - expect(() => Exonum.merklePatriciaProof(rootHash)).to.throw(Error); - }); - }); - - it('should throw error when invalid proofNode parameter', function() { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var args = [ - true, null, undefined, [], 42, 'Hello world', new Date() - ]; - - args.forEach(function(proofNode) { - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode)).to.throw(TypeError); - }); - }); - - it('should throw error when invalid byte array key parameter', function() { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var proofNode = {}; - var args = [ + ) + expect(element).to.equal('7acfd59d96d77ed99169fdc0826a6ef8a6b45d87ac00536373882dfa7ba70925') + }) + + it('should throw error when rootHash parameter of wrong type', function () { + var args = [ + true, null, undefined, [], {}, 42, new Date() + ] + + args.forEach(function (rootHash) { + expect(() => Exonum.merklePatriciaProof(rootHash)).to.throw(TypeError) + }) + }) + + it('should throw error when invalid rootHash parameter', function () { + var args = [ + '6z56f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13', + '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff1' + ] + + args.forEach(function (rootHash) { + expect(() => Exonum.merklePatriciaProof(rootHash)).to.throw(Error) + }) + }) + + it('should throw error when invalid proofNode parameter', function () { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var args = [ + true, null, undefined, [], 42, 'Hello world', new Date() + ] + + args.forEach(function (proofNode) { + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode)).to.throw(TypeError) + }) + }) + + it('should throw error when invalid byte array key parameter', function () { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var proofNode = {} + var args = [ [1, 114], [1, true, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0], [1, null, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0], @@ -144,591 +144,590 @@ describe('Check proof of Merkle Patricia tree', function() { [1, new Date(), 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0], [1, 256, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0], [1, -1, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0, 1, 114, 5, 0] - ]; - - args.forEach(function(key) { - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - }); - - it('should throw error when invalid string key parameter', function() { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var proofNode = {}; - var args = [ - '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff1', - '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff1z', - '' - ]; - - args.forEach(function(key) { - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - }); - - it('should throw error when key parameter of wrong type', function() { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var proofNode = {}; - var args = [ - true, null, undefined, 42, [], {}, new Date() - ]; - - args.forEach(function(key) { - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - }); - - it('should throw error when root is empty but rootHash is wrong', function() { - var rootHash = '0000000000000000000000000000000000000000000000000000000000000001'; - var proofNode = {}; - var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - - it('should throw error when key of node is invalid binary string', function() { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var proofNode = {'11110000111100': {}}; - var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - - proofNode = {'111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001a': {}}; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - - proofNode = {'1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110013': {}}; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - - it('should throw error when it is invalid hash is value of tree node', function() { - var vals = [ - '', - '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff1', - '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff1z' - ]; - - vals.forEach(function(val) { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var proofNode = {'1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': val}; - var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - }); - - it('should throw error when wrong rootHash parameter is passed (element is not found)', function() { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var proofNode = {'1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'}; - var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - - it('should throw error when invalid key with hash is in the root (element is not found)', function() { - var rootHash = '335ec501d811725a9e60f89a1b67103e6fa5e65712a007ed33324719a6e2de3a'; - var proofNode = {'1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'}; - var key = 'f0f1f2f3f0f1f2f3f0f1f2f3f0f1f2f3f0f1f2f3f0f1f2f3f0f1f2f3f0f1f2f3'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - - it('should throw error when value is of invalid type', function() { - var vals = [ - false, null, undefined, 'Hello world', 42, new Date() - ]; - - vals.forEach(function(val) { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var proofNode = { - '1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': { - val: val - } - }; - var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - }); - - it('should throw error when invalid symbols in bytes array', function() { - var vals = [ + ] + + args.forEach(function (key) { + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + }) + + it('should throw error when invalid string key parameter', function () { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var proofNode = {} + var args = [ + '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff1', + '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff1z', + '' + ] + + args.forEach(function (key) { + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + }) + + it('should throw error when key parameter of wrong type', function () { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var proofNode = {} + var args = [ + true, null, undefined, 42, [], {}, new Date() + ] + + args.forEach(function (key) { + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + }) + + it('should throw error when root is empty but rootHash is wrong', function () { + var rootHash = '0000000000000000000000000000000000000000000000000000000000000001' + var proofNode = {} + var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + + it('should throw error when key of node is invalid binary string', function () { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var proofNode = {'11110000111100': {}} + var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + + proofNode = {'111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001a': {}} + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + + proofNode = {'1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110013': {}} + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + + it('should throw error when it is invalid hash is value of tree node', function () { + var vals = [ + '', + '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff1', + '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff1z' + ] + + vals.forEach(function (val) { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var proofNode = {'1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': val} + var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + }) + + it('should throw error when wrong rootHash parameter is passed (element is not found)', function () { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var proofNode = {'1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'} + var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + + it('should throw error when invalid key with hash is in the root (element is not found)', function () { + var rootHash = '335ec501d811725a9e60f89a1b67103e6fa5e65712a007ed33324719a6e2de3a' + var proofNode = {'1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'} + var key = 'f0f1f2f3f0f1f2f3f0f1f2f3f0f1f2f3f0f1f2f3f0f1f2f3f0f1f2f3f0f1f2f3' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + + it('should throw error when value is of invalid type', function () { + var vals = [ + false, null, undefined, 'Hello world', 42, new Date() + ] + + vals.forEach(function (val) { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var proofNode = { + '1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': { + val: val + } + } + var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + }) + + it('should throw error when invalid symbols in bytes array', function () { + var vals = [ [1, 'a', 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4] - ]; - - vals.forEach(function(val) { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var proofNode = { - '1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': { - val: val - } - }; - var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError); - }); - }); - - it('should throw error when invalid bytes array is on value position', function() { - var vals = [ + ] + + vals.forEach(function (val) { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var proofNode = { + '1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': { + val: val + } + } + var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError) + }) + }) + + it('should throw error when invalid bytes array is on value position', function () { + var vals = [ [1, -1, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4], [1, 256, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4] - ]; - - vals.forEach(function(val) { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var proofNode = { - '1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': { - val: val - } - }; - var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError); - }); - }); - - it('should throw error when invalid value type', function() { - var vals = [ - false, undefined, [], 42, new Date() - ]; - - vals.forEach(function(val) { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var proofNode = { - '1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': val - }; - var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - }); - - it('should throw error when invalid type parameter', function() { - var vals = [ - null, false, 42, {}, [], new Date() - ]; - - vals.forEach(function(type) { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var proofNode = { - '1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': { - val: { - name: 'John', - surname: 'Doe' - } - } - }; - var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, type)).to.throw(TypeError); - }); - }); - - it('should throw error when single node tree with wrong type parameter', function() { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var proofNode = { - '1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': { - val: { - name: 'John', - surname: 'Doe' - } - } - }; - var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} - }); - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, Type)).to.throw(TypeError); - }); - - it('should throw error when single node tree with rootHash parameter not equal to actual hash (element is found)', function() { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var proofNode = { - '1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': { - val: { - balance: 4096 - } - } - }; - var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} - }); - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, Type)).to.throw(Error); - }); - - it('should throw error when single node tree with invalid key with value in the root (element is found)', function() { - var rootHash = '8cc79fea15327c3d6b11b8427ea0ea0a975fae454fbca696da03a033498cee05'; - var proofNode = { - '1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': { - val: { - balance: 4096 - } - } - }; - var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} - }); - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, Type)).to.throw(Error); - }); - - it('should throw error when single node tree with invalid key in the root of proofNode parameter', function() { - var rootHash = '8be78622dc7fd18b069a226133f1e943652bc5d53fd5df3d59735f49da1df692'; - var proofNode = { - '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': 'dbc1b4c900ffe48d575b5da5c638040125f65db0fe3e24494b76ea986457d986' - }; - var key = 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - - it('should throw error when single node tree with invalid key with value in the root', function() { - var rootHash = '8be78622dc7fd18b069a226133f1e943652bc5d53fd5df3d59735f49da1df692'; - var proofNode = { - '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': { - 'val': [ - 2 - ] - } - }; - var key = 'f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - - it('should throw error when invalid number of children in the root node', function() { - var rootHash = '0000000000000000000000000000000000000000000000000000000000000001'; - var proofNode = { - '1': '', - '2': '', - '3': '' - }; - var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - - it('should throw error when tree with array as key parameter is passed ', function() { - var rootHash = '8be78622dc7fd18b069a226133f1e943652bc5d53fd5df3d59735f49da1df692'; - var proofNode = { - '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': 'dbc1b4c900ffe48d575b5da5c638040125f65db0fe3e24494b76ea986457d986' - }; - var key = [244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244]; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError); - }); - - it('should throw error when wrong rootHash parameter', function() { - var data = require('./data/invalid-MPT-wrong-root-hash.json'); - var rootHash = data.root_hash; - var proofNode = data.proof; - var key = data.searched_key; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - - it('should throw error when invalid binary key', function() { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '12323': {}, - '5927': {} - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError); - }); - - it('should throw error when tree contains non full key and value of wrong type', function() { - [true, null, undefined, [], 42, new Date()].forEach(function(val) { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '0': val, - '1': {} - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError); - }); - }); - - it('should throw error when tree contains full key and value of wrong type', function() { - [true, null, undefined, [], 42, new Date()].forEach(function(val) { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '0011001010001111110000101101101011111110000101010111001100101110011110010011110000111001011111111011110110100101111111111110111001110011111110011111001110011110111100001100100101110011010010111111011110001001000010000110000001000101101111100000101010100': val, - '1': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError); - }); - }); - - it('should throw error when tree contains non full key and invalid hash', function() { - var args = [ - 'Hello world', - 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6ez', - '' - ]; - - args.forEach(function(val) { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '0': val, - '1': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - }); - - it('should throw error when tree contains full key and invalid hash', function() { - var args = [ - 'Hello world', - 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6ez', - '' - ]; - - args.forEach(function(val) { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': val, - '1': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - }); - - it('should throw error when tree contains full key and missed value', function() { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': { - 'age': 5 - }, - '1': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - - it('should throw error when tree contains full key and duplicated value', function() { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': { - val: [25, 13] - }, - '0110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': { - val: [71] - } - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - - it('should throw error when tree contains non full key and value on wrong position', function() { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '011001101': { - val: [25, 13] - }, - '1': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - - it('should throw error when tree contains key is of wrong length', function() { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6', - '11100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101': { - val: [25, 13] - } - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - - it('should throw error when tree contains full key and value of wrong type', function() { - [false, null, 42].forEach(function(val) { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': val, - '1': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError); - }); - }); - - it('should throw error when tree contains full key and invalid value', function() { - ['Hello world'].forEach(function(val) { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': val, - '1': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - }); - - it('should throw error when tree contains full key and value as invalid binary array', function() { - [[false], [null], ['Hello world'], [[]], [{}], [new Date()]].forEach(function(val) { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': { - val: val - }, - '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError); - }); - }); - - it('should throw error when tree contains full key and value as binary array with wrong value', function() { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': { - val: [257] - }, - '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError); - }); - - it('should throw error when tree contains full key and wrong type parameter', function() { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': { - val: { - name: 'John', - surname: 'Doe' - } - }, - '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - var Type = Exonum.newType({ - size: 80, - fields: { - pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, - name: {type: Exonum.String, size: 8, from: 32, to: 40}, - balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, - history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} - } - }); - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, Type)).to.throw(TypeError); - }); - - it('should throw error when tree contains non full key and wrong type parameter', function() { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '111': { - '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6', - '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100': { - val: { - name: 'John', - surname: 'Doe' - } - } - }, - '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - var Type = Exonum.newType({ - size: 80, - fields: { - pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, - name: {type: Exonum.String, size: 8, from: 32, to: 40}, - balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, - history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} - } - }); - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, Type)).to.throw(TypeError); - }); - - it('should throw error when tree contains duplicated left leaf', function() { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '111': { - '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6', - '0110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100': { - val: [255, 0, 5] - } - }, - '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - - it('should throw error when tree contains duplicated right leaf', function() { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '111': { - '1': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6', - '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100': { - val: [255, 0, 5] - } - }, - '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' - }; - var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - - it('should throw error when tree contains left key which is part of search key but branch is not expanded', function() { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '111': { - '01111111010111000100100111101010110010111100011010100000100111111110101011011000011000000000100001000100000101101101100010101110110101101010001100000101110100011101101111100100101110100110010011011100011111011010110010100011111011010011000101111011010': '9be1fdaa5e58640e6c17dba7e734c56ec7ccab77f823933301661e3514284dd7', - '11111111010111000100100111101010110010111100011010100000100110111110101011011000011000000000100001000100000101101101100010101110110101101010001100000101110100011101101111100100101110100110010011011100011111011010110010100011111011010011000101111011010': '9be1fdaa5e58640e6c17dba7e734c56ec7ccab77f823933301661e3514284dd7', - }, - '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' - }; - var key = 'ecdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - - it('should throw error when tree contains right key which is part of search key but branch is not expanded', function() { - var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55'; - var proofNode = { - '111': { - '01111111010111000100100111101010110010111100011010100000100111111110101011011000011000000000100001000100000101101101100010101110110101101010001100000101110100011101101111100100101110100110010011011100011111011010110010100011111011010011000101111011010': '9be1fdaa5e58640e6c17dba7e734c56ec7ccab77f823933301661e3514284dd7', - '11111111010111000100100111101010110010111100011010100000100110111110101011011000011000000000100001000100000101101101100010101110110101101010001100000101110100011101101111100100101110100110010011011100011111011010110010100011111011010011000101111011010': '9be1fdaa5e58640e6c17dba7e734c56ec7ccab77f823933301661e3514284dd7', - }, - '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' - }; - var key = 'fcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc'; - - expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error); - }); - -}); + ] + + vals.forEach(function (val) { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var proofNode = { + '1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': { + val: val + } + } + var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError) + }) + }) + + it('should throw error when invalid value type', function () { + var vals = [ + false, undefined, [], 42, new Date() + ] + + vals.forEach(function (val) { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var proofNode = { + '1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': val + } + var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + }) + + it('should throw error when invalid type parameter', function () { + var vals = [ + null, false, 42, {}, [], new Date() + ] + + vals.forEach(function (type) { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var proofNode = { + '1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': { + val: { + name: 'John', + surname: 'Doe' + } + } + } + var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, type)).to.throw(TypeError) + }) + }) + + it('should throw error when single node tree with wrong type parameter', function () { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var proofNode = { + '1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': { + val: { + name: 'John', + surname: 'Doe' + } + } + } + var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} + }) + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, Type)).to.throw(TypeError) + }) + + it('should throw error when single node tree with rootHash parameter not equal to actual hash (element is found)', function () { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var proofNode = { + '1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': { + val: { + balance: 4096 + } + } + } + var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} + }) + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, Type)).to.throw(Error) + }) + + it('should throw error when single node tree with invalid key with value in the root (element is found)', function () { + var rootHash = '8cc79fea15327c3d6b11b8427ea0ea0a975fae454fbca696da03a033498cee05' + var proofNode = { + '1111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011111100001111000111110010111100111111000011110001111100101111001111110000111100011111001011110011': { + val: { + balance: 4096 + } + } + } + var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} + }) + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, Type)).to.throw(Error) + }) + + it('should throw error when single node tree with invalid key in the root of proofNode parameter', function () { + var rootHash = '8be78622dc7fd18b069a226133f1e943652bc5d53fd5df3d59735f49da1df692' + var proofNode = { + '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': 'dbc1b4c900ffe48d575b5da5c638040125f65db0fe3e24494b76ea986457d986' + } + var key = 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + + it('should throw error when single node tree with invalid key with value in the root', function () { + var rootHash = '8be78622dc7fd18b069a226133f1e943652bc5d53fd5df3d59735f49da1df692' + var proofNode = { + '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': { + 'val': [ + 2 + ] + } + } + var key = 'f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + + it('should throw error when invalid number of children in the root node', function () { + var rootHash = '0000000000000000000000000000000000000000000000000000000000000001' + var proofNode = { + '1': '', + '2': '', + '3': '' + } + var key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + + it('should throw error when tree with array as key parameter is passed ', function () { + var rootHash = '8be78622dc7fd18b069a226133f1e943652bc5d53fd5df3d59735f49da1df692' + var proofNode = { + '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': 'dbc1b4c900ffe48d575b5da5c638040125f65db0fe3e24494b76ea986457d986' + } + var key = [244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244] + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError) + }) + + it('should throw error when wrong rootHash parameter', function () { + var data = require('./data/invalid-MPT-wrong-root-hash.json') + var rootHash = data.root_hash + var proofNode = data.proof + var key = data.searched_key + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + + it('should throw error when invalid binary key', function () { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '12323': {}, + '5927': {} + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError) + }) + + it('should throw error when tree contains non full key and value of wrong type', function () { + [true, null, undefined, [], 42, new Date()].forEach(function (val) { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '0': val, + '1': {} + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError) + }) + }) + + it('should throw error when tree contains full key and value of wrong type', function () { + [true, null, undefined, [], 42, new Date()].forEach(function (val) { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '0011001010001111110000101101101011111110000101010111001100101110011110010011110000111001011111111011110110100101111111111110111001110011111110011111001110011110111100001100100101110011010010111111011110001001000010000110000001000101101111100000101010100': val, + '1': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError) + }) + }) + + it('should throw error when tree contains non full key and invalid hash', function () { + var args = [ + 'Hello world', + 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6ez', + '' + ] + + args.forEach(function (val) { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '0': val, + '1': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + }) + + it('should throw error when tree contains full key and invalid hash', function () { + var args = [ + 'Hello world', + 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6ez', + '' + ] + + args.forEach(function (val) { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': val, + '1': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + }) + + it('should throw error when tree contains full key and missed value', function () { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': { + 'age': 5 + }, + '1': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + + it('should throw error when tree contains full key and duplicated value', function () { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': { + val: [25, 13] + }, + '0110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': { + val: [71] + } + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + + it('should throw error when tree contains non full key and value on wrong position', function () { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '011001101': { + val: [25, 13] + }, + '1': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + + it('should throw error when tree contains key is of wrong length', function () { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6', + '11100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101': { + val: [25, 13] + } + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + + it('should throw error when tree contains full key and value of wrong type', function () { + [false, null, 42].forEach(function (val) { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': val, + '1': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError) + }) + }) + + it('should throw error when tree contains full key and invalid value', function () { + ['Hello world'].forEach(function (val) { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': val, + '1': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + }) + + it('should throw error when tree contains full key and value as invalid binary array', function () { + [[false], [null], ['Hello world'], [[]], [{}], [new Date()]].forEach(function (val) { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': { + val: val + }, + '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError) + }) + }) + + it('should throw error when tree contains full key and value as binary array with wrong value', function () { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': { + val: [257] + }, + '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(TypeError) + }) + + it('should throw error when tree contains full key and wrong type parameter', function () { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110': { + val: { + name: 'John', + surname: 'Doe' + } + }, + '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + var Type = Exonum.newType({ + size: 80, + fields: { + pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, + name: {type: Exonum.String, size: 8, from: 32, to: 40}, + balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, + history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} + } + }) + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, Type)).to.throw(TypeError) + }) + + it('should throw error when tree contains non full key and wrong type parameter', function () { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '111': { + '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6', + '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100': { + val: { + name: 'John', + surname: 'Doe' + } + } + }, + '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + var Type = Exonum.newType({ + size: 80, + fields: { + pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, + name: {type: Exonum.String, size: 8, from: 32, to: 40}, + balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, + history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} + } + }) + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, Type)).to.throw(TypeError) + }) + + it('should throw error when tree contains duplicated left leaf', function () { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '111': { + '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6', + '0110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100': { + val: [255, 0, 5] + } + }, + '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + + it('should throw error when tree contains duplicated right leaf', function () { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '111': { + '1': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6', + '1110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100': { + val: [255, 0, 5] + } + }, + '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' + } + var key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + + it('should throw error when tree contains left key which is part of search key but branch is not expanded', function () { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '111': { + '01111111010111000100100111101010110010111100011010100000100111111110101011011000011000000000100001000100000101101101100010101110110101101010001100000101110100011101101111100100101110100110010011011100011111011010110010100011111011010011000101111011010': '9be1fdaa5e58640e6c17dba7e734c56ec7ccab77f823933301661e3514284dd7', + '11111111010111000100100111101010110010111100011010100000100110111110101011011000011000000000100001000100000101101101100010101110110101101010001100000101110100011101101111100100101110100110010011011100011111011010110010100011111011010011000101111011010': '9be1fdaa5e58640e6c17dba7e734c56ec7ccab77f823933301661e3514284dd7' + }, + '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' + } + var key = 'ecdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) + + it('should throw error when tree contains right key which is part of search key but branch is not expanded', function () { + var rootHash = '95d1d8dbad15bb04478fad0c3a9343ac32502ae975858749a8c29cb24cccdd55' + var proofNode = { + '111': { + '01111111010111000100100111101010110010111100011010100000100111111110101011011000011000000000100001000100000101101101100010101110110101101010001100000101110100011101101111100100101110100110010011011100011111011010110010100011111011010011000101111011010': '9be1fdaa5e58640e6c17dba7e734c56ec7ccab77f823933301661e3514284dd7', + '11111111010111000100100111101010110010111100011010100000100110111110101011011000011000000000100001000100000101101101100010101110110101101010001100000101110100011101101111100100101110100110010011011100011111011010110010100011111011010011000101111011010': '9be1fdaa5e58640e6c17dba7e734c56ec7ccab77f823933301661e3514284dd7' + }, + '0': 'e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6' + } + var key = 'fcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' + + expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key)).to.throw(Error) + }) +}) diff --git a/test/merkle-proof.js b/test/merkle-proof.js index 33deb5f..7567f7a 100644 --- a/test/merkle-proof.js +++ b/test/merkle-proof.js @@ -1,48 +1,48 @@ /* eslint-env node, mocha */ +/* eslint-disable no-unused-expressions */ -var expect = require('chai').expect; -var Exonum = require('../src'); +var expect = require('chai').expect +var Exonum = require('../src') -describe('Check proof of Merkle tree', function() { - - it('should return array of children of valid tree', function() { - var data = require('./common_data/merkle-tree/valid-merkle-tree.json'); - var elements = Exonum.merkleProof( +describe('Check proof of Merkle tree', function () { + it('should return array of children of valid tree', function () { + var data = require('./common_data/merkle-tree/valid-merkle-tree.json') + var elements = Exonum.merkleProof( data.root_hash, data.list_length, data.proof, [data.range_st, data.range_end - 1] - ); - expect(elements).to.deep.equal([ + ) + expect(elements).to.deep.equal([ [153, 209, 189, 13, 222, 26, 107, 28, 238, 121], [98, 142, 223, 244, 216, 184, 203, 213, 158, 53], [152, 213, 96, 73, 235, 62, 222, 64, 239, 47], [43, 93, 185, 75, 181, 229, 155, 34, 13, 95], [30, 13, 8, 60, 72, 173, 0, 135, 185, 216], [210, 127, 166, 231, 147, 251, 53, 14, 79, 139] - ]); - }); + ]) + }) - it('should return array of children of valid tree with range end placed out of possible range', function() { - var data = require('./common_data/merkle-tree/valid-merkle-tree-with-single-node.json'); - var elements = Exonum.merkleProof( + it('should return array of children of valid tree with range end placed out of possible range', function () { + var data = require('./common_data/merkle-tree/valid-merkle-tree-with-single-node.json') + var elements = Exonum.merkleProof( data.root_hash, data.list_length, data.proof, [data.range_st, data.range_end - 1] - ); - expect(elements).to.deep.equal([[7, 8]]); - }); + ) + expect(elements).to.deep.equal([[7, 8]]) + }) - it('should return array of children of fully balanced valid tree contained all its values', function() { - var data = require('./common_data/merkle-tree/valid-merkle-tree-fully-balanced-with-all-values.json'); - var elements = Exonum.merkleProof( + it('should return array of children of fully balanced valid tree contained all its values', function () { + var data = require('./common_data/merkle-tree/valid-merkle-tree-fully-balanced-with-all-values.json') + var elements = Exonum.merkleProof( data.root_hash, data.list_length, data.proof, [data.range_st, data.range_end - 1] - ); - expect(elements).to.deep.equal([ + ) + expect(elements).to.deep.equal([ [1, 2], [2, 3], [3, 4], @@ -51,18 +51,18 @@ describe('Check proof of Merkle tree', function() { [6, 7], [7, 8], [8, 9] - ]); - }); + ]) + }) - it('should return array of children of valid tree with hashes as values', function() { - var data = require('./common_data/merkle-tree/valid-merkle-tree-with-byte-arrays-as-values.json'); - var elements = Exonum.merkleProof( + it('should return array of children of valid tree with hashes as values', function () { + var data = require('./common_data/merkle-tree/valid-merkle-tree-with-byte-arrays-as-values.json') + var elements = Exonum.merkleProof( data.root_hash, data.list_length, data.proof, [data.range_st, data.range_end - 1] - ); - expect(elements).to.deep.equal([ + ) + expect(elements).to.deep.equal([ [134, 140, 39, 206, 51, 52, 195, 129, 247, 238], [84, 134, 129, 99, 48, 28, 82, 50, 93, 196], [45, 124, 194, 40, 35, 96, 7, 14, 48, 166], @@ -134,312 +134,311 @@ describe('Check proof of Merkle tree', function() { [42, 182, 237, 121, 206, 58, 234, 33, 57, 179], [146, 109, 161, 235, 50, 152, 154, 204, 249, 233], [106, 37, 197, 193, 108, 6, 226, 7, 120, 12] - ]); - }); - - it('should throw error when the tree with rootHash of wrong type', function() { - var args = [ - true, - null, - undefined, + ]) + }) + + it('should throw error when the tree with rootHash of wrong type', function () { + var args = [ + true, + null, + undefined, [], {}, - 42, - new Date() - ]; - - args.forEach(function(rootHash) { - expect(() => Exonum.merkleProof(rootHash, 8, {}, [0, 8])).to.throw(TypeError); - }); - }); - - it('should throw error when the tree with invalid rootHash', function() { - var args = [ - '6z56f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13', - '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff1' - ]; - - args.forEach(function(rootHash) { - expect(() => Exonum.merkleProof(rootHash, 8, {}, [0, 8])).to.throw(Error); - }); - }); - - it('should throw error when the tree with invalid count', function() { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var args = [ - true, - null, - undefined, + 42, + new Date() + ] + + args.forEach(function (rootHash) { + expect(() => Exonum.merkleProof(rootHash, 8, {}, [0, 8])).to.throw(TypeError) + }) + }) + + it('should throw error when the tree with invalid rootHash', function () { + var args = [ + '6z56f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13', + '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff1' + ] + + args.forEach(function (rootHash) { + expect(() => Exonum.merkleProof(rootHash, 8, {}, [0, 8])).to.throw(Error) + }) + }) + + it('should throw error when the tree with invalid count', function () { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var args = [ + true, + null, + undefined, [], {}, - 'Hello world', - new Date() - ]; - - args.forEach(function(count) { - expect(() => Exonum.merkleProof(rootHash, count, {}, [0, 8])).to.throw(Error); - }); - }); - - it('should throw error when the tree with count below', function() { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - - [-42, '-42'].forEach(function(count) { - expect(() => Exonum.merkleProof(rootHash, count, {}, [0, 8])).to.throw(RangeError); - }); - }); - - it('should throw error when the tree with invalid proofNode', function() { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var args = [ - true, - null, - undefined, + 'Hello world', + new Date() + ] + + args.forEach(function (count) { + expect(() => Exonum.merkleProof(rootHash, count, {}, [0, 8])).to.throw(Error) + }) + }) + + it('should throw error when the tree with count below', function () { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; + + [-42, '-42'].forEach(function (count) { + expect(() => Exonum.merkleProof(rootHash, count, {}, [0, 8])).to.throw(RangeError) + }) + }) + + it('should throw error when the tree with invalid proofNode', function () { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var args = [ + true, + null, + undefined, [], - 'Hello world', - 42, - new Date() - ]; - - args.forEach(function(proofNode) { - expect(() => Exonum.merkleProof(rootHash, 8, proofNode, [0, 8])).to.throw(TypeError); - }); - }); - - it('should throw error when the tree with invalid range', function() { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var args = [ - true, null, undefined, [], {}, 'Hello world', 42, new Date(), + 'Hello world', + 42, + new Date() + ] + + args.forEach(function (proofNode) { + expect(() => Exonum.merkleProof(rootHash, 8, proofNode, [0, 8])).to.throw(TypeError) + }) + }) + + it('should throw error when the tree with invalid range', function () { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var args = [ + true, null, undefined, [], {}, 'Hello world', 42, new Date(), [0], [0, 8, 16], [true, 8], [null, 8], [undefined, 8], [[], 8], [{}, 8], ['Hello world', 8], [new Date(), 8], [8, true], [8, null], [8, undefined], [8, []], [8, {}], [8, 'Hello world'], [8, new Date()] - ]; + ] - args.forEach(function(range) { - expect(() => Exonum.merkleProof(rootHash, 8, {}, range)).to.throw(Error); - }); - }); + args.forEach(function (range) { + expect(() => Exonum.merkleProof(rootHash, 8, {}, range)).to.throw(Error) + }) + }) - it('should throw error when the tree with invalid range', function() { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; + it('should throw error when the tree with invalid range', function () { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - [[-1, 8], ['-1', 8], [0, -1], [0, '-1']].forEach(function(range) { - expect(() => Exonum.merkleProof(rootHash, 8, {}, range)).to.throw(RangeError); - }); - }); + [[-1, 8], ['-1', 8], [0, -1], [0, '-1']].forEach(function (range) { + expect(() => Exonum.merkleProof(rootHash, 8, {}, range)).to.throw(RangeError) + }) + }) - it('should throw error when the tree with range start is out of range', function() { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var count = 8; - var proofNode = {}; - var range = [9, 8]; + it('should throw error when the tree with range start is out of range', function () { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var count = 8 + var proofNode = {} + var range = [9, 8] - expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(RangeError); - }); + expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(RangeError) + }) - it('should return empty array when the tree with elements that out of tree range', function() { - var elements = Exonum.merkleProof( + it('should return empty array when the tree with elements that out of tree range', function () { + var elements = Exonum.merkleProof( '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13', 8, {}, [9, 9] - ); - expect(elements).to.deep.equal([]); + ) + expect(elements).to.deep.equal([]) + }) + + it('should throw error when the tree with leaf on wrong height', function () { + var data = require('./common_data/merkle-tree/invalid-merkle-tree-with-leaf-on-wrong-height.json') + var rootHash = data.root_hash + var count = data.list_length + var proofNode = data.proof + var range = [data.range_st, data.range_end - 1] + + expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error) + }) + + it('should throw error when the tree with wrong index of value node', function () { + var data = require('./data/invalid-merkle-tree-with-wrong-index-of-value-node.json') + var rootHash = data.root_hash + var count = data.list_length + var proofNode = data.proof + var range = [data.range_st, data.range_end - 1] + + expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error) + }) + + it('should throw error when the tree with value on wrong position', function () { + var data = require('./data/invalid-merkle-tree-with-value-on-wrong-position.json') + var rootHash = data.root_hash + var count = data.list_length + var proofNode = data.proof + var range = [data.range_st, data.range_end - 1] + + expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error) + }) + + it('should throw error when the tree with invalid type of type parameter', function () { + [null, 42, [], new Date()].forEach(function (type) { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var count = 2 + var proofNode = { + left: {val: [255, 128]}, + right: 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fc' + } + var range = [0, 2] + + expect(() => Exonum.merkleProof(rootHash, count, proofNode, range, type)).to.throw(Error) + }) + }) + + it('should throw error when the tree with invalid value', function () { + var Type = Exonum.newType({ + size: 32, + fields: {hash: {type: Exonum.Hash, size: 32, from: 0, to: 32}} }); - it('should throw error when the tree with leaf on wrong height', function() { - var data = require('./common_data/merkle-tree/invalid-merkle-tree-with-leaf-on-wrong-height.json'); - var rootHash = data.root_hash; - var count = data.list_length; - var proofNode = data.proof; - var range = [data.range_st, data.range_end - 1]; - - expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error); - }); - - it('should throw error when the tree with wrong index of value node', function() { - var data = require('./data/invalid-merkle-tree-with-wrong-index-of-value-node.json'); - var rootHash = data.root_hash; - var count = data.list_length; - var proofNode = data.proof; - var range = [data.range_st, data.range_end - 1]; - - expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error); - }); - - it('should throw error when the tree with value on wrong position', function() { - var data = require('./data/invalid-merkle-tree-with-value-on-wrong-position.json'); - var rootHash = data.root_hash; - var count = data.list_length; - var proofNode = data.proof; - var range = [data.range_st, data.range_end - 1]; - - expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error); - }); - - it('should throw error when the tree with invalid type of type parameter', function() { - [null, 42, [], new Date()].forEach(function(type) { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var count = 2; - var proofNode = { - left: {val: [255, 128]}, - right: 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fc' - }; - var range = [0, 2]; - - expect(() => Exonum.merkleProof(rootHash, count, proofNode, range, type)).to.throw(Error); - }); - }); - - it('should throw error when the tree with invalid value', function() { - var Type = Exonum.newType({ - size: 32, - fields: {hash: {type: Exonum.Hash, size: 32, from: 0, to: 32}} - }); - - [42, 'Hello world', [], new Date()].forEach(function(val) { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var count = 2; - var proofNode = { - left: {val: val}, - right: 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fc' - }; - var range = [0, 2]; - - expect(() => Exonum.merkleProof(rootHash, count, proofNode, range, Type)).to.throw(Error); - }); - }); - - it('should throw error when the tree with invalid value not corresponding to passed type', function() { - var Type = Exonum.newType({ - size: 32, - fields: {hash: {type: Exonum.Hash, size: 32, from: 0, to: 32}} - }); - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var count = 2; - var proofNode = { - left: {val: {name: 'John'}}, - right: 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fc' - }; - var range = [0, 2]; - - expect(() => Exonum.merkleProof(rootHash, count, proofNode, range, Type)).to.throw(TypeError); - }); - - it('should throw error when the tree with invalid array of 8-bit integers as value', function() { - var args = [ - true, {}, 42, 'Hello world', new Date(), + [42, 'Hello world', [], new Date()].forEach(function (val) { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var count = 2 + var proofNode = { + left: {val: val}, + right: 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fc' + } + var range = [0, 2] + + expect(() => Exonum.merkleProof(rootHash, count, proofNode, range, Type)).to.throw(Error) + }) + }) + + it('should throw error when the tree with invalid value not corresponding to passed type', function () { + var Type = Exonum.newType({ + size: 32, + fields: {hash: {type: Exonum.Hash, size: 32, from: 0, to: 32}} + }) + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var count = 2 + var proofNode = { + left: {val: {name: 'John'}}, + right: 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fc' + } + var range = [0, 2] + + expect(() => Exonum.merkleProof(rootHash, count, proofNode, range, Type)).to.throw(TypeError) + }) + + it('should throw error when the tree with invalid array of 8-bit integers as value', function () { + var args = [ + true, {}, 42, 'Hello world', new Date(), [153, 256], [153, -1], [153, true], [153, null], [153, undefined], [153, 'Hello world'], [153, {}], [153, []], [153, new Date()] - ]; - - args.forEach(function(val) { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var count = 2; - var proofNode = { - left: {val: val}, - right: 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fc' - }; - var range = [0, 2]; - - expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error); - }); - }); - - it('should throw error when the tree with missed left node', function() { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var count = 4; - var proofNode = { - left: { - right: {val: [255, 128]} - }, - right: 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fc' - }; - var range = [0, 2]; - - expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error); - }); - - it('should throw error when the tree with invalid string in left node', function() { - var args = [ - 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fz', - 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365c', - 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fa52', - '', - true, - null, - undefined, + ] + + args.forEach(function (val) { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var count = 2 + var proofNode = { + left: {val: val}, + right: 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fc' + } + var range = [0, 2] + + expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error) + }) + }) + + it('should throw error when the tree with missed left node', function () { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var count = 4 + var proofNode = { + left: { + right: {val: [255, 128]} + }, + right: 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fc' + } + var range = [0, 2] + + expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error) + }) + + it('should throw error when the tree with invalid string in left node', function () { + var args = [ + 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fz', + 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365c', + 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fa52', + '', + true, + null, + undefined, [], - 42 - ]; - - args.forEach(function(hash) { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var count = 2; - var proofNode = { - left: hash, - right: 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fc' - }; - var range = [0, 2]; - - expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error); - }); - }); - - it('should throw error when the tree with invalid string in right node', function() { - var args = [ - 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fz', - 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365c', - 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fa52', - '', - true, - null, - undefined, + 42 + ] + + args.forEach(function (hash) { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var count = 2 + var proofNode = { + left: hash, + right: 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fc' + } + var range = [0, 2] + + expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error) + }) + }) + + it('should throw error when the tree with invalid string in right node', function () { + var args = [ + 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fz', + 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365c', + 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fa52', + '', + true, + null, + undefined, [], - 42 - ]; - - args.forEach(function(hash) { - var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13'; - var count = 2; - var proofNode = { - left: 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fc', - right: hash - }; - var range = [0, 2]; - - expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error); - }); - }); - - it('should throw error when the tree with missed right leaf inside right tree branch', function() { - var data = require('./common_data/merkle-tree/invalid-merkle-tree-missed-right-leaf-on-left-branch.json'); - var rootHash = data.root_hash; - var count = data.list_length; - var proofNode = data.proof; - var range = [data.range_st, data.range_end - 1]; - - expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error); - }); - - it('should throw error when the tree with wrong rootHash', function() { - var data = require('./data/invalid-merkle-tree-with-wrong-root-hash.json'); - var rootHash = data.root_hash; - var count = data.list_length; - var proofNode = data.proof; - var range = [data.range_st, data.range_end - 1]; - - expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error); - }); - - it('should throw error when the tree with wrong amount of elements', function() { - var data = require('./data/invalid-merkle-tree-with-wrong-amount-of-elements.json'); - var rootHash = data.root_hash; - var count = data.list_length; - var proofNode = data.proof; - var range = [data.range_st, data.range_end - 1]; - - expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error); - }); - -}); + 42 + ] + + args.forEach(function (hash) { + var rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' + var count = 2 + var proofNode = { + left: 'b267fa0930dede7557b805fe643a3ce8ebe4434e366924df1d622785365cf0fc', + right: hash + } + var range = [0, 2] + + expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error) + }) + }) + + it('should throw error when the tree with missed right leaf inside right tree branch', function () { + var data = require('./common_data/merkle-tree/invalid-merkle-tree-missed-right-leaf-on-left-branch.json') + var rootHash = data.root_hash + var count = data.list_length + var proofNode = data.proof + var range = [data.range_st, data.range_end - 1] + + expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error) + }) + + it('should throw error when the tree with wrong rootHash', function () { + var data = require('./data/invalid-merkle-tree-with-wrong-root-hash.json') + var rootHash = data.root_hash + var count = data.list_length + var proofNode = data.proof + var range = [data.range_st, data.range_end - 1] + + expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error) + }) + + it('should throw error when the tree with wrong amount of elements', function () { + var data = require('./data/invalid-merkle-tree-with-wrong-amount-of-elements.json') + var rootHash = data.root_hash + var count = data.list_length + var proofNode = data.proof + var range = [data.range_st, data.range_end - 1] + + expect(() => Exonum.merkleProof(rootHash, count, proofNode, range)).to.throw(Error) + }) +}) diff --git a/test/readme.js b/test/readme.js index 5fbf01e..b3a2fb4 100644 --- a/test/readme.js +++ b/test/readme.js @@ -1,66 +1,67 @@ /* eslint-env node, mocha */ +/* eslint-disable no-unused-expressions */ -var expect = require('chai').expect; -var Exonum = require('../src'); +var expect = require('chai').expect +var Exonum = require('../src') -describe('Examples from README.md', function() { - describe('Custom type section', function() { - var User = Exonum.newType({ - size: 9, - fields: { - name: {type: Exonum.String, size: 8, from: 0, to: 8}, - age: {type: Exonum.Int8, size: 1, from: 8, to: 9} - } - }); - var data = { - name: 'Tom', - age: 34 - }; - var keyPair = { - publicKey: 'fa7f9ee43aff70c879f80fa7fd15955c18b98c72310b09e7818310325050cf7a', - secretKey: '978e3321bd6331d56e5f4c2bdb95bf471e95a77a6839e68d4241e7b0932ebe2bfa7f9ee43aff70c879f80fa7fd15955c18b98c72310b09e7818310325050cf7a' - }; - var signature = 'c1db9a5f01ebdff27e02652a9aae5c9a4ac88787587dabceb9f471ae0b8e051b9632dfd26922f6abf24ff2d3275028fe286703d25ee7fe6b1711e89af4a7d307'; +describe('Examples from README.md', function () { + describe('Custom type section', function () { + var User = Exonum.newType({ + size: 9, + fields: { + name: {type: Exonum.String, size: 8, from: 0, to: 8}, + age: {type: Exonum.Int8, size: 1, from: 8, to: 9} + } + }) + var data = { + name: 'Tom', + age: 34 + } + var keyPair = { + publicKey: 'fa7f9ee43aff70c879f80fa7fd15955c18b98c72310b09e7818310325050cf7a', + secretKey: '978e3321bd6331d56e5f4c2bdb95bf471e95a77a6839e68d4241e7b0932ebe2bfa7f9ee43aff70c879f80fa7fd15955c18b98c72310b09e7818310325050cf7a' + } + var signature = 'c1db9a5f01ebdff27e02652a9aae5c9a4ac88787587dabceb9f471ae0b8e051b9632dfd26922f6abf24ff2d3275028fe286703d25ee7fe6b1711e89af4a7d307' - it('should sign custom type', function() { - expect(Exonum.sign(keyPair.secretKey, data, User)).to.equal(signature); - }); + it('should sign custom type', function () { + expect(Exonum.sign(keyPair.secretKey, data, User)).to.equal(signature) + }) - it('should verify custom type signature', function() { - expect(Exonum.verifySignature(signature, keyPair.publicKey, data, User)).to.be.true; - }); - }); + it('should verify custom type signature', function () { + expect(Exonum.verifySignature(signature, keyPair.publicKey, data, User)).to.be.true + }) + }) - describe('Transaction section', function() { - var SendFunds = Exonum.newMessage({ - size: 72, - network_id: 0, - protocol_version: 0, - service_id: 0, - message_id: 0, - fields: { - from: {type: Exonum.Hash, size: 32, from: 0, to: 32}, - to: {type: Exonum.Hash, size: 32, from: 32, to: 64}, - amount: {type: Exonum.Uint64, size: 8, from: 64, to: 72} - } - }); - var data = { - from: '6752be882314f5bbbc9a6af2ae634fc07038584a4a77510ea5eced45f54dc030', - to: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36', - amount: 50 - }; - var keyPair = { - publicKey: 'fa7f9ee43aff70c879f80fa7fd15955c18b98c72310b09e7818310325050cf7a', - secretKey: '978e3321bd6331d56e5f4c2bdb95bf471e95a77a6839e68d4241e7b0932ebe2bfa7f9ee43aff70c879f80fa7fd15955c18b98c72310b09e7818310325050cf7a' - }; - var signature = '8ff692b47d17f7738ec2d19f5296d3810909a62fe1480eb752b531f8e17056f6578985090db822612f88c3bcad4f0539401836e5ad58913c489784ff3e415a0b'; + describe('Transaction section', function () { + var SendFunds = Exonum.newMessage({ + size: 72, + network_id: 0, + protocol_version: 0, + service_id: 0, + message_id: 0, + fields: { + from: {type: Exonum.Hash, size: 32, from: 0, to: 32}, + to: {type: Exonum.Hash, size: 32, from: 32, to: 64}, + amount: {type: Exonum.Uint64, size: 8, from: 64, to: 72} + } + }) + var data = { + from: '6752be882314f5bbbc9a6af2ae634fc07038584a4a77510ea5eced45f54dc030', + to: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36', + amount: 50 + } + var keyPair = { + publicKey: 'fa7f9ee43aff70c879f80fa7fd15955c18b98c72310b09e7818310325050cf7a', + secretKey: '978e3321bd6331d56e5f4c2bdb95bf471e95a77a6839e68d4241e7b0932ebe2bfa7f9ee43aff70c879f80fa7fd15955c18b98c72310b09e7818310325050cf7a' + } + var signature = '8ff692b47d17f7738ec2d19f5296d3810909a62fe1480eb752b531f8e17056f6578985090db822612f88c3bcad4f0539401836e5ad58913c489784ff3e415a0b' - it('should sign transaction', function() { - expect(SendFunds.sign(keyPair.secretKey, data)).to.equal(signature); - }); + it('should sign transaction', function () { + expect(SendFunds.sign(keyPair.secretKey, data)).to.equal(signature) + }) - it('should verify transaction signature', function() { - expect(SendFunds.verifySignature(signature, keyPair.publicKey, data)).to.be.true; - }); - }); -}); + it('should verify transaction signature', function () { + expect(SendFunds.verifySignature(signature, keyPair.publicKey, data)).to.be.true + }) + }) +}) diff --git a/test/serialization.js b/test/serialization.js index 2011af5..a65ba49 100644 --- a/test/serialization.js +++ b/test/serialization.js @@ -1,147 +1,146 @@ /* eslint-env node, mocha */ - -var expect = require('chai').expect; -var Exonum = require('../src'); - -describe('Serialize data into array of 8-bit integers', function() { - - it('should serialize data of newType type and return array of 8-bit integers', function() { - var Wallet = Exonum.newType({ - size: 80, - fields: { - pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, - name: {type: Exonum.String, size: 8, from: 32, to: 40}, - balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, - history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} - } - }); - var walletData = { - pub_key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36', - name: 'Smart wallet', - balance: 359120, - history_hash: '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030' - }; - - var buffer = Wallet.serialize(walletData); - - expect(buffer).to.deep.equal([245, 134, 74, 182, 165, 162, 25, 6, 102, 180, 124, 103, 107, 207, 21, 161, 242, 240, 119, 3, 197, 188, 175, 181, 116, 154, 167, 53, 206, 139, 124, 54, 80, 0, 0, 0, 12, 0, 0, 0, 208, 122, 5, 0, 0, 0, 0, 0, 103, 82, 190, 136, 35, 20, 245, 187, 188, 154, 106, 242, 174, 99, 79, 192, 112, 56, 88, 74, 74, 119, 81, 14, 165, 236, 237, 69, 245, 77, 192, 48, 83, 109, 97, 114, 116, 32, 119, 97, 108, 108, 101, 116]); - }); - - it('should serialize data of complicated non-fixed newType type and return array of 8-bit integers', function() { - var User = Exonum.newType({ - size: 16, - fields: { - name: {type: Exonum.String, size: 8, from: 0, to: 8}, - surname: {type: Exonum.String, size: 8, from: 8, to: 16} - } - }); - var Transaction = Exonum.newType({ - size: 40, - fields: { - from: {type: User, size: 16, from: 0, to: 16}, - to: {type: User, size: 16, from: 16, to: 32}, - sum: {type: Exonum.Uint64, size: 8, from: 32, to: 40} - } - }); - var transactionData = { - from: { - name: 'John', - surname: 'Doe' - }, - to: { - name: 'Steven', - surname: 'Black' - }, - sum: 200 - }; - - var buffer = Transaction.serialize(transactionData); - - expect(buffer).to.deep.equal([40, 0, 0, 0, 4, 0, 0, 0, 44, 0, 0, 0, 3, 0, 0, 0, 47, 0, 0, 0, 6, 0, 0, 0, 53, 0, 0, 0, 5, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 74, 111, 104, 110, 68, 111, 101, 83, 116, 101, 118, 101, 110, 66, 108, 97, 99, 107]); - }); - - it('should serialize data of complicated fixed newType type and return array of 8-bit integers', function() { - var Wallet = Exonum.newType({ - size: 16, - fields: { - id: {type: Exonum.Uint64, size: 8, from: 0, to: 8}, - balance: {type: Exonum.Uint64, size: 8, from: 8, to: 16} - } - }); - var Transaction = Exonum.newType({ - size: 40, - fields: { - from: {type: Wallet, size: 16, from: 0, to: 16}, - to: {type: Wallet, size: 16, from: 16, to: 32}, - sum: {type: Exonum.Uint64, size: 8, from: 32, to: 40} - } - }); - var transactionData = { - from: { - id: 57, - balance: 500 - }, - to: { - id: 921, - balance: 0 - }, - sum: 200 - }; - - var buffer = Transaction.serialize(transactionData); - - expect(buffer).to.deep.equal([57, 0, 0, 0, 0, 0, 0, 0, 244, 1, 0, 0, 0, 0, 0, 0, 153, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0]); - }); - - it('should serialize data (with inherited properties that should be ignored) of newType type and return array of 8-bit integers', function() { - var Wallet = Exonum.newType({ - size: 80, - fields: { - pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, - name: {type: Exonum.String, size: 8, from: 32, to: 40}, - balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, - history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} - } - }); - - function Data() { - this.pub_key = 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36'; - this.name = 'Smart wallet'; - this.balance = 359120; - this.history_hash = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030'; - return this; - } - - function DataAncestor() { - return this; - } - - DataAncestor.prototype.someMethod = function() { - return this; - }; - - Data.prototype = Object.create(DataAncestor.prototype); - - var walletData = new Data(); - - var buffer = Wallet.serialize(walletData); - - expect(buffer).to.deep.equal([245, 134, 74, 182, 165, 162, 25, 6, 102, 180, 124, 103, 107, 207, 21, 161, 242, 240, 119, 3, 197, 188, 175, 181, 116, 154, 167, 53, 206, 139, 124, 54, 80, 0, 0, 0, 12, 0, 0, 0, 208, 122, 5, 0, 0, 0, 0, 0, 103, 82, 190, 136, 35, 20, 245, 187, 188, 154, 106, 242, 174, 99, 79, 192, 112, 56, 88, 74, 74, 119, 81, 14, 165, 236, 237, 69, 245, 77, 192, 48, 83, 109, 97, 114, 116, 32, 119, 97, 108, 108, 101, 116]); - }); - - it('should throw error when some data parameters are missed', function() { - var Wallet = Exonum.newType({ - size: 80, - fields: { - pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, - name: {type: Exonum.String, size: 8, from: 32, to: 40}, - balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, - history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} - } - }); - var walletData = {fake: 123}; - - expect(() => Wallet.serialize(walletData)).to.throw(TypeError); - }); - -}); +/* eslint-disable no-unused-expressions */ + +var expect = require('chai').expect +var Exonum = require('../src') + +describe('Serialize data into array of 8-bit integers', function () { + it('should serialize data of newType type and return array of 8-bit integers', function () { + var Wallet = Exonum.newType({ + size: 80, + fields: { + pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, + name: {type: Exonum.String, size: 8, from: 32, to: 40}, + balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, + history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} + } + }) + var walletData = { + pub_key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36', + name: 'Smart wallet', + balance: 359120, + history_hash: '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030' + } + + var buffer = Wallet.serialize(walletData) + + expect(buffer).to.deep.equal([245, 134, 74, 182, 165, 162, 25, 6, 102, 180, 124, 103, 107, 207, 21, 161, 242, 240, 119, 3, 197, 188, 175, 181, 116, 154, 167, 53, 206, 139, 124, 54, 80, 0, 0, 0, 12, 0, 0, 0, 208, 122, 5, 0, 0, 0, 0, 0, 103, 82, 190, 136, 35, 20, 245, 187, 188, 154, 106, 242, 174, 99, 79, 192, 112, 56, 88, 74, 74, 119, 81, 14, 165, 236, 237, 69, 245, 77, 192, 48, 83, 109, 97, 114, 116, 32, 119, 97, 108, 108, 101, 116]) + }) + + it('should serialize data of complicated non-fixed newType type and return array of 8-bit integers', function () { + var User = Exonum.newType({ + size: 16, + fields: { + name: {type: Exonum.String, size: 8, from: 0, to: 8}, + surname: {type: Exonum.String, size: 8, from: 8, to: 16} + } + }) + var Transaction = Exonum.newType({ + size: 40, + fields: { + from: {type: User, size: 16, from: 0, to: 16}, + to: {type: User, size: 16, from: 16, to: 32}, + sum: {type: Exonum.Uint64, size: 8, from: 32, to: 40} + } + }) + var transactionData = { + from: { + name: 'John', + surname: 'Doe' + }, + to: { + name: 'Steven', + surname: 'Black' + }, + sum: 200 + } + + var buffer = Transaction.serialize(transactionData) + + expect(buffer).to.deep.equal([40, 0, 0, 0, 4, 0, 0, 0, 44, 0, 0, 0, 3, 0, 0, 0, 47, 0, 0, 0, 6, 0, 0, 0, 53, 0, 0, 0, 5, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 74, 111, 104, 110, 68, 111, 101, 83, 116, 101, 118, 101, 110, 66, 108, 97, 99, 107]) + }) + + it('should serialize data of complicated fixed newType type and return array of 8-bit integers', function () { + var Wallet = Exonum.newType({ + size: 16, + fields: { + id: {type: Exonum.Uint64, size: 8, from: 0, to: 8}, + balance: {type: Exonum.Uint64, size: 8, from: 8, to: 16} + } + }) + var Transaction = Exonum.newType({ + size: 40, + fields: { + from: {type: Wallet, size: 16, from: 0, to: 16}, + to: {type: Wallet, size: 16, from: 16, to: 32}, + sum: {type: Exonum.Uint64, size: 8, from: 32, to: 40} + } + }) + var transactionData = { + from: { + id: 57, + balance: 500 + }, + to: { + id: 921, + balance: 0 + }, + sum: 200 + } + + var buffer = Transaction.serialize(transactionData) + + expect(buffer).to.deep.equal([57, 0, 0, 0, 0, 0, 0, 0, 244, 1, 0, 0, 0, 0, 0, 0, 153, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0]) + }) + + it('should serialize data (with inherited properties that should be ignored) of newType type and return array of 8-bit integers', function () { + var Wallet = Exonum.newType({ + size: 80, + fields: { + pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, + name: {type: Exonum.String, size: 8, from: 32, to: 40}, + balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, + history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} + } + }) + + function Data () { + this.pub_key = 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36' + this.name = 'Smart wallet' + this.balance = 359120 + this.history_hash = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030' + return this + } + + function DataAncestor () { + return this + } + + DataAncestor.prototype.someMethod = function () { + return this + } + + Data.prototype = Object.create(DataAncestor.prototype) + + var walletData = new Data() + + var buffer = Wallet.serialize(walletData) + + expect(buffer).to.deep.equal([245, 134, 74, 182, 165, 162, 25, 6, 102, 180, 124, 103, 107, 207, 21, 161, 242, 240, 119, 3, 197, 188, 175, 181, 116, 154, 167, 53, 206, 139, 124, 54, 80, 0, 0, 0, 12, 0, 0, 0, 208, 122, 5, 0, 0, 0, 0, 0, 103, 82, 190, 136, 35, 20, 245, 187, 188, 154, 106, 242, 174, 99, 79, 192, 112, 56, 88, 74, 74, 119, 81, 14, 165, 236, 237, 69, 245, 77, 192, 48, 83, 109, 97, 114, 116, 32, 119, 97, 108, 108, 101, 116]) + }) + + it('should throw error when some data parameters are missed', function () { + var Wallet = Exonum.newType({ + size: 80, + fields: { + pub_key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}, + name: {type: Exonum.String, size: 8, from: 32, to: 40}, + balance: {type: Exonum.Uint64, size: 8, from: 40, to: 48}, + history_hash: {type: Exonum.Hash, size: 32, from: 48, to: 80} + } + }) + var walletData = {fake: 123} + + expect(() => Wallet.serialize(walletData)).to.throw(TypeError) + }) +}) diff --git a/test/types.js b/test/types.js index 0b05554..f6ac270 100644 --- a/test/types.js +++ b/test/types.js @@ -1,995 +1,964 @@ /* eslint-env node, mocha */ - -var expect = require('chai').expect; -var Exonum = require('../src'); - -describe('Check built-in types', function() { - - describe('Process Hash', function() { - - it('should serialize data and return array of 8-bit integers when the value is valid hexadecimal string', function() { - var Type = Exonum.newType({ - size: 32, - fields: {hash: {type: Exonum.Hash, size: 32, from: 0, to: 32}} - }); - var data = {hash: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36'}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([245, 134, 74, 182, 165, 162, 25, 6, 102, 180, 124, 103, 107, 207, 21, 161, 242, 240, 119, 3, 197, 188, 175, 181, 116, 154, 167, 53, 206, 139, 124, 54]); - }); - - it('should throw error when the range of segment is invalid', function() { - var Type = Exonum.newType({ - size: 32, - fields: {hash: {type: Exonum.Hash, size: 32, from: 0, to: 16}} - }); - var data = {hash: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36'}; - - expect(() => Type.serialize(data)).to.throw(Error); - }); - - it('should throw error when the value is invalid string', function() { - var Type = Exonum.newType({ - size: 32, - fields: {hash: {type: Exonum.Hash, size: 32, from: 0, to: 32}} - }); - var data = {hash: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3z'}; - - expect(() => Type.serialize(data)).to.throw(Error); - }); - - it('should throw error when the value is too long string', function() { - var Type = Exonum.newType({ - size: 32, - fields: {hash: {type: Exonum.Hash, size: 32, from: 0, to: 32}} - }); - var data = {hash: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c365'}; - - expect(() => Type.serialize(data)).to.throw(Error); - }); - - it('should throw error when the value is too short string', function() { - var Type = Exonum.newType({ - size: 32, - fields: {hash: {type: Exonum.Hash, size: 32, from: 0, to: 32}} - }); - var data = {hash: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3'}; - - expect(() => Type.serialize(data)).to.throw(Error); - }); - - it('should throw error when the value of invalid type', function() { - var Type = Exonum.newType({ - size: 32, - fields: {hash: {type: Exonum.Hash, size: 32, from: 0, to: 32}} - }); - - [true, null, undefined, 57, [], {}, new Date()].forEach(function(hash) { - expect(() => Type.serialize({hash: hash})).to.throw(TypeError); - }); - }); - - }); - - describe('Process PublicKey', function() { - - it('should serialize data and return array of 8-bit integers when the value is valid string', function() { - var Type = Exonum.newType({ - size: 32, - fields: {key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}} - }); - var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36'}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([245, 134, 74, 182, 165, 162, 25, 6, 102, 180, 124, 103, 107, 207, 21, 161, 242, 240, 119, 3, 197, 188, 175, 181, 116, 154, 167, 53, 206, 139, 124, 54]); - }); - - it('should throw error when the range of segment is invalid', function() { - var Type = Exonum.newType({ - size: 32, - fields: {key: {type: Exonum.PublicKey, size: 32, from: 0, to: 16}} - }); - var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36'}; - - expect(() => Type.serialize(data)).to.throw(Error); - }); - - it('should throw error when the value is invalid string', function() { - var Type = Exonum.newType({ - size: 32, - fields: {key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}} - }); - var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3z'}; - - expect(() => Type.serialize(data)).to.throw(Error); - }); - - it('should throw error when the value is too long string', function() { - var Type = Exonum.newType({ - size: 32, - fields: {key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}} - }); - var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c365'}; - - expect(() => Type.serialize(data)).to.throw(Error); - }); - - it('should throw error when the value is too short string', function() { - var Type = Exonum.newType({ - size: 32, - fields: {key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}} - }); - var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3'}; - - expect(() => Type.serialize(data)).to.throw(Error); - }); - - it('should throw error when the value of invalid type', function() { - var Type = Exonum.newType({ - size: 32, - fields: {key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}} - }); - - [true, null, undefined, 57, [], {}, new Date()].forEach(function(key) { - expect(() => Type.serialize({key: key})).to.throw(TypeError); - }); - }); - - }); - - describe('Process Digest', function() { - - it('should serialize data and return array of 8-bit integers when the value is valid string', function() { - var Type = Exonum.newType({ - size: 64, - fields: {key: {type: Exonum.Digest, size: 64, from: 0, to: 64}} - }); - var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36'}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([245, 134, 74, 182, 165, 162, 25, 6, 102, 180, 124, 103, 107, 207, 21, 161, 242, 240, 119, 3, 197, 188, 175, 181, 116, 154, 167, 53, 206, 139, 124, 54, 245, 134, 74, 182, 165, 162, 25, 6, 102, 180, 124, 103, 107, 207, 21, 161, 242, 240, 119, 3, 197, 188, 175, 181, 116, 154, 167, 53, 206, 139, 124, 54]); - }); - - it('should throw error when the range of segment is invalid', function() { - var Type = Exonum.newType({ - size: 64, - fields: {key: {type: Exonum.Digest, size: 64, from: 0, to: 32}} - }); - var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36'}; - - expect(() => Type.serialize(data)).to.throw(Error); - }); - - it('should throw error when the value is invalid string', function() { - var Type = Exonum.newType({ - size: 64, - fields: {key: {type: Exonum.Digest, size: 64, from: 0, to: 64}} - }); - var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3zf5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3z'}; - - expect(() => Type.serialize(data)).to.throw(Error); - }); - - it('should throw error when the value is too long string', function() { - var Type = Exonum.newType({ - size: 64, - fields: {key: {type: Exonum.Digest, size: 64, from: 0, to: 64}} - }); - var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c365f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c365'}; - - expect(() => Type.serialize(data)).to.throw(Error); - }); - - it('should throw error when the value is too short string', function() { - var Type = Exonum.newType({ - size: 64, - fields: {key: {type: Exonum.Digest, size: 64, from: 0, to: 64}} - }); - var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3'}; - - expect(() => Type.serialize(data)).to.throw(Error); - }); - - it('should throw error when the value of invalid type', function() { - var Type = Exonum.newType({ - size: 64, - fields: {key: {type: Exonum.Digest, size: 64, from: 0, to: 64}} - }); - - [true, null, undefined, 57, [], {}, new Date()].forEach(function(key) { - expect(() => Type.serialize({key: key})).to.throw(TypeError); - }); - }); - - }); - - describe('Process Timespec', function() { - - it('should serialize data and return array of 8-bit integers when the value is valid timestamp in nanoseconds passed as positive number', function() { - var Type = Exonum.newType({ - size: 8, - fields: {since: {type: Exonum.Timespec, size: 8, from: 0, to: 8}} - }); - var data = {since: 1483979894237}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([221, 45, 24, 132, 89, 1, 0, 0]); - }); - - it('should serialize data and return array of 8-bit integers when the value is valid timestamp in nanoseconds passed as string', function() { - var Type = Exonum.newType({ - size: 8, - fields: {since: {type: Exonum.Timespec, size: 8, from: 0, to: 8}} - }); - var data = {since: '18446744073709551615'}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([255, 255, 255, 255, 255, 255, 255, 255]); - }); - - it('should throw error when the value is negative number', function() { - var Type = Exonum.newType({ - size: 8, - fields: {since: {type: Exonum.Timespec, size: 8, from: 0, to: 8}} - }); - - expect(() => Type.serialize({since: -1483979894237})).to.throw(TypeError); - }); - - it('should throw error when the range of segment is invalid', function() { - var Type = Exonum.newType({ - size: 8, - fields: {since: {type: Exonum.Timespec, size: 8, from: 0, to: 4}} - }); - - expect(() => Type.serialize({since: 1483979894237})).to.throw(Error); - }); - - it('should throw error when the value is out of range', function() { - var Type = Exonum.newType({ - size: 8, - fields: {since: {type: Exonum.Timespec, size: 8, from: 0, to: 8}} - }); - - expect(() => Type.serialize({since: '18446744073709551616'})).to.throw(TypeError); - }); - - it('should throw error when the value of invalid type', function() { - var Type = Exonum.newType({ - size: 8, - fields: {since: {type: Exonum.Timespec, size: 8, from: 0, to: 8}} - }); - - [true, null, undefined, [], {}, new Date()].forEach(function(since) { - expect(() => Type.serialize({since: since})).to.throw(TypeError); - }); - }); - - }); - - describe('Process Bool', function() { - - it('should serialize data and return array of 8-bit integers when the value is valid positive boolean', function() { - var Type = Exonum.newType({ - size: 1, - fields: {active: {type: Exonum.Bool, size: 1, from: 0, to: 1}} - }); - var data = {active: true}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([1]); - }); - - it('should serialize data and return array of 8-bit integers when the value is valid negative boolean', function() { - var Type = Exonum.newType({ - size: 1, - fields: {active: {type: Exonum.Bool, size: 1, from: 0, to: 1}} - }); - var data = {active: false}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([0]); - }); - - it('should throw error when the range of segment is invalid', function() { - var Type = Exonum.newType({ - size: 1, - fields: {active: {type: Exonum.Bool, size: 1, from: 0, to: 0}} - }); - expect(() => Type.serialize({active: true})).to.throw(Error); - }); - - it('should throw error when the value of invalid type', function() { - var Type = Exonum.newType({ - size: 1, - fields: {active: {type: Exonum.Bool, size: 1, from: 0, to: 1}} - }); - - ['Hello world', null, undefined, 57, [], {}, new Date()].forEach(function(active) { - expect(() => Type.serialize({active: active})).to.throw(TypeError); - }); - }); - - }); - - describe('Process String', function() { - - it('should serialize data and return array of 8-bit integers when the value is valid string', function() { - var Type = Exonum.newType({ - size: 8, - fields: {text: {type: Exonum.String, size: 8, from: 0, to: 8}} - }); - var data = {text: 'Hello world'}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([8, 0, 0, 0, 11, 0, 0, 0, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]); - }); - - it('should throw error when the range of segment is invalid', function() { - var Type = Exonum.newType({ - size: 8, - fields: {text: {type: Exonum.String, size: 8, from: 0, to: 4}} - }); - - expect(() => Type.serialize({text: 'Hello world'})).to.throw(Error); - }); - - it('should throw error when the value of invalid type', function() { - var Type = Exonum.newType({ - size: 8, - fields: {text: {type: Exonum.String, size: 8, from: 0, to: 8}} - }); - - [true, null, undefined, 57, [], {}, new Date()].forEach(function(text) { - expect(() => Type.serialize({text: text})).to.throw(TypeError); - }); - }); - - }); - - describe('Process Int8', function() { - - it('should serialize data and return array of 8-bit integers when the value is valid positive number', function() { - var Type = Exonum.newType({ - size: 1, - fields: {balance: {type: Exonum.Int8, size: 1, from: 0, to: 1}} - }); - var data = {balance: 120}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([120]); - }); - - it('should serialize data and return array of 8-bit integers when the value is valid negative number', function() { - var Type = Exonum.newType({ - size: 1, - fields: {balance: {type: Exonum.Int8, size: 1, from: 0, to: 1}} - }); - var data = {balance: -120}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([136]); - }); - - it('should throw error when the range of segment is invalid', function() { - var Type = Exonum.newType({ - size: 1, - fields: {balance: {type: Exonum.Int8, size: 1, from: 0, to: 0}} - }); - expect(() => Type.serialize({balance: 120})).to.throw(Error); - }); - - it('should throw error when the value is too big positive number', function() { - var Type = Exonum.newType({ - size: 1, - fields: {balance: {type: Exonum.Int8, size: 1, from: 0, to: 1}} - }); - expect(() => Type.serialize({balance: 130})).to.throw(TypeError); - }); - - it('should throw error when the value is too big negative number', function() { - var Type = Exonum.newType({ - size: 1, - fields: {balance: {type: Exonum.Int8, size: 1, from: 0, to: 1}} - }); - expect(() => Type.serialize({balance: -130})).to.throw(TypeError); - }); - - it('should throw error when the value of invalid type', function() { - var Type = Exonum.newType({ - size: 1, - fields: {balance: {type: Exonum.Int8, size: 1, from: 0, to: 1}} - }); - - [true, null, undefined, [], {}, new Date()].forEach(function(balance) { - expect(() => Type.serialize({balance: balance})).to.throw(TypeError); - }); - }); - - }); - - describe('Process Int16', function() { - - it('should serialize data and return array of 8-bit integers when the value is valid positive number', function() { - var Type = Exonum.newType({ - size: 2, - fields: {balance: {type: Exonum.Int16, size: 2, from: 0, to: 2}} - }); - var data = {balance: 30767}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([47, 120]); - }); - - it('should serialize data and return array of 8-bit integers when the value is valid negative number', function() { - var Type = Exonum.newType({ - size: 2, - fields: {balance: {type: Exonum.Int16, size: 2, from: 0, to: 2}} - }); - var data = {balance: -30767}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([209, 135]); - }); - - it('should throw error when the range of segment is invalid', function() { - var Type = Exonum.newType({ - size: 2, - fields: {balance: {type: Exonum.Int16, size: 2, from: 0, to: 1}} - }); - - expect(() => Type.serialize({balance: 30767})).to.throw(Error); - }); - - it('should throw error when the value is too big positive number', function() { - var Type = Exonum.newType({ - size: 2, - fields: {balance: {type: Exonum.Int16, size: 2, from: 0, to: 2}} - }); - - expect(() => Type.serialize({balance: 32769})).to.throw(TypeError); - }); - - it('should throw error when the value is too big negative number', function() { - var Type = Exonum.newType({ - size: 2, - fields: {balance: {type: Exonum.Int16, size: 2, from: 0, to: 2}} - }); - - expect(() => Type.serialize({balance: -32770})).to.throw(TypeError); - }); - - it('should throw error when the value of invalid type', function() { - var Type = Exonum.newType({ - size: 2, - fields: {balance: {type: Exonum.Int16, size: 2, from: 0, to: 2}} - }); - - [true, null, undefined, [], {}, new Date()].forEach(function(balance) { - expect(() => Type.serialize({balance: balance})).to.throw(TypeError); - }); - }); - - }); - - describe('Process Int32', function() { - - it('should serialize data and return array of 8-bit integers when the value is valid positive number', function() { - var Type = Exonum.newType({ - size: 4, - fields: {balance: {type: Exonum.Int32, size: 4, from: 0, to: 4}} - }); - var data = {balance: 1147483647}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([255, 53, 101, 68]); - }); - - it('should serialize data and return array of 8-bit integers when the value is valid negative number', function() { - var Type = Exonum.newType({ - size: 4, - fields: {balance: {type: Exonum.Int32, size: 4, from: 0, to: 4}} - }); - var data = {balance: -1147483648}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([0, 202, 154, 187]); - }); - - it('should throw error when the range of segment is invalid', function() { - var Type = Exonum.newType({ - size: 4, - fields: {balance: {type: Exonum.Int32, size: 4, from: 0, to: 3}} - }); - - expect(() => Type.serialize({balance: 613228})).to.throw(Error); - }); - - it('should throw error when the value is too big positive number', function() { - var Type = Exonum.newType({ - size: 4, - fields: {balance: {type: Exonum.Int32, size: 4, from: 0, to: 4}} - }); - - expect(() => Type.serialize({balance: 2147483649})).to.throw(TypeError); - }); - - it('should throw error when the value is too big negative number', function() { - var Type = Exonum.newType({ - size: 4, - fields: {balance: {type: Exonum.Int32, size: 4, from: 0, to: 4}} - }); - - expect(() => Type.serialize({balance: -2147483650})).to.throw(TypeError); - }); - - it('should throw error when the value of invalid type', function() { - var Type = Exonum.newType({ - size: 4, - fields: {balance: {type: Exonum.Int32, size: 4, from: 0, to: 4}} - }); - - [true, null, undefined, [], {}, new Date()].forEach(function(balance) { - expect(() => Type.serialize({balance: balance})).to.throw(TypeError); - }); - }); - - }); - - describe('Process Int64', function() { - - it('should serialize data and return array of 8-bit integers when the value is valid positive number', function() { - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} - }); - var data = {balance: 900719925474000}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([208, 50, 51, 51, 51, 51, 3, 0]); - }); - - it('should serialize data and return array of 8-bit integers when the value is valid positive number as string', function() { - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} - }); - var data = {balance: '9223372036854775807'}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([255, 255, 255, 255, 255, 255, 255, 127]); - }); - - it('should serialize data and return array of 8-bit integers when the value is valid negative number', function() { - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} - }); - var data = {balance: -90071992547}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([29, 119, 74, 7, 235, 255, 255, 255]); - }); - - it('should serialize data and return array of 8-bit integers when the value is valid negative number as string', function() { - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} - }); - var data = {balance: '-9223372036854775808'}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([0, 0, 0, 0, 0, 0, 0, 128]); - }); - - it('should throw error when the range of segment is invalid', function() { - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 4}} - }); - - expect(() => Type.serialize({balance: 613228})).to.throw(Error); - }); - - it('should throw error when the value is too big positive number', function() { - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} - }); - - expect(() => Type.serialize({balance: '9223372036854775808'})).to.throw(TypeError); - }); - - it('should throw error when the value is too big negative number', function() { - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} - }); - - expect(() => Type.serialize({balance: '-9223372036854775809'})).to.throw(TypeError); - }); - - it('should throw error when the value of invalid type', function() { - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} - }); - - [true, null, undefined, [], {}, new Date()].forEach(function(balance) { - expect(() => Type.serialize({balance: balance})).to.throw(TypeError); - }); - }); - - }); - - describe('Process Uint8', function() { - - it('should serialize data and return array of 8-bit integers when the value is valid positive number', function() { - var Type = Exonum.newType({ - size: 1, - fields: {balance: {type: Exonum.Uint8, size: 1, from: 0, to: 1}} - }); - var data = {balance: 230}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([230]); - }); - - it('should throw error when the range of segment is invalid', function() { - var Type = Exonum.newType({ - size: 1, - fields: {balance: {type: Exonum.Uint8, size: 1, from: 0, to: 0}} - }); - - expect(() => Type.serialize({balance: 230})).to.throw(Error); - }); - - it('should throw error when the value is negative number', function() { - var Type = Exonum.newType({ - size: 1, - fields: {balance: {type: Exonum.Uint8, size: 1, from: 0, to: 1}} - }); - - expect(() => Type.serialize({balance: -1})).to.throw(TypeError); - }); - - it('should throw error when the value is out of range', function() { - var Type = Exonum.newType({ - size: 1, - fields: {balance: {type: Exonum.Uint8, size: 1, from: 0, to: 1}} - }); - - expect(() => Type.serialize({balance: 256})).to.throw(TypeError); - }); - - it('should throw error when the value of invalid type', function() { - var Type = Exonum.newType({ - size: 1, - fields: {balance: {type: Exonum.Uint8, size: 1, from: 0, to: 1}} - }); - - [true, null, undefined, [], {}, new Date()].forEach(function(balance) { - expect(() => Type.serialize({balance: balance})).to.throw(TypeError); - }); - }); - - }); - - describe('Process Uint16', function() { - - it('should serialize data and return array of 8-bit integers when the value is valid positive number', function() { - var Type = Exonum.newType({ - size: 2, - fields: {balance: {type: Exonum.Uint16, size: 2, from: 0, to: 2}} - }); - var data = {balance: 60535}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([119, 236]); - }); - - it('should throw error when the range of segment is invalid', function() { - var Type = Exonum.newType({ - size: 2, - fields: {balance: {type: Exonum.Uint16, size: 2, from: 0, to: 1}} - }); - - expect(() => Type.serialize({balance: 60535})).to.throw(Error); - }); - - it('should throw error when the value is negative number', function() { - var Type = Exonum.newType({ - size: 2, - fields: {balance: {type: Exonum.Uint16, size: 2, from: 0, to: 2}} - }); - - expect(() => Type.serialize({balance: -1})).to.throw(TypeError); - }); - - it('should throw error when the value is out of range', function() { - var Type = Exonum.newType({ - size: 2, - fields: {balance: {type: Exonum.Uint16, size: 2, from: 0, to: 2}} - }); - - expect(() => Type.serialize({balance: 65536})).to.throw(TypeError); - }); - - it('should throw error when the value of invalid type', function() { - var Type = Exonum.newType({ - size: 2, - fields: {balance: {type: Exonum.Uint16, size: 2, from: 0, to: 2}} - }); - - [true, null, undefined, [], {}, new Date()].forEach(function(balance) { - expect(() => Type.serialize({balance: balance})).to.throw(TypeError); - }); - }); - - }); - - describe('Process Uint32', function() { - - it('should serialize data and return array of 8-bit integers when the value is valid positive number', function() { - var Type = Exonum.newType({ - size: 4, - fields: {balance: {type: Exonum.Uint32, size: 4, from: 0, to: 4}} - }); - var data = {balance: 613228}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([108, 91, 9, 0]); - }); - - it('should throw error when the range of segment is invalid', function() { - var Type = Exonum.newType({ - size: 4, - fields: {balance: {type: Exonum.Uint32, size: 4, from: 0, to: 3}} - }); - - expect(() => Type.serialize({balance: 613228})).to.throw(Error); - }); - - it('should throw error when the value is negative number', function() { - var Type = Exonum.newType({ - size: 4, - fields: {balance: {type: Exonum.Uint32, size: 4, from: 0, to: 4}} - }); - - expect(() => Type.serialize({balance: -1})).to.throw(TypeError); - }); - - it('should throw error when the value is out of range', function() { - var Type = Exonum.newType({ - size: 4, - fields: {balance: {type: Exonum.Uint32, size: 4, from: 0, to: 4}} - }); - - expect(() => Type.serialize({balance: 4294967296})).to.throw(TypeError); - }); - - it('should throw error when the value of invalid type', function() { - var Type = Exonum.newType({ - size: 4, - fields: {balance: {type: Exonum.Uint32, size: 4, from: 0, to: 4}} - }); - - [true, null, undefined, [], {}, new Date()].forEach(function(balance) { - expect(() => Type.serialize({balance: balance})).to.throw(TypeError); - }); - }); - - }); - - describe('Process Uint64', function() { - - it('should serialize data and return array of 8-bit integers when the value is valid positive number', function() { - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Uint64, size: 8, from: 0, to: 8}} - }); - var data = {balance: 613228}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([108, 91, 9, 0, 0, 0, 0, 0]); - }); - - it('should serialize data and return array of 8-bit integers when the value is valid positive number passed as string', function() { - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Uint64, size: 8, from: 0, to: 8}} - }); - var data = {balance: '9007199254740993'}; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([1, 0, 0, 0, 0, 0, 32, 0]); - }); - - it('should throw error when the range of segment is invalid', function() { - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Uint64, size: 8, from: 0, to: 4}} - }); - - expect(() => Type.serialize({balance: 613228})).to.throw(Error); - }); - - it('should throw error when the value is negative number', function() { - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Uint64, size: 8, from: 0, to: 8}} - }); - - expect(() => Type.serialize({balance: -613228})).to.throw(TypeError); - }); - - it('should throw error when the value is out of range', function() { - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Uint64, size: 8, from: 0, to: 8}} - }); - - expect(() => Type.serialize({balance: '18446744073709551616'})).to.throw(TypeError); - }); - - it('should throw error when the value of invalid type', function() { - var Type = Exonum.newType({ - size: 8, - fields: {balance: {type: Exonum.Uint64, size: 8, from: 0, to: 8}} - }); - - [true, null, undefined, [], {}, new Date()].forEach(function(balance) { - expect(() => Type.serialize({balance: balance})).to.throw(TypeError); - }); - }); - - }); - - describe('Process FixedBuffer', function() { - - it('should serialize data and return array of 8-bit integers when the value is valid fixed buffer passed as array', function() { - var Type = Exonum.newType({ - size: 16, - fields: { - balance: {type: Exonum.Uint64, size: 8, from: 0, to: 8}, - phrase: {type: Exonum.FixedBuffer, size: 8, from: 8, to: 16} - } - }); - var data = { - balance: 613228, - phrase: [245, 134, 74, 182, 165, 162, 25, 6] - }; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([108, 91, 9, 0, 0, 0, 0, 0, 245, 134, 74, 182, 165, 162, 25, 6]); - }); - - it('should serialize data and return array of 8-bit integers when the value is valid fixed buffer passed as hexadecimal string', function() { - var Type = Exonum.newType({ - size: 16, - fields: { - balance: {type: Exonum.Uint64, size: 8, from: 0, to: 8}, - phrase: {type: Exonum.FixedBuffer, size: 8, from: 8, to: 16} - } - }); - var data = { - balance: 613228, - phrase: 'f5864ab6a5a21906' - }; - var buffer = Type.serialize(data); - - expect(buffer).to.deep.equal([108, 91, 9, 0, 0, 0, 0, 0, 245, 134, 74, 182, 165, 162, 25, 6]); - }); - - it('should throw error when the range of segment is invalid', function() { - var Type = Exonum.newType({ - size: 8, - fields: { - phrase: {type: Exonum.FixedBuffer, size: 8, from: 0, to: 4} - } - }); - var data = { - phrase: [245, 134, 74, 182, 165, 162, 25, 6] - }; - - expect(() => Type.serialize(data)).to.throw(Error); - }); - - it('should throw error when the value is too long bytes array', function() { - var Type = Exonum.newType({ - size: 8, - fields: { - phrase: {type: Exonum.FixedBuffer, size: 8, from: 0, to: 8} - } - }); - var data = { - phrase: [245, 134, 74, 182, 165, 162, 25, 6, 5] - }; - - expect(() => Type.serialize(data)).to.throw(TypeError); - }); - - it('should throw error when the value is too short bytes array', function() { - var Type = Exonum.newType({ - size: 8, - fields: { - phrase: {type: Exonum.FixedBuffer, size: 8, from: 0, to: 8} - } - }); - var data = { - phrase: [245, 134, 74, 182, 165, 162, 25] - }; - - expect(() => Type.serialize(data)).to.throw(TypeError); - }); - - it('should throw error when the value is invalid bytes array', function() { - var Type = Exonum.newType({ - size: 1, - fields: { - phrase: {type: Exonum.FixedBuffer, size: 1, from: 0, to: 1} - } - }); - - [[300], [-5]].forEach(function(phrase) { - expect(() => Type.serialize({phrase: phrase})).to.throw(TypeError); - }); - }); - - it('should throw error when the value is bytes array of wrong type', function() { - var Type = Exonum.newType({ - size: 1, - fields: { - phrase: {type: Exonum.FixedBuffer, size: 1, from: 0, to: 1} - } - }); - - [[true], [null], [undefined], ['Hello world'], [[]], [{}], [new Date()]].forEach(function(phrase) { - expect(() => Type.serialize({phrase: phrase})).to.throw(TypeError); - }); - }); - - it('should throw error when the value is too short hexadecimal string', function() { - var Type = Exonum.newType({ - size: 8, - fields: { - phrase: {type: Exonum.FixedBuffer, size: 8, from: 0, to: 8} - } - }); - var data = { - phrase: 'f5864ab6a5a219' - }; - - expect(() => Type.serialize(data)).to.throw(Error); - }); - - it('should throw error when the value is invalid hexadecimal string', function() { - var Type = Exonum.newType({ - size: 8, - fields: { - phrase: {type: Exonum.FixedBuffer, size: 8, from: 0, to: 8} - } - }); - var data = { - phrase: 'f5864ab6a5a2190z' - }; - - expect(() => Type.serialize(data)).to.throw(Error); - }); - - it('should throw error when the value of wrong type', function() { - var Type = Exonum.newType({ - size: 8, - fields: { - phrase: {type: Exonum.FixedBuffer, size: 8, from: 0, to: 8} - } - }); - - [true, null, undefined, 57, [], {}, new Date()].forEach(function(phrase) { - expect(() => Type.serialize({phrase: phrase})).to.throw(TypeError); - }); - }); - - }); - -}); +/* eslint-disable no-unused-expressions */ + +var expect = require('chai').expect +var Exonum = require('../src') + +describe('Check built-in types', function () { + describe('Process Hash', function () { + it('should serialize data and return array of 8-bit integers when the value is valid hexadecimal string', function () { + var Type = Exonum.newType({ + size: 32, + fields: {hash: {type: Exonum.Hash, size: 32, from: 0, to: 32}} + }) + var data = {hash: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36'} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([245, 134, 74, 182, 165, 162, 25, 6, 102, 180, 124, 103, 107, 207, 21, 161, 242, 240, 119, 3, 197, 188, 175, 181, 116, 154, 167, 53, 206, 139, 124, 54]) + }) + + it('should throw error when the range of segment is invalid', function () { + var Type = Exonum.newType({ + size: 32, + fields: {hash: {type: Exonum.Hash, size: 32, from: 0, to: 16}} + }) + var data = {hash: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36'} + + expect(() => Type.serialize(data)).to.throw(Error) + }) + + it('should throw error when the value is invalid string', function () { + var Type = Exonum.newType({ + size: 32, + fields: {hash: {type: Exonum.Hash, size: 32, from: 0, to: 32}} + }) + var data = {hash: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3z'} + + expect(() => Type.serialize(data)).to.throw(Error) + }) + + it('should throw error when the value is too long string', function () { + var Type = Exonum.newType({ + size: 32, + fields: {hash: {type: Exonum.Hash, size: 32, from: 0, to: 32}} + }) + var data = {hash: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c365'} + + expect(() => Type.serialize(data)).to.throw(Error) + }) + + it('should throw error when the value is too short string', function () { + var Type = Exonum.newType({ + size: 32, + fields: {hash: {type: Exonum.Hash, size: 32, from: 0, to: 32}} + }) + var data = {hash: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3'} + + expect(() => Type.serialize(data)).to.throw(Error) + }) + + it('should throw error when the value of invalid type', function () { + var Type = Exonum.newType({ + size: 32, + fields: {hash: {type: Exonum.Hash, size: 32, from: 0, to: 32}} + }); + + [true, null, undefined, 57, [], {}, new Date()].forEach(function (hash) { + expect(() => Type.serialize({hash: hash})).to.throw(TypeError) + }) + }) + }) + + describe('Process PublicKey', function () { + it('should serialize data and return array of 8-bit integers when the value is valid string', function () { + var Type = Exonum.newType({ + size: 32, + fields: {key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}} + }) + var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36'} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([245, 134, 74, 182, 165, 162, 25, 6, 102, 180, 124, 103, 107, 207, 21, 161, 242, 240, 119, 3, 197, 188, 175, 181, 116, 154, 167, 53, 206, 139, 124, 54]) + }) + + it('should throw error when the range of segment is invalid', function () { + var Type = Exonum.newType({ + size: 32, + fields: {key: {type: Exonum.PublicKey, size: 32, from: 0, to: 16}} + }) + var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36'} + + expect(() => Type.serialize(data)).to.throw(Error) + }) + + it('should throw error when the value is invalid string', function () { + var Type = Exonum.newType({ + size: 32, + fields: {key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}} + }) + var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3z'} + + expect(() => Type.serialize(data)).to.throw(Error) + }) + + it('should throw error when the value is too long string', function () { + var Type = Exonum.newType({ + size: 32, + fields: {key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}} + }) + var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c365'} + + expect(() => Type.serialize(data)).to.throw(Error) + }) + + it('should throw error when the value is too short string', function () { + var Type = Exonum.newType({ + size: 32, + fields: {key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}} + }) + var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3'} + + expect(() => Type.serialize(data)).to.throw(Error) + }) + + it('should throw error when the value of invalid type', function () { + var Type = Exonum.newType({ + size: 32, + fields: {key: {type: Exonum.PublicKey, size: 32, from: 0, to: 32}} + }); + + [true, null, undefined, 57, [], {}, new Date()].forEach(function (key) { + expect(() => Type.serialize({key: key})).to.throw(TypeError) + }) + }) + }) + + describe('Process Digest', function () { + it('should serialize data and return array of 8-bit integers when the value is valid string', function () { + var Type = Exonum.newType({ + size: 64, + fields: {key: {type: Exonum.Digest, size: 64, from: 0, to: 64}} + }) + var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36'} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([245, 134, 74, 182, 165, 162, 25, 6, 102, 180, 124, 103, 107, 207, 21, 161, 242, 240, 119, 3, 197, 188, 175, 181, 116, 154, 167, 53, 206, 139, 124, 54, 245, 134, 74, 182, 165, 162, 25, 6, 102, 180, 124, 103, 107, 207, 21, 161, 242, 240, 119, 3, 197, 188, 175, 181, 116, 154, 167, 53, 206, 139, 124, 54]) + }) + + it('should throw error when the range of segment is invalid', function () { + var Type = Exonum.newType({ + size: 64, + fields: {key: {type: Exonum.Digest, size: 64, from: 0, to: 32}} + }) + var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36'} + + expect(() => Type.serialize(data)).to.throw(Error) + }) + + it('should throw error when the value is invalid string', function () { + var Type = Exonum.newType({ + size: 64, + fields: {key: {type: Exonum.Digest, size: 64, from: 0, to: 64}} + }) + var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3zf5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3z'} + + expect(() => Type.serialize(data)).to.throw(Error) + }) + + it('should throw error when the value is too long string', function () { + var Type = Exonum.newType({ + size: 64, + fields: {key: {type: Exonum.Digest, size: 64, from: 0, to: 64}} + }) + var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c365f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c365'} + + expect(() => Type.serialize(data)).to.throw(Error) + }) + + it('should throw error when the value is too short string', function () { + var Type = Exonum.newType({ + size: 64, + fields: {key: {type: Exonum.Digest, size: 64, from: 0, to: 64}} + }) + var data = {key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3'} + + expect(() => Type.serialize(data)).to.throw(Error) + }) + + it('should throw error when the value of invalid type', function () { + var Type = Exonum.newType({ + size: 64, + fields: {key: {type: Exonum.Digest, size: 64, from: 0, to: 64}} + }); + + [true, null, undefined, 57, [], {}, new Date()].forEach(function (key) { + expect(() => Type.serialize({key: key})).to.throw(TypeError) + }) + }) + }) + + describe('Process Timespec', function () { + it('should serialize data and return array of 8-bit integers when the value is valid timestamp in nanoseconds passed as positive number', function () { + var Type = Exonum.newType({ + size: 8, + fields: {since: {type: Exonum.Timespec, size: 8, from: 0, to: 8}} + }) + var data = {since: 1483979894237} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([221, 45, 24, 132, 89, 1, 0, 0]) + }) + + it('should serialize data and return array of 8-bit integers when the value is valid timestamp in nanoseconds passed as string', function () { + var Type = Exonum.newType({ + size: 8, + fields: {since: {type: Exonum.Timespec, size: 8, from: 0, to: 8}} + }) + var data = {since: '18446744073709551615'} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([255, 255, 255, 255, 255, 255, 255, 255]) + }) + + it('should throw error when the value is negative number', function () { + var Type = Exonum.newType({ + size: 8, + fields: {since: {type: Exonum.Timespec, size: 8, from: 0, to: 8}} + }) + + expect(() => Type.serialize({since: -1483979894237})).to.throw(TypeError) + }) + + it('should throw error when the range of segment is invalid', function () { + var Type = Exonum.newType({ + size: 8, + fields: {since: {type: Exonum.Timespec, size: 8, from: 0, to: 4}} + }) + + expect(() => Type.serialize({since: 1483979894237})).to.throw(Error) + }) + + it('should throw error when the value is out of range', function () { + var Type = Exonum.newType({ + size: 8, + fields: {since: {type: Exonum.Timespec, size: 8, from: 0, to: 8}} + }) + + expect(() => Type.serialize({since: '18446744073709551616'})).to.throw(TypeError) + }) + + it('should throw error when the value of invalid type', function () { + var Type = Exonum.newType({ + size: 8, + fields: {since: {type: Exonum.Timespec, size: 8, from: 0, to: 8}} + }); + + [true, null, undefined, [], {}, new Date()].forEach(function (since) { + expect(() => Type.serialize({since: since})).to.throw(TypeError) + }) + }) + }) + + describe('Process Bool', function () { + it('should serialize data and return array of 8-bit integers when the value is valid positive boolean', function () { + var Type = Exonum.newType({ + size: 1, + fields: {active: {type: Exonum.Bool, size: 1, from: 0, to: 1}} + }) + var data = {active: true} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([1]) + }) + + it('should serialize data and return array of 8-bit integers when the value is valid negative boolean', function () { + var Type = Exonum.newType({ + size: 1, + fields: {active: {type: Exonum.Bool, size: 1, from: 0, to: 1}} + }) + var data = {active: false} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([0]) + }) + + it('should throw error when the range of segment is invalid', function () { + var Type = Exonum.newType({ + size: 1, + fields: {active: {type: Exonum.Bool, size: 1, from: 0, to: 0}} + }) + expect(() => Type.serialize({active: true})).to.throw(Error) + }) + + it('should throw error when the value of invalid type', function () { + var Type = Exonum.newType({ + size: 1, + fields: {active: {type: Exonum.Bool, size: 1, from: 0, to: 1}} + }); + + ['Hello world', null, undefined, 57, [], {}, new Date()].forEach(function (active) { + expect(() => Type.serialize({active: active})).to.throw(TypeError) + }) + }) + }) + + describe('Process String', function () { + it('should serialize data and return array of 8-bit integers when the value is valid string', function () { + var Type = Exonum.newType({ + size: 8, + fields: {text: {type: Exonum.String, size: 8, from: 0, to: 8}} + }) + var data = {text: 'Hello world'} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([8, 0, 0, 0, 11, 0, 0, 0, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]) + }) + + it('should throw error when the range of segment is invalid', function () { + var Type = Exonum.newType({ + size: 8, + fields: {text: {type: Exonum.String, size: 8, from: 0, to: 4}} + }) + + expect(() => Type.serialize({text: 'Hello world'})).to.throw(Error) + }) + + it('should throw error when the value of invalid type', function () { + var Type = Exonum.newType({ + size: 8, + fields: {text: {type: Exonum.String, size: 8, from: 0, to: 8}} + }); + + [true, null, undefined, 57, [], {}, new Date()].forEach(function (text) { + expect(() => Type.serialize({text: text})).to.throw(TypeError) + }) + }) + }) + + describe('Process Int8', function () { + it('should serialize data and return array of 8-bit integers when the value is valid positive number', function () { + var Type = Exonum.newType({ + size: 1, + fields: {balance: {type: Exonum.Int8, size: 1, from: 0, to: 1}} + }) + var data = {balance: 120} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([120]) + }) + + it('should serialize data and return array of 8-bit integers when the value is valid negative number', function () { + var Type = Exonum.newType({ + size: 1, + fields: {balance: {type: Exonum.Int8, size: 1, from: 0, to: 1}} + }) + var data = {balance: -120} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([136]) + }) + + it('should throw error when the range of segment is invalid', function () { + var Type = Exonum.newType({ + size: 1, + fields: {balance: {type: Exonum.Int8, size: 1, from: 0, to: 0}} + }) + expect(() => Type.serialize({balance: 120})).to.throw(Error) + }) + + it('should throw error when the value is too big positive number', function () { + var Type = Exonum.newType({ + size: 1, + fields: {balance: {type: Exonum.Int8, size: 1, from: 0, to: 1}} + }) + expect(() => Type.serialize({balance: 130})).to.throw(TypeError) + }) + + it('should throw error when the value is too big negative number', function () { + var Type = Exonum.newType({ + size: 1, + fields: {balance: {type: Exonum.Int8, size: 1, from: 0, to: 1}} + }) + expect(() => Type.serialize({balance: -130})).to.throw(TypeError) + }) + + it('should throw error when the value of invalid type', function () { + var Type = Exonum.newType({ + size: 1, + fields: {balance: {type: Exonum.Int8, size: 1, from: 0, to: 1}} + }); + + [true, null, undefined, [], {}, new Date()].forEach(function (balance) { + expect(() => Type.serialize({balance: balance})).to.throw(TypeError) + }) + }) + }) + + describe('Process Int16', function () { + it('should serialize data and return array of 8-bit integers when the value is valid positive number', function () { + var Type = Exonum.newType({ + size: 2, + fields: {balance: {type: Exonum.Int16, size: 2, from: 0, to: 2}} + }) + var data = {balance: 30767} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([47, 120]) + }) + + it('should serialize data and return array of 8-bit integers when the value is valid negative number', function () { + var Type = Exonum.newType({ + size: 2, + fields: {balance: {type: Exonum.Int16, size: 2, from: 0, to: 2}} + }) + var data = {balance: -30767} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([209, 135]) + }) + + it('should throw error when the range of segment is invalid', function () { + var Type = Exonum.newType({ + size: 2, + fields: {balance: {type: Exonum.Int16, size: 2, from: 0, to: 1}} + }) + + expect(() => Type.serialize({balance: 30767})).to.throw(Error) + }) + + it('should throw error when the value is too big positive number', function () { + var Type = Exonum.newType({ + size: 2, + fields: {balance: {type: Exonum.Int16, size: 2, from: 0, to: 2}} + }) + + expect(() => Type.serialize({balance: 32769})).to.throw(TypeError) + }) + + it('should throw error when the value is too big negative number', function () { + var Type = Exonum.newType({ + size: 2, + fields: {balance: {type: Exonum.Int16, size: 2, from: 0, to: 2}} + }) + + expect(() => Type.serialize({balance: -32770})).to.throw(TypeError) + }) + + it('should throw error when the value of invalid type', function () { + var Type = Exonum.newType({ + size: 2, + fields: {balance: {type: Exonum.Int16, size: 2, from: 0, to: 2}} + }); + + [true, null, undefined, [], {}, new Date()].forEach(function (balance) { + expect(() => Type.serialize({balance: balance})).to.throw(TypeError) + }) + }) + }) + + describe('Process Int32', function () { + it('should serialize data and return array of 8-bit integers when the value is valid positive number', function () { + var Type = Exonum.newType({ + size: 4, + fields: {balance: {type: Exonum.Int32, size: 4, from: 0, to: 4}} + }) + var data = {balance: 1147483647} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([255, 53, 101, 68]) + }) + + it('should serialize data and return array of 8-bit integers when the value is valid negative number', function () { + var Type = Exonum.newType({ + size: 4, + fields: {balance: {type: Exonum.Int32, size: 4, from: 0, to: 4}} + }) + var data = {balance: -1147483648} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([0, 202, 154, 187]) + }) + + it('should throw error when the range of segment is invalid', function () { + var Type = Exonum.newType({ + size: 4, + fields: {balance: {type: Exonum.Int32, size: 4, from: 0, to: 3}} + }) + + expect(() => Type.serialize({balance: 613228})).to.throw(Error) + }) + + it('should throw error when the value is too big positive number', function () { + var Type = Exonum.newType({ + size: 4, + fields: {balance: {type: Exonum.Int32, size: 4, from: 0, to: 4}} + }) + + expect(() => Type.serialize({balance: 2147483649})).to.throw(TypeError) + }) + + it('should throw error when the value is too big negative number', function () { + var Type = Exonum.newType({ + size: 4, + fields: {balance: {type: Exonum.Int32, size: 4, from: 0, to: 4}} + }) + + expect(() => Type.serialize({balance: -2147483650})).to.throw(TypeError) + }) + + it('should throw error when the value of invalid type', function () { + var Type = Exonum.newType({ + size: 4, + fields: {balance: {type: Exonum.Int32, size: 4, from: 0, to: 4}} + }); + + [true, null, undefined, [], {}, new Date()].forEach(function (balance) { + expect(() => Type.serialize({balance: balance})).to.throw(TypeError) + }) + }) + }) + + describe('Process Int64', function () { + it('should serialize data and return array of 8-bit integers when the value is valid positive number', function () { + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} + }) + var data = {balance: 900719925474000} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([208, 50, 51, 51, 51, 51, 3, 0]) + }) + + it('should serialize data and return array of 8-bit integers when the value is valid positive number as string', function () { + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} + }) + var data = {balance: '9223372036854775807'} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([255, 255, 255, 255, 255, 255, 255, 127]) + }) + + it('should serialize data and return array of 8-bit integers when the value is valid negative number', function () { + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} + }) + var data = {balance: -90071992547} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([29, 119, 74, 7, 235, 255, 255, 255]) + }) + + it('should serialize data and return array of 8-bit integers when the value is valid negative number as string', function () { + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} + }) + var data = {balance: '-9223372036854775808'} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([0, 0, 0, 0, 0, 0, 0, 128]) + }) + + it('should throw error when the range of segment is invalid', function () { + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 4}} + }) + + expect(() => Type.serialize({balance: 613228})).to.throw(Error) + }) + + it('should throw error when the value is too big positive number', function () { + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} + }) + + expect(() => Type.serialize({balance: '9223372036854775808'})).to.throw(TypeError) + }) + + it('should throw error when the value is too big negative number', function () { + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} + }) + + expect(() => Type.serialize({balance: '-9223372036854775809'})).to.throw(TypeError) + }) + + it('should throw error when the value of invalid type', function () { + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Int64, size: 8, from: 0, to: 8}} + }); + + [true, null, undefined, [], {}, new Date()].forEach(function (balance) { + expect(() => Type.serialize({balance: balance})).to.throw(TypeError) + }) + }) + }) + + describe('Process Uint8', function () { + it('should serialize data and return array of 8-bit integers when the value is valid positive number', function () { + var Type = Exonum.newType({ + size: 1, + fields: {balance: {type: Exonum.Uint8, size: 1, from: 0, to: 1}} + }) + var data = {balance: 230} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([230]) + }) + + it('should throw error when the range of segment is invalid', function () { + var Type = Exonum.newType({ + size: 1, + fields: {balance: {type: Exonum.Uint8, size: 1, from: 0, to: 0}} + }) + + expect(() => Type.serialize({balance: 230})).to.throw(Error) + }) + + it('should throw error when the value is negative number', function () { + var Type = Exonum.newType({ + size: 1, + fields: {balance: {type: Exonum.Uint8, size: 1, from: 0, to: 1}} + }) + + expect(() => Type.serialize({balance: -1})).to.throw(TypeError) + }) + + it('should throw error when the value is out of range', function () { + var Type = Exonum.newType({ + size: 1, + fields: {balance: {type: Exonum.Uint8, size: 1, from: 0, to: 1}} + }) + + expect(() => Type.serialize({balance: 256})).to.throw(TypeError) + }) + + it('should throw error when the value of invalid type', function () { + var Type = Exonum.newType({ + size: 1, + fields: {balance: {type: Exonum.Uint8, size: 1, from: 0, to: 1}} + }); + + [true, null, undefined, [], {}, new Date()].forEach(function (balance) { + expect(() => Type.serialize({balance: balance})).to.throw(TypeError) + }) + }) + }) + + describe('Process Uint16', function () { + it('should serialize data and return array of 8-bit integers when the value is valid positive number', function () { + var Type = Exonum.newType({ + size: 2, + fields: {balance: {type: Exonum.Uint16, size: 2, from: 0, to: 2}} + }) + var data = {balance: 60535} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([119, 236]) + }) + + it('should throw error when the range of segment is invalid', function () { + var Type = Exonum.newType({ + size: 2, + fields: {balance: {type: Exonum.Uint16, size: 2, from: 0, to: 1}} + }) + + expect(() => Type.serialize({balance: 60535})).to.throw(Error) + }) + + it('should throw error when the value is negative number', function () { + var Type = Exonum.newType({ + size: 2, + fields: {balance: {type: Exonum.Uint16, size: 2, from: 0, to: 2}} + }) + + expect(() => Type.serialize({balance: -1})).to.throw(TypeError) + }) + + it('should throw error when the value is out of range', function () { + var Type = Exonum.newType({ + size: 2, + fields: {balance: {type: Exonum.Uint16, size: 2, from: 0, to: 2}} + }) + + expect(() => Type.serialize({balance: 65536})).to.throw(TypeError) + }) + + it('should throw error when the value of invalid type', function () { + var Type = Exonum.newType({ + size: 2, + fields: {balance: {type: Exonum.Uint16, size: 2, from: 0, to: 2}} + }); + + [true, null, undefined, [], {}, new Date()].forEach(function (balance) { + expect(() => Type.serialize({balance: balance})).to.throw(TypeError) + }) + }) + }) + + describe('Process Uint32', function () { + it('should serialize data and return array of 8-bit integers when the value is valid positive number', function () { + var Type = Exonum.newType({ + size: 4, + fields: {balance: {type: Exonum.Uint32, size: 4, from: 0, to: 4}} + }) + var data = {balance: 613228} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([108, 91, 9, 0]) + }) + + it('should throw error when the range of segment is invalid', function () { + var Type = Exonum.newType({ + size: 4, + fields: {balance: {type: Exonum.Uint32, size: 4, from: 0, to: 3}} + }) + + expect(() => Type.serialize({balance: 613228})).to.throw(Error) + }) + + it('should throw error when the value is negative number', function () { + var Type = Exonum.newType({ + size: 4, + fields: {balance: {type: Exonum.Uint32, size: 4, from: 0, to: 4}} + }) + + expect(() => Type.serialize({balance: -1})).to.throw(TypeError) + }) + + it('should throw error when the value is out of range', function () { + var Type = Exonum.newType({ + size: 4, + fields: {balance: {type: Exonum.Uint32, size: 4, from: 0, to: 4}} + }) + + expect(() => Type.serialize({balance: 4294967296})).to.throw(TypeError) + }) + + it('should throw error when the value of invalid type', function () { + var Type = Exonum.newType({ + size: 4, + fields: {balance: {type: Exonum.Uint32, size: 4, from: 0, to: 4}} + }); + + [true, null, undefined, [], {}, new Date()].forEach(function (balance) { + expect(() => Type.serialize({balance: balance})).to.throw(TypeError) + }) + }) + }) + + describe('Process Uint64', function () { + it('should serialize data and return array of 8-bit integers when the value is valid positive number', function () { + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Uint64, size: 8, from: 0, to: 8}} + }) + var data = {balance: 613228} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([108, 91, 9, 0, 0, 0, 0, 0]) + }) + + it('should serialize data and return array of 8-bit integers when the value is valid positive number passed as string', function () { + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Uint64, size: 8, from: 0, to: 8}} + }) + var data = {balance: '9007199254740993'} + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([1, 0, 0, 0, 0, 0, 32, 0]) + }) + + it('should throw error when the range of segment is invalid', function () { + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Uint64, size: 8, from: 0, to: 4}} + }) + + expect(() => Type.serialize({balance: 613228})).to.throw(Error) + }) + + it('should throw error when the value is negative number', function () { + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Uint64, size: 8, from: 0, to: 8}} + }) + + expect(() => Type.serialize({balance: -613228})).to.throw(TypeError) + }) + + it('should throw error when the value is out of range', function () { + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Uint64, size: 8, from: 0, to: 8}} + }) + + expect(() => Type.serialize({balance: '18446744073709551616'})).to.throw(TypeError) + }) + + it('should throw error when the value of invalid type', function () { + var Type = Exonum.newType({ + size: 8, + fields: {balance: {type: Exonum.Uint64, size: 8, from: 0, to: 8}} + }); + + [true, null, undefined, [], {}, new Date()].forEach(function (balance) { + expect(() => Type.serialize({balance: balance})).to.throw(TypeError) + }) + }) + }) + + describe('Process FixedBuffer', function () { + it('should serialize data and return array of 8-bit integers when the value is valid fixed buffer passed as array', function () { + var Type = Exonum.newType({ + size: 16, + fields: { + balance: {type: Exonum.Uint64, size: 8, from: 0, to: 8}, + phrase: {type: Exonum.FixedBuffer, size: 8, from: 8, to: 16} + } + }) + var data = { + balance: 613228, + phrase: [245, 134, 74, 182, 165, 162, 25, 6] + } + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([108, 91, 9, 0, 0, 0, 0, 0, 245, 134, 74, 182, 165, 162, 25, 6]) + }) + + it('should serialize data and return array of 8-bit integers when the value is valid fixed buffer passed as hexadecimal string', function () { + var Type = Exonum.newType({ + size: 16, + fields: { + balance: {type: Exonum.Uint64, size: 8, from: 0, to: 8}, + phrase: {type: Exonum.FixedBuffer, size: 8, from: 8, to: 16} + } + }) + var data = { + balance: 613228, + phrase: 'f5864ab6a5a21906' + } + var buffer = Type.serialize(data) + + expect(buffer).to.deep.equal([108, 91, 9, 0, 0, 0, 0, 0, 245, 134, 74, 182, 165, 162, 25, 6]) + }) + + it('should throw error when the range of segment is invalid', function () { + var Type = Exonum.newType({ + size: 8, + fields: { + phrase: {type: Exonum.FixedBuffer, size: 8, from: 0, to: 4} + } + }) + var data = { + phrase: [245, 134, 74, 182, 165, 162, 25, 6] + } + + expect(() => Type.serialize(data)).to.throw(Error) + }) + + it('should throw error when the value is too long bytes array', function () { + var Type = Exonum.newType({ + size: 8, + fields: { + phrase: {type: Exonum.FixedBuffer, size: 8, from: 0, to: 8} + } + }) + var data = { + phrase: [245, 134, 74, 182, 165, 162, 25, 6, 5] + } + + expect(() => Type.serialize(data)).to.throw(TypeError) + }) + + it('should throw error when the value is too short bytes array', function () { + var Type = Exonum.newType({ + size: 8, + fields: { + phrase: {type: Exonum.FixedBuffer, size: 8, from: 0, to: 8} + } + }) + var data = { + phrase: [245, 134, 74, 182, 165, 162, 25] + } + + expect(() => Type.serialize(data)).to.throw(TypeError) + }) + + it('should throw error when the value is invalid bytes array', function () { + var Type = Exonum.newType({ + size: 1, + fields: { + phrase: {type: Exonum.FixedBuffer, size: 1, from: 0, to: 1} + } + }); + + [[300], [-5]].forEach(function (phrase) { + expect(() => Type.serialize({phrase: phrase})).to.throw(TypeError) + }) + }) + + it('should throw error when the value is bytes array of wrong type', function () { + var Type = Exonum.newType({ + size: 1, + fields: { + phrase: {type: Exonum.FixedBuffer, size: 1, from: 0, to: 1} + } + }); + + [[true], [null], [undefined], ['Hello world'], [[]], [{}], [new Date()]].forEach(function (phrase) { + expect(() => Type.serialize({phrase: phrase})).to.throw(TypeError) + }) + }) + + it('should throw error when the value is too short hexadecimal string', function () { + var Type = Exonum.newType({ + size: 8, + fields: { + phrase: {type: Exonum.FixedBuffer, size: 8, from: 0, to: 8} + } + }) + var data = { + phrase: 'f5864ab6a5a219' + } + + expect(() => Type.serialize(data)).to.throw(Error) + }) + + it('should throw error when the value is invalid hexadecimal string', function () { + var Type = Exonum.newType({ + size: 8, + fields: { + phrase: {type: Exonum.FixedBuffer, size: 8, from: 0, to: 8} + } + }) + var data = { + phrase: 'f5864ab6a5a2190z' + } + + expect(() => Type.serialize(data)).to.throw(Error) + }) + + it('should throw error when the value of wrong type', function () { + var Type = Exonum.newType({ + size: 8, + fields: { + phrase: {type: Exonum.FixedBuffer, size: 8, from: 0, to: 8} + } + }); + + [true, null, undefined, 57, [], {}, new Date()].forEach(function (phrase) { + expect(() => Type.serialize({phrase: phrase})).to.throw(TypeError) + }) + }) + }) +})