diff --git a/README.md b/README.md index 4f923e7..4df97ff 100644 --- a/README.md +++ b/README.md @@ -97,11 +97,10 @@ there must be a strict serialization rules. This rules are formed by the data st ```javascript let type = Exonum.newType({ - size: 12, - fields: { - balance: {type: Exonum.Uint32, size: 4, from: 0, to: 4}, - name: {type: Exonum.String, size: 8, from: 4, to: 12} - } + fields: [ + { name: 'balance', type: Exonum.Uint32 }, + { name: 'name', type: Exonum.String } + ] }) ``` @@ -109,40 +108,37 @@ let type = Exonum.newType({ | Property | Description | Type | |---|---|---| -| **size** | The total length in bytes. | `Number` | -| **fields** | List of fields. | `Object` | +| **fields** | List of fields. | `Array` | Field structure: | Field | Description | Type | |---|---|---| -| **type** | Definition of the field type. | [Built-in type](#built-in-types), [array](#arrays) or [custom data type](#nested-data-types) defined by the developer. | -| **size** | Total length of the field in bytes. | `Number` | -| **from** | The beginning of the field segment in the byte array. | `Number` | -| **to** | The end of the field segment in the byte array. | `Number` | +| **name** | Field name. | `String` | +| **type** | Definition of the field type. | [Built-in type](#built-in-types), [array](#arrays) or [custom data type](#nested-data-types) defined by the developer. | ### Built-in types There are several primitive types are built it into the library. These types must be used when constructing custom data types. -| Name | Size | Description | Type | -|---|---|---|---| -| **Int8** | 1 | Number in a range from `-128` to `127`. | `Number` | -| **Int16** | 2 | Number in a range from `-32768` to `32767`. | `Number` | -| **Int32** | 4 | Number in a range from `-2147483648` to `2147483647`. | `Number` | -| **Int64** | 8 | Number in a range from `-9223372036854775808` to `9223372036854775807`. | `Number` or `String`\* | -| **Uint8** | 1 | Number in a range from `0` to `255`. | `Number` | -| **Uint16** | 2 | Number in a range from `0` to `65535`. | `Number` | -| **Uint32** | 4 | Number in a range from `0` to `4294967295`. | `Number` | -| **Uint64** | 8 | Number in a range from `0` to `18446744073709551615`. | `Number` or `String`\* | -| **Float32** | 4 | Floating point number in a range from `-3.40282347e+38f32` to `3.40282347e+38f32`. | `Number` or `String`\* | -| **Float64** | 8 | Floating point number in a range from `-1.7976931348623157e+308f64` to `1.7976931348623157e+308f64`. | `Number` or `String`\* | -| **String** | 8\*\* | A string of variable length consisting of UTF-8 characters. | `String` | -| **Hash** | 32 | Hexadecimal string. | `String` | -| **PublicKey** | 32 | Hexadecimal string. | `String` | -| **Digest** | 64 | Hexadecimal string. | `String` | -| **Bool** | 1 | Value of boolean type. | `Boolean` | +| Name | Description | Type | +|---|---|---| +| **Int8** | Number in a range from `-128` to `127`. | `Number` | +| **Int16** | Number in a range from `-32768` to `32767`. | `Number` | +| **Int32** | Number in a range from `-2147483648` to `2147483647`. | `Number` | +| **Int64** | Number in a range from `-9223372036854775808` to `9223372036854775807`. | `Number` or `String`\* | +| **Uint8** | Number in a range from `0` to `255`. | `Number` | +| **Uint16** | Number in a range from `0` to `65535`. | `Number` | +| **Uint32** | Number in a range from `0` to `4294967295`. | `Number` | +| **Uint64** | Number in a range from `0` to `18446744073709551615`. | `Number` or `String`\* | +| **Float32** | Floating point number in a range from `-3.40282347e+38f32` to `3.40282347e+38f32`. | `Number` or `String`\* | +| **Float64** | Floating point number in a range from `-1.7976931348623157e+308f64` to `1.7976931348623157e+308f64`. | `Number` or `String`\* | +| **String** | A string of variable length consisting of UTF-8 characters. | `String` | +| **Hash** | Hexadecimal string. | `String` | +| **PublicKey** | Hexadecimal string. | `String` | +| **Digest** | Hexadecimal string. | `String` | +| **Bool** | Value of boolean type. | `Boolean` | *\*JavaScript limits minimum and maximum integer number. Minimum safe integer in JavaScript is `-(2^53-1)` which is equal to `-9007199254740991`. @@ -151,38 +147,28 @@ For unsafe numbers out of the safe range use `String` only. To determine either number is safe use built-in JavaScript function [Number.isSafeInteger()][is-safe-integer].* -*\*\*Size of 8 bytes is due to the specifics of string [serialization][docs:architecture:serialization:segment-pointers] -using segment pointers. -Actual string length is limited only by the general message size limits which is depends on OS, browser and -hardware configuration.* - ### Nested data types Custom data type defined by the developer can be a field of other custom data type. -A nested type, regardless of its real size, always takes **8 bytes** in the parent type due to the specifics of its -[serialization][docs:architecture:serialization:segment-pointers] using segment pointers. - An example of a nested type: ```javascript // Define a nested data type let date = Exonum.newType({ - size: 4, - fields: { - day: {type: Exonum.Uint8, size: 1, from: 0, to: 1}, - month: {type: Exonum.Uint8, size: 1, from: 1, to: 2}, - year: {type: Exonum.Uint16, size: 2, from: 2, to: 4} - } + fields: [ + { name: 'day', type: Exonum.Uint8 }, + { name: 'month', type: Exonum.Uint8 }, + { name: 'year', type: Exonum.Uint16 } + ] }) // Define a data type let payment = Exonum.newType({ - size: 16, - fields: { - date: {type: date, size: 8, from: 0, to: 8}, - amount: {type: Exonum.Uint64, size: 8, from: 8, to: 16} - } + fields: [ + { name: 'date', type: date }, + { name: 'amount', type: Exonum.Uint64 } + ] }) ``` @@ -197,27 +183,21 @@ in the Rust language. | Property | Description | Type | |---|---|---| -| **size** | Length of the nested field type. | `Number` | | **type** | Definition of the field type. | [Built-in type](#built-in-types), array or [custom data type](#nested-data-types) defined by the developer. | -An array, regardless of its real size, always takes **8 bytes** in the parent type due to the specifics of its -[serialization][docs:architecture:serialization:segment-pointers] using segment pointers. - An example of an array type field: ```javascript // Define an array let year = Exonum.newArray({ - size: 2, type: Exonum.Uint16 }) // Define a data type let type = Exonum.newType({ - size: 8, - fields: { - years: {type: year, size: 8, from: 0, to: 8} - } + fields: [ + { name: 'years', type: year } + ] }) ``` @@ -226,22 +206,19 @@ An example of an array nested in an array: ```javascript // Define an array let distance = Exonum.newArray({ - size: 4, type: Exonum.Uint32 }) // Define an array with child elements of an array type let distances = Exonum.newArray({ - size: 8, type: distance }) // Define a data type let type = Exonum.newType({ - size: 8, - fields: { - measurements: {type: distances, size: 8, from: 0, to: 8} - } + fields: [ + { name: 'measurements', type: distances } + ] }) ``` @@ -268,13 +245,12 @@ An example of serialization into a byte array: ```javascript // Define a data type let user = Exonum.newType({ - size: 21, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16}, - age: {type: Exonum.Uint8, size: 1, from: 16, to: 17}, - balance: {type: Exonum.Uint32, size: 4, from: 17, to: 21} - } + fields: [ + { name: 'firstName', type: Exonum.String }, + { name: 'lastName', type: Exonum.String }, + { name: 'age', type: Exonum.Uint8 }, + { name: 'balance', type: Exonum.Uint32 } + ] }) // Data to be serialized @@ -319,13 +295,12 @@ An example of hash calculation: ```javascript // Define a data type let user = Exonum.newType({ - size: 21, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16}, - age: {type: Exonum.Uint8, size: 1, from: 16, to: 17}, - balance: {type: Exonum.Uint32, size: 4, from: 17, to: 21} - } + fields: [ + { name: 'firstName', type: Exonum.String }, + { name: 'lastName', type: Exonum.String }, + { name: 'age', type: Exonum.Uint8 }, + { name: 'balance', type: Exonum.Uint32 } + ] }) // Data that has been hashed @@ -399,13 +374,12 @@ An example of data signing: ```javascript // Define a data type let user = Exonum.newType({ - size: 21, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16}, - age: {type: Exonum.Uint8, size: 1, from: 16, to: 17}, - balance: {type: Exonum.Uint32, size: 4, from: 17, to: 21} - } + fields: [ + { name: 'firstName', type: Exonum.String }, + { name: 'lastName', type: Exonum.String }, + { name: 'age', type: Exonum.Uint8 }, + { name: 'balance', type: Exonum.Uint32 } + ] }) // Data to be signed @@ -453,13 +427,12 @@ An example of signature verification: ```javascript // Define a data type let user = Exonum.newType({ - size: 21, - fields: { - firstName: {type: Exonum.String, size: 8, from: 0, to: 8}, - lastName: {type: Exonum.String, size: 8, from: 8, to: 16}, - age: {type: Exonum.Uint8, size: 1, from: 16, to: 17}, - balance: {type: Exonum.Uint32, size: 4, from: 17, to: 21} - } + fields: [ + { name: 'firstName', type: Exonum.String }, + { name: 'lastName', type: Exonum.String }, + { name: 'age', type: Exonum.Uint8 }, + { name: 'balance', type: Exonum.Uint32 } + ] }) // Data that has been signed @@ -503,12 +476,11 @@ let sendFunds = Exonum.newMessage({ protocol_version: 0, service_id: 130, message_id: 128, - size: 72, - 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} - } + fields: [ + { name: 'from', type: Exonum.Hash }, + { name: 'to', type: Exonum.Hash }, + { name: 'amount', type: Exonum.Uint64 } + ] }) ``` @@ -521,8 +493,7 @@ let sendFunds = Exonum.newMessage({ | **service_id** | [Service ID][docs:architecture:serialization:service-id]. | `Number` | | **message_id** | [Message ID][docs:architecture:serialization:message-id]. | `Number` | | **signature** | Signature as hexadecimal string. *Optional.* | `String` | -| **size** | The total length in bytes. | `Number` | -| **fields** | List of fields. | `Object` | +| **fields** | List of fields. | `Array` | Field structure is identical to field structure of [custom data type](#define-data-type). @@ -713,7 +684,6 @@ Exonum Client is licensed under the Apache License (Version 2.0). See [LICENSE]( [docs:clients]: https://exonum.com/doc/architecture/clients [docs:architecture:services]: https://exonum.com/doc/architecture/services [docs:architecture:serialization]: https://exonum.com/doc/architecture/serialization -[docs:architecture:serialization:segment-pointers]: https://exonum.com/doc/architecture/serialization/#segment-pointers [docs:architecture:serialization:network-id]: https://exonum.com/doc/architecture/serialization/#etwork-id [docs:architecture:serialization:protocol-version]: https://exonum.com/doc/architecture/serialization/#protocol-version [docs:architecture:serialization:service-id]: https://exonum.com/doc/architecture/serialization/#service-id diff --git a/package-lock.json b/package-lock.json index d8d33ca..395979d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "exonum-client", - "version": "0.5.0", + "version": "0.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 9a05902..eb9315c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "exonum-client", - "version": "0.5.0", + "version": "0.6.0", "description": "Light Client for Exonum Blockchain", "main": "./lib/index.js", "engines": { diff --git a/src/blockchain/block.js b/src/blockchain/block.js index 1ea2b03..0c63441 100644 --- a/src/blockchain/block.js +++ b/src/blockchain/block.js @@ -9,23 +9,21 @@ 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 } - } + fields: [ + { name: 'schema_version', type: primitive.Uint16 }, + { name: 'proposer_id', type: primitive.Uint16 }, + { name: 'height', type: primitive.Uint64 }, + { name: 'tx_count', type: primitive.Uint32 }, + { name: 'prev_hash', type: primitive.Hash }, + { name: 'tx_hash', type: primitive.Hash }, + { name: 'state_hash', type: primitive.Hash } + ] }) 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 } - } + fields: [ + { name: 'secs', type: primitive.Uint64 }, + { name: 'nanos', type: primitive.Uint32 } + ] }) /** @@ -63,19 +61,18 @@ export function verifyBlock (data, validators, networkId) { } const 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 } - } + fields: [ + { name: 'validator', type: primitive.Uint16 }, + { name: 'height', type: primitive.Uint64 }, + { name: 'round', type: primitive.Uint32 }, + { name: 'propose_hash', type: primitive.Hash }, + { name: 'block_hash', type: primitive.Hash }, + { name: 'time', type: SystemTime } + ] }) const validatorsTotalNumber = validators.length diff --git a/src/blockchain/merkle-patricia.js b/src/blockchain/merkle-patricia.js index f360370..e3e5008 100644 --- a/src/blockchain/merkle-patricia.js +++ b/src/blockchain/merkle-patricia.js @@ -17,28 +17,25 @@ const MERKLE_PATRICIA_KEY_LENGTH = 32 */ export function merklePatriciaProof (rootHash, proofNode, key, type) { const 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 } - } + fields: [ + { name: 'variant', type: primitive.Uint8 }, + { name: 'key', type: primitive.Hash }, + { name: 'length', type: primitive.Uint8 } + ] }) const 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 } - } + fields: [ + { name: 'left_hash', type: primitive.Hash }, + { name: 'right_hash', type: primitive.Hash }, + { name: 'left_key', type: DBKey }, + { name: 'right_key', type: DBKey } + ] }) const RootBranch = newType({ - size: 66, - fields: { - key: { type: DBKey, size: 34, from: 0, to: 34 }, - hash: { type: primitive.Hash, size: 32, from: 34, to: 66 } - } + fields: [ + { name: 'key', type: DBKey }, + { name: 'hash', type: primitive.Hash } + ] }) /** diff --git a/src/types/array.js b/src/types/array.js index 4feab25..9184b0a 100644 --- a/src/types/array.js +++ b/src/types/array.js @@ -7,7 +7,10 @@ import * as serialization from './serialization' class NewArray { constructor (type) { this.type = type.type - this.size = type.size + } + + size () { + return 8 } /** diff --git a/src/types/generic.js b/src/types/generic.js index 27e5086..0024a00 100644 --- a/src/types/generic.js +++ b/src/types/generic.js @@ -1,5 +1,6 @@ import * as serialization from './serialization' import * as crypto from '../crypto' +import { String } from './primitive' /** * @constructor @@ -7,10 +8,28 @@ import * as crypto from '../crypto' */ class NewType { constructor (type) { - this.size = type.size + type.fields.forEach(field => { + if (field.name === undefined) { + throw new TypeError('Name prop is missed.') + } + if (field.type === undefined) { + throw new TypeError('Type prop is missed.') + } + }) + this.fields = type.fields } + size () { + return this.fields.reduce((accumulator, field) => { + if (fieldIsFixed(field)) { + return accumulator + field.type.size() + } else { + return accumulator + 8 + } + }, 0) + } + /** * Serialize data of NewType type into array of 8-bit integers * @param {Object} data @@ -68,3 +87,34 @@ export function newType (type) { export function isInstanceofOfNewType (type) { return type instanceof NewType } + +/** + * Check if field is of fixed-length type. Fixed-length means field serialized (inserted) directly into buffer without pointer + * @param {Object} field + * @returns {boolean} + */ +export function fieldIsFixed (field) { + if (isInstanceofOfNewType(field.type)) { + return newTypeIsFixed(field.type) + } else if (field.type === String) { + return false + } + return true +} + +/** + * Check if all nested fields are of fixed-length type + * @param {Object} type + * @returns {boolean} + */ +export function newTypeIsFixed (type) { + let areFixed = true + + type.fields.forEach(field => { + if (!fieldIsFixed(field)) { + areFixed = false + } + }) + + return areFixed +} diff --git a/src/types/message.js b/src/types/message.js index 491f12c..2dd6745 100644 --- a/src/types/message.js +++ b/src/types/message.js @@ -1,5 +1,5 @@ import * as primitive from './primitive' -import { newType } from './generic' +import { fieldIsFixed, newType } from './generic' import * as serialization from './serialization' import * as crypto from '../crypto' @@ -11,7 +11,15 @@ const SIGNATURE_LENGTH = 64 */ class NewMessage { constructor (type) { - this.size = type.size + type.fields.forEach(field => { + if (field.name === undefined) { + throw new TypeError('Name prop is missed.') + } + if (field.type === undefined) { + throw new TypeError('Type prop is missed.') + } + }) + this.network_id = type.network_id this.protocol_version = type.protocol_version this.message_id = type.message_id @@ -20,6 +28,16 @@ class NewMessage { this.fields = type.fields } + size () { + return this.fields.reduce((accumulator, field) => { + if (fieldIsFixed(field)) { + return accumulator + field.type.size() + } else { + return accumulator + 8 + } + }, 0) + } + /** * Serialize data of NewMessage type into array of 8-bit integers * @param {Object} data @@ -28,14 +46,13 @@ class NewMessage { */ serialize (data, cutSignature) { const 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 } - } + fields: [ + { name: 'network_id', type: primitive.Uint8 }, + { name: 'protocol_version', type: primitive.Uint8 }, + { name: 'message_id', type: primitive.Uint16 }, + { name: 'service_id', type: primitive.Uint16 }, + { name: 'payload', type: primitive.Uint32 } + ] }) let buffer = MessageHead.serialize({ @@ -47,14 +64,14 @@ class NewMessage { }) // serialize and append message body - buffer = serialization.serialize(buffer, MessageHead.size, data, this, true) + buffer = serialization.serialize(buffer, 10, data, this, true) // calculate payload and insert it into buffer - primitive.Uint32(buffer.length + SIGNATURE_LENGTH, buffer, MessageHead.fields.payload.from, MessageHead.fields.payload.to) + primitive.Uint32.serialize(buffer.length + SIGNATURE_LENGTH, buffer, 6) if (cutSignature !== true) { // append signature - primitive.Digest(this.signature, buffer, buffer.length, buffer.length + SIGNATURE_LENGTH) + primitive.Digest.serialize(this.signature, buffer, buffer.length) } return buffer diff --git a/src/types/primitive.js b/src/types/primitive.js index b419c92..4b9fddf 100644 --- a/src/types/primitive.js +++ b/src/types/primitive.js @@ -19,16 +19,11 @@ const MAX_UINT64 = '18446744073709551615' * @param {string} str * @param {Array} buffer * @param {number} from - * @param {number} to */ -function insertHexadecimalToByteArray (str, buffer, from, to) { +function insertHexadecimalToByteArray (str, buffer, from) { for (let i = 0; i < str.length; i += 2) { buffer[from] = parseInt(str.substr(i, 2), 16) from++ - - if (from > to) { - break - } } return buffer } @@ -38,15 +33,15 @@ function insertHexadecimalToByteArray (str, buffer, from, to) { * @param {number|bigInt} number * @param {Array} buffer * @param {number} from - * @param {number} to + * @param {number} size * @returns {boolean} */ -function insertIntegerToByteArray (number, buffer, from, to) { +function insertIntegerToByteArray (number, buffer, from, size) { let value = bigInt(number) // convert a number-like object into a big integer - for (let pos = from; pos < to; pos++) { + for (let pos = 0; pos < size; pos++) { const divmod = value.divmod(256) - buffer[pos] = divmod.remainder.value + buffer[from + pos] = divmod.remainder.value value = divmod.quotient } @@ -97,286 +92,350 @@ function insertStringToByteArray (str, buffer, from) { } } -/** - * @param {number} value - * @param {Array} buffer - * @param {number} 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 class Int8 { + static size () { + return 1 } - if (value < 0) { - value = MAX_UINT8 + value + 1 - } + /** + * @param {number} value + * @param {Array} buffer + * @param {number} from + * @returns {Array} + */ + static serialize (value, buffer, from) { + if (!validate.validateInteger(value, MIN_INT8, MAX_INT8, from, this.size())) { + throw new TypeError('Int8 of wrong type is passed: ' + value) + } - return insertIntegerToByteArray(value, buffer, from, to) -} + if (value < 0) { + value = MAX_UINT8 + value + 1 + } -/** - * @param {number} value - * @param {Array} buffer - * @param {number} from - * @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) + return insertIntegerToByteArray(value, buffer, from, this.size()) } +} - if (value < 0) { - value = MAX_UINT16 + value + 1 +export class Int16 { + static size () { + return 2 } - return insertIntegerToByteArray(value, buffer, from, to) -} + /** + * @param {number} value + * @param {Array} buffer + * @param {number} from + * @returns {Array} + */ + static serialize (value, buffer, from) { + if (!validate.validateInteger(value, MIN_INT16, MAX_INT16, from, this.size())) { + throw new TypeError('Int16 of wrong type is passed: ' + value) + } -/** - * @param {number} value - * @param {Array} buffer - * @param {number} from - * @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) + if (value < 0) { + value = MAX_UINT16 + value + 1 + } + + return insertIntegerToByteArray(value, buffer, from, this.size()) } +} - if (value < 0) { - value = MAX_UINT32 + value + 1 +export class Int32 { + static size () { + return 4 } - return insertIntegerToByteArray(value, buffer, from, to) + /** + * @param {number} value + * @param {Array} buffer + * @param {number} from + * @returns {Array} + */ + static serialize (value, buffer, from) { + if (!validate.validateInteger(value, MIN_INT32, MAX_INT32, from, this.size())) { + throw new TypeError('Int32 of wrong type is passed: ' + value) + } + + if (value < 0) { + value = MAX_UINT32 + value + 1 + } + + return insertIntegerToByteArray(value, buffer, from, this.size()) + } } -/** - * @param {number|string} value - * @param {Array} buffer - * @param {number} from - * @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 class Int64 { + static size () { + return 8 } - let val = bigInt(value) + /** + * @param {number|string} value + * @param {Array} buffer + * @param {number} from + * @returns {Array} + */ + static serialize (value, buffer, from) { + if (!validate.validateBigInteger(value, MIN_INT64, MAX_INT64, from, this.size())) { + throw new TypeError('Int64 of wrong type is passed: ' + value) + } - if (val.isNegative()) { - val = bigInt(MAX_UINT64).plus(1).plus(val) - } + let val = bigInt(value) - return insertIntegerToByteArray(val, buffer, from, to) + if (val.isNegative()) { + val = bigInt(MAX_UINT64).plus(1).plus(val) + } + + return insertIntegerToByteArray(val, buffer, from, this.size()) + } } -/** - * @param {number} value - * @param {Array} buffer - * @param {number} from - * @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 class Uint8 { + static size () { + return 1 } - return insertIntegerToByteArray(value, buffer, from, to) + /** + * @param {number} value + * @param {Array} buffer + * @param {number} from + * @returns {Array} + */ + static serialize (value, buffer, from) { + if (!validate.validateInteger(value, 0, MAX_UINT8, from, this.size())) { + throw new TypeError('Uint8 of wrong type is passed: ' + value) + } + + return insertIntegerToByteArray(value, buffer, from, this.size()) + } } -/** - * @param {number} value - * @param {Array} buffer - * @param {number} from - * @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 class Uint16 { + static size () { + return 2 } - return insertIntegerToByteArray(value, buffer, from, to) + /** + * @param {number} value + * @param {Array} buffer + * @param {number} from + * @returns {Array} + */ + static serialize (value, buffer, from) { + if (!validate.validateInteger(value, 0, MAX_UINT16, from, this.size())) { + throw new TypeError('Uint16 of wrong type is passed: ' + value) + } + + return insertIntegerToByteArray(value, buffer, from, this.size()) + } } -/** - * @param {number} value - * @param {Array} buffer - * @param {number} from - * @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 class Uint32 { + static size () { + return 4 } - return insertIntegerToByteArray(value, buffer, from, to) + /** + * @param {number} value + * @param {Array} buffer + * @param {number} from + * @returns {Array} + */ + static serialize (value, buffer, from) { + if (!validate.validateInteger(value, 0, MAX_UINT32, from, this.size())) { + throw new TypeError('Uint32 of wrong type is passed: ' + value) + } + + return insertIntegerToByteArray(value, buffer, from, this.size()) + } } -/** - * @param {number|string} value - * @param {Array} buffer - * @param {number} from - * @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 class Uint64 { + static size () { + return 8 } - const val = bigInt(value) + /** + * @param {number|string} value + * @param {Array} buffer + * @param {number} from + * @returns {Array} + */ + static serialize (value, buffer, from) { + if (!validate.validateBigInteger(value, 0, MAX_UINT64, from, this.size())) { + throw new TypeError('Uint64 of wrong type is passed: ' + value) + } + + const val = bigInt(value) - return insertIntegerToByteArray(val, buffer, from, to) + return insertIntegerToByteArray(val, buffer, from, this.size()) + } } -/** - * @param {number} value - * @param {Array} buffer - * @param {number} from - * @param {number} to - * @returns {Array} - */ -export function Float32 (value, buffer, from, to) { - if (!validate.validateFloat(value, from, to, 4)) { - throw new TypeError('Float32 of wrong type is passed: ' + value) +export class Float32 { + static size () { + return 4 } - return insertFloatToByteArray(value, buffer, from, 23, 4) + /** + * @param {string} value + * @param {Array} buffer + * @param {number} from + * @returns {Array} + */ + static serialize (value, buffer, from) { + if (!validate.validateFloat(value, from, this.size())) { + throw new TypeError('Float32 of wrong type is passed: ' + value) + } + + return insertFloatToByteArray(value, buffer, from, 23, this.size()) + } } -/** - * @param {number} value - * @param {Array} buffer - * @param {number} from - * @param {number} to - * @returns {Array} - */ -export function Float64 (value, buffer, from, to) { - if (!validate.validateFloat(value, from, to, 8)) { - throw new TypeError('Float64 of wrong type is passed: ' + value) +export class Float64 { + static size () { + return 8 } - return insertFloatToByteArray(value, buffer, from, 52, 8) + /** + * @param {string} value + * @param {Array} buffer + * @param {number} from + * @returns {Array} + */ + static serialize (value, buffer, from) { + if (!validate.validateFloat(value, from, this.size())) { + throw new TypeError('Float64 of wrong type is passed: ' + value) + } + + return insertFloatToByteArray(value, buffer, from, 52, this.size()) + } } -/** - * @param {string} string - * @param {Array} buffer - * @param {number} from - * @param {number} to - * @param {number} relativeFromIndex - * @returns {Array} - */ -export function String (string, buffer, from, to, relativeFromIndex) { - 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.') +export class String { + static size () { + return 8 } - const bufferLength = buffer.length - Uint32(relativeFromIndex, 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 + /** + * @param {string} string + * @param {Array} buffer + * @param {number} from + * @param {number} relativeFromIndex + * @returns {Array} + */ + static serialize (string, buffer, from, relativeFromIndex) { + if (typeof string !== 'string') { + throw new TypeError('Wrong data type is passed as String. String is required') + } - return buffer -} + const bufferLength = buffer.length + Uint32.serialize(relativeFromIndex, buffer, from) // index where string content starts in buffer + insertStringToByteArray(string, buffer, bufferLength) // string content + Uint32.serialize(buffer.length - bufferLength, buffer, from + 4) // string length -/** - * @param {string} hash - * @param {Array} buffer - * @param {number} from - * @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) + return buffer } +} - if ((to - from) !== 32) { - throw new Error('Hash segment is of wrong length. 32 bytes long is required to store transmitted value.') +export class Hash { + static size () { + return 32 } - return insertHexadecimalToByteArray(hash, buffer, from, to) -} + /** + * @param {string} value + * @param {Array} buffer + * @param {number} from + * @returns {Array} + */ + static serialize (value, buffer, from) { + if (!validate.validateHexadecimal(value)) { + throw new TypeError('Hash of wrong type is passed: ' + value) + } -/** - * @param {string} digest - * @param {Array} buffer - * @param {number} from - * @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) + return insertHexadecimalToByteArray(value, buffer, from) } +} - if ((to - from) !== 64) { - throw new Error('Digest segment is of wrong length. 64 bytes long is required to store transmitted value.') +export class Digest { + static size () { + return 64 } - return insertHexadecimalToByteArray(digest, buffer, from, to) -} + /** + * @param {string} value + * @param {Array} buffer + * @param {number} from + * @returns {Array} + */ + static serialize (value, buffer, from) { + if (!validate.validateHexadecimal(value, this.size())) { + throw new TypeError('Digest of wrong type is passed: ' + value) + } -/** - * @param {string} publicKey - * @param {Array} buffer - * @param {number} from - * @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) + return insertHexadecimalToByteArray(value, buffer, from) } +} - if ((to - from) !== 32) { - throw new Error('PublicKey segment is of wrong length. 32 bytes long is required to store transmitted value.') +export class PublicKey { + static size () { + return 32 } - return insertHexadecimalToByteArray(publicKey, buffer, from, to) + /** + * @param {string} value + * @param {Array} buffer + * @param {number} from + * @returns {Array} + */ + static serialize (value, buffer, from) { + if (!validate.validateHexadecimal(value)) { + throw new TypeError('PublicKey of wrong type is passed: ' + value) + } + + return insertHexadecimalToByteArray(value, buffer, from) + } } -/** - * @param {boolean} value - * @param {Array} buffer - * @param {number} from - * @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 class Bool { + static size () { + return 1 } - return insertIntegerToByteArray(value ? 1 : 0, buffer, from, to) + /** + * @param {boolean} value + * @param {Array} buffer + * @param {number} from + * @returns {Array} + */ + static serialize (value, buffer, from) { + if (typeof value !== 'boolean') { + throw new TypeError('Wrong data type is passed as Boolean. Boolean is required') + } + + return insertIntegerToByteArray(value ? 1 : 0, buffer, from, this.size()) + } } +export class Timespec { + static size () { + return 8 + } + /** * @param {number|string} nanoseconds * @param {Array} buffer * @param {number} from - * @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) - } + static serialize (nanoseconds, buffer, from) { + if (!validate.validateBigInteger(nanoseconds, 0, MAX_UINT64, from, this.size())) { + throw new TypeError('Timespec of wrong type is passed: ' + nanoseconds) + } - const val = bigInt(nanoseconds) + const val = bigInt(nanoseconds) - return insertIntegerToByteArray(val, buffer, from, to) + return insertIntegerToByteArray(val, buffer, from, this.size()) + } } diff --git a/src/types/serialization.js b/src/types/serialization.js index 7cc207a..c8810d9 100644 --- a/src/types/serialization.js +++ b/src/types/serialization.js @@ -1,4 +1,4 @@ -import { isInstanceofOfNewType } from './generic' +import { isInstanceofOfNewType, newTypeIsFixed, fieldIsFixed } from './generic' import { isInstanceofOfNewArray } from './array' import { Uint32, String } from './primitive' @@ -12,34 +12,6 @@ import { Uint32, String } from './primitive' * @returns {Array} */ export function serialize (buffer, shift, data, type, isTransactionBody) { - /** - * Check if field is of fixed-length type. Fixed-length means field serialized (inserted) directly into buffer without pointer - * @param {Object} field - * @returns {boolean} - */ - function fieldIsFixed (field) { - if (isInstanceofOfNewType(field.type)) { - return fieldsAreFixed(field.type.fields) - } else if (field.type === String) { - return false - } - return true - } - - /** - * Check if all fields are of fixed-length type - * @param {Array} fields - * @returns {boolean} - */ - function fieldsAreFixed (fields) { - for (let fieldName in fields) { - if (!fieldIsFixed(fields[fieldName])) { - return false - } - } - return true - } - /** * Serialize instanceof of NewType * @param {Array} buffer @@ -50,13 +22,13 @@ export function serialize (buffer, shift, data, type, isTransactionBody) { * @returns {Array} */ function serializeInstanceofOfNewType (buffer, shift, from, data, type) { - if (fieldsAreFixed(type.fields)) { + if (newTypeIsFixed(type)) { buffer = serialize(buffer, from, data, type) } else { const end = buffer.length - Uint32(end - shift, buffer, from, from + 4) // start index + Uint32.serialize(end - shift, buffer, from) // start index buffer = serialize(buffer, end, data, type) - Uint32(buffer.length - end, buffer, from + 4, from + 8) // length + Uint32.serialize(buffer.length - end, buffer, from + 4) // length } return buffer @@ -76,8 +48,8 @@ export function serialize (buffer, shift, data, type, isTransactionBody) { throw new TypeError('Data of wrong type is passed. Array expected.') } - Uint32(buffer.length, buffer, from, from + 4) // start index - Uint32(data.length, buffer, from + 4, from + 8) // array length + Uint32.serialize(buffer.length, buffer, from) // start index + Uint32.serialize(data.length, buffer, from + 4) // array length if (isInstanceofOfNewType(type.type)) { const start = buffer.length @@ -91,9 +63,9 @@ export function serialize (buffer, shift, data, type, isTransactionBody) { const index = start + i * 8 const end = buffer.length - Uint32(end - shift, buffer, index, index + 4) // start index + Uint32.serialize(end - shift, buffer, index) // start index buffer = serialize(buffer, end, data[i], type.type) - Uint32(buffer.length - end, buffer, index + 4, index + 8) // length + Uint32.serialize(buffer.length - end, buffer, index + 4) // length } } else if (isInstanceofOfNewArray(type.type)) { const start = buffer.length @@ -112,36 +84,45 @@ export function serialize (buffer, shift, data, type, isTransactionBody) { throw new TypeError('Array of String types is not supported.') } else { for (let item of data) { - buffer = type.type(item, buffer, buffer.length, buffer.length + type.size) + buffer = type.type.serialize(item, buffer, buffer.length, buffer.length + type.type.size()) } } return buffer } - for (let i = 0; i < type.size; i++) { + // reserve array cells + for (let i = 0; i < type.size(); i++) { buffer[shift + i] = 0 } - for (let fieldName in type.fields) { - const fieldData = data[fieldName] + let localShift = 0 + type.fields.forEach(field => { + const value = data[field.name] - if (fieldData === undefined) { - throw new TypeError('Field ' + fieldName + ' is not defined.') + if (value === undefined) { + throw new TypeError('Field ' + field.name + ' is not defined.') } - const fieldType = type.fields[fieldName] - const from = shift + fieldType.from - const fieldShift = (isTransactionBody === true) ? 0 : shift + const from = shift + localShift - if (isInstanceofOfNewType(fieldType.type)) { - buffer = serializeInstanceofOfNewType(buffer, fieldShift, from, fieldData, fieldType.type) - } else if (isInstanceofOfNewArray(fieldType.type)) { - buffer = serializeInstanceofOfNewArray(buffer, fieldShift, from, fieldData, fieldType.type) + const nestedShift = (isTransactionBody === true) ? 0 : shift + + if (isInstanceofOfNewType(field.type)) { + buffer = serializeInstanceofOfNewType(buffer, nestedShift, from, value, field.type) + if (fieldIsFixed(field)) { + localShift += field.type.size() + } else { + localShift += 8 + } + } else if (isInstanceofOfNewArray(field.type)) { + buffer = serializeInstanceofOfNewArray(buffer, nestedShift, from, value, field.type) + localShift += field.type.size() } else { - buffer = fieldType.type(fieldData, buffer, from, shift + fieldType.to, buffer.length - fieldShift) + buffer = field.type.serialize(value, buffer, from, buffer.length - nestedShift) + localShift += field.type.size() } - } + }) return buffer } diff --git a/src/types/validate.js b/src/types/validate.js index 27446c7..f672d18 100644 --- a/src/types/validate.js +++ b/src/types/validate.js @@ -5,16 +5,12 @@ import bigInt from 'big-integer' * @param {number} min * @param {number} max * @param {number} from - * @param {number} to * @param {number} length * @returns {boolean} */ -export function validateInteger (value, min, max, from, to, length) { +export function validateInteger (value, min, max, from, length) { if (typeof value !== 'number' || value < min || value > max) { return false - } else if ((to - from) !== length) { - // segment is of wrong length - return false } return true @@ -25,17 +21,14 @@ export function validateInteger (value, min, max, from, to, length) { * @param {number} min * @param {number} max * @param {number} from - * @param {number} to * @param {number} length * @returns {*} */ -export function validateBigInteger (value, min, max, from, to, length) { +export function validateBigInteger (value, min, max, from, length) { if (!(typeof value === 'number' || typeof value === 'string')) { return false - } else if ((to - from) !== length) { - // segment is of wrong length - return false } + let val try { val = bigInt(value) @@ -53,17 +46,13 @@ export function validateBigInteger (value, min, max, from, to, length) { /** * @param {number} value * @param {number} from - * @param {number} to * @param {number} length * @returns {boolean} */ -export function validateFloat (value, from, to, length) { +export function validateFloat (value, from, length) { if (typeof value !== 'number' && typeof value !== 'string') { // wrong type return false - } else if ((to - from) !== length) { - // segment is of wrong length - return false } return true diff --git a/test/common_data/serialization/cryptography-config.json b/test/common_data/serialization/cryptography-config.json index eec2b79..696a076 100644 --- a/test/common_data/serialization/cryptography-config.json +++ b/test/common_data/serialization/cryptography-config.json @@ -1,261 +1,188 @@ { "type1": { - "size": 80, - "fields": { - "pub_key": { - "type": "PublicKey", - "size": 32, - "from": 0, - "to": 32 - }, - "name": { - "type": "String", - "size": 8, - "from": 32, - "to": 40 - }, - "balance": { - "type": "Uint64", - "size": 8, - "from": 40, - "to": 48 - }, - "history_hash": { - "type": "Hash", - "size": 32, - "from": 48, - "to": 80 + "fields": [ + { + "name": "pub_key", + "type": "PublicKey" + }, + { + "name": "name", + "type": "String" + }, + { + "name": "balance", + "type": "Uint64" + }, + { + "name": "history_hash", + "type": "Hash" } - } + ] }, "type2": { - "size": 80, - "fields": { - "pub_key": { - "type": "PublicKey", - "size": 32, - "from": 0, - "to": 32 - }, - "name": { - "type": "String", - "size": 8, - "from": 32, - "to": 40 - }, - "balance": { - "type": "Uint64", - "size": 8, - "from": 40, - "to": 48 - }, - "history_hash": { - "type": "Hash", - "size": 32, - "from": 48, - "to": 80 + "fields": [ + { + "name": "pub_key", + "type": "PublicKey" + }, + { + "name": "name", + "type": "String" + }, + { + "name": "balance", + "type": "Uint64" + }, + { + "name": "history_hash", + "type": "Hash" } - } + ] }, "type3": { "as": "message", - "size": 18, "network_id": 0, "protocol_version": 0, "service_id": 1, "message_id": 2, - "fields": { - "name": { - "type": "String", - "size": 8, - "from": 0, - "to": 8 - }, - "age": { - "type": "Uint8", - "size": 1, - "from": 8, - "to": 9 - }, - "balance": { - "type": "Uint64", - "size": 8, - "from": 9, - "to": 17 - }, - "status": { - "type": "Bool", - "size": 1, - "from": 17, - "to": 18 + "fields": [ + { + "name": "name", + "type": "String" + }, + { + "name": "age", + "type": "Uint8" + }, + { + "name": "balance", + "type": "Uint64" + }, + { + "name": "status", + "type": "Bool" } - }, + ], "signature": "dad76b4c3b067d53265534bde4d9ff59987d00f87e0e1a633613576195a4cbc1e0a43a58c67c34c98019f791812699d010655c4eccec448e46e5524471a8c401" }, "type4": { "as": "message", - "size": 18, "network_id": 0, "protocol_version": 0, "service_id": 1, "message_id": 2, - "fields": { - "name": { - "type": "String", - "size": 8, - "from": 0, - "to": 8 - }, - "age": { - "type": "Uint8", - "size": 1, - "from": 8, - "to": 9 - }, - "balance": { - "type": "Uint64", - "size": 8, - "from": 9, - "to": 17 - }, - "status": { - "type": "Bool", - "size": 1, - "from": 17, - "to": 18 + "fields": [ + { + "name": "name", + "type": "String" + }, + { + "name": "age", + "type": "Uint8" + }, + { + "name": "balance", + "type": "Uint64" + }, + { + "name": "status", + "type": "Bool" } - }, + ], "signature": "dad76b4c3b067d53265534bde4d9ff59987d00f87e0e1a633613576195a4cbc1e0a43a58c67c34c98019f791812699d010655c4eccec448e46e5524471a8c401" }, "type5": { - "size": 80, - "fields": { - "pub_key": { - "type": "PublicKey", - "size": 32, - "from": 0, - "to": 32 - }, - "name": { - "type": "String", - "size": 8, - "from": 32, - "to": 40 - }, - "balance": { - "type": "Uint64", - "size": 8, - "from": 40, - "to": 48 - }, - "history_hash": { - "type": "Hash", - "size": 32, - "from": 48, - "to": 80 + "fields": [ + { + "name": "pub_key", + "type": "PublicKey" + }, + { + "name": "name", + "type": "String" + }, + { + "name": "balance", + "type": "Uint64" + }, + { + "name": "history_hash", + "type": "Hash" } - } + ] }, "type6": { - "size": 16, - "fields": { - "firstName": { - "type": "String", - "size": 8, - "from": 0, - "to": 8 - }, - "lastName": { - "type": "String", - "size": 8, - "from": 8, - "to": 16 + "fields": [ + { + "name": "firstName", + "type": "String" + }, + { + "name": "lastName", + "type": "String" } - } + ] }, "type7": { "as": "message", - "size": 18, "network_id": 0, "protocol_version": 0, "service_id": 1, "message_id": 2, - "fields": { - "name": { - "type": "String", - "size": 8, - "from": 0, - "to": 8 - }, - "age": { - "type": "Uint8", - "size": 1, - "from": 8, - "to": 9 - }, - "balance": { - "type": "Uint64", - "size": 8, - "from": 9, - "to": 17 - }, - "status": { - "type": "Bool", - "size": 1, - "from": 17, - "to": 18 + "fields": [ + { + "name": "name", + "type": "String" + }, + { + "name": "age", + "type": "Uint8" + }, + { + "name": "balance", + "type": "Uint64" + }, + { + "name": "status", + "type": "Bool" } - } + ] }, "type8": { "as": "message", - "size": 18, "network_id": 0, "protocol_version": 0, "service_id": 1, "message_id": 2, - "fields": { - "name": { - "type": "String", - "size": 8, - "from": 0, - "to": 8 - }, - "age": { - "type": "Uint8", - "size": 1, - "from": 8, - "to": 9 - }, - "balance": { - "type": "Uint64", - "size": 8, - "from": 9, - "to": 17 - }, - "status": { - "type": "Bool", - "size": 1, - "from": 17, - "to": 18 + "fields": [ + { + "name": "name", + "type": "String" + }, + { + "name": "age", + "type": "Uint8" + }, + { + "name": "balance", + "type": "Uint64" + }, + { + "name": "status", + "type": "Bool" } - } + ] }, "type9": { - "size": 16, - "fields": { - "firstName": { - "type": "String", - "size": 8, - "from": 0, - "to": 8 - }, - "lastName": { - "type": "String", - "size": 8, - "from": 8, - "to": 16 + "fields": [ + { + "name": "firstName", + "type": "String" + }, + { + "name": "lastName", + "type": "String" } - } + ] } } diff --git a/test/common_data/serialization/serialization-config.json b/test/common_data/serialization/serialization-config.json index faa520d..77507d3 100644 --- a/test/common_data/serialization/serialization-config.json +++ b/test/common_data/serialization/serialization-config.json @@ -1,283 +1,202 @@ { "wallet": { - "size": 80, - "fields": { - "pub_key": { - "type": "PublicKey", - "size": 32, - "from": 0, - "to": 32 - }, - "name": { - "type": "String", - "size": 8, - "from": 32, - "to": 40 - }, - "balance": { - "type": "Uint64", - "size": 8, - "from": 40, - "to": 48 - }, - "history_hash": { - "type": "Hash", - "size": 32, - "from": 48, - "to": 80 + "fields": [ + { + "name": "pub_key", + "type": "PublicKey" + }, + { + "name": "name", + "type": "String" + }, + { + "name": "balance", + "type": "Uint64" + }, + { + "name": "history_hash", + "type": "Hash" } - } + ] }, "user": { - "size": 64, - "fields": { - "public_key": { - "type": "PublicKey", - "size": 32, - "from": 0, - "to": 32 - }, - "login": { - "type": "String", - "size": 8, - "from": 32, - "to": 40 - }, - "name": { - "type": "String", - "size": 8, - "from": 40, - "to": 48 - }, - "url": { - "type": "String", - "size": 8, - "from": 48, - "to": 56 - }, - "avatar_url": { - "type": "String", - "size": 8, - "from": 56, - "to": 64 + "fields": [ + { + "name": "public_key", + "type": "PublicKey" + }, + { + "name": "login", + "type": "String" + }, + { + "name": "name", + "type": "String" + }, + { + "name": "url", + "type": "String" + }, + { + "name": "avatar_url", + "type": "String" } - } + ] }, "user2": { - "size": 16, - "fields": { - "name": { - "type": "String", - "size": 8, - "from": 0, - "to": 8 - }, - "surname": { - "type": "String", - "size": 8, - "from": 8, - "to": 16 + "fields": [ + { + "name": "name", + "type": "String" + }, + { + "name": "surname", + "type": "String" } - } + ] }, "transaction": { - "size": 24, - "fields": { - "from": { - "type": "user2", - "size": 8, - "from": 0, - "to": 8 - }, - "to": { - "type": "user2", - "size": 8, - "from": 8, - "to": 16 - }, - "sum": { - "type": "Uint64", - "size": 8, - "from": 16, - "to": 24 + "fields": [ + { + "name": "from", + "type": "user2" + }, + { + "name": "to", + "type": "user2" + }, + { + "name": "sum", + "type": "Uint64" } - } + ] }, "user3": { - "size": 12, - "fields": { - "name": { - "type": "String", - "size": 8, - "from": 0, - "to": 8 + "fields": [ + { + "name": "name", + "type": "String" } - } + ] }, "transaction2": { - "size": 16, - "fields": { - "to": { - "type": "user3", - "size": 8, - "from": 0, - "to": 8 - }, - "sum": { - "type": "Uint64", - "size": 8, - "from": 8, - "to": 16 + "fields": [ + { + "name": "to", + "type": "user3" + }, + { + "name": "sum", + "type": "Uint64" } - } + ] }, "wallet2": { - "size": 16, - "fields": { - "id": { - "type": "Uint64", - "size": 8, - "from": 0, - "to": 8 - }, - "balance": { - "type": "Uint64", - "size": 8, - "from": 8, - "to": 16 + "fields": [ + { + "name": "id", + "type": "Uint64" + }, + { + "name": "balance", + "type": "Uint64" } - } + ] }, "transaction3": { - "size": 24, - "fields": { - "from": { - "type": "wallet2", - "size": 8, - "from": 0, - "to": 8 - }, - "to": { - "type": "wallet2", - "size": 8, - "from": 8, - "to": 16 - }, - "sum": { - "type": "Uint64", - "size": 8, - "from": 16, - "to": 24 + "fields": [ + { + "name": "from", + "type": "wallet2" + }, + { + "name": "to", + "type": "wallet2" + }, + { + "name": "sum", + "type": "Uint64" } - } + ] }, "wallet3": { - "size": 80, - "fields": { - "pub_key": { - "type": "PublicKey", - "size": 32, - "from": 0, - "to": 32 - }, - "name": { - "type": "String", - "size": 8, - "from": 32, - "to": 40 - }, - "balance": { - "type": "Uint64", - "size": 8, - "from": 40, - "to": 48 - }, - "history_hash": { - "type": "Hash", - "size": 32, - "from": 48, - "to": 80 + "fields": [ + { + "name": "pub_key", + "type": "PublicKey" + }, + { + "name": "name", + "type": "String" + }, + { + "name": "balance", + "type": "Uint64" + }, + { + "name": "history_hash", + "type": "Hash" } - } + ] }, "wallet4": { - "size": 80, - "fields": { - "pub_key": { - "type": "PublicKey", - "size": 32, - "from": 0, - "to": 32 - }, - "name": { - "type": "String", - "size": 8, - "from": 32, - "to": 40 - }, - "balance": { - "type": "Uint64", - "size": 8, - "from": 40, - "to": 48 - }, - "history_hash": { - "type": "Hash", - "size": 32, - "from": 48, - "to": 80 + "fields": [ + { + "name": "pub_key", + "type": "PublicKey" + }, + { + "name": "name", + "type": "String" + }, + { + "name": "balance", + "type": "Uint64" + }, + { + "name": "history_hash", + "type": "Hash" } - } + ] }, "userArray": { "as": "array", - "size": 64, "type": "user" }, "addUserArray": { "as": "message", - "size": 40, "network_id": 0, "protocol_version": 0, "service_id": 198, "message_id": 0, "signature": "a8f09060198192799b3bdc1634878369bb2a72fdb6c0c5dd92636605723be24e57feebe705116287604f1f93df8953d2abab9ce2ddad7e6a1d83a7651376640c", - "fields": { - "public_key": { - "type": "PublicKey", - "size": 32, - "from": 0, - "to": 32 - }, - "content": { - "type": "userArray", - "size": 8, - "from": 32, - "to": 40 + "fields": [ + { + "name": "public_key", + "type": "PublicKey" + }, + { + "name": "content", + "type": "userArray" } - } + ] }, "addUser": { "as": "message", - "size": 40, "network_id": 0, "protocol_version": 0, "service_id": 198, "message_id": 0, "signature": "a8f09060198192799b3bdc1634878369bb2a72fdb6c0c5dd92636605723be24e57feebe705116287604f1f93df8953d2abab9ce2ddad7e6a1d83a7651376640c", - "fields": { - "public_key": { - "type": "PublicKey", - "size": 32, - "from": 0, - "to": 32 - }, - "content": { - "type": "user", - "size": 8, - "from": 32, - "to": 40 + "fields": [ + { + "name": "public_key", + "type": "PublicKey" + }, + { + "name": "content", + "type": "user" } - } + ] } } diff --git a/test/common_data/serialization/serialization.json b/test/common_data/serialization/serialization.json index d2525f1..1e2986b 100644 --- a/test/common_data/serialization/serialization.json +++ b/test/common_data/serialization/serialization.json @@ -57,7 +57,7 @@ }, "sum": 200 }, - "serialized": [16, 0, 0, 0, 20, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 74, 111, 104, 110, 32, 68, 111, 101] + "serialized": [16, 0, 0, 0, 16, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 74, 111, 104, 110, 32, 68, 111, 101] }, "transactionData3":{ "data":{ @@ -71,6 +71,6 @@ }, "sum": 200 }, - "serialized":[57, 0, 0, 0, 0, 0, 0, 0, 153, 3, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0] + "serialized":[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] } } diff --git a/test/common_data/serialization/types-config.json b/test/common_data/serialization/types-config.json index c94f147..a64420c 100644 --- a/test/common_data/serialization/types-config.json +++ b/test/common_data/serialization/types-config.json @@ -1,194 +1,142 @@ { "type1": { - "size": 32, - "fields": { - "hash": { - "type": "Hash", - "size": 32, - "from": 0, - "to": 32 + "fields": [ + { + "name": "hash", + "type": "Hash" } - } + ] }, "type2": { - "size": 32, - "fields": { - "key": { - "type": "PublicKey", - "size": 32, - "from": 0, - "to": 32 + "fields": [ + { + "name": "key", + "type": "PublicKey" } - } + ] }, "type3": { - "size": 64, - "fields": { - "key": { - "type": "Digest", - "size": 64, - "from": 0, - "to": 64 + "fields": [ + { + "name": "key", + "type": "Digest" } - } + ] }, "type4": { - "size": 8, - "fields": { - "since": { - "type": "Timespec", - "size": 8, - "from": 0, - "to": 8 + "fields": [ + { + "name": "since", + "type": "Timespec" } - } + ] }, "type5": { - "size": 1, - "fields": { - "active": { - "type": "Bool", - "size": 1, - "from": 0, - "to": 1 + "fields": [ + { + "name": "active", + "type": "Bool" } - } + ] }, "type6": { - "size": 8, - "fields": { - "text": { - "type": "String", - "size": 8, - "from": 0, - "to": 8 + "fields": [ + { + "name": "text", + "type": "String" } - } + ] }, "type7": { - "size": 1, - "fields": { - "balance": { - "type": "Int8", - "size": 1, - "from": 0, - "to": 1 + "fields": [ + { + "name": "balance", + "type": "Int8" } - } + ] }, "type8": { - "size": 2, - "fields": { - "balance": { - "type": "Int16", - "size": 2, - "from": 0, - "to": 2 + "fields": [ + { + "name": "balance", + "type": "Int16" } - } + ] }, "type9": { - "size": 4, - "fields": { - "balance": { - "type": "Int32", - "size": 4, - "from": 0, - "to": 4 + "fields": [ + { + "name": "balance", + "type": "Int32" } - } + ] }, "type10": { - "size": 8, - "fields": { - "balance": { - "type": "Int64", - "size": 8, - "from": 0, - "to": 8 + "fields": [ + { + "name": "balance", + "type": "Int64" } - } + ] }, "type11": { - "size": 1, - "fields": { - "balance": { - "type": "Uint8", - "size": 1, - "from": 0, - "to": 1 + "fields": [ + { + "name": "balance", + "type": "Uint8" } - } + ] }, "type12": { - "size": 2, - "fields": { - "balance": { - "type": "Uint16", - "size": 2, - "from": 0, - "to": 2 + "fields": [ + { + "name": "balance", + "type": "Uint16" } - } + ] }, "type13": { - "size": 4, - "fields": { - "balance": { - "type": "Uint32", - "size": 4, - "from": 0, - "to": 4 + "fields": [ + { + "name": "balance", + "type": "Uint32" } - } + ] }, "type14": { - "size": 8, - "fields": { - "balance": { - "type": "Uint64", - "size": 8, - "from": 0, - "to": 8 + "fields": [ + { + "name": "balance", + "type": "Uint64" } - } + ] }, "type15-1": { "as": "array", - "size": 32, "type": "Hash" }, "type15-2": { - "size": 8, - "fields": { - "list": { - "type": "type15-1", - "size": 8, - "from": 0, - "to": 8 + "fields": [ + { + "name": "list", + "type": "type15-1" } - } + ] }, "type16": { - "size": 4, - "fields": { - "balance": { - "type": "Float32", - "size": 4, - "from": 0, - "to": 4 + "fields": [ + { + "name": "balance", + "type": "Float32" } - } + ] }, "type17": { - "size": 8, - "fields": { - "balance": { - "type": "Float64", - "size": 8, - "from": 0, - "to": 8 - } - } + "fields": [ + { + "name": "balance", + "type": "Float64" + } + ] } } diff --git a/test/cryptography.js b/test/cryptography.js index bf59a05..21d9d46 100644 --- a/test/cryptography.js +++ b/test/cryptography.js @@ -140,11 +140,10 @@ describe('Check cryptography', function () { const publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' const signature = '7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040e' const 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 } - } + fields: [ + { name: 'firstName', type: Exonum.String }, + { name: 'lastName', type: Exonum.String } + ] }) const userData = { firstName: 'John', @@ -158,11 +157,10 @@ describe('Check cryptography', function () { const publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' const signature = '7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040e' const 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 } - } + fields: [ + { name: 'firstName', type: Exonum.String }, + { name: 'lastName', type: Exonum.String } + ] }) const userData = { firstName: 'John', @@ -176,17 +174,16 @@ describe('Check cryptography', function () { const publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' const signature = '4006cef1884941850a6b97a64ed7f12d1e1053188618ef71b8c9f87438b943b1969e08011e45db8299bb738fec60c9dcd1936ab9ba44392cacc7f0385f18dd09' const 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 } - } + fields: [ + { name: 'name', type: Exonum.String }, + { name: 'age', type: Exonum.Uint8 }, + { name: 'balance', type: Exonum.Uint64 }, + { name: 'status', type: Exonum.Bool } + ] }) const messageData = { name: 'John Doe', @@ -202,17 +199,16 @@ describe('Check cryptography', function () { const publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' const signature = '4006cef1884941850a6b97a64ed7f12d1e1053188618ef71b8c9f87438b943b1969e08011e45db8299bb738fec60c9dcd1936ab9ba44392cacc7f0385f18dd09' const 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 } - } + fields: [ + { name: 'name', type: Exonum.String }, + { name: 'age', type: Exonum.Uint8 }, + { name: 'balance', type: Exonum.Uint64 }, + { name: 'status', type: Exonum.Bool } + ] }) const messageData = { name: 'John Doe', @@ -228,11 +224,10 @@ describe('Check cryptography', function () { const publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' const signature = '7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040e' const 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 } - } + fields: [ + { name: 'firstName', type: Exonum.String }, + { name: 'lastName', type: Exonum.String } + ] }) const userData = { firstName: 'John', @@ -247,11 +242,10 @@ describe('Check cryptography', function () { const publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' const signature = '7ccad21d76359c8c3ed1161eb8231edd44a91d53ea468d23f8528e2985e5547f72f98ccc61d96ecad173bdc29627abbf6d46908807f6dd0a0d767ae3887d040b' const 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 } - } + fields: [ + { name: 'firstName', type: Exonum.String }, + { name: 'lastName', type: Exonum.String } + ] }) const userData = { firstName: 'John', @@ -278,17 +272,16 @@ describe('Check cryptography', function () { const publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' const signature = '24a5224702d670c95a78ef1f753c9e6e698da5b2a2c52dcc51b5bf9e556e717fb763b1a5e78bd39e5369a139ab68ae50dd19a129038e8da3af30985f09549500' const 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 } - } + fields: [ + { name: 'name', type: Exonum.String }, + { name: 'age', type: Exonum.Uint8 }, + { name: 'balance', type: Exonum.Uint64 }, + { name: 'status', type: Exonum.Bool } + ] }) const someData = { sum: 500, @@ -318,11 +311,10 @@ describe('Check cryptography', function () { const publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' const signature = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' const 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 } - } + fields: [ + { name: 'firstName', type: Exonum.String }, + { name: 'lastName', type: Exonum.String } + ] }) const userData = { firstName: 'John', @@ -338,11 +330,10 @@ describe('Check cryptography', function () { const publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' const signature = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7Z' const 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 } - } + fields: [ + { name: 'firstName', type: Exonum.String }, + { name: 'lastName', type: Exonum.String } + ] }) const userData = { firstName: 'John', @@ -357,11 +348,10 @@ describe('Check cryptography', function () { it('should throw error when the signature parameter is of wrong type', function () { const publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C36' const 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 } - } + fields: [ + { name: 'firstName', type: Exonum.String }, + { name: 'lastName', type: Exonum.String } + ] }) const userData = { firstName: 'John', @@ -379,11 +369,10 @@ describe('Check cryptography', function () { const publicKey = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C' const signature = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C' const 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 } - } + fields: [ + { name: 'firstName', type: Exonum.String }, + { name: 'lastName', type: Exonum.String } + ] }) const userData = { firstName: 'John', @@ -399,11 +388,10 @@ describe('Check cryptography', function () { const publicKey = 'F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C3Z' const signature = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C' const 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 } - } + fields: [ + { name: 'firstName', type: Exonum.String }, + { name: 'lastName', type: Exonum.String } + ] }) const userData = { firstName: 'John', @@ -418,11 +406,10 @@ describe('Check cryptography', function () { it('should throw error when the publicKey parameter is of wrong type', function () { const signature = '6752BE882314F5BBBC9A6AF2AE634FC07038584A4A77510EA5ECED45F54DC030F5864AB6A5A2190666B47C676BCF15A1F2F07703C5BCAFB5749AA735CE8B7C' const 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 } - } + fields: [ + { name: 'firstName', type: Exonum.String }, + { name: 'lastName', type: Exonum.String } + ] }) const userData = { firstName: 'John', @@ -440,11 +427,10 @@ describe('Check cryptography', function () { describe('Generate key pair', function () { it('should generate random key pair of secret and public keys, serialize it and return serialized array', function () { const 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 } - } + fields: [ + { name: 'publicKey', type: Exonum.Hash }, + { name: 'secretKey', type: Exonum.Digest } + ] }) const data = Exonum.keyPair() const buffer = Type.serialize(data) @@ -456,8 +442,9 @@ describe('Check cryptography', function () { describe('Generate random Uint64', function () { it('should generate random value of Uint64 type, serialize and return serialized array', function () { const Type = Exonum.newType({ - size: 8, - fields: { balance: { type: Exonum.Uint64, size: 8, from: 0, to: 8 } } + fields: [ + { name: 'balance', type: Exonum.Uint64 } + ] }) const data = { balance: Exonum.randomUint64() } const buffer = Type.serialize(data) diff --git a/test/data_schema/dataSchema.js b/test/data_schema/dataSchema.js index aa45a56..db4b27b 100644 --- a/test/data_schema/dataSchema.js +++ b/test/data_schema/dataSchema.js @@ -13,11 +13,9 @@ export default class DataSchema { Object.keys(schema).forEach(key => { const item = schema[key] if (!item.as || item.as === 'type' || item.as === 'message') { - Object.keys(item.fields) - .forEach(fieldKey => { - const field = item.fields[fieldKey] - field.type = this.getTypeOrArray(field.type) - }) + item.fields.forEach(field => { + field.type = this.getTypeOrArray(field.type) + }) if (!item.as || item.as === 'type') this.types[key] = Exonum.newType(item) if (item.as === 'message') this.messages[key] = Exonum.newMessage(item) } else if (item.as === 'array') { diff --git a/test/merkle-patricia-proof.js b/test/merkle-patricia-proof.js index 918698c..7d810f0 100644 --- a/test/merkle-patricia-proof.js +++ b/test/merkle-patricia-proof.js @@ -17,13 +17,12 @@ describe('Check proof of Merkle Patricia tree', function () { it('should return the child of single child valid tree', function () { const Type = Exonum.newType({ - size: 80, - fields: { - pub_key: { type: Exonum.PublicKey, size: 32, from: 0, to: 32 }, - balance: { type: Exonum.Uint64, size: 8, from: 32, to: 40 }, - history_len: { type: Exonum.Uint64, size: 8, from: 40, to: 48 }, - history_hash: { type: Exonum.Hash, size: 32, from: 48, to: 80 } - } + fields: [ + { name: 'pub_key', type: Exonum.PublicKey }, + { name: 'balance', type: Exonum.Uint64 }, + { name: 'history_len', type: Exonum.Uint64 }, + { name: 'history_hash', type: Exonum.Hash } + ] }) const data = require('./common_data/merkle-patricia-tree/valid-MPT-single-child.json') const element = Exonum.merklePatriciaProof( @@ -342,8 +341,9 @@ describe('Check proof of Merkle Patricia tree', function () { } const key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' const Type = Exonum.newType({ - size: 8, - fields: { balance: { type: Exonum.Int64, size: 8, from: 0, to: 8 } } + fields: [ + { name: 'balance', type: Exonum.Uint64 } + ] }) expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, Type)).to.throw(TypeError) @@ -360,8 +360,9 @@ describe('Check proof of Merkle Patricia tree', function () { } const key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' const Type = Exonum.newType({ - size: 8, - fields: { balance: { type: Exonum.Int64, size: 8, from: 0, to: 8 } } + fields: [ + { name: 'balance', type: Exonum.Uint64 } + ] }) expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, Type)).to.throw(Error) @@ -378,8 +379,9 @@ describe('Check proof of Merkle Patricia tree', function () { } const key = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' const Type = Exonum.newType({ - size: 8, - fields: { balance: { type: Exonum.Int64, size: 8, from: 0, to: 8 } } + fields: [ + { name: 'balance', type: Exonum.Uint64 } + ] }) expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, Type)).to.throw(Error) @@ -636,13 +638,12 @@ describe('Check proof of Merkle Patricia tree', function () { } const key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' const 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 } - } + fields: [ + { name: 'pub_key', type: Exonum.PublicKey }, + { name: 'name', type: Exonum.String }, + { name: 'balance', type: Exonum.Uint64 }, + { name: 'history_hash', type: Exonum.Hash } + ] }) expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, Type)).to.throw(TypeError) @@ -664,13 +665,12 @@ describe('Check proof of Merkle Patricia tree', function () { } const key = '2dd5bcc350a02229e987e1d2be7d6a3bc62daab50f8d7ce71eaf69b6093fcdc3' const 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 } - } + fields: [ + { name: 'pub_key', type: Exonum.PublicKey }, + { name: 'name', type: Exonum.String }, + { name: 'balance', type: Exonum.Uint64 }, + { name: 'history_hash', type: Exonum.Hash } + ] }) expect(() => Exonum.merklePatriciaProof(rootHash, proofNode, key, Type)).to.throw(TypeError) diff --git a/test/merkle-proof.js b/test/merkle-proof.js index 2453924..ea7f60c 100644 --- a/test/merkle-proof.js +++ b/test/merkle-proof.js @@ -293,8 +293,9 @@ describe('Check proof of Merkle tree', function () { it('should throw error when the tree with invalid value', function () { const Type = Exonum.newType({ - size: 32, - fields: { hash: { type: Exonum.Hash, size: 32, from: 0, to: 32 } } + fields: [ + { name: 'hash', type: Exonum.Hash } + ] }); [42, 'Hello world', [], new Date()].forEach(function (val) { @@ -312,8 +313,9 @@ describe('Check proof of Merkle tree', function () { it('should throw error when the tree with invalid value not corresponding to passed type', function () { const Type = Exonum.newType({ - size: 32, - fields: { hash: { type: Exonum.Hash, size: 32, from: 0, to: 32 } } + fields: [ + { name: 'hash', type: Exonum.Hash } + ] }) const rootHash = '6956f2d3b391b1106e160210de1345c563cbece4199fd13f5c195207e429ff13' const count = 2 diff --git a/test/readme.js b/test/readme.js index 286d9ca..f4d5034 100644 --- a/test/readme.js +++ b/test/readme.js @@ -7,11 +7,10 @@ const Exonum = require('../src') describe('Examples from README.md', function () { describe('Custom type section', function () { const 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 } - } + fields: [ + { name: 'name', type: Exonum.String }, + { name: 'age', type: Exonum.Int8 } + ] }) const data = { name: 'Tom', @@ -34,16 +33,15 @@ describe('Examples from README.md', function () { describe('Transaction section', function () { const 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 } - } + fields: [ + { name: 'from', type: Exonum.Hash }, + { name: 'to', type: Exonum.Hash }, + { name: 'amount', type: Exonum.Uint64 } + ] }) const data = { from: '6752be882314f5bbbc9a6af2ae634fc07038584a4a77510ea5eced45f54dc030', diff --git a/test/serialization.js b/test/serialization.js index ffdced7..f564328 100644 --- a/test/serialization.js +++ b/test/serialization.js @@ -44,32 +44,6 @@ describe('Serialize data into array of 8-bit integers', function () { expect(buffer).to.deep.equal(serializationMock.transactionData3.serialized) }) - it('should serialize data (with inherited properties that should be ignored) of newType type and return array of 8-bit integers', function () { - 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) - - const walletData = new Data() - - const buffer = scheme.getType('wallet3').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 () { const walletData = { fake: 123 } diff --git a/test/types.js b/test/types.js index 408d132..b4e427e 100644 --- a/test/types.js +++ b/test/types.js @@ -16,15 +16,22 @@ describe('Check built-in types', function () { expect(buffer).to.deep.equal(typesMock.type1.serialized) }) - it('should throw error when the range of segment is invalid', function () { - const Type = Exonum.newType({ - size: 32, - fields: { hash: { type: Exonum.Hash, size: 32, from: 0, to: 16 } } - }) - const data = { hash: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36' } + it('should throw error when the name prop is missed', function () { + expect(() => Exonum.newType({ + fields: [ + { type: Exonum.Hash } + ] + })) + .to.throw(Error, 'Name prop is missed.') + }) - expect(() => Type.serialize(data)) - .to.throw(Error, 'Hash segment is of wrong length. 32 bytes long is required to store transmitted value.') + it('should throw error when the type prop is missed', function () { + expect(() => Exonum.newType({ + fields: [ + { name: 'hash' } + ] + })) + .to.throw(Error, 'Type prop is missed.') }) it('should throw error when the value is invalid string', function () { @@ -60,17 +67,6 @@ describe('Check built-in types', function () { expect(buffer).to.deep.equal(typesMock.type2.serialized) }) - it('should throw error when the range of segment is invalid', function () { - const Type = Exonum.newType({ - size: 32, - fields: { key: { type: Exonum.PublicKey, size: 32, from: 0, to: 16 } } - }) - const data = { key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36' } - - expect(() => Type.serialize(data)) - .to.throw(Error, 'PublicKey segment is of wrong length. 32 bytes long is required to store transmitted value.') - }) - it('should throw error when the value is invalid string', function () { expect(() => scheme.getType('type2').serialize(invalidTypesMock.type2.data)) .to.throw(TypeError, 'PublicKey of wrong type is passed: f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3z') @@ -103,17 +99,6 @@ describe('Check built-in types', function () { expect(buffer).to.deep.equal(typesMock.type3.serialized) }) - it('should throw error when the range of segment is invalid', function () { - const Type = Exonum.newType({ - size: 64, - fields: { key: { type: Exonum.Digest, size: 64, from: 0, to: 32 } } - }) - const data = { key: 'f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c36' } - - expect(() => Type.serialize(data)) - .to.throw(Error, 'Digest segment is of wrong length. 64 bytes long is required to store transmitted value.') - }) - it('should throw error when the value is invalid string', function () { expect(() => scheme.getType('type3').serialize(invalidTypesMock.type3.data)) .to.throw(TypeError, 'Digest of wrong type is passed: f5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3zf5864ab6a5a2190666b47c676bcf15a1f2f07703c5bcafb5749aa735ce8b7c3z') @@ -148,8 +133,9 @@ describe('Check built-in types', function () { it('should serialize data and return array of 8-bit integers when the value is valid timestamp in nanoseconds passed as string', function () { const Type = Exonum.newType({ - size: 8, - fields: { since: { type: Exonum.Timespec, size: 8, from: 0, to: 8 } } + fields: [ + { name: 'since', type: Exonum.Timespec } + ] }) const data = { since: '18446744073709551615' } const buffer = Type.serialize(data) @@ -162,16 +148,6 @@ describe('Check built-in types', function () { .to.throw(TypeError, 'Timespec of wrong type is passed: -1483979894237') }) - it('should throw error when the range of segment is invalid', function () { - const Type = Exonum.newType({ - size: 8, - fields: { since: { type: Exonum.Timespec, size: 8, from: 0, to: 4 } } - }) - - expect(() => Type.serialize({ since: 1483979894237 })) - .to.throw(TypeError, 'Timespec of wrong type is passed: 1483979894237') - }) - it('should throw error when the value is out of range', function () { expect(() => scheme.getType('type4').serialize(invalidTypesMock['type4-1'].data)) .to.throw(TypeError, 'Timespec of wrong type is passed: 18446744073709551616') @@ -197,8 +173,9 @@ describe('Check built-in types', function () { it('should serialize data and return array of 8-bit integers when the value is valid negative boolean', function () { const Type = Exonum.newType({ - size: 1, - fields: { active: { type: Exonum.Bool, size: 1, from: 0, to: 1 } } + fields: [ + { name: 'active', type: Exonum.Bool } + ] }) const data = { active: false } const buffer = Type.serialize(data) @@ -206,16 +183,6 @@ describe('Check built-in types', function () { expect(buffer).to.deep.equal([0]) }) - it('should throw error when the range of segment is invalid', function () { - const Type = Exonum.newType({ - size: 1, - fields: { active: { type: Exonum.Bool, size: 1, from: 0, to: 0 } } - }) - - expect(() => Type.serialize({ active: true })) - .to.throw(Error, 'Bool segment is of wrong length. 1 bytes long is required to store transmitted value.') - }) - it('should throw error when the value of invalid type', function () { expect(() => scheme.getType('type5').serialize({ active: undefined })) .to.throw(TypeError, 'Field active is not defined.'); @@ -233,16 +200,6 @@ describe('Check built-in types', function () { expect(buffer).to.deep.equal(typesMock.type6.serialized) }) - it('should throw error when the range of segment is invalid', function () { - const 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, 'String segment is of wrong length. 8 bytes long is required to store transmitted value.') - }) - it('should throw error when the value of invalid type', function () { expect(() => scheme.getType('type6').serialize({ text: undefined })) .to.throw(TypeError, 'Field text is not defined.'); @@ -263,8 +220,9 @@ describe('Check built-in types', function () { it('should serialize data and return array of 8-bit integers when the value is valid negative number', function () { const Type = Exonum.newType({ - size: 1, - fields: { balance: { type: Exonum.Int8, size: 1, from: 0, to: 1 } } + fields: [ + { name: 'balance', type: Exonum.Int8 } + ] }) const data = { balance: -120 } const buffer = Type.serialize(data) @@ -272,15 +230,6 @@ describe('Check built-in types', function () { expect(buffer).to.deep.equal([136]) }) - it('should throw error when the range of segment is invalid', function () { - const Type = Exonum.newType({ - size: 1, - fields: { balance: { type: Exonum.Int8, size: 1, from: 0, to: 0 } } - }) - expect(() => Type.serialize({ balance: 120 })) - .to.throw(TypeError, 'Int8 of wrong type is passed: 120') - }) - it('should throw error when the value is too big positive number', function () { expect(() => scheme.getType('type7').serialize(invalidTypesMock.type7.data)) .to.throw(TypeError, 'Int8 of wrong type is passed: 130') @@ -315,16 +264,6 @@ describe('Check built-in types', function () { expect(buffer).to.deep.equal([209, 135]) }) - it('should throw error when the range of segment is invalid', function () { - const Type = Exonum.newType({ - size: 2, - fields: { balance: { type: Exonum.Int16, size: 2, from: 0, to: 1 } } - }) - - expect(() => Type.serialize({ balance: 30767 })) - .to.throw(TypeError, 'Int16 of wrong type is passed: 30767') - }) - it('should throw error when the value is too big positive number', function () { expect(() => scheme.getType('type8').serialize(invalidTypesMock.type8.data)) .to.throw(TypeError, 'Int16 of wrong type is passed: 32769') @@ -360,16 +299,6 @@ describe('Check built-in types', function () { expect(buffer).to.deep.equal([0, 202, 154, 187]) }) - it('should throw error when the range of segment is invalid', function () { - const Type = Exonum.newType({ - size: 4, - fields: { balance: { type: Exonum.Int32, size: 4, from: 0, to: 3 } } - }) - - expect(() => Type.serialize({ balance: 613228 })) - .to.throw(TypeError, 'Int32 of wrong type is passed: 613228') - }) - it('should throw error when the value is too big positive number', function () { expect(() => scheme.getType('type9').serialize(invalidTypesMock.type9.data)) .to.throw(TypeError, 'Int32 of wrong type is passed: 2147483649') @@ -413,8 +342,9 @@ describe('Check built-in types', function () { it('should serialize data and return array of 8-bit integers when the value is valid negative number as string', function () { const Type = Exonum.newType({ - size: 8, - fields: { balance: { type: Exonum.Int64, size: 8, from: 0, to: 8 } } + fields: [ + { name: 'balance', type: Exonum.Int64 } + ] }) const data = { balance: '-9223372036854775808' } const buffer = Type.serialize(data) @@ -422,16 +352,6 @@ describe('Check built-in types', function () { 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 () { - const Type = Exonum.newType({ - size: 8, - fields: { balance: { type: Exonum.Int64, size: 8, from: 0, to: 4 } } - }) - - expect(() => Type.serialize({ balance: 613228 })) - .to.throw(TypeError, 'Int64 of wrong type is passed: 613228') - }) - it('should throw error when the value is too big positive number', function () { expect(() => scheme.getType('type10').serialize(invalidTypesMock.type10.data)) .to.throw(TypeError, 'Int64 of wrong type is passed: 9223372036854775808') @@ -459,16 +379,6 @@ describe('Check built-in types', function () { expect(buffer).to.deep.equal(typesMock.type11.serialized) }) - it('should throw error when the range of segment is invalid', function () { - const Type = Exonum.newType({ - size: 1, - fields: { balance: { type: Exonum.Uint8, size: 1, from: 0, to: 0 } } - }) - - expect(() => Type.serialize({ balance: 230 })) - .to.throw(TypeError, 'Uint8 of wrong type is passed: 230') - }) - it('should throw error when the value is negative number', function () { expect(() => scheme.getType('type11').serialize(invalidTypesMock.type11.data)) .to.throw(TypeError, 'Uint8 of wrong type is passed: -1') @@ -496,16 +406,6 @@ describe('Check built-in types', function () { expect(buffer).to.deep.equal(typesMock.type12.serialized) }) - it('should throw error when the range of segment is invalid', function () { - const Type = Exonum.newType({ - size: 2, - fields: { balance: { type: Exonum.Uint16, size: 2, from: 0, to: 1 } } - }) - - expect(() => Type.serialize({ balance: 60535 })) - .to.throw(TypeError, 'Uint16 of wrong type is passed: 60535') - }) - it('should throw error when the value is negative number', function () { expect(() => scheme.getType('type12').serialize(invalidTypesMock.type12.data)) .to.throw(TypeError, 'Uint16 of wrong type is passed: -1') @@ -533,16 +433,6 @@ describe('Check built-in types', function () { expect(buffer).to.deep.equal(typesMock.type13.serialized) }) - it('should throw error when the range of segment is invalid', function () { - const Type = Exonum.newType({ - size: 4, - fields: { balance: { type: Exonum.Uint32, size: 4, from: 0, to: 3 } } - }) - - expect(() => Type.serialize({ balance: 613228 })) - .to.throw(TypeError, 'Uint32 of wrong type is passed: 613228') - }) - it('should throw error when the value is negative number', function () { expect(() => scheme.getType('type13').serialize(invalidTypesMock.type13.data)) .to.throw(TypeError, 'Uint32 of wrong type is passed: -1') @@ -572,8 +462,9 @@ describe('Check built-in types', function () { it('should serialize data and return array of 8-bit integers when the value is valid positive number passed as string', function () { const Type = Exonum.newType({ - size: 8, - fields: { balance: { type: Exonum.Uint64, size: 8, from: 0, to: 8 } } + fields: [ + { name: 'balance', type: Exonum.Uint64 } + ] }) const data = { balance: '9007199254740993' } const buffer = Type.serialize(data) @@ -581,16 +472,6 @@ describe('Check built-in types', function () { 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 () { - const Type = Exonum.newType({ - size: 8, - fields: { balance: { type: Exonum.Uint64, size: 8, from: 0, to: 4 } } - }) - - expect(() => Type.serialize({ balance: 613228 })) - .to.throw(TypeError, 'Uint64 of wrong type is passed: 613228') - }) - it('should throw error when the value is negative number', function () { expect(() => scheme.getType('type14').serialize(invalidTypesMock.type14.data)) .to.throw(TypeError, 'Uint64 of wrong type is passed: -613228') @@ -639,16 +520,6 @@ describe('Check built-in types', function () { expect(buffer).to.deep.equal([255, 255, 127, 255]) }) - it('should throw error when the range of segment is invalid', function () { - const Type = Exonum.newType({ - size: 4, - fields: { balance: { type: Exonum.Float32, size: 4, from: 0, to: 3 } } - }) - - expect(() => Type.serialize({ balance: 3.14 })) - .to.throw(TypeError, 'Float32 of wrong type is passed: 3.14') - }) - it('should throw error when the value of invalid type', function () { expect(() => scheme.getType('type16').serialize({ balance: undefined })) .to.throw(TypeError, 'Field balance is not defined.'); @@ -687,16 +558,6 @@ describe('Check built-in types', function () { expect(buffer).to.deep.equal([255, 255, 255, 255, 255, 255, 239, 255]) }) - it('should throw error when the range of segment is invalid', function () { - const Type = Exonum.newType({ - size: 8, - fields: { balance: { type: Exonum.Float64, size: 8, from: 0, to: 4 } } - }) - - expect(() => Type.serialize({ balance: 613.228 })) - .to.throw(TypeError, 'Float64 of wrong type is passed: 613.228') - }) - it('should throw error when the value of invalid type', function () { expect(() => scheme.getType('type17').serialize({ balance: undefined })) .to.throw(TypeError, 'Field balance is not defined.'); @@ -716,14 +577,12 @@ describe('Check built-in types', function () { it('should serialize valid array of PublicKey type and return array of 8-bit integers', function () { const Arr = Exonum.newArray({ - size: 32, type: Exonum.PublicKey }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [ @@ -737,14 +596,12 @@ describe('Check built-in types', function () { it('should serialize valid array of Digest type and return array of 8-bit integers', function () { const Arr = Exonum.newArray({ - size: 64, type: Exonum.Digest }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [ @@ -757,14 +614,12 @@ describe('Check built-in types', function () { it('should serialize valid array of Timespec type and return array of 8-bit integers', function () { const Arr = Exonum.newArray({ - size: 8, type: Exonum.Timespec }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [ @@ -779,14 +634,12 @@ describe('Check built-in types', function () { it('should serialize valid array of Bool type and return array of 8-bit integers', function () { const Arr = Exonum.newArray({ - size: 1, type: Exonum.Bool }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [true, true, false] @@ -797,14 +650,12 @@ describe('Check built-in types', function () { it('should serialize valid array of Int8 type and return array of 8-bit integers', function () { const Arr = Exonum.newArray({ - size: 1, type: Exonum.Int8 }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [ @@ -819,14 +670,12 @@ describe('Check built-in types', function () { it('should serialize valid array of Int16 type and return array of 8-bit integers', function () { const Arr = Exonum.newArray({ - size: 2, type: Exonum.Int16 }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [ @@ -841,14 +690,12 @@ describe('Check built-in types', function () { it('should serialize valid array of Int32 type and return array of 8-bit integers', function () { const Arr = Exonum.newArray({ - size: 4, type: Exonum.Int32 }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [ @@ -865,14 +712,12 @@ describe('Check built-in types', function () { it('should serialize valid array of Int64 type and return array of 8-bit integers', function () { const Arr = Exonum.newArray({ - size: 8, type: Exonum.Int64 }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [ @@ -888,14 +733,12 @@ describe('Check built-in types', function () { it('should serialize valid array of Uint8 type and return array of 8-bit integers', function () { const Arr = Exonum.newArray({ - size: 1, type: Exonum.Uint8 }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [ @@ -910,14 +753,12 @@ describe('Check built-in types', function () { it('should serialize valid array of Uint16 type and return array of 8-bit integers', function () { const Arr = Exonum.newArray({ - size: 2, type: Exonum.Uint16 }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [ @@ -932,14 +773,12 @@ describe('Check built-in types', function () { it('should serialize valid array of Uint32 type and return array of 8-bit integers', function () { const Arr = Exonum.newArray({ - size: 4, type: Exonum.Uint32 }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [ @@ -956,14 +795,12 @@ describe('Check built-in types', function () { it('should serialize valid array of Uint64 type and return array of 8-bit integers', function () { const Arr = Exonum.newArray({ - size: 8, type: Exonum.Uint64 }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [ @@ -979,18 +816,15 @@ describe('Check built-in types', function () { it('should serialize valid array of Array type and return array of 8-bit integers', function () { const NestedArr = Exonum.newArray({ - size: 1, type: Exonum.Uint8 }) const Arr = Exonum.newArray({ - size: 8, type: NestedArr }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [ @@ -1004,22 +838,19 @@ describe('Check built-in types', function () { it('should serialize valid array of fixed-length newType type and return array of 8-bit integers', function () { const NestedType = Exonum.newType({ - size: 4, - fields: { - day: { type: Exonum.Uint8, size: 1, from: 0, to: 1 }, - month: { type: Exonum.Uint8, size: 1, from: 1, to: 2 }, - year: { type: Exonum.Uint16, size: 2, from: 2, to: 4 } - } + fields: [ + { name: 'day', type: Exonum.Uint8 }, + { name: 'month', type: Exonum.Uint8 }, + { name: 'year', type: Exonum.Uint16 } + ] }) const Arr = Exonum.newArray({ - size: 4, type: NestedType }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [ @@ -1033,21 +864,18 @@ describe('Check built-in types', function () { it('should serialize valid array of non-fixed-length newType type and return array of 8-bit integers', function () { const NestedType = Exonum.newType({ - size: 9, - fields: { - name: { type: Exonum.String, size: 8, from: 0, to: 8 }, - age: { type: Exonum.Uint8, size: 1, from: 8, to: 9 } - } + fields: [ + { name: 'name', type: Exonum.String }, + { name: 'age', type: Exonum.Uint8 } + ] }) const Arr = Exonum.newArray({ - type: NestedType, - size: 9 + type: NestedType }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [ @@ -1061,32 +889,28 @@ describe('Check built-in types', function () { it('should serialize valid array of nested newType types and return array of 8-bit integers', function () { const Profile = Exonum.newType({ - size: 11, - fields: { - id: { type: Exonum.Uint8, size: 1, from: 0, to: 1 }, - name: { type: Exonum.String, size: 8, from: 1, to: 9 }, - since: { type: Exonum.Uint16, size: 2, from: 9, to: 11 } - } + fields: [ + { name: 'id', type: Exonum.Uint8 }, + { name: 'name', type: Exonum.String }, + { name: 'since', type: Exonum.Uint16 } + ] }) const Arr = Exonum.newArray({ - type: Profile, - size: 11 + type: Profile }) const Diploma = Exonum.newType({ - size: 10, - fields: { - title: { type: Exonum.String, size: 8, from: 0, to: 8 }, - year: { type: Exonum.Uint16, size: 2, from: 8, to: 10 } - } + fields: [ + { name: 'title', type: Exonum.String }, + { name: 'year', type: Exonum.Uint16 } + ] }) const User = Exonum.newType({ - size: 25, - fields: { - name: { type: Exonum.String, size: 8, from: 0, to: 8 }, - age: { type: Exonum.Uint8, size: 1, from: 8, to: 9 }, - profiles: { type: Arr, size: 8, from: 9, to: 17 }, - diploma: { type: Diploma, size: 8, from: 17, to: 25 } - } + fields: [ + { name: 'name', type: Exonum.String }, + { name: 'age', type: Exonum.Uint8 }, + { name: 'profiles', type: Arr }, + { name: 'diploma', type: Diploma } + ] }) const data = { name: 'John Doe', @@ -1114,14 +938,12 @@ describe('Check built-in types', function () { it('should throw error when value of wrong type is passed', function () { const Arr = Exonum.newArray({ - size: 1, type: Exonum.Bool }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [ @@ -1133,13 +955,12 @@ describe('Check built-in types', function () { it('should throw error when type of wrong type is passed', function () { const Arr = Exonum.newArray({ - type: Exonum.Int8 + type: Exonum.String }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [ @@ -1151,14 +972,12 @@ describe('Check built-in types', function () { it('should throw error when array of String type is passed', function () { const Arr = Exonum.newArray({ - size: 8, type: Exonum.String }) const Type = Exonum.newType({ - size: 8, - fields: { - list: { type: Arr, size: 8, from: 0, to: 8 } - } + fields: [ + { name: 'list', type: Arr } + ] }) const data = { list: [