From c4d82f6391e3fdb800ce1d2189792ed4ceb4a5f7 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Tue, 26 Jul 2022 20:56:36 +0300 Subject: [PATCH 01/39] Update lisk-validators to return single error and compatible type check - Closes #7156 --- .../commands/genesis-block/create.ts | 8 +- .../commands/transaction/create.ts | 6 +- elements/lisk-api-client/src/transaction.ts | 8 +- elements/lisk-chain/src/block_assets.ts | 14 +- elements/lisk-chain/src/block_header.ts | 30 +- elements/lisk-chain/src/transaction.ts | 8 +- elements/lisk-codec/src/codec.ts | 9 +- elements/lisk-p2p/src/utils/validate.ts | 19 +- elements/lisk-transactions/src/validate.ts | 12 +- elements/lisk-validator/src/errors.ts | 5 +- elements/lisk-validator/src/lisk_validator.ts | 14 +- .../test/lisk_validator.spec.ts | 90 +--- .../test/lisk_validator_errors.spec.ts | 26 +- .../test/lisk_validator_formats.spec.ts | 95 ++-- .../test/lisk_validator_keywords.spec.ts | 461 +++++++++--------- .../src/plugin/endpoint.ts | 14 +- .../src/endpoint.ts | 8 +- framework/src/application.ts | 8 +- framework/src/controller/jsonrpc/utils.ts | 12 +- .../src/engine/consensus/network_endpoint.ts | 35 +- .../synchronizer/base_synchronizer.ts | 6 +- framework/src/engine/endpoint/chain.ts | 13 +- framework/src/engine/endpoint/txpool.ts | 14 +- framework/src/engine/generator/endpoint.ts | 8 +- framework/src/engine/generator/generator.ts | 7 +- .../src/engine/generator/network_endpoint.ts | 32 +- .../auth/commands/register_multisignature.ts | 10 +- framework/src/modules/auth/module.ts | 7 +- .../dpos_v2/commands/delegate_registration.ts | 12 +- framework/src/modules/dpos_v2/commands/pom.ts | 11 +- .../dpos_v2/commands/update_generator_key.ts | 12 +- .../src/modules/dpos_v2/commands/vote.ts | 10 +- framework/src/modules/dpos_v2/module.ts | 13 +- framework/src/modules/fee/module.ts | 8 +- .../mainchain/commands/cc_update.ts | 9 +- .../commands/sidechain_registration.ts | 11 +- .../mainchain/commands/state_recovery.ts | 11 +- .../sidechain/commands/cc_update.ts | 9 +- .../commands/mainchain_registration.ts | 9 +- .../src/modules/interoperability/utils.ts | 8 +- framework/src/modules/random/endpoint.ts | 8 +- framework/src/modules/random/module.ts | 14 +- framework/src/modules/reward/module.ts | 8 +- .../modules/token/cc_commands/cc_forward.ts | 8 +- .../modules/token/cc_commands/cc_transfer.ts | 8 +- .../src/modules/token/commands/cc_transfer.ts | 10 +- .../src/modules/token/commands/transfer.ts | 10 +- framework/src/modules/token/endpoint.ts | 14 +- framework/src/modules/token/module.ts | 13 +- framework/src/modules/validators/endpoint.ts | 7 +- framework/src/modules/validators/module.ts | 8 +- framework/src/plugins/base_plugin.ts | 13 +- .../modules/dpos_v2/commands/vote.spec.ts | 10 +- .../schema/application_config_schema.spec.ts | 47 +- 54 files changed, 538 insertions(+), 742 deletions(-) diff --git a/commander/src/bootstrapping/commands/genesis-block/create.ts b/commander/src/bootstrapping/commands/genesis-block/create.ts index 7dfdc8cf50d..609f2d2dca6 100644 --- a/commander/src/bootstrapping/commands/genesis-block/create.ts +++ b/commander/src/bootstrapping/commands/genesis-block/create.ts @@ -22,7 +22,7 @@ import * as fs from 'fs-extra'; import { join, resolve } from 'path'; import * as inquirer from 'inquirer'; import * as ProgressBar from 'progress'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BlockJSON } from '@liskhq/lisk-chain'; import { createMnemonicPassphrase } from '../../../utils/mnemonic'; import { @@ -193,10 +193,8 @@ export abstract class BaseGenesisBlockCommand extends Command { // If assetsFile exist, create from assetsFile and default config/accounts are not needed if (assetsFile) { const assetsJSON = (await fs.readJSON(resolve(assetsFile))) as GenesisAssetsInput; - const assetSchemaError = validator.validate(genesisAssetsSchema, assetsJSON); - if (assetSchemaError.length) { - throw new LiskValidationError(assetSchemaError); - } + validator.validate(genesisAssetsSchema, assetsJSON); + const genesisBlock = await app.generateGenesisBlock({ assets: assetsJSON.assets.map(a => ({ moduleID: a.moduleID, diff --git a/commander/src/bootstrapping/commands/transaction/create.ts b/commander/src/bootstrapping/commands/transaction/create.ts index 06a61a300a2..e62d29f0e7c 100644 --- a/commander/src/bootstrapping/commands/transaction/create.ts +++ b/commander/src/bootstrapping/commands/transaction/create.ts @@ -122,11 +122,7 @@ const validateAndSignTransaction = ( ) as Schema; const txObject = codec.fromJSON(schema.transaction, { ...transactionWithoutParams, params: '' }); - const transactionErrors = validator.validator.validate(schema.transaction, txObject); - - if (transactionErrors.length) { - throw new validator.LiskValidationError([...transactionErrors]); - } + validator.validator.validate(schema.transaction, txObject); const paramsObject = paramsSchema ? codec.fromJSON(paramsSchema, params) : {}; diff --git a/elements/lisk-api-client/src/transaction.ts b/elements/lisk-api-client/src/transaction.ts index 353630e7224..160e9cd58aa 100644 --- a/elements/lisk-api-client/src/transaction.ts +++ b/elements/lisk-api-client/src/transaction.ts @@ -18,7 +18,7 @@ import { computeMinFee, } from '@liskhq/lisk-transactions'; import { address as cryptoAddress } from '@liskhq/lisk-cryptography'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { codec } from '@liskhq/lisk-codec'; import { decodeTransaction, @@ -337,13 +337,11 @@ export class Transaction { throw new Error('Transaction must be an object.'); } const { params, ...rest } = transaction as Record; - const errors = validator.validate(this._schema.transaction, { + validator.validate(this._schema.transaction, { ...rest, params: Buffer.alloc(0), }); - if (errors.length) { - throw new LiskValidationError(errors); - } + if (Buffer.isBuffer(params)) { throw new Error('Transaction parameter is not decoded.'); } diff --git a/elements/lisk-chain/src/block_assets.ts b/elements/lisk-chain/src/block_assets.ts index fd965908b13..c0fe3193a3f 100644 --- a/elements/lisk-chain/src/block_assets.ts +++ b/elements/lisk-chain/src/block_assets.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { codec } from '@liskhq/lisk-codec'; import { MerkleTree } from '@liskhq/lisk-tree'; import { blockAssetSchema } from './schema'; @@ -87,10 +87,8 @@ export class BlockAssets { let last = this._assets[0]; let i = 0; for (const asset of this._assets) { - const errors = validator.validate(blockAssetSchema, asset); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(blockAssetSchema, asset); + // Data size of each module should not be greater than max asset data size if (asset.data.byteLength > MAX_ASSET_DATA_SIZE_BYTES) { throw new Error( @@ -117,10 +115,8 @@ export class BlockAssets { let last = this._assets[0]; let i = 0; for (const asset of this._assets) { - const errors = validator.validate(blockAssetSchema, asset); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(blockAssetSchema, asset); + if (last.moduleID > asset.moduleID) { throw new Error('Assets are not sorted in the increasing values of moduleID.'); } diff --git a/elements/lisk-chain/src/block_header.ts b/elements/lisk-chain/src/block_header.ts index e0ad3cfd35d..392cc97765a 100644 --- a/elements/lisk-chain/src/block_header.ts +++ b/elements/lisk-chain/src/block_header.ts @@ -12,12 +12,15 @@ * Removal or modification of this copyright notice is prohibited. */ -import { ed, utils } from '@liskhq/lisk-cryptography'; -import { codec } from '@liskhq/lisk-codec'; -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; -import { EMPTY_BUFFER, EMPTY_HASH, SIGNATURE_LENGTH_BYTES, TAG_BLOCK_HEADER } from './constants'; -import { blockHeaderSchema, blockHeaderSchemaWithId, signingBlockHeaderSchema } from './schema'; -import { JSONObject } from './types'; +import {ed, utils} from '@liskhq/lisk-cryptography'; +import {codec} from '@liskhq/lisk-codec'; +import {LiskValidationError, validator} from '@liskhq/lisk-validator'; +import {LiskErrorObject} from "@liskhq/lisk-validator/dist-node/types"; +import {JSONObject} from './types'; +import {EMPTY_BUFFER, EMPTY_HASH, SIGNATURE_LENGTH_BYTES, TAG_BLOCK_HEADER} from './constants'; +import {blockHeaderSchema, blockHeaderSchemaWithId, signingBlockHeaderSchema} from './schema'; + + export interface BlockHeaderAttrs { readonly version: number; @@ -174,10 +177,8 @@ export class BlockHeader { } public validate(): void { - const errors = validator.validate(blockHeaderSchema, this._getBlockHeaderProps()); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(blockHeaderSchema, this._getBlockHeaderProps()); + if (this.previousBlockID.length === 0) { throw new Error('Previous block id must not be empty.'); } @@ -188,7 +189,10 @@ export class BlockHeader { public validateGenesis(): void { const header = this._getBlockHeaderProps(); - const errors = validator.validate(blockHeaderSchema, header); + + validator.validate(blockHeaderSchema, header); + + const errors: LiskErrorObject[] = [] if (header.previousBlockID.length !== 32) { errors.push({ @@ -301,9 +305,7 @@ export class BlockHeader { } public getSigningBytes(): Buffer { - const blockHeaderBytes = codec.encode(signingBlockHeaderSchema, this._getSigningProps()); - - return blockHeaderBytes; + return codec.encode(signingBlockHeaderSchema, this._getSigningProps()); } public sign(networkIdentifier: Buffer, privateKey: Buffer): void { diff --git a/elements/lisk-chain/src/transaction.ts b/elements/lisk-chain/src/transaction.ts index 6b573c9336e..c436a00a6a3 100644 --- a/elements/lisk-chain/src/transaction.ts +++ b/elements/lisk-chain/src/transaction.ts @@ -14,7 +14,7 @@ import { codec } from '@liskhq/lisk-codec'; import { utils, address, ed } from '@liskhq/lisk-cryptography'; -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { TAG_TRANSACTION } from './constants'; import { JSONObject } from './types'; @@ -155,10 +155,8 @@ export class Transaction { } public validate(): void { - const schemaErrors = validator.validate(transactionSchema, this); - if (schemaErrors.length > 0) { - throw new LiskValidationError(schemaErrors); - } + validator.validate(transactionSchema, this); + if (this.signatures.length === 0) { throw new Error('Signatures must not be empty'); } diff --git a/elements/lisk-codec/src/codec.ts b/elements/lisk-codec/src/codec.ts index 2034621ce2c..2044e8f8381 100644 --- a/elements/lisk-codec/src/codec.ts +++ b/elements/lisk-codec/src/codec.ts @@ -13,8 +13,6 @@ */ import { - ErrorObject, - LiskValidationError, validator, liskSchemaIdentifier, } from '@liskhq/lisk-validator'; @@ -60,12 +58,7 @@ export const validateSchema = (schema: { $schema: schema.$schema ?? liskSchemaIdentifier, }; - const errors: ReadonlyArray = validator.validateSchema(schemaToValidate); - - if (errors.length) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-call - throw new LiskValidationError([...errors]); - } + validator.validateSchema(schemaToValidate); try { // To validate keyword schema we have to compile it diff --git a/elements/lisk-p2p/src/utils/validate.ts b/elements/lisk-p2p/src/utils/validate.ts index 29ce557e710..6f097817534 100644 --- a/elements/lisk-p2p/src/utils/validate.ts +++ b/elements/lisk-p2p/src/utils/validate.ts @@ -146,25 +146,26 @@ export const validatePeerInfoList = ( }; export const validateRPCRequest = (request: unknown): void => { - const errors = validator.validate(rpcRequestSchema, request as Record); - - if (errors.length) { + try { + validator.validate(rpcRequestSchema, request as Record); + } catch { throw new Error('RPC request format is invalid.'); } }; export const validateProtocolMessage = (message: unknown): void => { - const errors = validator.validate(protocolMessageSchema, message as Record); - - if (errors.length) { + try { + validator.validate(protocolMessageSchema, message as Record); + } catch { throw new Error('Protocol message format is invalid.'); } + }; export const validatePacket = (packet: unknown): void => { - const errors = validator.validate(packetSchema, packet as P2PMessagePacket | P2PRequestPacket); - - if (errors.length) { + try { + validator.validate(packetSchema, packet as P2PMessagePacket | P2PRequestPacket); + } catch { throw new Error('Packet format is invalid.'); } }; diff --git a/elements/lisk-transactions/src/validate.ts b/elements/lisk-transactions/src/validate.ts index 83800db6727..00d3a3aff14 100644 --- a/elements/lisk-transactions/src/validate.ts +++ b/elements/lisk-transactions/src/validate.ts @@ -24,13 +24,11 @@ export const validateTransaction = ( ...transactionObject, params: Buffer.alloc(0), }; - const schemaErrors = validator.validate( + validator.validate( baseTransactionSchema, transactionObjectWithEmptyParameters, ); - if (schemaErrors.length) { - return new LiskValidationError([...schemaErrors]); - } + if (!paramsSchema) { return undefined; } @@ -38,9 +36,7 @@ export const validateTransaction = ( if (typeof transactionObject.params !== 'object' || transactionObject.params === null) { return new Error('Transaction object params must be of type object and not null'); } - const paramsSchemaErrors = validator.validate(paramsSchema, transactionObject.params); - if (paramsSchemaErrors.length) { - return new LiskValidationError([...paramsSchemaErrors]); - } + validator.validate(paramsSchema, transactionObject.params); + return undefined; }; diff --git a/elements/lisk-validator/src/errors.ts b/elements/lisk-validator/src/errors.ts index a8c65850c65..3237bb4a6b2 100644 --- a/elements/lisk-validator/src/errors.ts +++ b/elements/lisk-validator/src/errors.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { LiskErrorObject } from './types'; +import {LiskErrorObject} from './types'; // Ajv.ErrorObject makes `schemaPath` and `dataPath` required // While these are not if we want to infer default values from validation @@ -86,7 +86,6 @@ export class LiskValidationError extends Error { } private _compileErrors(): string[] { - const errorMsgs = this.errors.map(errorFormatter); - return errorMsgs; + return this.errors.map(errorFormatter); } } diff --git a/elements/lisk-validator/src/lisk_validator.ts b/elements/lisk-validator/src/lisk_validator.ts index bf786db7e4f..7574924f1d1 100644 --- a/elements/lisk-validator/src/lisk_validator.ts +++ b/elements/lisk-validator/src/lisk_validator.ts @@ -13,7 +13,7 @@ * */ -import Ajv, { AnySchema, ValidateFunction } from 'ajv'; +import Ajv, {SchemaObject, ValidateFunction} from 'ajv'; import addDefaultFormats from 'ajv-formats'; import * as formats from './formats'; import { convertErrorsToLegacyFormat, LiskValidationError } from './errors'; @@ -69,20 +69,16 @@ class LiskValidator { this._validator.addKeyword(dataTypeKeyword); } - public validate(schema: object, data: object): LiskErrorObject[] { + public validate>(schema: object, data: unknown): asserts data is T { if (!this._validator.validate(schema, data)) { - return convertErrorsToLegacyFormat(this._validator.errors as LiskErrorObject[]); + throw new LiskValidationError(convertErrorsToLegacyFormat(this._validator.errors as LiskErrorObject[])); } - - return []; } - public validateSchema(schema: AnySchema | boolean): ReadonlyArray { + public validateSchema(schema: object): asserts schema is SchemaObject { if (!this._validator.validateSchema(schema)) { - return convertErrorsToLegacyFormat(this._validator.errors as LiskErrorObject[]); + throw new LiskValidationError(convertErrorsToLegacyFormat(this._validator.errors as LiskErrorObject[])); } - - return []; } public compile(schema: object | boolean): ValidateFunction { diff --git a/elements/lisk-validator/test/lisk_validator.spec.ts b/elements/lisk-validator/test/lisk_validator.spec.ts index 3f89934bd61..aef5504b81c 100644 --- a/elements/lisk-validator/test/lisk_validator.spec.ts +++ b/elements/lisk-validator/test/lisk_validator.spec.ts @@ -38,7 +38,6 @@ describe('validator', () => { }); it('should return error on schema with type other than "object"', () => { - // Arrange const invalidSchema = { $id: '/myInvalidSchema', $schema: 'http://lisk.com/lisk-schema/schema#', @@ -46,61 +45,32 @@ describe('validator', () => { properties: {}, }; - // Act - const errors = validator.validateSchema(invalidSchema); - - // Assert - expect(errors).toContainEqual({ - dataPath: '.type', - keyword: 'const', - message: 'must be equal to constant', - schemaPath: '#/properties/type/const', - params: { allowedValue: 'object' }, - }); + const msg = "Lisk validator found 2 error[s]:\nmust be equal to constant\nmust NOT have fewer than 1 items" + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) }); + it('should return error when "type" is not defined', () => { - // Arrange const invalidSchema = { ...validSchema }; delete (invalidSchema as any).type; - // Act - const errors = validator.validateSchema(invalidSchema); - - // Assert - expect(errors).toContainEqual({ - dataPath: '', - keyword: 'required', - message: "must have required property 'type'", - schemaPath: '#/required', - params: { missingProperty: 'type' }, - }); + const msg = "Lisk validator found 1 error[s]:\nMissing property, must have required property 'type'" + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) }); + it('should return error when "$id" is not defined', () => { - // Arrange const invalidSchema = { ...validSchema }; delete (invalidSchema as any).$id; - // Act - const errors = validator.validateSchema(invalidSchema); - - // Assert - expect(errors).toContainEqual({ - dataPath: '', - keyword: 'required', - message: "must have required property '$id'", - schemaPath: '#/required', - params: { missingProperty: '$id' }, - }); + const msg = "Lisk validator found 1 error[s]:\nMissing property, must have required property '$id'" + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) }); // As the schema is always overridden it('should not return error when "$schema" is not defined', () => { - // Arrange const invalidSchema = cloneDeep(validSchema); delete invalidSchema.$schema; - // Assert - expect(validator.validateSchema(invalidSchema)).toEqual([]); + expect(() => validator.validateSchema(invalidSchema)).not.toThrow() }); it('should throw error when "$schema" value is defined other than lisk-schema uri', () => { @@ -115,21 +85,11 @@ describe('validator', () => { }); it('should return error when "properties" is not defined', () => { - // Arrange const invalidSchema = cloneDeep(validSchema); delete invalidSchema.properties; - // Act - const errors = validator.validateSchema(invalidSchema); - - // Assert - expect(errors).toContainEqual({ - dataPath: '', - keyword: 'required', - message: "must have required property 'properties'", - schemaPath: '#/required', - params: { missingProperty: 'properties' }, - }); + const msg = "Lisk validator found 1 error[s]:\nMissing property, must have required property 'properties'" + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) }); it('should return error when "properties" are not camelcase', () => { @@ -141,36 +101,16 @@ describe('validator', () => { }, }; - // Act - const errors = validator.validateSchema(invalidSchema); - - // Assert - expect(errors).toContainEqual({ - dataPath: '.properties', - keyword: 'format', - message: 'must match format "camelCase"', - schemaPath: '#/properties/properties/propertyNames/format', - params: { format: 'camelCase' }, - propertyName: 'my-custom-prop', - }); + const msg = "Lisk validator found 2 error[s]:\nProperty '.properties' must match format \"camelCase\""; + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) }); it('should return error when "properties" are empty object', () => { - // Arrange const invalidSchema = cloneDeep(validSchema); delete invalidSchema.properties.myProp; - // Act - const errors = validator.validateSchema(invalidSchema); - - // Assert - expect(errors).toContainEqual({ - dataPath: '.properties', - keyword: 'minProperties', - message: 'must NOT have fewer than 1 items', - schemaPath: '#/properties/properties/minProperties', - params: { limit: 1 }, - }); + const msg = "Lisk validator found 1 error[s]:\nmust NOT have fewer than 1 items"; + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) }); }); }); diff --git a/elements/lisk-validator/test/lisk_validator_errors.spec.ts b/elements/lisk-validator/test/lisk_validator_errors.spec.ts index b982cc51027..6855fd95f60 100644 --- a/elements/lisk-validator/test/lisk_validator_errors.spec.ts +++ b/elements/lisk-validator/test/lisk_validator_errors.spec.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. * */ -import { LiskValidationError, validator } from '../src'; +import { validator } from '../src'; // eslint-disable-next-line @typescript-eslint/no-var-requires const cloneDeep = require('lodash.clonedeep'); @@ -44,9 +44,7 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nProperty '.myProp' should be of type 'string'"; - expect(() => { - throw new LiskValidationError([...validator.validate(schema, obj)]); - }).toThrow(expectedError); + expect(() => validator.validate(schema, obj)).toThrow(expectedError) }); it('should format minLength errors', () => { @@ -58,9 +56,7 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have fewer than 2 characters"; - expect(() => { - throw new LiskValidationError([...validator.validate(schema, obj)]); - }).toThrow(expectedError); + expect(() => validator.validate(schema, obj)).toThrow(expectedError) }); it('should format maxLength errors', () => { @@ -72,9 +68,7 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have more than 5 characters"; - expect(() => { - throw new LiskValidationError([...validator.validate(schema, obj)]); - }).toThrow(expectedError); + expect(() => validator.validate(schema, obj)).toThrow(expectedError) }); it('should format custom format errors', () => { @@ -86,9 +80,7 @@ describe('LiskValidationError formatter', () => { const expectedError = 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' must match format "hex"'; - expect(() => { - throw new LiskValidationError([...validator.validate(schema, obj)]); - }).toThrow(expectedError); + expect(() => validator.validate(schema, obj)).toThrow(expectedError) }); it('should format missing required property errors', () => { @@ -97,9 +89,7 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nMissing property, must have required property 'myProp'"; - expect(() => { - throw new LiskValidationError([...validator.validate(schema, obj)]); - }).toThrow(expectedError); + expect(() => validator.validate(schema, obj)).toThrow(expectedError) }); it('should format additional property errors', () => { @@ -130,8 +120,6 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nProperty '.myProp' has extraneous property 'bar'"; - expect(() => { - throw new LiskValidationError([...validator.validate(schema, obj)]); - }).toThrow(expectedError); + expect(() => validator.validate(schema, obj)).toThrow(expectedError) }); }); diff --git a/elements/lisk-validator/test/lisk_validator_formats.spec.ts b/elements/lisk-validator/test/lisk_validator_formats.spec.ts index f9a327bd344..87a521d17d0 100644 --- a/elements/lisk-validator/test/lisk_validator_formats.spec.ts +++ b/elements/lisk-validator/test/lisk_validator_formats.spec.ts @@ -45,26 +45,16 @@ describe('validator formats', () => { it('should validate to true when valid hex string is provided', () => { expect( - validator.validate(schema, { target: '23b9ed818526a928bce91b96fb4508babb121ee2' }), - ).toEqual([]); + () => validator.validate(schema, { target: '23b9ed818526a928bce91b96fb4508babb121ee2' }) + ).not.toThrow() }); it('should validate to false when not hex is provided', () => { - const expectedError = [ - { - keyword: 'format', - dataPath: '.target', - schemaPath: '#/allOf/1/properties/target/format', - params: { format: 'hex' }, - message: 'must match format "hex"', - }, - ]; + const expectedError = "Lisk validator found 1 error[s]:\nProperty '.target' must match format \"hex\""; - expect( - validator.validate(schema, { - target: 'notValid?!hex-!!@', - }), - ).toEqual(expectedError); + expect(() => validator.validate(schema, { + target: 'notValid?!hex-!!@', + })).toThrow(expectedError) }); }); @@ -79,25 +69,15 @@ describe('validator formats', () => { }; it('should validate to false for invalid path', () => { - const expectedError = [ - { - keyword: 'format', - dataPath: '.rootPath', - schemaPath: '#/properties/rootPath/format', - params: { format: 'path' }, - message: 'must match format "path"', - }, - ]; - - expect(validator.validate(pathSchema, { rootPath: 'lisk' })).toEqual(expectedError); + expect(() => validator.validate(pathSchema, { rootPath: 'lisk' })).toThrow("Property '.rootPath' must match format \"path\"") }); it('should validate to true for valid path with tilde', () => { - expect(validator.validate(pathSchema, { rootPath: '~/.lisk' })).toBeEmpty(); + expect(() => validator.validate(pathSchema, { rootPath: '~/.lisk' })).not.toThrow(); }); it('should validate to true for valid path', () => { - expect(validator.validate(pathSchema, { rootPath: '/tmp/lisk/test/' })).toBeEmpty(); + expect(() => validator.validate(pathSchema, { rootPath: '/tmp/lisk/test/' })).not.toThrow(); }); }); @@ -112,15 +92,8 @@ describe('validator formats', () => { }; it('should validate to false for invalid path', () => { - const expectedError = [ - { - keyword: 'format', - dataPath: '.encryptedPassphrase', - schemaPath: '#/properties/encryptedPassphrase/format', - params: { format: 'encryptedPassphrase' }, - message: 'must match format "encryptedPassphrase"', - }, - ]; + const expectedError = + "Lisk validator found 1 error[s]:\nProperty '.encryptedPassphrase' must match format \"encryptedPassphrase\""; [ 'cipherText', @@ -128,20 +101,20 @@ describe('validator formats', () => { 'cipherText=abcd1234&iterations=10000&iv=ef012345cipherText=abcd1234&iterations=10000&iv=ef012345', ].forEach(text => { expect( - validator.validate(encryptedPassphraseSchema, { + () => validator.validate(encryptedPassphraseSchema, { encryptedPassphrase: text, }), - ).toEqual(expectedError); + ).toThrow(expectedError); }); }); it('should validate to true for valid encrypted passphrase', () => { ['cipherText=abcd1234', 'cipherText=abcd1234&iterations=10000&iv=ef012345'].forEach(text => { expect( - validator.validate(encryptedPassphraseSchema, { + () => validator.validate(encryptedPassphraseSchema, { encryptedPassphrase: text, }), - ).toBeEmpty(); + ).not.toThrow(); }); }); }); @@ -157,26 +130,20 @@ describe('validator formats', () => { }; it('should validate to false for invalid camel case text', () => { - const expectedError = [ - { - keyword: 'format', - dataPath: '.camelCaseRegex', - schemaPath: '#/properties/camelCaseRegex/format', - params: { format: 'camelCase' }, - message: 'must match format "camelCase"', - }, - ]; + const expectedError = "Lisk validator found 1 error[s]:\nProperty '.camelCaseRegex' must match format \"camelCase\""; ['NotCamelCase', '123Case', '_camelCase'].forEach(text => { - expect(validator.validate(camelCaseRegexSchema, { camelCaseRegex: text })).toEqual( - expectedError, - ); + expect( + () => validator.validate(camelCaseRegexSchema, { camelCaseRegex: text }) + ).toThrow(expectedError); }); }); it('should validate to true for valid camel case text', () => { ['camelCase'].forEach(text => { - expect(validator.validate(camelCaseRegexSchema, { camelCaseRegex: text })).toBeEmpty(); + expect( + () => validator.validate(camelCaseRegexSchema, { camelCaseRegex: text }) + ).not.toThrow(); }); }); }); @@ -192,24 +159,20 @@ describe('validator formats', () => { }; it('should validate to false for invalid semantic versions', () => { - const expectedError = [ - { - keyword: 'format', - dataPath: '.version', - schemaPath: '#/properties/version/format', - params: { format: 'version' }, - message: 'must match format "version"', - }, - ]; + const expectedError = "Lisk validator found 1 error[s]:\nProperty '.version' must match format \"version\""; ['9999999999999999.4.7.4', 'alpha one', '1.2.12.102', '4.6.3.9.2-alpha2'].forEach(text => { - expect(validator.validate(versionSchema, { version: text })).toEqual(expectedError); + expect( + () =>validator.validate(versionSchema, { version: text }) + ).toThrow(expectedError); }); }); it('should validate to true for valid semantic versions', () => { ['1.2.0', '1.0.0-alpha.0', 'v1.2.3', '1.0.0-beta+exp.sha.5114f85'].forEach(text => { - expect(validator.validate(versionSchema, { version: text })).toBeEmpty(); + expect( + () =>validator.validate(versionSchema, { version: text }) + ).not.toThrow() }); }); }); diff --git a/elements/lisk-validator/test/lisk_validator_keywords.spec.ts b/elements/lisk-validator/test/lisk_validator_keywords.spec.ts index dd60f6fb8a8..10e3d32d98e 100644 --- a/elements/lisk-validator/test/lisk_validator_keywords.spec.ts +++ b/elements/lisk-validator/test/lisk_validator_keywords.spec.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. * */ -import { LiskValidationError, validator } from '../src'; +import {LiskValidationError, validator} from '../src'; // eslint-disable-next-line @typescript-eslint/no-var-requires const cloneDeep = require('lodash.clonedeep'); @@ -84,326 +84,331 @@ describe('validator keywords', () => { describe('dataType value validation', () => { describe('string', () => { - it('should return empty error if valid', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'string', fieldNumber: 1 } }, - }, - { myProp: 'string' }, - ); - expect(result).toBeEmpty(); + it('should not throw error if valid', () => { + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'string', fieldNumber: 1}}, + }, + {myProp: 'string'}, + ) + ).not.toThrow(); }); it('should be invalid if minLength is not satisfied', () => { - const result = validator.validate( - { - ...validSchema, - properties: { - myProp: { dataType: 'string', fieldNumber: 1, minLength: 3 }, + expect( + () => validator.validate( + { + ...validSchema, + properties: { + myProp: {dataType: 'string', fieldNumber: 1, minLength: 3}, + }, }, - }, - { myProp: 'ch' }, - ); - expect(result).toHaveLength(1); + {myProp: 'ch'}, + )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have fewer than 3 characters"); }); it('should be invalid if maxLength is not satisfied', () => { - const result = validator.validate( - { - ...validSchema, - properties: { - myProp: { dataType: 'string', fieldNumber: 1, maxLength: 3 }, + expect( + () => validator.validate( + { + ...validSchema, + properties: { + myProp: {dataType: 'string', fieldNumber: 1, maxLength: 3}, + }, }, - }, - { myProp: 'change' }, - ); - expect(result).toHaveLength(1); + {myProp: 'change'}, + )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have more than 3 characters"); }); it('should be invalid if not string', () => { - const result = validator.validate( - { - ...validSchema, - properties: { - myProp: { dataType: 'string', fieldNumber: 1, maxLength: 3 }, + expect( + () => validator.validate( + { + ...validSchema, + properties: { + myProp: {dataType: 'string', fieldNumber: 1, maxLength: 3}, + }, }, - }, - { myProp: 32 }, - ); - expect(result).toHaveLength(1); + {myProp: 32}, + )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation") }); }); describe('bytes', () => { - it('should return empty error if valid', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'bytes', fieldNumber: 1 } }, - }, - { myProp: Buffer.from('value') }, - ); - expect(result).toBeEmpty(); + it('should not throw error if valid', () => { + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'bytes', fieldNumber: 1}}, + }, + {myProp: Buffer.from('value')}, + )).not.toThrow() }); it('should be invalid if minLength is not satisfied', () => { - const result = validator.validate( - { - ...validSchema, - properties: { - myProp: { dataType: 'bytes', fieldNumber: 1, minLength: 10 }, + expect( + () => validator.validate( + { + ...validSchema, + properties: { + myProp: {dataType: 'bytes', fieldNumber: 1, minLength: 10}, + }, }, - }, - { myProp: Buffer.alloc(9) }, - ); - expect(result).toHaveLength(1); - expect(result[0].message).toEqual('minLength not satisfied'); - expect(result[0].params).toEqual({ - dataType: 'bytes', - minLength: 10, - length: 9, - }); + {myProp: Buffer.alloc(9)}, + )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' minLength not satisfied") }); it('should be invalid if maxLength is not satisfied', () => { - const result = validator.validate( - { - ...validSchema, - properties: { - myProp: { dataType: 'bytes', fieldNumber: 1, maxLength: 10 }, + expect( + () => validator.validate( + { + ...validSchema, + properties: { + myProp: {dataType: 'bytes', fieldNumber: 1, maxLength: 10}, + }, }, - }, - { myProp: Buffer.alloc(11) }, - ); - expect(result).toHaveLength(1); - expect(result[0].message).toEqual('maxLength exceeded'); - expect(result[0].params).toEqual({ - dataType: 'bytes', - maxLength: 10, - length: 11, - }); + {myProp: Buffer.alloc(11)}, + )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' maxLength exceeded") }); it('should be invalid if not Buffer', () => { - const result = validator.validate( - { - ...validSchema, - properties: { - myProp: { dataType: 'bytes', fieldNumber: 1, maxLength: 10 }, + expect( + () => validator.validate( + { + ...validSchema, + properties: { + myProp: {dataType: 'bytes', fieldNumber: 1, maxLength: 10}, + }, }, - }, - { myProp: 'string' }, - ); - expect(result).toHaveLength(1); + {myProp: 'string'}, + )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation") }); }); describe('boolean', () => { - it('should return empty error if valid', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'boolean', fieldNumber: 1 } }, - }, - { myProp: true }, - ); - expect(result).toBeEmpty(); + it('should not throw error if valid', () => { + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'boolean', fieldNumber: 1}}, + }, + {myProp: true}, + )).not.toThrow() }); it('should be invalid if not boolean', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'boolean', fieldNumber: 1 } }, - }, - { myProp: 1 }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'boolean', fieldNumber: 1}}, + }, + {myProp: 1} + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation") }); }); describe('uint32', () => { - it('should return empty error if valid', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, - }, - { myProp: 0 }, - ); - expect(result).toBeEmpty(); + it('should not throw error if valid', () => { + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + }, + {myProp: 0}, + )).not.toThrow(); }); it('should be invalid if not number', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, - }, - { myProp: 'value' }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + }, + {myProp: 'value'}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); it('should be invalid if number has decimal', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, - }, - { myProp: 1.23 }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + }, + {myProp: 1.23}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); it('should be invalid if negative', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, - }, - { myProp: -1 }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + }, + {myProp: -1}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); it('should be invalid if above uint32 range', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, - }, - { myProp: 4294967296 }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + }, + {myProp: 4294967296}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); }); describe('uint64', () => { - it('should return empty error if valid', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint64', fieldNumber: 1 } }, - }, - { myProp: BigInt(32) }, - ); - expect(result).toBeEmpty(); + it('should not throw error if valid', () => { + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint64', fieldNumber: 1}}, + }, + {myProp: BigInt(32)}, + ) + ).not.toThrow(); }); it('should be invalid if not bigint', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint64', fieldNumber: 1 } }, - }, - { myProp: 32 }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint64', fieldNumber: 1}}, + }, + {myProp: 32}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); it('should be invalid if negative', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint64', fieldNumber: 1 } }, - }, - { myProp: BigInt(-32) }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint64', fieldNumber: 1}}, + }, + {myProp: BigInt(-32)}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); it('should be invalid if above uint64 range', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint64', fieldNumber: 1 } }, - }, - { myProp: BigInt('18446744073709551616') }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint64', fieldNumber: 1}}, + }, + {myProp: BigInt('18446744073709551616')}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); }); describe('sint32', () => { - it('should return empty error if valid', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'sint32', fieldNumber: 1 } }, - }, - { myProp: -32 }, - ); - expect(result).toBeEmpty(); + it('should not throw error if valid', () => { + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'sint32', fieldNumber: 1}}, + }, + {myProp: -32}, + ) + ).not.toThrow(); }); it('should be invalid if not number', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'sint32', fieldNumber: 1 } }, - }, - { myProp: 'value' }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'sint32', fieldNumber: 1}}, + }, + {myProp: 'value'}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); it('should be invalid if number has decimal', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'sint32', fieldNumber: 1 } }, - }, - { myProp: -1.23 }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'sint32', fieldNumber: 1}}, + }, + {myProp: -1.23}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); it('should be invalid if not sint32 range', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'sint32', fieldNumber: 1 } }, - }, - { myProp: -2147483649 }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'sint32', fieldNumber: 1}}, + }, + {myProp: -2147483649}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); }); describe('sint64', () => { - it('should return empty error if valid', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'sint64', fieldNumber: 1 } }, - }, - { myProp: BigInt(-32) }, - ); - expect(result).toBeEmpty(); + it('should not throw error if valid', () => { + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'sint64', fieldNumber: 1}}, + }, + {myProp: BigInt(-32)}, + ) + ).not.toThrow() }); it('should be invalid if not bigint', () => { - const result = validator.validate( + expect( + () => validator.validate( { ...validSchema, - properties: { myProp: { dataType: 'sint64', fieldNumber: 1 } }, + properties: {myProp: {dataType: 'sint64', fieldNumber: 1}}, }, - { myProp: 32 }, - ); - expect(result).toHaveLength(1); + {myProp: 32}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); it('should be invalid if above sint64 range', () => { - const result = validator.validate( + expect( + () => validator.validate( { ...validSchema, - properties: { myProp: { dataType: 'sint64', fieldNumber: 1 } }, + properties: {myProp: {dataType: 'sint64', fieldNumber: 1}}, }, - { myProp: BigInt('-9223372036854775809') }, - ); - expect(result).toHaveLength(1); + {myProp: BigInt('-9223372036854775809')}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); }); }); diff --git a/framework-plugins/lisk-framework-faucet-plugin/src/plugin/endpoint.ts b/framework-plugins/lisk-framework-faucet-plugin/src/plugin/endpoint.ts index 58583cb2cdc..8f5c9b69efa 100644 --- a/framework-plugins/lisk-framework-faucet-plugin/src/plugin/endpoint.ts +++ b/framework-plugins/lisk-framework-faucet-plugin/src/plugin/endpoint.ts @@ -24,7 +24,7 @@ import { import { authorizeParamsSchema, fundParamsSchema } from './schemas'; import { FaucetPluginConfig, State } from './types'; -const { validator, LiskValidationError } = liskValidator; +const { validator} = liskValidator; export class Endpoint extends BasePluginEndpoint { private _state: State = { publicKey: undefined, passphrase: undefined }; @@ -38,11 +38,7 @@ export class Endpoint extends BasePluginEndpoint { } // eslint-disable-next-line @typescript-eslint/require-await public async authorize(context: PluginEndpointContext): Promise<{ result: string }> { - const errors = validator.validate(authorizeParamsSchema, context.params); - - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(authorizeParamsSchema, context.params); const { enable, password } = context.params; @@ -71,13 +67,9 @@ export class Endpoint extends BasePluginEndpoint { } public async fundTokens(context: PluginEndpointContext): Promise<{ result: string }> { - const errors = validator.validate(fundParamsSchema, context.params); + validator.validate(fundParamsSchema, context.params); const { address, token } = context.params; - if (errors.length) { - throw new LiskValidationError(errors); - } - if (!this._state.publicKey || !this._state.passphrase) { throw new Error('Faucet is not enabled.'); } diff --git a/framework-plugins/lisk-framework-report-misbehavior-plugin/src/endpoint.ts b/framework-plugins/lisk-framework-report-misbehavior-plugin/src/endpoint.ts index 87178933774..6813c3fad8e 100644 --- a/framework-plugins/lisk-framework-report-misbehavior-plugin/src/endpoint.ts +++ b/framework-plugins/lisk-framework-report-misbehavior-plugin/src/endpoint.ts @@ -20,7 +20,7 @@ import { import { actionParamsSchema } from './schemas'; import { ReportMisbehaviorPluginConfig, State } from './types'; -const { validator, LiskValidationError } = liskValidator; +const { validator} = liskValidator; const { encrypt, address } = cryptography; export class Endpoint extends BasePluginEndpoint { @@ -34,11 +34,7 @@ export class Endpoint extends BasePluginEndpoint { // eslint-disable-next-line @typescript-eslint/require-await public async authorize(context: PluginEndpointContext): Promise<{ result: string }> { - const errors = validator.validate(actionParamsSchema, context.params); - - if (errors.length) { - throw new LiskValidationError([...errors]); - } + validator.validate(actionParamsSchema, context.params); const { enable, password } = context.params; diff --git a/framework/src/application.ts b/framework/src/application.ts index 4398be11eb9..f0d16077fe3 100644 --- a/framework/src/application.ts +++ b/framework/src/application.ts @@ -19,7 +19,7 @@ import * as assert from 'assert'; import * as childProcess from 'child_process'; import { Block } from '@liskhq/lisk-chain'; import { Database, StateDB } from '@liskhq/lisk-db'; -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { objects, jobHandlers } from '@liskhq/lisk-utils'; import { APP_EVENT_SHUTDOWN, APP_EVENT_READY } from './constants'; import { @@ -143,10 +143,8 @@ export class Application { config.label ?? `lisk-${config.genesis?.communityIdentifier}`; const mergedConfig = objects.mergeDeep({}, appConfig, config) as ApplicationConfig; - const applicationConfigErrors = validator.validate(applicationConfigSchema, mergedConfig); - if (applicationConfigErrors.length) { - throw new LiskValidationError(applicationConfigErrors); - } + validator.validate(applicationConfigSchema, mergedConfig); + this.config = mergedConfig; const { plugins, ...rootConfigs } = this.config; diff --git a/framework/src/controller/jsonrpc/utils.ts b/framework/src/controller/jsonrpc/utils.ts index 7779847281d..ab7d7fbd158 100644 --- a/framework/src/controller/jsonrpc/utils.ts +++ b/framework/src/controller/jsonrpc/utils.ts @@ -11,7 +11,7 @@ * * Removal or modification of this copyright notice is prohibited. */ -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { JSONRPCErrorObject, ID, @@ -69,17 +69,11 @@ export function validateJSONRPCRequest(data: unknown): asserts data is RequestOb if (typeof data !== 'object' || data === null) { throw new Error('Data must be type of object.'); } - const errors = validator.validate(requestSchema, data); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(requestSchema, data); } export const validateJSONRPCNotification = (data: Record): void => { - const errors = validator.validate(notificationSchema, data); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(notificationSchema, data); }; export const notificationRequest = ( diff --git a/framework/src/engine/consensus/network_endpoint.ts b/framework/src/engine/consensus/network_endpoint.ts index 8d3348d38e8..b1b72e7c2de 100644 --- a/framework/src/engine/consensus/network_endpoint.ts +++ b/framework/src/engine/consensus/network_endpoint.ts @@ -16,7 +16,7 @@ import { InMemoryDatabase, Database } from '@liskhq/lisk-db'; import { Chain, StateStore } from '@liskhq/lisk-chain'; import { codec } from '@liskhq/lisk-codec'; import { objects } from '@liskhq/lisk-utils'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { Logger } from '../../logger'; import { Network } from '../network'; import { @@ -97,10 +97,10 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { }); throw error; } - const errors = validator.validate(getBlocksFromIdRequestSchema, decodedData); - if (errors.length) { - const error = new LiskValidationError(errors); + try { + validator.validate(getBlocksFromIdRequestSchema, decodedData); + } catch (error) { this._logger.warn( { err: error, @@ -149,25 +149,29 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { getHighestCommonBlockRequestSchema, data as never, ); - const errors = validator.validate(getHighestCommonBlockRequestSchema, blockIds); - if (errors.length || !objects.bufferArrayUniqueItems(blockIds.ids)) { - const error = new LiskValidationError(errors); - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + const logDataAndApplyPenalty = (data? : unknown) => { this._logger.warn( - { - err: error, - req: data, - }, + data, 'getHighestCommonBlock request validation failed', ); this._network.applyPenaltyOnPeer({ peerId, penalty: 100, }); + } + + try { + validator.validate(getHighestCommonBlockRequestSchema, blockIds); + } catch (error) { + logDataAndApplyPenalty({ err: error, req: data}) throw error; } + if (!objects.bufferArrayUniqueItems(blockIds.ids)) { + logDataAndApplyPenalty({ req: data}); + } + const commonBlockHeaderID = await this._chain.dataAccess.getHighestCommonBlockID(blockIds.ids); return codec.encode(getHighestCommonBlockResponseSchema, { @@ -202,10 +206,9 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { throw error; } - const errors = validator.validate(singleCommitSchema, decodedData.singleCommit); - - if (errors.length) { - const error = new LiskValidationError(errors); + try { + validator.validate(singleCommitSchema, decodedData.singleCommit); + } catch (error) { this._logger.debug( { peerId, penalty: 100 }, 'Adding penalty on peer for invalid single commit', diff --git a/framework/src/engine/consensus/synchronizer/base_synchronizer.ts b/framework/src/engine/consensus/synchronizer/base_synchronizer.ts index 0f022b5b6e4..bb848f83566 100644 --- a/framework/src/engine/consensus/synchronizer/base_synchronizer.ts +++ b/framework/src/engine/consensus/synchronizer/base_synchronizer.ts @@ -78,8 +78,10 @@ export abstract class BaseSynchronizer { getHighestCommonBlockResponseSchema, data, ); - const errors = validator.validate(getHighestCommonBlockResponseSchema, decodedResp); - if (errors.length) { + + try { + validator.validate(getHighestCommonBlockResponseSchema, decodedResp); + } catch { throw new ApplyPenaltyAndAbortError(peerId, 'Invalid common block response format'); } return this._chain.dataAccess.getBlockHeaderByID(decodedResp.id); diff --git a/framework/src/engine/endpoint/chain.ts b/framework/src/engine/endpoint/chain.ts index f46a9abea84..b22a1946682 100644 --- a/framework/src/engine/endpoint/chain.ts +++ b/framework/src/engine/endpoint/chain.ts @@ -23,7 +23,7 @@ import { TransactionJSON, } from '@liskhq/lisk-chain'; import { InMemoryDatabase, Database, NotFoundError } from '@liskhq/lisk-db'; -import { isHexString, LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { isHexString, validator } from '@liskhq/lisk-validator'; import { SparseMerkleTree, SMTProof } from '@liskhq/lisk-tree'; import { JSONObject } from '../../types'; import { RequestContext } from '../rpc/rpc_server'; @@ -187,10 +187,8 @@ export class ChainEndpoint { } public async proveEvents(context: RequestContext): Promise> { - const errors = validator.validate(proveEventsRequestSchema, context.params); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(proveEventsRequestSchema, context.params); + const { height, queries } = context.params as { height: number; queries: string[] }; const queryBytes = queries.map(q => Buffer.from(q, 'hex')); const events = await this._chain.dataAccess.getEvents(height); @@ -232,10 +230,7 @@ export class ChainEndpoint { // eslint-disable-next-line @typescript-eslint/require-await public async areHeadersContradicting(context: RequestContext): Promise<{ valid: boolean }> { - const errors = validator.validate(areHeadersContradictingRequestSchema, context.params); - if (errors.length > 0) { - throw new LiskValidationError(errors); - } + validator.validate(areHeadersContradictingRequestSchema, context.params); const bftHeader1 = BlockHeader.fromBytes(Buffer.from(context.params.header1 as string, 'hex')); const bftHeader2 = BlockHeader.fromBytes(Buffer.from(context.params.header2 as string, 'hex')); diff --git a/framework/src/engine/endpoint/txpool.ts b/framework/src/engine/endpoint/txpool.ts index ebc78206672..2f841e046b4 100644 --- a/framework/src/engine/endpoint/txpool.ts +++ b/framework/src/engine/endpoint/txpool.ts @@ -15,7 +15,7 @@ import { Database } from '@liskhq/lisk-db'; import { Chain, Transaction, Event, StateStore } from '@liskhq/lisk-chain'; import { TransactionPool } from '@liskhq/lisk-transaction-pool'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { Broadcaster } from '../generator/broadcaster'; import { InvalidTransactionError } from '../generator/errors'; import { @@ -59,10 +59,8 @@ export class TxpoolEndpoint { } public async postTransaction(ctx: RequestContext): Promise { - const reqErrors = validator.validate(postTransactionRequestSchema, ctx.params); - if (reqErrors?.length) { - throw new LiskValidationError(reqErrors); - } + validator.validate(postTransactionRequestSchema, ctx.params); + const req = (ctx.params as unknown) as PostTransactionRequest; const transaction = Transaction.fromBytes(Buffer.from(req.transaction, 'hex')); @@ -110,10 +108,8 @@ export class TxpoolEndpoint { } public async dryRunTransaction(ctx: RequestContext): Promise { - const reqErrors = validator.validate(dryRunTransactionRequestSchema, ctx.params); - if (reqErrors?.length) { - throw new LiskValidationError(reqErrors); - } + validator.validate(dryRunTransactionRequestSchema, ctx.params); + const req = (ctx.params as unknown) as DryRunTransactionRequest; const transaction = Transaction.fromBytes(Buffer.from(req.transaction, 'hex')); diff --git a/framework/src/engine/generator/endpoint.ts b/framework/src/engine/generator/endpoint.ts index 40e4937a3dc..4adb3a450de 100644 --- a/framework/src/engine/generator/endpoint.ts +++ b/framework/src/engine/generator/endpoint.ts @@ -15,7 +15,7 @@ import { encrypt, ed, bls, address as cryptoAddress } from '@liskhq/lisk-cryptography'; import { Batch, Database } from '@liskhq/lisk-db'; import { dataStructures } from '@liskhq/lisk-utils'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { GeneratorStore } from './generator_store'; import { getLastGeneratedInfo, @@ -78,10 +78,8 @@ export class Endpoint { } public async updateStatus(ctx: RequestContext): Promise { - const reqErrors = validator.validate(updateStatusRequestSchema, ctx.params); - if (reqErrors?.length) { - throw new LiskValidationError(reqErrors); - } + validator.validate(updateStatusRequestSchema, ctx.params); + const req = (ctx.params as unknown) as UpdateStatusRequest; const address = Buffer.from(req.address, 'hex'); const encryptedGenerator = this._generators.find(item => item.address.equals(address)); diff --git a/framework/src/engine/generator/generator.ts b/framework/src/engine/generator/generator.ts index f2c955093d6..19fed7d454f 100644 --- a/framework/src/engine/generator/generator.ts +++ b/framework/src/engine/generator/generator.ts @@ -28,7 +28,7 @@ import { Database, Batch, SparseMerkleTree } from '@liskhq/lisk-db'; import { TransactionPool, events } from '@liskhq/lisk-transaction-pool'; import { MerkleTree } from '@liskhq/lisk-tree'; import { dataStructures, jobHandlers } from '@liskhq/lisk-utils'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { EVENT_NETWORK_READY } from '../events'; import { Logger } from '../../logger'; import { GenesisConfig } from '../../types'; @@ -379,10 +379,7 @@ export class Generator { }; const encodedData = codec.decode(getTransactionsResponseSchema, data); - const validatorErrors = validator.validate(getTransactionsResponseSchema, encodedData); - if (validatorErrors.length) { - throw new LiskValidationError(validatorErrors); - } + validator.validate(getTransactionsResponseSchema, encodedData); const transactions = encodedData.transactions.map(transaction => Transaction.fromBytes(transaction), diff --git a/framework/src/engine/generator/network_endpoint.ts b/framework/src/engine/generator/network_endpoint.ts index 7d7ca0f2748..0c171550ae9 100644 --- a/framework/src/engine/generator/network_endpoint.ts +++ b/framework/src/engine/generator/network_endpoint.ts @@ -13,7 +13,7 @@ */ import { codec } from '@liskhq/lisk-codec'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { objects as objectUtils } from '@liskhq/lisk-utils'; import { TransactionPool } from '@liskhq/lisk-transaction-pool'; import { Chain, Transaction } from '@liskhq/lisk-chain'; @@ -81,14 +81,27 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { if (Buffer.isBuffer(data)) { decodedData = codec.decode(getTransactionRequestSchema, data); - const errors = validator.validate(getTransactionRequestSchema, decodedData); - if (errors.length || !objectUtils.bufferArrayUniqueItems(decodedData.transactionIds)) { - this._logger.warn({ err: errors, peerId }, 'Received invalid getTransactions body'); + + const logDataAndApplyPenalty = (data? : unknown) => { + this._logger.warn( + data, + 'Received invalid getTransactions body', + ); this.network.applyPenaltyOnPeer({ peerId, penalty: 100, }); - throw new LiskValidationError(errors); + } + + try { + validator.validate(getTransactionRequestSchema, decodedData); + } catch (err) { + logDataAndApplyPenalty({ err: err, peerId }) + throw err; + } + + if (!objectUtils.bufferArrayUniqueItems(decodedData.transactionIds)) { + logDataAndApplyPenalty({ peerId }) } } @@ -180,15 +193,16 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { postTransactionsAnnouncementSchema, data, ); - const errors = validator.validate(postTransactionsAnnouncementSchema, decodedData); - if (errors.length) { - this._logger.warn({ err: errors, peerId }, 'Received invalid transactions body'); + try { + validator.validate(postTransactionsAnnouncementSchema, decodedData); + } catch (err) { + this._logger.warn({ err: err, peerId }, 'Received invalid transactions body'); this.network.applyPenaltyOnPeer({ peerId, penalty: 100, }); - throw new LiskValidationError(errors); + throw err; } this.event.emit(GENERATOR_EVENT_NEW_TRANSACTION_ANNOUNCEMENT, decodedData); diff --git a/framework/src/modules/auth/commands/register_multisignature.ts b/framework/src/modules/auth/commands/register_multisignature.ts index ad462b96817..258035bae8b 100644 --- a/framework/src/modules/auth/commands/register_multisignature.ts +++ b/framework/src/modules/auth/commands/register_multisignature.ts @@ -13,7 +13,7 @@ */ import { objects as objectUtils } from '@liskhq/lisk-utils'; -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { BaseCommand } from '../..'; import { CommandExecuteContext, @@ -43,12 +43,12 @@ export class RegisterMultisignatureCommand extends BaseCommand { const { transaction } = context; const { mandatoryKeys, optionalKeys, numberOfSignatures } = context.params; - const errors = validator.validate(registerMultisignatureParamsSchema, context.params); - - if (errors.length > 0) { + try { + validator.validate(registerMultisignatureParamsSchema, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } diff --git a/framework/src/modules/auth/module.ts b/framework/src/modules/auth/module.ts index 9cbf357fd61..2c8fa565c7a 100644 --- a/framework/src/modules/auth/module.ts +++ b/framework/src/modules/auth/module.ts @@ -15,7 +15,7 @@ import { NotFoundError, TAG_TRANSACTION } from '@liskhq/lisk-chain'; import { objects as objectUtils } from '@liskhq/lisk-utils'; import { codec } from '@liskhq/lisk-codec'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseModule, ModuleMetadata } from '../base_module'; import { GenesisBlockExecuteContext, @@ -89,11 +89,8 @@ export class AuthModule extends BaseModule { } keys.push(storeKey); - const errors = validator.validate(authAccountSchema, storeValue); + validator.validate(authAccountSchema, storeValue); - if (errors.length > 0) { - throw new LiskValidationError(errors); - } const { mandatoryKeys, optionalKeys, numberOfSignatures } = storeValue; if (mandatoryKeys.length > 0) { if (!objectUtils.bufferArrayOrderByLex(mandatoryKeys)) { diff --git a/framework/src/modules/dpos_v2/commands/delegate_registration.ts b/framework/src/modules/dpos_v2/commands/delegate_registration.ts index 1aec8aaa14a..c52a9aa6aa9 100644 --- a/framework/src/modules/dpos_v2/commands/delegate_registration.ts +++ b/framework/src/modules/dpos_v2/commands/delegate_registration.ts @@ -12,13 +12,13 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { CommandVerifyContext, VerificationResult, VerifyStatus, CommandExecuteContext, -} from '../../../state_machine/types'; +} from '../../../state_machine'; import { BaseCommand } from '../../base_command'; import { COMMAND_ID_DELEGATE_REGISTRATION, @@ -49,12 +49,12 @@ export class DelegateRegistrationCommand extends BaseCommand { ): Promise { const { transaction } = context; - const errors = validator.validate(delegateRegistrationCommandParamsSchema, context.params); - - if (errors.length > 0) { + try { + validator.validate(delegateRegistrationCommandParamsSchema, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } diff --git a/framework/src/modules/dpos_v2/commands/pom.ts b/framework/src/modules/dpos_v2/commands/pom.ts index f3929ea2bc0..b3072c94e60 100644 --- a/framework/src/modules/dpos_v2/commands/pom.ts +++ b/framework/src/modules/dpos_v2/commands/pom.ts @@ -12,14 +12,14 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { BlockHeader } from '@liskhq/lisk-chain'; import { CommandVerifyContext, VerificationResult, VerifyStatus, CommandExecuteContext, -} from '../../../state_machine/types'; +} from '../../../state_machine'; import { BaseCommand } from '../../base_command'; import { COMMAND_ID_POM, @@ -62,12 +62,13 @@ export class ReportDelegateMisbehaviorCommand extends BaseCommand { public async verify( context: CommandVerifyContext, ): Promise { - const errors = validator.validate(this.schema, context.params); - if (errors.length > 0) { + try { + validator.validate(this.schema, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } diff --git a/framework/src/modules/dpos_v2/commands/update_generator_key.ts b/framework/src/modules/dpos_v2/commands/update_generator_key.ts index 512facdaad9..7066c67d8ce 100644 --- a/framework/src/modules/dpos_v2/commands/update_generator_key.ts +++ b/framework/src/modules/dpos_v2/commands/update_generator_key.ts @@ -12,13 +12,13 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { CommandVerifyContext, VerificationResult, VerifyStatus, CommandExecuteContext, -} from '../../../state_machine/types'; +} from '../../../state_machine'; import { BaseCommand } from '../../base_command'; import { COMMAND_ID_UPDATE_GENERATOR_KEY, @@ -45,12 +45,12 @@ export class UpdateGeneratorKeyCommand extends BaseCommand { ): Promise { const { transaction } = context; - const errors = validator.validate(updateGeneratorKeyCommandParamsSchema, context.params); - - if (errors.length > 0) { + try { + validator.validate(updateGeneratorKeyCommandParamsSchema, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } diff --git a/framework/src/modules/dpos_v2/commands/vote.ts b/framework/src/modules/dpos_v2/commands/vote.ts index 4b85f018fcc..a467eb550df 100644 --- a/framework/src/modules/dpos_v2/commands/vote.ts +++ b/framework/src/modules/dpos_v2/commands/vote.ts @@ -20,7 +20,7 @@ import { VerificationResult, VerifyStatus, CommandExecuteContext, -} from '../../../state_machine/types'; +} from '../../../state_machine'; import { BaseCommand } from '../../base_command'; import { COMMAND_ID_VOTE, @@ -64,12 +64,12 @@ export class VoteCommand extends BaseCommand { params: { votes }, } = context; - const validationErrors = validator.validate(this.schema, context.params); - - if (validationErrors.length > 0) { + try { + validator.validate(this.schema, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new AggregateValidationError('Parameter is not valid.', validationErrors), + error: new AggregateValidationError('Parameter is not valid.', err.toString()), }; } diff --git a/framework/src/modules/dpos_v2/module.ts b/framework/src/modules/dpos_v2/module.ts index 44b436f3524..78fe0b46abf 100644 --- a/framework/src/modules/dpos_v2/module.ts +++ b/framework/src/modules/dpos_v2/module.ts @@ -14,7 +14,7 @@ import { utils } from '@liskhq/lisk-cryptography'; import { objects as objectUtils, dataStructures, objects } from '@liskhq/lisk-utils'; -import { isUInt64, LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { isUInt64, validator } from '@liskhq/lisk-validator'; import { codec } from '@liskhq/lisk-codec'; import { GenesisBlockExecuteContext, BlockAfterExecuteContext } from '../../state_machine'; import { BaseModule, ModuleInitArgs, ModuleMetadata } from '../base_module'; @@ -170,10 +170,7 @@ export class DPoSModule extends BaseModule { public async init(args: ModuleInitArgs) { const { moduleConfig } = args; const config = objects.mergeDeep({}, defaultConfig, moduleConfig) as ModuleConfigJSON; - const errors = validator.validate(configSchema, config); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(configSchema, config); this._moduleConfig = getModuleConfig(config); @@ -191,11 +188,7 @@ export class DPoSModule extends BaseModule { return; } const genesisStore = codec.decode(genesisStoreSchema, assetBytes); - const errors = validator.validate(genesisStoreSchema, genesisStore); - - if (errors.length > 0) { - throw new LiskValidationError(errors); - } + validator.validate(genesisStoreSchema, genesisStore); // validators property check const dposValidatorAddresses = []; diff --git a/framework/src/modules/fee/module.ts b/framework/src/modules/fee/module.ts index ba93299db39..8381e0ce1f1 100644 --- a/framework/src/modules/fee/module.ts +++ b/framework/src/modules/fee/module.ts @@ -14,7 +14,7 @@ import { address, utils } from '@liskhq/lisk-cryptography'; import { objects } from '@liskhq/lisk-utils'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseModule, ModuleInitArgs, ModuleMetadata } from '../base_module'; import { defaultConfig, MODULE_ID_FEE } from './constants'; import { BaseFee, TokenAPI } from './types'; @@ -56,10 +56,8 @@ export class FeeModule extends BaseModule { public async init(args: ModuleInitArgs): Promise { const { genesisConfig, moduleConfig } = args; const config = objects.mergeDeep({}, defaultConfig, moduleConfig); - const errors = validator.validate(configSchema, config); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(configSchema, config); + this._tokenID = Buffer.from(config.feeTokenID, 'hex'); this._minFeePerByte = genesisConfig.minFeePerByte; this._baseFees = genesisConfig.baseFees.map(fee => ({ ...fee, baseFee: BigInt(fee.baseFee) })); diff --git a/framework/src/modules/interoperability/mainchain/commands/cc_update.ts b/framework/src/modules/interoperability/mainchain/commands/cc_update.ts index f0747f3b370..d2e054e168c 100644 --- a/framework/src/modules/interoperability/mainchain/commands/cc_update.ts +++ b/framework/src/modules/interoperability/mainchain/commands/cc_update.ts @@ -13,7 +13,7 @@ */ import { codec } from '@liskhq/lisk-codec'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { certificateSchema } from '../../../../engine/consensus/certificate_generation/schema'; import { Certificate } from '../../../../engine/consensus/certificate_generation/types'; import { @@ -76,12 +76,13 @@ export class MainchainCCUpdateCommand extends BaseInteroperabilityCommand { context: CommandVerifyContext, ): Promise { const { params: txParams, transaction, getStore } = context; - const errors = validator.validate(crossChainUpdateTransactionParams, context.params); - if (errors.length > 0) { + try { + validator.validate(crossChainUpdateTransactionParams, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } diff --git a/framework/src/modules/interoperability/mainchain/commands/sidechain_registration.ts b/framework/src/modules/interoperability/mainchain/commands/sidechain_registration.ts index 922bdb0ad96..5c9fca838c2 100644 --- a/framework/src/modules/interoperability/mainchain/commands/sidechain_registration.ts +++ b/framework/src/modules/interoperability/mainchain/commands/sidechain_registration.ts @@ -14,7 +14,7 @@ import { codec } from '@liskhq/lisk-codec'; import { utils } from '@liskhq/lisk-cryptography'; -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { MainchainInteroperabilityStore } from '../store'; import { BaseInteroperabilityCommand } from '../../base_interoperability_command'; import { @@ -51,7 +51,7 @@ import { VerificationResult, VerifyStatus, CommandExecuteContext, -} from '../../../../state_machine/types'; +} from '../../../../state_machine'; export class SidechainRegistrationCommand extends BaseInteroperabilityCommand { public id = COMMAND_ID_SIDECHAIN_REG_BUFFER; @@ -65,12 +65,13 @@ export class SidechainRegistrationCommand extends BaseInteroperabilityCommand { transaction, params: { certificateThreshold, initValidators, genesisBlockID, name }, } = context; - const errors = validator.validate(sidechainRegParams, context.params); - if (errors.length > 0) { + try { + validator.validate(sidechainRegParams, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } diff --git a/framework/src/modules/interoperability/mainchain/commands/state_recovery.ts b/framework/src/modules/interoperability/mainchain/commands/state_recovery.ts index 5e2f0f3d203..1b1cc600556 100644 --- a/framework/src/modules/interoperability/mainchain/commands/state_recovery.ts +++ b/framework/src/modules/interoperability/mainchain/commands/state_recovery.ts @@ -14,7 +14,7 @@ import { sparseMerkleTree } from '@liskhq/lisk-tree'; import { utils } from '@liskhq/lisk-cryptography'; -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { MainchainInteroperabilityStore } from '../store'; import { BaseInteroperabilityCommand } from '../../base_interoperability_command'; import { @@ -30,7 +30,7 @@ import { CommandVerifyContext, VerificationResult, VerifyStatus, -} from '../../../../state_machine/types'; +} from '../../../../state_machine'; import { createRecoverCCMsgAPIContext } from '../../../../testing'; export class StateRecoveryCommand extends BaseInteroperabilityCommand { @@ -44,12 +44,13 @@ export class StateRecoveryCommand extends BaseInteroperabilityCommand { const { params: { chainID, storeEntries, siblingHashes }, } = context; - const errors = validator.validate(this.schema, context.params); - if (errors.length > 0) { + try { + validator.validate(this.schema, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } diff --git a/framework/src/modules/interoperability/sidechain/commands/cc_update.ts b/framework/src/modules/interoperability/sidechain/commands/cc_update.ts index 7756fa82e69..d3cc9ad4d7e 100644 --- a/framework/src/modules/interoperability/sidechain/commands/cc_update.ts +++ b/framework/src/modules/interoperability/sidechain/commands/cc_update.ts @@ -13,7 +13,7 @@ */ import { codec } from '@liskhq/lisk-codec'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { certificateSchema } from '../../../../engine/consensus/certificate_generation/schema'; import { Certificate } from '../../../../engine/consensus/certificate_generation/types'; import { @@ -74,12 +74,13 @@ export class SidechainCCUpdateCommand extends BaseInteroperabilityCommand { context: CommandVerifyContext, ): Promise { const { params: txParams, transaction, getStore } = context; - const errors = validator.validate(crossChainUpdateTransactionParams, context.params); - if (errors.length > 0) { + try { + validator.validate(crossChainUpdateTransactionParams, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } diff --git a/framework/src/modules/interoperability/sidechain/commands/mainchain_registration.ts b/framework/src/modules/interoperability/sidechain/commands/mainchain_registration.ts index a3de4458955..31bde8fcc6f 100644 --- a/framework/src/modules/interoperability/sidechain/commands/mainchain_registration.ts +++ b/framework/src/modules/interoperability/sidechain/commands/mainchain_registration.ts @@ -14,7 +14,7 @@ import { codec } from '@liskhq/lisk-codec'; import { utils, bls } from '@liskhq/lisk-cryptography'; -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { CCM_STATUS_OK, CHAIN_REGISTERED, @@ -74,11 +74,12 @@ export class MainchainRegistrationCommand extends BaseInteroperabilityCommand { }; } - const registrationParamsErrors = validator.validate(mainchainRegParams, context.params); - if (registrationParamsErrors.length > 0) { + try { + validator.validate(mainchainRegParams, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(registrationParamsErrors), + error: err, }; } diff --git a/framework/src/modules/interoperability/utils.ts b/framework/src/modules/interoperability/utils.ts index 537d29b0388..3294591fc7a 100644 --- a/framework/src/modules/interoperability/utils.ts +++ b/framework/src/modules/interoperability/utils.ts @@ -15,7 +15,7 @@ import { regularMerkleTree, sparseMerkleTree } from '@liskhq/lisk-tree'; import { codec } from '@liskhq/lisk-codec'; import { utils, bls } from '@liskhq/lisk-cryptography'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { DB_KEY_STATE_STORE } from '@liskhq/lisk-chain'; import { ActiveValidators, @@ -67,12 +67,8 @@ interface CommonExecutionLogicArgs { export const getIDAsKeyForStore = (id: number) => utils.intToBuffer(id, 4); export const validateFormat = (ccm: CCMsg) => { - const errors = validator.validate(ccmSchema, ccm); - if (errors.length) { - const error = new LiskValidationError(errors); + validator.validate(ccmSchema, ccm); - throw error; - } const serializedCCM = codec.encode(ccmSchema, ccm); if (serializedCCM.byteLength > MAX_CCM_SIZE) { throw new Error(`Cross chain message is over the the max ccm size limit of ${MAX_CCM_SIZE}`); diff --git a/framework/src/modules/random/endpoint.ts b/framework/src/modules/random/endpoint.ts index 8b01b807f26..3b866e2993a 100644 --- a/framework/src/modules/random/endpoint.ts +++ b/framework/src/modules/random/endpoint.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { ModuleEndpointContext } from '../../types'; import { BaseEndpoint } from '../base_endpoint'; import { STORE_PREFIX_RANDOM, EMPTY_KEY } from './constants'; @@ -22,10 +22,8 @@ import { getSeedRevealValidity } from './utils'; export class RandomEndpoint extends BaseEndpoint { public async isSeedRevealValid(context: ModuleEndpointContext): Promise<{ valid: boolean }> { - const errors = validator.validate(isSeedRevealValidRequestSchema, context.params); - if (errors.length > 0) { - throw new LiskValidationError([...errors]); - } + validator.validate(isSeedRevealValidRequestSchema, context.params); + const { generatorAddress, seedReveal } = context.params; const randomDataStore = context.getStore(this.moduleID, STORE_PREFIX_RANDOM); const { validatorReveals } = await randomDataStore.getWithSchema( diff --git a/framework/src/modules/random/module.ts b/framework/src/modules/random/module.ts index db7b3d70957..35f7898298a 100644 --- a/framework/src/modules/random/module.ts +++ b/framework/src/modules/random/module.ts @@ -15,7 +15,7 @@ import { utils } from '@liskhq/lisk-cryptography'; import { codec } from '@liskhq/lisk-codec'; import { dataStructures, objects } from '@liskhq/lisk-utils'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BlockAfterExecuteContext, BlockVerifyContext, @@ -88,15 +88,11 @@ export class RandomModule extends BaseModule { public async init(args: ModuleInitArgs): Promise { const { moduleConfig, generatorConfig } = args; const config = objects.mergeDeep({}, defaultConfig, moduleConfig); - const errors = validator.validate(randomModuleConfig, config); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(randomModuleConfig, config); + if (generatorConfig && Object.entries(generatorConfig).length > 0) { - const generatorErrors = validator.validate(randomModuleGeneratorConfig, generatorConfig); - if (generatorErrors.length) { - throw new LiskValidationError(generatorErrors); - } + validator.validate(randomModuleGeneratorConfig, generatorConfig); + this._generatorConfig = (generatorConfig.hashOnions as JSONObject[]).map(ho => ({ ...ho, address: Buffer.from(ho.address, 'hex'), diff --git a/framework/src/modules/reward/module.ts b/framework/src/modules/reward/module.ts index e80c5a9ed13..4025ce8dcfa 100644 --- a/framework/src/modules/reward/module.ts +++ b/framework/src/modules/reward/module.ts @@ -14,7 +14,7 @@ import { utils } from '@liskhq/lisk-cryptography'; import { objects } from '@liskhq/lisk-utils'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseModule, ModuleInitArgs, ModuleMetadata } from '../base_module'; import { defaultConfig, MODULE_ID_REWARD } from './constants'; import { ModuleConfig, RandomAPI, TokenAPI, TokenIDReward } from './types'; @@ -63,10 +63,8 @@ export class RewardModule extends BaseModule { public async init(args: ModuleInitArgs): Promise { const { moduleConfig } = args; const config = objects.mergeDeep({}, defaultConfig, moduleConfig); - const errors = validator.validate(configSchema, config); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(configSchema, config); + this._moduleConfig = (config as unknown) as ModuleConfig; this._tokenIDReward = this._moduleConfig.tokenIDReward; diff --git a/framework/src/modules/token/cc_commands/cc_forward.ts b/framework/src/modules/token/cc_commands/cc_forward.ts index 4818f26d705..1b85be78f26 100644 --- a/framework/src/modules/token/cc_commands/cc_forward.ts +++ b/framework/src/modules/token/cc_commands/cc_forward.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ import { codec } from '@liskhq/lisk-codec'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseCCCommand } from '../../interoperability/base_cc_command'; import { CCCommandExecuteContext } from '../../interoperability/types'; import { TokenAPI } from '../api'; @@ -60,10 +60,8 @@ export class CCForwardCommand extends BaseCCCommand { let params: CCForwardMessageParams; try { params = codec.decode(crossChainForwardMessageParams, ccm.params); - const errors = validator.validate(crossChainTransferMessageParams, params); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(crossChainTransferMessageParams, params); + } catch (error) { ctx.logger.debug({ err: error as Error }, 'Error verifying the params.'); if (ccm.status === CCM_STATUS_OK) { diff --git a/framework/src/modules/token/cc_commands/cc_transfer.ts b/framework/src/modules/token/cc_commands/cc_transfer.ts index f57e1b5660f..5bfd0a193c4 100644 --- a/framework/src/modules/token/cc_commands/cc_transfer.ts +++ b/framework/src/modules/token/cc_commands/cc_transfer.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ import { codec } from '@liskhq/lisk-codec'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseCCCommand } from '../../interoperability/base_cc_command'; import { CCCommandExecuteContext } from '../../interoperability/types'; import { TokenAPI } from '../api'; @@ -73,10 +73,8 @@ export class CCTransferCommand extends BaseCCCommand { let tokenLocalID; try { params = codec.decode(crossChainTransferMessageParams, ccm.params); - const errors = validator.validate(crossChainTransferMessageParams, params); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(crossChainTransferMessageParams, params); + [tokenChainID, tokenLocalID] = splitTokenID(params.tokenID); if (tokenChainID.equals(ownChainID)) { const escrowedAmount = await this._tokenAPI.getEscrowedAmount( diff --git a/framework/src/modules/token/commands/cc_transfer.ts b/framework/src/modules/token/commands/cc_transfer.ts index 6c9b1037490..b4ebdab011c 100644 --- a/framework/src/modules/token/commands/cc_transfer.ts +++ b/framework/src/modules/token/commands/cc_transfer.ts @@ -11,7 +11,7 @@ * * Removal or modification of this copyright notice is prohibited. */ -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseCommand } from '../../base_command'; import { CommandExecuteContext, @@ -46,11 +46,13 @@ export class CCTransferCommand extends BaseCommand { // eslint-disable-next-line @typescript-eslint/require-await public async verify(context: CommandVerifyContext): Promise { const { params } = context; - const errors = validator.validate(this.schema, params); - if (errors.length) { + + try { + validator.validate(this.schema, params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } return { diff --git a/framework/src/modules/token/commands/transfer.ts b/framework/src/modules/token/commands/transfer.ts index 30d54e41894..5eeff4b768f 100644 --- a/framework/src/modules/token/commands/transfer.ts +++ b/framework/src/modules/token/commands/transfer.ts @@ -11,7 +11,7 @@ * * Removal or modification of this copyright notice is prohibited. */ -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseCommand } from '../../base_command'; import { CommandExecuteContext, @@ -44,11 +44,13 @@ export class TransferCommand extends BaseCommand { // eslint-disable-next-line @typescript-eslint/require-await public async verify(context: CommandVerifyContext): Promise { const { params } = context; - const errors = validator.validate(transferParamsSchema, params); - if (errors.length) { + + try { + validator.validate(transferParamsSchema, params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } return { diff --git a/framework/src/modules/token/endpoint.ts b/framework/src/modules/token/endpoint.ts index 81f2634a42a..dba3140f100 100644 --- a/framework/src/modules/token/endpoint.ts +++ b/framework/src/modules/token/endpoint.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { NotFoundError } from '../../state_machine'; import { JSONObject, ModuleEndpointContext } from '../../types'; import { BaseEndpoint } from '../base_endpoint'; @@ -49,10 +49,8 @@ export class TokenEndpoint extends BaseEndpoint { public async getBalances( context: ModuleEndpointContext, ): Promise<{ balances: JSONObject[] }> { - const errors = validator.validate(getBalancesRequestSchema, context.params); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(getBalancesRequestSchema, context.params); + const address = Buffer.from(context.params.address as string, 'hex'); const userStore = context.getStore(this.moduleID, STORE_PREFIX_USER); const userData = await userStore.iterateWithSchema( @@ -76,10 +74,8 @@ export class TokenEndpoint extends BaseEndpoint { } public async getBalance(context: ModuleEndpointContext): Promise> { - const errors = validator.validate(getBalanceRequestSchema, context.params); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(getBalanceRequestSchema, context.params); + const address = Buffer.from(context.params.address as string, 'hex'); const tokenID = Buffer.from(context.params.tokenID as string, 'hex'); const canonicalTokenID = await this._tokenAPI.getCanonicalTokenID( diff --git a/framework/src/modules/token/module.ts b/framework/src/modules/token/module.ts index 6b84a640026..4def461937e 100644 --- a/framework/src/modules/token/module.ts +++ b/framework/src/modules/token/module.ts @@ -11,7 +11,7 @@ * * Removal or modification of this copyright notice is prohibited. */ -import { isUInt64, LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { isUInt64, validator } from '@liskhq/lisk-validator'; import { codec } from '@liskhq/lisk-codec'; import { objects, dataStructures } from '@liskhq/lisk-utils'; import { @@ -125,10 +125,8 @@ export class TokenModule extends BaseInteroperableModule { public async init(args: ModuleInitArgs) { const { moduleConfig } = args; const config = objects.mergeDeep({}, defaultConfig, moduleConfig) as ModuleConfig; - const errors = validator.validate(configSchema, config); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(configSchema, config); + this._minBalances = config.minBalances.map(mb => ({ tokenID: Buffer.from(mb.tokenID, 'hex'), amount: BigInt(mb.amount), @@ -147,10 +145,7 @@ export class TokenModule extends BaseInteroperableModule { return; } const genesisStore = codec.decode(genesisTokenStoreSchema, assetBytes); - const errors = validator.validate(genesisTokenStoreSchema, genesisStore); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(genesisTokenStoreSchema, genesisStore); const userStore = context.getStore(this.id, STORE_PREFIX_USER); const copiedUserStore = [...genesisStore.userSubstore]; diff --git a/framework/src/modules/validators/endpoint.ts b/framework/src/modules/validators/endpoint.ts index 280d4134581..fdff6853d6e 100644 --- a/framework/src/modules/validators/endpoint.ts +++ b/framework/src/modules/validators/endpoint.ts @@ -13,7 +13,7 @@ */ import { utils, bls } from '@liskhq/lisk-cryptography'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { NotFoundError } from '@liskhq/lisk-db'; import { ModuleEndpointContext } from '../../types'; import { BaseEndpoint } from '../base_endpoint'; @@ -22,10 +22,7 @@ import { MODULE_ID_VALIDATORS, STORE_PREFIX_BLS_KEYS } from './constants'; export class ValidatorsEndpoint extends BaseEndpoint { public async validateBLSKey(ctx: ModuleEndpointContext): Promise<{ valid: boolean }> { - const reqErrors = validator.validate(validateBLSKeyRequestSchema, ctx.params); - if (reqErrors?.length) { - throw new LiskValidationError(reqErrors); - } + validator.validate(validateBLSKeyRequestSchema, ctx.params); const req = (ctx.params as unknown) as ValidateBLSKeyRequest; const { proofOfPossession, blsKey } = req; diff --git a/framework/src/modules/validators/module.ts b/framework/src/modules/validators/module.ts index 2d589096675..f8ab7424041 100644 --- a/framework/src/modules/validators/module.ts +++ b/framework/src/modules/validators/module.ts @@ -14,7 +14,7 @@ import { utils } from '@liskhq/lisk-cryptography'; import { objects } from '@liskhq/lisk-utils'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseModule, ModuleInitArgs, ModuleMetadata } from '../base_module'; import { defaultConfig, @@ -59,10 +59,8 @@ export class ValidatorsModule extends BaseModule { public async init(args: ModuleInitArgs): Promise { const { moduleConfig } = args; const config = objects.mergeDeep({}, defaultConfig, moduleConfig); - const errors = validator.validate(configSchema, config); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(configSchema, config); + this._blockTime = config.blockTime as number; this.api.init({ diff --git a/framework/src/plugins/base_plugin.ts b/framework/src/plugins/base_plugin.ts index 8299a951436..4dfd9792119 100644 --- a/framework/src/plugins/base_plugin.ts +++ b/framework/src/plugins/base_plugin.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ import { join } from 'path'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { APIClient, createIPCClient } from '@liskhq/lisk-api-client'; import { objects } from '@liskhq/lisk-utils'; import { Logger } from '../logger'; @@ -71,10 +71,7 @@ export const validatePluginSpec = (pluginInstance: BasePlugin): void => { } if (pluginInstance.configSchema) { - const errors = validator.validateSchema(pluginInstance.configSchema); - if (errors.length) { - throw new LiskValidationError([...errors]); - } + validator.validateSchema(pluginInstance.configSchema); } }; @@ -120,11 +117,7 @@ export abstract class BasePlugin> { if (this.configSchema) { this._config = objects.mergeDeep({}, this.configSchema.default ?? {}, context.config) as T; - const errors = validator.validate(this.configSchema, this.config as Record); - - if (errors.length) { - throw new LiskValidationError([...errors]); - } + validator.validate(this.configSchema, this.config as Record); } else { this._config = {} as T; } diff --git a/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts b/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts index 0a0f16052e2..8dfb5d5fc6b 100644 --- a/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts +++ b/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts @@ -226,8 +226,9 @@ describe('VoteCommand', () => { }); it('should return errors', () => { - const errors = validator.validate(command.schema, transactionParamsDecoded); - expect(errors[0].message).toInclude('should pass "dataType" keyword validation'); + expect( + () => validator.validate(command.schema, transactionParamsDecoded) + ).toThrow('should pass "dataType" keyword validation') }); }); @@ -244,8 +245,9 @@ describe('VoteCommand', () => { }); it('should return errors', () => { - const errors = validator.validate(command.schema, transactionParamsDecoded); - expect(errors[0].message).toInclude('should pass "dataType" keyword validation'); + expect( + () => validator.validate(command.schema, transactionParamsDecoded) + ).toThrow('should pass "dataType" keyword validation') }); }); }); diff --git a/framework/test/unit/schema/application_config_schema.spec.ts b/framework/test/unit/schema/application_config_schema.spec.ts index d652ba22025..a415a4c24e9 100644 --- a/framework/test/unit/schema/application_config_schema.spec.ts +++ b/framework/test/unit/schema/application_config_schema.spec.ts @@ -14,7 +14,7 @@ import { validator } from '@liskhq/lisk-validator'; import { objects } from '@liskhq/lisk-utils'; -import { applicationConfigSchema } from '../../../src/schema/application_config_schema'; +import { applicationConfigSchema } from '../../../src/schema'; describe('schema/application_config_schema.js', () => { it('application config schema must match to the snapshot.', () => { @@ -22,56 +22,35 @@ describe('schema/application_config_schema.js', () => { }); it('should validate the defined schema', () => { - const errors = validator.validateSchema(applicationConfigSchema); - - expect(errors).toHaveLength(0); + expect( + () => validator.validateSchema(applicationConfigSchema) + ).not.toThrow() }); it('should validate if module properties are objects', () => { const config = objects.cloneDeep(applicationConfigSchema.default); config.genesis.modules = { myModule: { myProp: 1 } }; - const errors = validator.validate(applicationConfigSchema, config); - - expect(errors).toHaveLength(0); + expect( + () => validator.validate(applicationConfigSchema, config) + ).not.toThrow() }); it('should not validate if module properties are not objects', () => { const config = objects.cloneDeep(applicationConfigSchema.default); config.genesis.modules = { myModule: 10 }; - const errors = validator.validate(applicationConfigSchema, config); - - expect(errors).toHaveLength(1); - expect(errors[0]).toEqual( - expect.objectContaining({ - dataPath: '.genesis.modules.myModule', - keyword: 'type', - message: 'must be object', - }), - ); + expect( + () => validator.validate(applicationConfigSchema, config) + ).toThrow("Property '.genesis.modules.myModule' should be of type 'object'") }); it('should not validate if module properties are not valid format', () => { const config = objects.cloneDeep(applicationConfigSchema.default); config.genesis.modules = { 'my-custom-module': { myProp: 1 } }; - const errors = validator.validate(applicationConfigSchema, config); - - expect(errors).toHaveLength(2); - expect(errors[0]).toEqual( - expect.objectContaining({ - dataPath: '.genesis.modules', - keyword: 'pattern', - message: 'must match pattern "^[a-zA-Z][a-zA-Z0-9_]*$"', - }), - ); - expect(errors[1]).toEqual( - expect.objectContaining({ - dataPath: '.genesis.modules', - keyword: 'propertyNames', - message: 'property name must be valid', - }), - ); + expect( + () => validator.validate(applicationConfigSchema, config) + ).toThrow("must match pattern \"^[a-zA-Z][a-zA-Z0-9_]*$\"\nproperty name must be valid") }); }); From 767b22374be4624d96e1d65e257e6fd9ac189700 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Wed, 27 Jul 2022 12:35:46 +0300 Subject: [PATCH 02/39] revert import(s) formatting --- elements/lisk-chain/src/block_header.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/elements/lisk-chain/src/block_header.ts b/elements/lisk-chain/src/block_header.ts index 392cc97765a..e91a555bbe4 100644 --- a/elements/lisk-chain/src/block_header.ts +++ b/elements/lisk-chain/src/block_header.ts @@ -12,15 +12,13 @@ * Removal or modification of this copyright notice is prohibited. */ -import {ed, utils} from '@liskhq/lisk-cryptography'; -import {codec} from '@liskhq/lisk-codec'; -import {LiskValidationError, validator} from '@liskhq/lisk-validator'; +import { ed, utils } from '@liskhq/lisk-cryptography'; +import { codec } from '@liskhq/lisk-codec'; +import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { EMPTY_BUFFER, EMPTY_HASH, SIGNATURE_LENGTH_BYTES, TAG_BLOCK_HEADER } from './constants'; +import { blockHeaderSchema, blockHeaderSchemaWithId, signingBlockHeaderSchema } from './schema'; +import { JSONObject } from './types'; import {LiskErrorObject} from "@liskhq/lisk-validator/dist-node/types"; -import {JSONObject} from './types'; -import {EMPTY_BUFFER, EMPTY_HASH, SIGNATURE_LENGTH_BYTES, TAG_BLOCK_HEADER} from './constants'; -import {blockHeaderSchema, blockHeaderSchemaWithId, signingBlockHeaderSchema} from './schema'; - - export interface BlockHeaderAttrs { readonly version: number; @@ -189,7 +187,6 @@ export class BlockHeader { public validateGenesis(): void { const header = this._getBlockHeaderProps(); - validator.validate(blockHeaderSchema, header); const errors: LiskErrorObject[] = [] From 37f6ae69ec8ee5f5c0f42bd966522a6393b2c095 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Wed, 27 Jul 2022 12:49:50 +0300 Subject: [PATCH 03/39] fix broken test --- .../test/lisk_validator.spec.ts | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/elements/lisk-validator/test/lisk_validator.spec.ts b/elements/lisk-validator/test/lisk_validator.spec.ts index aef5504b81c..1dc8b946bf9 100644 --- a/elements/lisk-validator/test/lisk_validator.spec.ts +++ b/elements/lisk-validator/test/lisk_validator.spec.ts @@ -33,8 +33,7 @@ describe('validator', () => { }; it('should pass on for "object" type', () => { - // Assert - expect(validator.validateSchema(validSchema)).toEqual([]); + expect(() => validator.validateSchema(validSchema)).not.toThrow(); }); it('should return error on schema with type other than "object"', () => { @@ -45,24 +44,27 @@ describe('validator', () => { properties: {}, }; - const msg = "Lisk validator found 2 error[s]:\nmust be equal to constant\nmust NOT have fewer than 1 items" - expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) + const msg = + 'Lisk validator found 2 error[s]:\nmust be equal to constant\nmust NOT have fewer than 1 items'; + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg); }); it('should return error when "type" is not defined', () => { const invalidSchema = { ...validSchema }; delete (invalidSchema as any).type; - const msg = "Lisk validator found 1 error[s]:\nMissing property, must have required property 'type'" - expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) + const msg = + "Lisk validator found 1 error[s]:\nMissing property, must have required property 'type'"; + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg); }); it('should return error when "$id" is not defined', () => { const invalidSchema = { ...validSchema }; delete (invalidSchema as any).$id; - const msg = "Lisk validator found 1 error[s]:\nMissing property, must have required property '$id'" - expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) + const msg = + "Lisk validator found 1 error[s]:\nMissing property, must have required property '$id'"; + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg); }); // As the schema is always overridden @@ -70,7 +72,7 @@ describe('validator', () => { const invalidSchema = cloneDeep(validSchema); delete invalidSchema.$schema; - expect(() => validator.validateSchema(invalidSchema)).not.toThrow() + expect(() => validator.validateSchema(invalidSchema)).not.toThrow(); }); it('should throw error when "$schema" value is defined other than lisk-schema uri', () => { @@ -88,8 +90,9 @@ describe('validator', () => { const invalidSchema = cloneDeep(validSchema); delete invalidSchema.properties; - const msg = "Lisk validator found 1 error[s]:\nMissing property, must have required property 'properties'" - expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) + const msg = + "Lisk validator found 1 error[s]:\nMissing property, must have required property 'properties'"; + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg); }); it('should return error when "properties" are not camelcase', () => { @@ -101,16 +104,17 @@ describe('validator', () => { }, }; - const msg = "Lisk validator found 2 error[s]:\nProperty '.properties' must match format \"camelCase\""; - expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) + const msg = + 'Lisk validator found 2 error[s]:\nProperty \'.properties\' must match format "camelCase"'; + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg); }); it('should return error when "properties" are empty object', () => { const invalidSchema = cloneDeep(validSchema); delete invalidSchema.properties.myProp; - const msg = "Lisk validator found 1 error[s]:\nmust NOT have fewer than 1 items"; - expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) + const msg = 'Lisk validator found 1 error[s]:\nmust NOT have fewer than 1 items'; + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg); }); }); }); From afc46c4d89b53427955b7a3589596dacf906b3c0 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Wed, 27 Jul 2022 14:13:21 +0300 Subject: [PATCH 04/39] refactor to use shorthand property name --- framework/src/engine/consensus/network_endpoint.ts | 6 +++--- framework/src/engine/generator/network_endpoint.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/framework/src/engine/consensus/network_endpoint.ts b/framework/src/engine/consensus/network_endpoint.ts index b1b72e7c2de..a0757179067 100644 --- a/framework/src/engine/consensus/network_endpoint.ts +++ b/framework/src/engine/consensus/network_endpoint.ts @@ -163,9 +163,9 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { try { validator.validate(getHighestCommonBlockRequestSchema, blockIds); - } catch (error) { - logDataAndApplyPenalty({ err: error, req: data}) - throw error; + } catch (err) { + logDataAndApplyPenalty({ err, req: data}) + throw err; } if (!objects.bufferArrayUniqueItems(blockIds.ids)) { diff --git a/framework/src/engine/generator/network_endpoint.ts b/framework/src/engine/generator/network_endpoint.ts index 0c171550ae9..b3b5cf1817b 100644 --- a/framework/src/engine/generator/network_endpoint.ts +++ b/framework/src/engine/generator/network_endpoint.ts @@ -96,7 +96,7 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { try { validator.validate(getTransactionRequestSchema, decodedData); } catch (err) { - logDataAndApplyPenalty({ err: err, peerId }) + logDataAndApplyPenalty({ err, peerId }) throw err; } From 13e83fe0de4fb4c512ff3724747b678bb504aed7 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Wed, 27 Jul 2022 14:19:55 +0300 Subject: [PATCH 05/39] use shorthand property name --- framework/src/engine/generator/network_endpoint.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/engine/generator/network_endpoint.ts b/framework/src/engine/generator/network_endpoint.ts index b3b5cf1817b..8bc78fb14dd 100644 --- a/framework/src/engine/generator/network_endpoint.ts +++ b/framework/src/engine/generator/network_endpoint.ts @@ -197,7 +197,7 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { try { validator.validate(postTransactionsAnnouncementSchema, decodedData); } catch (err) { - this._logger.warn({ err: err, peerId }, 'Received invalid transactions body'); + this._logger.warn({ err, peerId }, 'Received invalid transactions body'); this.network.applyPenaltyOnPeer({ peerId, penalty: 100, From 8c89bc6538491fac0ac818041a50544420259d78 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Wed, 27 Jul 2022 14:43:35 +0300 Subject: [PATCH 06/39] refactor to follow existing format --- .../src/engine/generator/network_endpoint.ts | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/framework/src/engine/generator/network_endpoint.ts b/framework/src/engine/generator/network_endpoint.ts index 8bc78fb14dd..1190c55d14c 100644 --- a/framework/src/engine/generator/network_endpoint.ts +++ b/framework/src/engine/generator/network_endpoint.ts @@ -82,26 +82,23 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { if (Buffer.isBuffer(data)) { decodedData = codec.decode(getTransactionRequestSchema, data); - const logDataAndApplyPenalty = (data? : unknown) => { - this._logger.warn( - data, - 'Received invalid getTransactions body', - ); + try { + validator.validate(getTransactionRequestSchema, decodedData); + } catch (err) { + this._logger.warn({ err, peerId }, 'Received invalid getTransactions body'); this.network.applyPenaltyOnPeer({ peerId, penalty: 100, }); - } - - try { - validator.validate(getTransactionRequestSchema, decodedData); - } catch (err) { - logDataAndApplyPenalty({ err, peerId }) throw err; } if (!objectUtils.bufferArrayUniqueItems(decodedData.transactionIds)) { - logDataAndApplyPenalty({ peerId }) + this._logger.warn({ peerId }, 'Received invalid getTransactions body'); + this.network.applyPenaltyOnPeer({ + peerId, + penalty: 100, + }); } } From e8467cecb7da0e611b3d9075362e94df909095c6 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Wed, 27 Jul 2022 20:27:00 +0300 Subject: [PATCH 07/39] replace manual conversion with type guards --- .../engine/consensus/synchronizer/base_synchronizer.ts | 4 ++-- framework/src/engine/endpoint/txpool.ts | 8 ++++---- framework/src/engine/generator/endpoint.ts | 4 ++-- framework/src/engine/generator/generator.ts | 6 +++--- .../src/modules/dpos_v2/commands/delegate_registration.ts | 8 ++++---- framework/src/modules/validators/endpoint.ts | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/framework/src/engine/consensus/synchronizer/base_synchronizer.ts b/framework/src/engine/consensus/synchronizer/base_synchronizer.ts index bb848f83566..137d42c1fda 100644 --- a/framework/src/engine/consensus/synchronizer/base_synchronizer.ts +++ b/framework/src/engine/consensus/synchronizer/base_synchronizer.ts @@ -100,8 +100,8 @@ export abstract class BaseSynchronizer { if (!data || !data.length) { throw new Error(`Peer ${peerId} did not respond with block`); } - const encodedData = codec.decode<{ blocks: Buffer[] }>(getBlocksFromIdResponseSchema, data); - return encodedData.blocks.map(block => Block.fromBytes(block)); + const decodedData = codec.decode<{ blocks: Buffer[] }>(getBlocksFromIdResponseSchema, data); + return decodedData.blocks.map(block => Block.fromBytes(block)); } public abstract run(receivedBlock: Block, peerId: string): Promise; diff --git a/framework/src/engine/endpoint/txpool.ts b/framework/src/engine/endpoint/txpool.ts index 2f841e046b4..0281f6f6e9b 100644 --- a/framework/src/engine/endpoint/txpool.ts +++ b/framework/src/engine/endpoint/txpool.ts @@ -59,9 +59,9 @@ export class TxpoolEndpoint { } public async postTransaction(ctx: RequestContext): Promise { - validator.validate(postTransactionRequestSchema, ctx.params); + validator.validate(postTransactionRequestSchema, ctx.params); - const req = (ctx.params as unknown) as PostTransactionRequest; + const req = ctx.params; const transaction = Transaction.fromBytes(Buffer.from(req.transaction, 'hex')); const { result } = await this._abi.verifyTransaction({ @@ -108,9 +108,9 @@ export class TxpoolEndpoint { } public async dryRunTransaction(ctx: RequestContext): Promise { - validator.validate(dryRunTransactionRequestSchema, ctx.params); + validator.validate(dryRunTransactionRequestSchema, ctx.params); - const req = (ctx.params as unknown) as DryRunTransactionRequest; + const req = ctx.params; const transaction = Transaction.fromBytes(Buffer.from(req.transaction, 'hex')); const { result } = await this._abi.verifyTransaction({ diff --git a/framework/src/engine/generator/endpoint.ts b/framework/src/engine/generator/endpoint.ts index 4adb3a450de..a7fb466ecb4 100644 --- a/framework/src/engine/generator/endpoint.ts +++ b/framework/src/engine/generator/endpoint.ts @@ -78,9 +78,9 @@ export class Endpoint { } public async updateStatus(ctx: RequestContext): Promise { - validator.validate(updateStatusRequestSchema, ctx.params); + validator.validate(updateStatusRequestSchema, ctx.params); - const req = (ctx.params as unknown) as UpdateStatusRequest; + const req = ctx.params; const address = Buffer.from(req.address, 'hex'); const encryptedGenerator = this._generators.find(item => item.address.equals(address)); diff --git a/framework/src/engine/generator/generator.ts b/framework/src/engine/generator/generator.ts index 19fed7d454f..34477b77963 100644 --- a/framework/src/engine/generator/generator.ts +++ b/framework/src/engine/generator/generator.ts @@ -377,11 +377,11 @@ export class Generator { })) as unknown) as { data: Buffer; }; - const encodedData = codec.decode(getTransactionsResponseSchema, data); + const transactionResponse = codec.decode(getTransactionsResponseSchema, data); - validator.validate(getTransactionsResponseSchema, encodedData); + validator.validate(getTransactionsResponseSchema, transactionResponse); - const transactions = encodedData.transactions.map(transaction => + const transactions = transactionResponse.transactions.map(transaction => Transaction.fromBytes(transaction), ); diff --git a/framework/src/modules/dpos_v2/commands/delegate_registration.ts b/framework/src/modules/dpos_v2/commands/delegate_registration.ts index c52a9aa6aa9..5012c9d2241 100644 --- a/framework/src/modules/dpos_v2/commands/delegate_registration.ts +++ b/framework/src/modules/dpos_v2/commands/delegate_registration.ts @@ -47,7 +47,7 @@ export class DelegateRegistrationCommand extends BaseCommand { public async verify( context: CommandVerifyContext, ): Promise { - const { transaction } = context; + const { transaction, params } = context; try { validator.validate(delegateRegistrationCommandParamsSchema, context.params); @@ -58,15 +58,15 @@ export class DelegateRegistrationCommand extends BaseCommand { }; } - if (!isUsername(context.params.name)) { + if (!isUsername(params.name)) { return { status: VerifyStatus.FAIL, - error: new Error(`'name' is in an unsupported format: ${context.params.name}`), + error: new Error(`'name' is in an unsupported format: ${params.name}`), }; } const nameSubstore = context.getStore(MODULE_ID_DPOS_BUFFER, STORE_PREFIX_NAME); - const nameExists = await nameSubstore.has(Buffer.from(context.params.name, 'utf8')); + const nameExists = await nameSubstore.has(Buffer.from(params.name, 'utf8')); if (nameExists) { return { diff --git a/framework/src/modules/validators/endpoint.ts b/framework/src/modules/validators/endpoint.ts index fdff6853d6e..d32615732bf 100644 --- a/framework/src/modules/validators/endpoint.ts +++ b/framework/src/modules/validators/endpoint.ts @@ -22,9 +22,9 @@ import { MODULE_ID_VALIDATORS, STORE_PREFIX_BLS_KEYS } from './constants'; export class ValidatorsEndpoint extends BaseEndpoint { public async validateBLSKey(ctx: ModuleEndpointContext): Promise<{ valid: boolean }> { - validator.validate(validateBLSKeyRequestSchema, ctx.params); + validator.validate(validateBLSKeyRequestSchema, ctx.params); - const req = (ctx.params as unknown) as ValidateBLSKeyRequest; + const req = ctx.params; const { proofOfPossession, blsKey } = req; const blsKeysSubStore = ctx.getStore( From a40a6b452c604f7086f592591655e13fc2585647 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 16:05:27 +0300 Subject: [PATCH 08/39] Fix ts error --- framework/src/modules/fee/module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/modules/fee/module.ts b/framework/src/modules/fee/module.ts index 8381e0ce1f1..b9707f091ba 100644 --- a/framework/src/modules/fee/module.ts +++ b/framework/src/modules/fee/module.ts @@ -58,7 +58,7 @@ export class FeeModule extends BaseModule { const config = objects.mergeDeep({}, defaultConfig, moduleConfig); validator.validate(configSchema, config); - this._tokenID = Buffer.from(config.feeTokenID, 'hex'); + this._tokenID = Buffer.from(config.feeTokenID as string, 'hex'); this._minFeePerByte = genesisConfig.minFeePerByte; this._baseFees = genesisConfig.baseFees.map(fee => ({ ...fee, baseFee: BigInt(fee.baseFee) })); } From 414e0949ae25e1eec810ec2a9473930aa364af7f Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 17:06:12 +0300 Subject: [PATCH 09/39] refactor `as string` with generics --- framework/src/modules/fee/module.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/src/modules/fee/module.ts b/framework/src/modules/fee/module.ts index b9707f091ba..bcd2b5bd315 100644 --- a/framework/src/modules/fee/module.ts +++ b/framework/src/modules/fee/module.ts @@ -17,7 +17,7 @@ import { objects } from '@liskhq/lisk-utils'; import { validator } from '@liskhq/lisk-validator'; import { BaseModule, ModuleInitArgs, ModuleMetadata } from '../base_module'; import { defaultConfig, MODULE_ID_FEE } from './constants'; -import { BaseFee, TokenAPI } from './types'; +import { BaseFee, ModuleConfig, TokenAPI } from './types'; import { TransactionExecuteContext, TransactionVerifyContext, @@ -56,9 +56,9 @@ export class FeeModule extends BaseModule { public async init(args: ModuleInitArgs): Promise { const { genesisConfig, moduleConfig } = args; const config = objects.mergeDeep({}, defaultConfig, moduleConfig); - validator.validate(configSchema, config); + validator.validate(configSchema, config); - this._tokenID = Buffer.from(config.feeTokenID as string, 'hex'); + this._tokenID = Buffer.from(config.feeTokenID, 'hex'); this._minFeePerByte = genesisConfig.minFeePerByte; this._baseFees = genesisConfig.baseFees.map(fee => ({ ...fee, baseFee: BigInt(fee.baseFee) })); } From fc6ab74de772658646bb0a6da744698abe1e3b5b Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 17:45:53 +0300 Subject: [PATCH 10/39] refactor to fix TypeScript errors --- .../src/bootstrapping/commands/transaction/create.ts | 4 ++-- elements/lisk-validator/src/index.ts | 4 ++-- elements/lisk-validator/src/lisk_validator.ts | 12 ++++++++---- .../src/plugin/endpoint.ts | 4 +++- .../src/endpoint.ts | 5 ++++- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/commander/src/bootstrapping/commands/transaction/create.ts b/commander/src/bootstrapping/commands/transaction/create.ts index e62d29f0e7c..d34fa7c2ec7 100644 --- a/commander/src/bootstrapping/commands/transaction/create.ts +++ b/commander/src/bootstrapping/commands/transaction/create.ts @@ -18,7 +18,7 @@ import { blockAssetSchema, eventSchema } from '@liskhq/lisk-chain'; import { codec, Schema } from '@liskhq/lisk-codec'; import * as cryptography from '@liskhq/lisk-cryptography'; import * as transactions from '@liskhq/lisk-transactions'; -import * as validator from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import Command, { flags as flagParser } from '@oclif/command'; import { Application, @@ -122,7 +122,7 @@ const validateAndSignTransaction = ( ) as Schema; const txObject = codec.fromJSON(schema.transaction, { ...transactionWithoutParams, params: '' }); - validator.validator.validate(schema.transaction, txObject); + validator.validate(schema.transaction, txObject); const paramsObject = paramsSchema ? codec.fromJSON(paramsSchema, params) : {}; diff --git a/elements/lisk-validator/src/index.ts b/elements/lisk-validator/src/index.ts index 93b15571909..58b55ed273a 100644 --- a/elements/lisk-validator/src/index.ts +++ b/elements/lisk-validator/src/index.ts @@ -12,11 +12,11 @@ * Removal or modification of this copyright notice is prohibited. * */ -import { validator, liskSchemaIdentifier } from './lisk_validator'; +import { validator, liskSchemaIdentifier, LiskValidator } from './lisk_validator'; // To keep backward compatibility import { LiskErrorObject as ErrorObject } from './types'; export * from './validation'; export * from './errors'; export * from './constants'; -export { validator, liskSchemaIdentifier, ErrorObject }; +export { validator, liskSchemaIdentifier, ErrorObject, LiskValidator }; diff --git a/elements/lisk-validator/src/lisk_validator.ts b/elements/lisk-validator/src/lisk_validator.ts index 7574924f1d1..11bfc5d4342 100644 --- a/elements/lisk-validator/src/lisk_validator.ts +++ b/elements/lisk-validator/src/lisk_validator.ts @@ -13,7 +13,7 @@ * */ -import Ajv, {SchemaObject, ValidateFunction} from 'ajv'; +import Ajv, { SchemaObject, ValidateFunction } from 'ajv'; import addDefaultFormats from 'ajv-formats'; import * as formats from './formats'; import { convertErrorsToLegacyFormat, LiskValidationError } from './errors'; @@ -24,7 +24,7 @@ import { LiskErrorObject } from './types'; export const liskSchemaIdentifier: string = liskMetaSchema.$id; -class LiskValidator { +export class LiskValidator { private readonly _validator: Ajv; public constructor() { @@ -71,13 +71,17 @@ class LiskValidator { public validate>(schema: object, data: unknown): asserts data is T { if (!this._validator.validate(schema, data)) { - throw new LiskValidationError(convertErrorsToLegacyFormat(this._validator.errors as LiskErrorObject[])); + throw new LiskValidationError( + convertErrorsToLegacyFormat(this._validator.errors as LiskErrorObject[]), + ); } } public validateSchema(schema: object): asserts schema is SchemaObject { if (!this._validator.validateSchema(schema)) { - throw new LiskValidationError(convertErrorsToLegacyFormat(this._validator.errors as LiskErrorObject[])); + throw new LiskValidationError( + convertErrorsToLegacyFormat(this._validator.errors as LiskErrorObject[]), + ); } } diff --git a/framework-plugins/lisk-framework-faucet-plugin/src/plugin/endpoint.ts b/framework-plugins/lisk-framework-faucet-plugin/src/plugin/endpoint.ts index 8f5c9b69efa..4f9a787a627 100644 --- a/framework-plugins/lisk-framework-faucet-plugin/src/plugin/endpoint.ts +++ b/framework-plugins/lisk-framework-faucet-plugin/src/plugin/endpoint.ts @@ -24,7 +24,9 @@ import { import { authorizeParamsSchema, fundParamsSchema } from './schemas'; import { FaucetPluginConfig, State } from './types'; -const { validator} = liskValidator; +// disabled for type annotation +// eslint-disable-next-line prefer-destructuring +const validator: liskValidator.LiskValidator = liskValidator.validator; export class Endpoint extends BasePluginEndpoint { private _state: State = { publicKey: undefined, passphrase: undefined }; diff --git a/framework-plugins/lisk-framework-report-misbehavior-plugin/src/endpoint.ts b/framework-plugins/lisk-framework-report-misbehavior-plugin/src/endpoint.ts index 6813c3fad8e..5638bb49306 100644 --- a/framework-plugins/lisk-framework-report-misbehavior-plugin/src/endpoint.ts +++ b/framework-plugins/lisk-framework-report-misbehavior-plugin/src/endpoint.ts @@ -20,7 +20,10 @@ import { import { actionParamsSchema } from './schemas'; import { ReportMisbehaviorPluginConfig, State } from './types'; -const { validator} = liskValidator; +// disabled for type annotation +// eslint-disable-next-line prefer-destructuring +const validator: liskValidator.LiskValidator = liskValidator.validator; + const { encrypt, address } = cryptography; export class Endpoint extends BasePluginEndpoint { From 437dadf29c76c2443f52b39d0b8297a90da4405c Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 18:07:03 +0300 Subject: [PATCH 11/39] fix - import should occur before import of `./constants` --- elements/lisk-chain/src/block_header.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elements/lisk-chain/src/block_header.ts b/elements/lisk-chain/src/block_header.ts index e91a555bbe4..3da1ef51bce 100644 --- a/elements/lisk-chain/src/block_header.ts +++ b/elements/lisk-chain/src/block_header.ts @@ -15,10 +15,10 @@ import { ed, utils } from '@liskhq/lisk-cryptography'; import { codec } from '@liskhq/lisk-codec'; import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { LiskErrorObject } from '@liskhq/lisk-validator/dist-node/types'; import { EMPTY_BUFFER, EMPTY_HASH, SIGNATURE_LENGTH_BYTES, TAG_BLOCK_HEADER } from './constants'; import { blockHeaderSchema, blockHeaderSchemaWithId, signingBlockHeaderSchema } from './schema'; import { JSONObject } from './types'; -import {LiskErrorObject} from "@liskhq/lisk-validator/dist-node/types"; export interface BlockHeaderAttrs { readonly version: number; @@ -189,7 +189,7 @@ export class BlockHeader { const header = this._getBlockHeaderProps(); validator.validate(blockHeaderSchema, header); - const errors: LiskErrorObject[] = [] + const errors: LiskErrorObject[] = []; if (header.previousBlockID.length !== 32) { errors.push({ From 228c3563fb8c46880865f3151b865db8247a2752 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 18:55:57 +0300 Subject: [PATCH 12/39] fix - `error Unsafe assignment of an any value @typescript-eslint/no-unsafe-assignment` --- .../src/engine/consensus/network_endpoint.ts | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/framework/src/engine/consensus/network_endpoint.ts b/framework/src/engine/consensus/network_endpoint.ts index a0757179067..4186fb77904 100644 --- a/framework/src/engine/consensus/network_endpoint.ts +++ b/framework/src/engine/consensus/network_endpoint.ts @@ -103,7 +103,7 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { } catch (error) { this._logger.warn( { - err: error, + err: error as Error, req: data, peerID: peerId, }, @@ -150,26 +150,23 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { data as never, ); - const logDataAndApplyPenalty = (data? : unknown) => { - this._logger.warn( - data, - 'getHighestCommonBlock request validation failed', - ); + const logDataAndApplyPenalty = (errData?: unknown) => { + this._logger.warn(errData, 'getHighestCommonBlock request validation failed'); this._network.applyPenaltyOnPeer({ peerId, penalty: 100, }); - } + }; try { - validator.validate(getHighestCommonBlockRequestSchema, blockIds); - } catch (err) { - logDataAndApplyPenalty({ err, req: data}) - throw err; + validator.validate(getHighestCommonBlockRequestSchema, blockIds); + } catch (error) { + logDataAndApplyPenalty({ err: error as Error, req: data }); + throw error; } if (!objects.bufferArrayUniqueItems(blockIds.ids)) { - logDataAndApplyPenalty({ req: data}); + logDataAndApplyPenalty({ req: data }); } const commonBlockHeaderID = await this._chain.dataAccess.getHighestCommonBlockID(blockIds.ids); From e26787f5ce04f481013c7a0969d600e91bbebfc0 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 19:20:28 +0300 Subject: [PATCH 13/39] fix - `error Unsafe assignment of an any value @typescript-eslint/no-unsafe-assignment` --- framework/src/engine/generator/network_endpoint.ts | 12 ++++++------ .../modules/auth/commands/register_multisignature.ts | 4 ++-- .../dpos_v2/commands/delegate_registration.ts | 4 ++-- framework/src/modules/dpos_v2/commands/pom.ts | 5 ++--- .../modules/dpos_v2/commands/update_generator_key.ts | 4 ++-- framework/src/modules/dpos_v2/commands/vote.ts | 2 +- .../interoperability/mainchain/commands/cc_update.ts | 2 +- .../mainchain/commands/sidechain_registration.ts | 4 ++-- .../mainchain/commands/state_recovery.ts | 4 ++-- .../interoperability/sidechain/commands/cc_update.ts | 2 +- .../sidechain/commands/mainchain_registration.ts | 4 ++-- framework/src/modules/token/commands/cc_transfer.ts | 2 +- framework/src/modules/token/commands/transfer.ts | 2 +- 13 files changed, 25 insertions(+), 26 deletions(-) diff --git a/framework/src/engine/generator/network_endpoint.ts b/framework/src/engine/generator/network_endpoint.ts index 1190c55d14c..c9c2697618d 100644 --- a/framework/src/engine/generator/network_endpoint.ts +++ b/framework/src/engine/generator/network_endpoint.ts @@ -84,13 +84,13 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { try { validator.validate(getTransactionRequestSchema, decodedData); - } catch (err) { - this._logger.warn({ err, peerId }, 'Received invalid getTransactions body'); + } catch (error) { + this._logger.warn({ err: error as Error, peerId }, 'Received invalid getTransactions body'); this.network.applyPenaltyOnPeer({ peerId, penalty: 100, }); - throw err; + throw error; } if (!objectUtils.bufferArrayUniqueItems(decodedData.transactionIds)) { @@ -193,13 +193,13 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { try { validator.validate(postTransactionsAnnouncementSchema, decodedData); - } catch (err) { - this._logger.warn({ err, peerId }, 'Received invalid transactions body'); + } catch (error) { + this._logger.warn({ err: error as Error, peerId }, 'Received invalid transactions body'); this.network.applyPenaltyOnPeer({ peerId, penalty: 100, }); - throw err; + throw error; } this.event.emit(GENERATOR_EVENT_NEW_TRANSACTION_ANNOUNCEMENT, decodedData); diff --git a/framework/src/modules/auth/commands/register_multisignature.ts b/framework/src/modules/auth/commands/register_multisignature.ts index 258035bae8b..5e3b7c2a5bf 100644 --- a/framework/src/modules/auth/commands/register_multisignature.ts +++ b/framework/src/modules/auth/commands/register_multisignature.ts @@ -13,7 +13,7 @@ */ import { objects as objectUtils } from '@liskhq/lisk-utils'; -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseCommand } from '../..'; import { CommandExecuteContext, @@ -48,7 +48,7 @@ export class RegisterMultisignatureCommand extends BaseCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/dpos_v2/commands/delegate_registration.ts b/framework/src/modules/dpos_v2/commands/delegate_registration.ts index 5012c9d2241..84a1afdcfd0 100644 --- a/framework/src/modules/dpos_v2/commands/delegate_registration.ts +++ b/framework/src/modules/dpos_v2/commands/delegate_registration.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { CommandVerifyContext, VerificationResult, @@ -54,7 +54,7 @@ export class DelegateRegistrationCommand extends BaseCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/dpos_v2/commands/pom.ts b/framework/src/modules/dpos_v2/commands/pom.ts index b3072c94e60..c6fa8da3ca1 100644 --- a/framework/src/modules/dpos_v2/commands/pom.ts +++ b/framework/src/modules/dpos_v2/commands/pom.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BlockHeader } from '@liskhq/lisk-chain'; import { CommandVerifyContext, @@ -62,13 +62,12 @@ export class ReportDelegateMisbehaviorCommand extends BaseCommand { public async verify( context: CommandVerifyContext, ): Promise { - try { validator.validate(this.schema, context.params); } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/dpos_v2/commands/update_generator_key.ts b/framework/src/modules/dpos_v2/commands/update_generator_key.ts index 7066c67d8ce..20881826e35 100644 --- a/framework/src/modules/dpos_v2/commands/update_generator_key.ts +++ b/framework/src/modules/dpos_v2/commands/update_generator_key.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { CommandVerifyContext, VerificationResult, @@ -50,7 +50,7 @@ export class UpdateGeneratorKeyCommand extends BaseCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/dpos_v2/commands/vote.ts b/framework/src/modules/dpos_v2/commands/vote.ts index a467eb550df..435db34e745 100644 --- a/framework/src/modules/dpos_v2/commands/vote.ts +++ b/framework/src/modules/dpos_v2/commands/vote.ts @@ -69,7 +69,7 @@ export class VoteCommand extends BaseCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: new AggregateValidationError('Parameter is not valid.', err.toString()), + error: new AggregateValidationError('Parameter is not valid.', err), }; } diff --git a/framework/src/modules/interoperability/mainchain/commands/cc_update.ts b/framework/src/modules/interoperability/mainchain/commands/cc_update.ts index d2e054e168c..0ef146eb6d8 100644 --- a/framework/src/modules/interoperability/mainchain/commands/cc_update.ts +++ b/framework/src/modules/interoperability/mainchain/commands/cc_update.ts @@ -82,7 +82,7 @@ export class MainchainCCUpdateCommand extends BaseInteroperabilityCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/interoperability/mainchain/commands/sidechain_registration.ts b/framework/src/modules/interoperability/mainchain/commands/sidechain_registration.ts index 5c9fca838c2..0c7c49a5462 100644 --- a/framework/src/modules/interoperability/mainchain/commands/sidechain_registration.ts +++ b/framework/src/modules/interoperability/mainchain/commands/sidechain_registration.ts @@ -14,7 +14,7 @@ import { codec } from '@liskhq/lisk-codec'; import { utils } from '@liskhq/lisk-cryptography'; -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { MainchainInteroperabilityStore } from '../store'; import { BaseInteroperabilityCommand } from '../../base_interoperability_command'; import { @@ -71,7 +71,7 @@ export class SidechainRegistrationCommand extends BaseInteroperabilityCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/interoperability/mainchain/commands/state_recovery.ts b/framework/src/modules/interoperability/mainchain/commands/state_recovery.ts index 1b1cc600556..1be52cc0acb 100644 --- a/framework/src/modules/interoperability/mainchain/commands/state_recovery.ts +++ b/framework/src/modules/interoperability/mainchain/commands/state_recovery.ts @@ -14,7 +14,7 @@ import { sparseMerkleTree } from '@liskhq/lisk-tree'; import { utils } from '@liskhq/lisk-cryptography'; -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { MainchainInteroperabilityStore } from '../store'; import { BaseInteroperabilityCommand } from '../../base_interoperability_command'; import { @@ -50,7 +50,7 @@ export class StateRecoveryCommand extends BaseInteroperabilityCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/interoperability/sidechain/commands/cc_update.ts b/framework/src/modules/interoperability/sidechain/commands/cc_update.ts index d3cc9ad4d7e..d81288a1e6e 100644 --- a/framework/src/modules/interoperability/sidechain/commands/cc_update.ts +++ b/framework/src/modules/interoperability/sidechain/commands/cc_update.ts @@ -80,7 +80,7 @@ export class SidechainCCUpdateCommand extends BaseInteroperabilityCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/interoperability/sidechain/commands/mainchain_registration.ts b/framework/src/modules/interoperability/sidechain/commands/mainchain_registration.ts index 31bde8fcc6f..52c818a2da7 100644 --- a/framework/src/modules/interoperability/sidechain/commands/mainchain_registration.ts +++ b/framework/src/modules/interoperability/sidechain/commands/mainchain_registration.ts @@ -14,7 +14,7 @@ import { codec } from '@liskhq/lisk-codec'; import { utils, bls } from '@liskhq/lisk-cryptography'; -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { CCM_STATUS_OK, CHAIN_REGISTERED, @@ -79,7 +79,7 @@ export class MainchainRegistrationCommand extends BaseInteroperabilityCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/token/commands/cc_transfer.ts b/framework/src/modules/token/commands/cc_transfer.ts index b4ebdab011c..f95ad10454b 100644 --- a/framework/src/modules/token/commands/cc_transfer.ts +++ b/framework/src/modules/token/commands/cc_transfer.ts @@ -52,7 +52,7 @@ export class CCTransferCommand extends BaseCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } return { diff --git a/framework/src/modules/token/commands/transfer.ts b/framework/src/modules/token/commands/transfer.ts index 5eeff4b768f..3a190f25787 100644 --- a/framework/src/modules/token/commands/transfer.ts +++ b/framework/src/modules/token/commands/transfer.ts @@ -50,7 +50,7 @@ export class TransferCommand extends BaseCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } return { From eac09d41a1623e48cd197e950726085583bc5e78 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 19:42:21 +0300 Subject: [PATCH 14/39] yarn run format --- framework/src/application.ts | 2 +- framework/src/controller/jsonrpc/utils.ts | 2 +- framework/src/engine/generator/generator.ts | 5 ++++- framework/src/modules/random/endpoint.ts | 2 +- .../modules/token/cc_commands/cc_forward.ts | 1 - .../modules/dpos_v2/commands/vote.spec.ts | 12 +++++------ .../schema/application_config_schema.spec.ts | 20 ++++++++----------- 7 files changed, 21 insertions(+), 23 deletions(-) diff --git a/framework/src/application.ts b/framework/src/application.ts index f0d16077fe3..af8e332a999 100644 --- a/framework/src/application.ts +++ b/framework/src/application.ts @@ -19,7 +19,7 @@ import * as assert from 'assert'; import * as childProcess from 'child_process'; import { Block } from '@liskhq/lisk-chain'; import { Database, StateDB } from '@liskhq/lisk-db'; -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { objects, jobHandlers } from '@liskhq/lisk-utils'; import { APP_EVENT_SHUTDOWN, APP_EVENT_READY } from './constants'; import { diff --git a/framework/src/controller/jsonrpc/utils.ts b/framework/src/controller/jsonrpc/utils.ts index ab7d7fbd158..9b46275ce59 100644 --- a/framework/src/controller/jsonrpc/utils.ts +++ b/framework/src/controller/jsonrpc/utils.ts @@ -11,7 +11,7 @@ * * Removal or modification of this copyright notice is prohibited. */ -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { JSONRPCErrorObject, ID, diff --git a/framework/src/engine/generator/generator.ts b/framework/src/engine/generator/generator.ts index 34477b77963..3abbf090691 100644 --- a/framework/src/engine/generator/generator.ts +++ b/framework/src/engine/generator/generator.ts @@ -377,7 +377,10 @@ export class Generator { })) as unknown) as { data: Buffer; }; - const transactionResponse = codec.decode(getTransactionsResponseSchema, data); + const transactionResponse = codec.decode( + getTransactionsResponseSchema, + data, + ); validator.validate(getTransactionsResponseSchema, transactionResponse); diff --git a/framework/src/modules/random/endpoint.ts b/framework/src/modules/random/endpoint.ts index 3b866e2993a..a46b142b1be 100644 --- a/framework/src/modules/random/endpoint.ts +++ b/framework/src/modules/random/endpoint.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { ModuleEndpointContext } from '../../types'; import { BaseEndpoint } from '../base_endpoint'; import { STORE_PREFIX_RANDOM, EMPTY_KEY } from './constants'; diff --git a/framework/src/modules/token/cc_commands/cc_forward.ts b/framework/src/modules/token/cc_commands/cc_forward.ts index 1b85be78f26..bba59039611 100644 --- a/framework/src/modules/token/cc_commands/cc_forward.ts +++ b/framework/src/modules/token/cc_commands/cc_forward.ts @@ -61,7 +61,6 @@ export class CCForwardCommand extends BaseCCCommand { try { params = codec.decode(crossChainForwardMessageParams, ccm.params); validator.validate(crossChainTransferMessageParams, params); - } catch (error) { ctx.logger.debug({ err: error as Error }, 'Error verifying the params.'); if (ccm.status === CCM_STATUS_OK) { diff --git a/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts b/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts index 8dfb5d5fc6b..2721e6ae129 100644 --- a/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts +++ b/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts @@ -226,9 +226,9 @@ describe('VoteCommand', () => { }); it('should return errors', () => { - expect( - () => validator.validate(command.schema, transactionParamsDecoded) - ).toThrow('should pass "dataType" keyword validation') + expect(() => validator.validate(command.schema, transactionParamsDecoded)).toThrow( + 'should pass "dataType" keyword validation', + ); }); }); @@ -245,9 +245,9 @@ describe('VoteCommand', () => { }); it('should return errors', () => { - expect( - () => validator.validate(command.schema, transactionParamsDecoded) - ).toThrow('should pass "dataType" keyword validation') + expect(() => validator.validate(command.schema, transactionParamsDecoded)).toThrow( + 'should pass "dataType" keyword validation', + ); }); }); }); diff --git a/framework/test/unit/schema/application_config_schema.spec.ts b/framework/test/unit/schema/application_config_schema.spec.ts index a415a4c24e9..7f8c6d2afb4 100644 --- a/framework/test/unit/schema/application_config_schema.spec.ts +++ b/framework/test/unit/schema/application_config_schema.spec.ts @@ -22,35 +22,31 @@ describe('schema/application_config_schema.js', () => { }); it('should validate the defined schema', () => { - expect( - () => validator.validateSchema(applicationConfigSchema) - ).not.toThrow() + expect(() => validator.validateSchema(applicationConfigSchema)).not.toThrow(); }); it('should validate if module properties are objects', () => { const config = objects.cloneDeep(applicationConfigSchema.default); config.genesis.modules = { myModule: { myProp: 1 } }; - expect( - () => validator.validate(applicationConfigSchema, config) - ).not.toThrow() + expect(() => validator.validate(applicationConfigSchema, config)).not.toThrow(); }); it('should not validate if module properties are not objects', () => { const config = objects.cloneDeep(applicationConfigSchema.default); config.genesis.modules = { myModule: 10 }; - expect( - () => validator.validate(applicationConfigSchema, config) - ).toThrow("Property '.genesis.modules.myModule' should be of type 'object'") + expect(() => validator.validate(applicationConfigSchema, config)).toThrow( + "Property '.genesis.modules.myModule' should be of type 'object'", + ); }); it('should not validate if module properties are not valid format', () => { const config = objects.cloneDeep(applicationConfigSchema.default); config.genesis.modules = { 'my-custom-module': { myProp: 1 } }; - expect( - () => validator.validate(applicationConfigSchema, config) - ).toThrow("must match pattern \"^[a-zA-Z][a-zA-Z0-9_]*$\"\nproperty name must be valid") + expect(() => validator.validate(applicationConfigSchema, config)).toThrow( + 'must match pattern "^[a-zA-Z][a-zA-Z0-9_]*$"\nproperty name must be valid', + ); }); }); From 3ade9c653494e550fb0693892c05e599edd06c79 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 20:10:12 +0300 Subject: [PATCH 15/39] yarn run format & some eslint fixes --- elements/lisk-chain/src/block_assets.ts | 2 +- elements/lisk-chain/src/transaction.ts | 12 +- elements/lisk-codec/src/codec.ts | 5 +- elements/lisk-p2p/src/utils/validate.ts | 3 +- elements/lisk-transactions/src/validate.ts | 5 +- elements/lisk-validator/src/errors.ts | 2 +- .../test/lisk_validator_errors.spec.ts | 12 +- .../test/lisk_validator_formats.spec.ts | 55 +-- .../test/lisk_validator_keywords.spec.ts | 345 ++++++++++-------- .../cc_commands/registration.spec.ts | 20 +- .../cc_commands/sidechain_terminated.spec.ts | 10 +- .../mainchain/commands/cc_update.spec.ts | 7 +- .../cc_commands/registration.spec.ts | 16 +- .../cc_commands/sidechain_terminated.spec.ts | 10 +- .../interoperability/sidechain/store.spec.ts | 4 +- .../modules/interoperability/store.spec.ts | 20 +- .../modules/interoperability/utils.spec.ts | 4 +- 17 files changed, 284 insertions(+), 248 deletions(-) diff --git a/elements/lisk-chain/src/block_assets.ts b/elements/lisk-chain/src/block_assets.ts index c0fe3193a3f..83dfac9260c 100644 --- a/elements/lisk-chain/src/block_assets.ts +++ b/elements/lisk-chain/src/block_assets.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { codec } from '@liskhq/lisk-codec'; import { MerkleTree } from '@liskhq/lisk-tree'; import { blockAssetSchema } from './schema'; diff --git a/elements/lisk-chain/src/transaction.ts b/elements/lisk-chain/src/transaction.ts index c436a00a6a3..007b59300f9 100644 --- a/elements/lisk-chain/src/transaction.ts +++ b/elements/lisk-chain/src/transaction.ts @@ -13,8 +13,8 @@ */ import { codec } from '@liskhq/lisk-codec'; -import { utils, address, ed } from '@liskhq/lisk-cryptography'; -import { validator} from '@liskhq/lisk-validator'; +import { address, ed, utils } from '@liskhq/lisk-cryptography'; +import { validator } from '@liskhq/lisk-validator'; import { TAG_TRANSACTION } from './constants'; import { JSONObject } from './types'; @@ -130,18 +130,14 @@ export class Transaction { } public getBytes(): Buffer { - const transactionBytes = codec.encode(transactionSchema, this as Record); - - return transactionBytes; + return codec.encode(transactionSchema, this as Record); } public getSigningBytes(): Buffer { - const transactionBytes = codec.encode(transactionSchema, ({ + return codec.encode(transactionSchema, ({ ...this, signatures: [], } as unknown) as Record); - - return transactionBytes; } public sign(networkIdentifier: Buffer, privateKey: Buffer): void { diff --git a/elements/lisk-codec/src/codec.ts b/elements/lisk-codec/src/codec.ts index 2044e8f8381..e8871ddca8a 100644 --- a/elements/lisk-codec/src/codec.ts +++ b/elements/lisk-codec/src/codec.ts @@ -12,10 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { - validator, - liskSchemaIdentifier, -} from '@liskhq/lisk-validator'; +import { validator, liskSchemaIdentifier } from '@liskhq/lisk-validator'; import { objects as objectUtils } from '@liskhq/lisk-utils'; import { generateKey } from './utils'; import { readObject, writeObject } from './collection'; diff --git a/elements/lisk-p2p/src/utils/validate.ts b/elements/lisk-p2p/src/utils/validate.ts index 6f097817534..d5d6f31487b 100644 --- a/elements/lisk-p2p/src/utils/validate.ts +++ b/elements/lisk-p2p/src/utils/validate.ts @@ -148,7 +148,7 @@ export const validatePeerInfoList = ( export const validateRPCRequest = (request: unknown): void => { try { validator.validate(rpcRequestSchema, request as Record); - } catch { + } catch { throw new Error('RPC request format is invalid.'); } }; @@ -159,7 +159,6 @@ export const validateProtocolMessage = (message: unknown): void => { } catch { throw new Error('Protocol message format is invalid.'); } - }; export const validatePacket = (packet: unknown): void => { diff --git a/elements/lisk-transactions/src/validate.ts b/elements/lisk-transactions/src/validate.ts index 00d3a3aff14..694ab0671ae 100644 --- a/elements/lisk-transactions/src/validate.ts +++ b/elements/lisk-transactions/src/validate.ts @@ -24,10 +24,7 @@ export const validateTransaction = ( ...transactionObject, params: Buffer.alloc(0), }; - validator.validate( - baseTransactionSchema, - transactionObjectWithEmptyParameters, - ); + validator.validate(baseTransactionSchema, transactionObjectWithEmptyParameters); if (!paramsSchema) { return undefined; diff --git a/elements/lisk-validator/src/errors.ts b/elements/lisk-validator/src/errors.ts index 3237bb4a6b2..d7a26e97ddb 100644 --- a/elements/lisk-validator/src/errors.ts +++ b/elements/lisk-validator/src/errors.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import {LiskErrorObject} from './types'; +import { LiskErrorObject } from './types'; // Ajv.ErrorObject makes `schemaPath` and `dataPath` required // While these are not if we want to infer default values from validation diff --git a/elements/lisk-validator/test/lisk_validator_errors.spec.ts b/elements/lisk-validator/test/lisk_validator_errors.spec.ts index 6855fd95f60..07021bd7c74 100644 --- a/elements/lisk-validator/test/lisk_validator_errors.spec.ts +++ b/elements/lisk-validator/test/lisk_validator_errors.spec.ts @@ -44,7 +44,7 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nProperty '.myProp' should be of type 'string'"; - expect(() => validator.validate(schema, obj)).toThrow(expectedError) + expect(() => validator.validate(schema, obj)).toThrow(expectedError); }); it('should format minLength errors', () => { @@ -56,7 +56,7 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have fewer than 2 characters"; - expect(() => validator.validate(schema, obj)).toThrow(expectedError) + expect(() => validator.validate(schema, obj)).toThrow(expectedError); }); it('should format maxLength errors', () => { @@ -68,7 +68,7 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have more than 5 characters"; - expect(() => validator.validate(schema, obj)).toThrow(expectedError) + expect(() => validator.validate(schema, obj)).toThrow(expectedError); }); it('should format custom format errors', () => { @@ -80,7 +80,7 @@ describe('LiskValidationError formatter', () => { const expectedError = 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' must match format "hex"'; - expect(() => validator.validate(schema, obj)).toThrow(expectedError) + expect(() => validator.validate(schema, obj)).toThrow(expectedError); }); it('should format missing required property errors', () => { @@ -89,7 +89,7 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nMissing property, must have required property 'myProp'"; - expect(() => validator.validate(schema, obj)).toThrow(expectedError) + expect(() => validator.validate(schema, obj)).toThrow(expectedError); }); it('should format additional property errors', () => { @@ -120,6 +120,6 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nProperty '.myProp' has extraneous property 'bar'"; - expect(() => validator.validate(schema, obj)).toThrow(expectedError) + expect(() => validator.validate(schema, obj)).toThrow(expectedError); }); }); diff --git a/elements/lisk-validator/test/lisk_validator_formats.spec.ts b/elements/lisk-validator/test/lisk_validator_formats.spec.ts index 87a521d17d0..6ea12f032a4 100644 --- a/elements/lisk-validator/test/lisk_validator_formats.spec.ts +++ b/elements/lisk-validator/test/lisk_validator_formats.spec.ts @@ -44,17 +44,20 @@ describe('validator formats', () => { }); it('should validate to true when valid hex string is provided', () => { - expect( - () => validator.validate(schema, { target: '23b9ed818526a928bce91b96fb4508babb121ee2' }) - ).not.toThrow() + expect(() => + validator.validate(schema, { target: '23b9ed818526a928bce91b96fb4508babb121ee2' }), + ).not.toThrow(); }); it('should validate to false when not hex is provided', () => { - const expectedError = "Lisk validator found 1 error[s]:\nProperty '.target' must match format \"hex\""; + const expectedError = + 'Lisk validator found 1 error[s]:\nProperty \'.target\' must match format "hex"'; - expect(() => validator.validate(schema, { - target: 'notValid?!hex-!!@', - })).toThrow(expectedError) + expect(() => + validator.validate(schema, { + target: 'notValid?!hex-!!@', + }), + ).toThrow(expectedError); }); }); @@ -69,7 +72,9 @@ describe('validator formats', () => { }; it('should validate to false for invalid path', () => { - expect(() => validator.validate(pathSchema, { rootPath: 'lisk' })).toThrow("Property '.rootPath' must match format \"path\"") + expect(() => validator.validate(pathSchema, { rootPath: 'lisk' })).toThrow( + 'Property \'.rootPath\' must match format "path"', + ); }); it('should validate to true for valid path with tilde', () => { @@ -93,15 +98,15 @@ describe('validator formats', () => { it('should validate to false for invalid path', () => { const expectedError = - "Lisk validator found 1 error[s]:\nProperty '.encryptedPassphrase' must match format \"encryptedPassphrase\""; + 'Lisk validator found 1 error[s]:\nProperty \'.encryptedPassphrase\' must match format "encryptedPassphrase"'; [ 'cipherText', 'cipherText=', 'cipherText=abcd1234&iterations=10000&iv=ef012345cipherText=abcd1234&iterations=10000&iv=ef012345', ].forEach(text => { - expect( - () => validator.validate(encryptedPassphraseSchema, { + expect(() => + validator.validate(encryptedPassphraseSchema, { encryptedPassphrase: text, }), ).toThrow(expectedError); @@ -110,8 +115,8 @@ describe('validator formats', () => { it('should validate to true for valid encrypted passphrase', () => { ['cipherText=abcd1234', 'cipherText=abcd1234&iterations=10000&iv=ef012345'].forEach(text => { - expect( - () => validator.validate(encryptedPassphraseSchema, { + expect(() => + validator.validate(encryptedPassphraseSchema, { encryptedPassphrase: text, }), ).not.toThrow(); @@ -130,19 +135,20 @@ describe('validator formats', () => { }; it('should validate to false for invalid camel case text', () => { - const expectedError = "Lisk validator found 1 error[s]:\nProperty '.camelCaseRegex' must match format \"camelCase\""; + const expectedError = + 'Lisk validator found 1 error[s]:\nProperty \'.camelCaseRegex\' must match format "camelCase"'; ['NotCamelCase', '123Case', '_camelCase'].forEach(text => { - expect( - () => validator.validate(camelCaseRegexSchema, { camelCaseRegex: text }) - ).toThrow(expectedError); + expect(() => validator.validate(camelCaseRegexSchema, { camelCaseRegex: text })).toThrow( + expectedError, + ); }); }); it('should validate to true for valid camel case text', () => { ['camelCase'].forEach(text => { - expect( - () => validator.validate(camelCaseRegexSchema, { camelCaseRegex: text }) + expect(() => + validator.validate(camelCaseRegexSchema, { camelCaseRegex: text }), ).not.toThrow(); }); }); @@ -159,20 +165,17 @@ describe('validator formats', () => { }; it('should validate to false for invalid semantic versions', () => { - const expectedError = "Lisk validator found 1 error[s]:\nProperty '.version' must match format \"version\""; + const expectedError = + 'Lisk validator found 1 error[s]:\nProperty \'.version\' must match format "version"'; ['9999999999999999.4.7.4', 'alpha one', '1.2.12.102', '4.6.3.9.2-alpha2'].forEach(text => { - expect( - () =>validator.validate(versionSchema, { version: text }) - ).toThrow(expectedError); + expect(() => validator.validate(versionSchema, { version: text })).toThrow(expectedError); }); }); it('should validate to true for valid semantic versions', () => { ['1.2.0', '1.0.0-alpha.0', 'v1.2.3', '1.0.0-beta+exp.sha.5114f85'].forEach(text => { - expect( - () =>validator.validate(versionSchema, { version: text }) - ).not.toThrow() + expect(() => validator.validate(versionSchema, { version: text })).not.toThrow(); }); }); }); diff --git a/elements/lisk-validator/test/lisk_validator_keywords.spec.ts b/elements/lisk-validator/test/lisk_validator_keywords.spec.ts index 10e3d32d98e..775d8f17156 100644 --- a/elements/lisk-validator/test/lisk_validator_keywords.spec.ts +++ b/elements/lisk-validator/test/lisk_validator_keywords.spec.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. * */ -import {LiskValidationError, validator} from '../src'; +import { LiskValidationError, validator } from '../src'; // eslint-disable-next-line @typescript-eslint/no-var-requires const cloneDeep = require('lodash.clonedeep'); @@ -85,330 +85,373 @@ describe('validator keywords', () => { describe('dataType value validation', () => { describe('string', () => { it('should not throw error if valid', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'string', fieldNumber: 1}}, + properties: { myProp: { dataType: 'string', fieldNumber: 1 } }, }, - {myProp: 'string'}, - ) + { myProp: 'string' }, + ), ).not.toThrow(); }); it('should be invalid if minLength is not satisfied', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, properties: { - myProp: {dataType: 'string', fieldNumber: 1, minLength: 3}, + myProp: { dataType: 'string', fieldNumber: 1, minLength: 3 }, }, }, - {myProp: 'ch'}, - )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have fewer than 3 characters"); + { myProp: 'ch' }, + ), + ).toThrow( + "Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have fewer than 3 characters", + ); }); it('should be invalid if maxLength is not satisfied', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, properties: { - myProp: {dataType: 'string', fieldNumber: 1, maxLength: 3}, + myProp: { dataType: 'string', fieldNumber: 1, maxLength: 3 }, }, }, - {myProp: 'change'}, - )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have more than 3 characters"); + { myProp: 'change' }, + ), + ).toThrow( + "Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have more than 3 characters", + ); }); it('should be invalid if not string', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, properties: { - myProp: {dataType: 'string', fieldNumber: 1, maxLength: 3}, + myProp: { dataType: 'string', fieldNumber: 1, maxLength: 3 }, }, }, - {myProp: 32}, - )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation") + { myProp: 32 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); }); describe('bytes', () => { it('should not throw error if valid', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'bytes', fieldNumber: 1}}, + properties: { myProp: { dataType: 'bytes', fieldNumber: 1 } }, }, - {myProp: Buffer.from('value')}, - )).not.toThrow() + { myProp: Buffer.from('value') }, + ), + ).not.toThrow(); }); it('should be invalid if minLength is not satisfied', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, properties: { - myProp: {dataType: 'bytes', fieldNumber: 1, minLength: 10}, + myProp: { dataType: 'bytes', fieldNumber: 1, minLength: 10 }, }, }, - {myProp: Buffer.alloc(9)}, - )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' minLength not satisfied") + { myProp: Buffer.alloc(9) }, + ), + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' minLength not satisfied"); }); it('should be invalid if maxLength is not satisfied', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, properties: { - myProp: {dataType: 'bytes', fieldNumber: 1, maxLength: 10}, + myProp: { dataType: 'bytes', fieldNumber: 1, maxLength: 10 }, }, }, - {myProp: Buffer.alloc(11)}, - )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' maxLength exceeded") + { myProp: Buffer.alloc(11) }, + ), + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' maxLength exceeded"); }); it('should be invalid if not Buffer', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, properties: { - myProp: {dataType: 'bytes', fieldNumber: 1, maxLength: 10}, + myProp: { dataType: 'bytes', fieldNumber: 1, maxLength: 10 }, }, }, - {myProp: 'string'}, - )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation") + { myProp: 'string' }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); }); describe('boolean', () => { it('should not throw error if valid', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'boolean', fieldNumber: 1}}, + properties: { myProp: { dataType: 'boolean', fieldNumber: 1 } }, }, - {myProp: true}, - )).not.toThrow() + { myProp: true }, + ), + ).not.toThrow(); }); it('should be invalid if not boolean', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'boolean', fieldNumber: 1}}, + properties: { myProp: { dataType: 'boolean', fieldNumber: 1 } }, }, - {myProp: 1} - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation") + { myProp: 1 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); }); describe('uint32', () => { it('should not throw error if valid', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, }, - {myProp: 0}, - )).not.toThrow(); + { myProp: 0 }, + ), + ).not.toThrow(); }); it('should be invalid if not number', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, }, - {myProp: 'value'}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: 'value' }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); it('should be invalid if number has decimal', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, }, - {myProp: 1.23}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: 1.23 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); it('should be invalid if negative', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, }, - {myProp: -1}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: -1 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); it('should be invalid if above uint32 range', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, }, - {myProp: 4294967296}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: 4294967296 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); }); describe('uint64', () => { it('should not throw error if valid', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint64', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint64', fieldNumber: 1 } }, }, - {myProp: BigInt(32)}, - ) + { myProp: BigInt(32) }, + ), ).not.toThrow(); }); it('should be invalid if not bigint', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint64', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint64', fieldNumber: 1 } }, }, - {myProp: 32}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: 32 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); it('should be invalid if negative', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint64', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint64', fieldNumber: 1 } }, }, - {myProp: BigInt(-32)}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: BigInt(-32) }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); it('should be invalid if above uint64 range', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint64', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint64', fieldNumber: 1 } }, }, - {myProp: BigInt('18446744073709551616')}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: BigInt('18446744073709551616') }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); }); describe('sint32', () => { it('should not throw error if valid', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'sint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'sint32', fieldNumber: 1 } }, }, - {myProp: -32}, - ) + { myProp: -32 }, + ), ).not.toThrow(); }); it('should be invalid if not number', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'sint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'sint32', fieldNumber: 1 } }, }, - {myProp: 'value'}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: 'value' }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); it('should be invalid if number has decimal', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'sint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'sint32', fieldNumber: 1 } }, }, - {myProp: -1.23}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: -1.23 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); it('should be invalid if not sint32 range', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'sint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'sint32', fieldNumber: 1 } }, }, - {myProp: -2147483649}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: -2147483649 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); }); describe('sint64', () => { it('should not throw error if valid', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'sint64', fieldNumber: 1}}, + properties: { myProp: { dataType: 'sint64', fieldNumber: 1 } }, }, - {myProp: BigInt(-32)}, - ) - ).not.toThrow() + { myProp: BigInt(-32) }, + ), + ).not.toThrow(); }); it('should be invalid if not bigint', () => { - expect( - () => validator.validate( - { - ...validSchema, - properties: {myProp: {dataType: 'sint64', fieldNumber: 1}}, - }, - {myProp: 32}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + expect(() => + validator.validate( + { + ...validSchema, + properties: { myProp: { dataType: 'sint64', fieldNumber: 1 } }, + }, + { myProp: 32 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); it('should be invalid if above sint64 range', () => { - expect( - () => validator.validate( - { - ...validSchema, - properties: {myProp: {dataType: 'sint64', fieldNumber: 1}}, - }, - {myProp: BigInt('-9223372036854775809')}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + expect(() => + validator.validate( + { + ...validSchema, + properties: { myProp: { dataType: 'sint64', fieldNumber: 1 } }, + }, + { myProp: BigInt('-9223372036854775809') }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); }); }); diff --git a/framework/test/unit/modules/interoperability/mainchain/cc_commands/registration.spec.ts b/framework/test/unit/modules/interoperability/mainchain/cc_commands/registration.spec.ts index 218e7dda903..40412bfe7fa 100644 --- a/framework/test/unit/modules/interoperability/mainchain/cc_commands/registration.spec.ts +++ b/framework/test/unit/modules/interoperability/mainchain/cc_commands/registration.spec.ts @@ -14,7 +14,7 @@ import { codec } from '@liskhq/lisk-codec'; import { utils } from '@liskhq/lisk-cryptography'; -import { MainchainCCRegistrationCommand } from '../../../../../../src/modules/interoperability/mainchain/cc_commands/registration'; +import { MainchainCCRegistrationCommand } from '../../../../../../src/modules/interoperability/mainchain/cc_commands'; import { MainchainInteroperabilityStore } from '../../../../../../src/modules/interoperability/mainchain/store'; import { registrationCCMParamsSchema } from '../../../../../../src/modules/interoperability/schemas'; import { CCCommandExecuteContext } from '../../../../../../src/modules/interoperability/types'; @@ -138,7 +138,7 @@ describe('MainchainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -165,7 +165,7 @@ describe('MainchainCCRegistrationCommand', () => { await ccRegistrationCommand.execute({ ...sampleExecuteContext, ccm: invalidCCM }); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -183,7 +183,7 @@ describe('MainchainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -201,7 +201,7 @@ describe('MainchainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -236,7 +236,7 @@ describe('MainchainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -271,7 +271,7 @@ describe('MainchainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -293,7 +293,7 @@ describe('MainchainCCRegistrationCommand', () => { networkIdentifier: differentNetworkID, }); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -321,7 +321,7 @@ describe('MainchainCCRegistrationCommand', () => { await ccRegistrationCommand.execute({ ...sampleExecuteContext, ccm: invalidCCM }); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -339,6 +339,6 @@ describe('MainchainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(0); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(0); }); }); diff --git a/framework/test/unit/modules/interoperability/mainchain/cc_commands/sidechain_terminated.spec.ts b/framework/test/unit/modules/interoperability/mainchain/cc_commands/sidechain_terminated.spec.ts index 43a0e3b9ea3..94dcb28927c 100644 --- a/framework/test/unit/modules/interoperability/mainchain/cc_commands/sidechain_terminated.spec.ts +++ b/framework/test/unit/modules/interoperability/mainchain/cc_commands/sidechain_terminated.spec.ts @@ -15,7 +15,7 @@ import { codec } from '@liskhq/lisk-codec'; import { utils } from '@liskhq/lisk-cryptography'; import { MAINCHAIN_ID_BUFFER } from '../../../../../../src/modules/interoperability/constants'; -import { MainchainCCSidechainTerminatedCommand } from '../../../../../../src/modules/interoperability/mainchain/cc_commands/sidechain_terminated'; +import { MainchainCCSidechainTerminatedCommand } from '../../../../../../src/modules/interoperability/mainchain/cc_commands'; import { MainchainInteroperabilityStore } from '../../../../../../src/modules/interoperability/mainchain/store'; import { sidechainTerminatedCCMParamsSchema } from '../../../../../../src/modules/interoperability/schemas'; import { CCCommandExecuteContext } from '../../../../../../src/modules/interoperability/types'; @@ -100,7 +100,7 @@ describe('MainchainCCSidechainTerminatedCommand', () => { it('should call terminateChainInternal when sendingChainID !== MAINCHAIN_ID', async () => { await ccSidechainTerminatedCommand.execute(sampleExecuteContextNew); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccmNew.sendingChainID, expect.objectContaining({ @@ -114,15 +114,15 @@ describe('MainchainCCSidechainTerminatedCommand', () => { hasTerminatedStateAccountMock.mockResolvedValueOnce(true); await ccSidechainTerminatedCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(0); - expect(createTerminatedStateAccountMock).toBeCalledTimes(0); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(0); + expect(createTerminatedStateAccountMock).toHaveBeenCalledTimes(0); }); it('should create an entry for the chainID in the terminated account substore when an entry does not exist and sendingChainID === MAINCHAIN_ID', async () => { hasTerminatedStateAccountMock.mockResolvedValueOnce(false); await ccSidechainTerminatedCommand.execute(sampleExecuteContext); - expect(createTerminatedStateAccountMock).toBeCalledTimes(1); + expect(createTerminatedStateAccountMock).toHaveBeenCalledTimes(1); expect(createTerminatedStateAccountMock).toHaveBeenCalledWith( ccmSidechainTerminatedParams.chainID, ccmSidechainTerminatedParams.stateRoot, diff --git a/framework/test/unit/modules/interoperability/mainchain/commands/cc_update.spec.ts b/framework/test/unit/modules/interoperability/mainchain/commands/cc_update.spec.ts index 9eedc22bb96..3a743304d04 100644 --- a/framework/test/unit/modules/interoperability/mainchain/commands/cc_update.spec.ts +++ b/framework/test/unit/modules/interoperability/mainchain/commands/cc_update.spec.ts @@ -22,6 +22,7 @@ import { CommandVerifyContext, testing, VerifyStatus, + MainchainCCUpdateCommand, } from '../../../../../../src'; import { ActiveValidator, @@ -31,7 +32,7 @@ import { ChannelData, CrossChainUpdateTransactionParams, } from '../../../../../../src/modules/interoperability/types'; -import { MainchainCCUpdateCommand } from '../../../../../../src/modules/interoperability/mainchain/commands/cc_update'; + import { Certificate } from '../../../../../../src/engine/consensus/certificate_generation/types'; import { certificateSchema } from '../../../../../../src/engine/consensus/certificate_generation/schema'; import * as interopUtils from '../../../../../../src/modules/interoperability/utils'; @@ -149,7 +150,7 @@ describe('CrossChainUpdateCommand', () => { let activeValidatorsUpdate: ActiveValidator[]; let sortedActiveValidatorsUpdate: ActiveValidator[]; - beforeEach(async () => { + beforeEach(() => { activeValidatorsUpdate = [ { blsKey: cryptography.utils.getRandomBytes(48), bftWeight: BigInt(1) }, { blsKey: cryptography.utils.getRandomBytes(48), bftWeight: BigInt(3) }, @@ -390,7 +391,7 @@ describe('CrossChainUpdateCommand', () => { let partnerValidatorsDataVerify: ChainValidators; let activeValidatorsVerify: ActiveValidator[]; - beforeEach(async () => { + beforeEach(() => { activeValidatorsVerify = [...activeValidatorsUpdate]; blockHeader = { height: 25, diff --git a/framework/test/unit/modules/interoperability/sidechain/cc_commands/registration.spec.ts b/framework/test/unit/modules/interoperability/sidechain/cc_commands/registration.spec.ts index e89f71bf8cd..54e86bf683f 100644 --- a/framework/test/unit/modules/interoperability/sidechain/cc_commands/registration.spec.ts +++ b/framework/test/unit/modules/interoperability/sidechain/cc_commands/registration.spec.ts @@ -138,7 +138,7 @@ describe('SidechainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -165,7 +165,7 @@ describe('SidechainCCRegistrationCommand', () => { await ccRegistrationCommand.execute({ ...sampleExecuteContext, ccm: invalidCCM }); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -183,7 +183,7 @@ describe('SidechainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -201,7 +201,7 @@ describe('SidechainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -236,7 +236,7 @@ describe('SidechainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -271,7 +271,7 @@ describe('SidechainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -293,7 +293,7 @@ describe('SidechainCCRegistrationCommand', () => { networkIdentifier: differentNetworkID, }); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -311,6 +311,6 @@ describe('SidechainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(0); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(0); }); }); diff --git a/framework/test/unit/modules/interoperability/sidechain/cc_commands/sidechain_terminated.spec.ts b/framework/test/unit/modules/interoperability/sidechain/cc_commands/sidechain_terminated.spec.ts index 9ffdf366e18..c43cf3928ed 100644 --- a/framework/test/unit/modules/interoperability/sidechain/cc_commands/sidechain_terminated.spec.ts +++ b/framework/test/unit/modules/interoperability/sidechain/cc_commands/sidechain_terminated.spec.ts @@ -15,7 +15,7 @@ import { codec } from '@liskhq/lisk-codec'; import { utils } from '@liskhq/lisk-cryptography'; import { MAINCHAIN_ID_BUFFER } from '../../../../../../src/modules/interoperability/constants'; -import { SidechainCCSidechainTerminatedCommand } from '../../../../../../src/modules/interoperability/sidechain/cc_commands/sidechain_terminated'; +import { SidechainCCSidechainTerminatedCommand } from '../../../../../../src/modules/interoperability/sidechain/cc_commands'; import { SidechainInteroperabilityStore } from '../../../../../../src/modules/interoperability/sidechain/store'; import { sidechainTerminatedCCMParamsSchema } from '../../../../../../src/modules/interoperability/schemas'; import { CCCommandExecuteContext } from '../../../../../../src/modules/interoperability/types'; @@ -100,7 +100,7 @@ describe('SidechainCCSidechainTerminatedCommand', () => { it('should call terminateChainInternal when sendingChainID !== MAINCHAIN_ID', async () => { await ccSidechainTerminatedCommand.execute(sampleExecuteContextNew); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccmNew.sendingChainID, expect.objectContaining({ @@ -114,15 +114,15 @@ describe('SidechainCCSidechainTerminatedCommand', () => { hasTerminatedStateAccountMock.mockResolvedValueOnce(true); await ccSidechainTerminatedCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(0); - expect(createTerminatedStateAccountMock).toBeCalledTimes(0); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(0); + expect(createTerminatedStateAccountMock).toHaveBeenCalledTimes(0); }); it('should create an entry for the chainID in the terminated account substore when an entry does not exist and sendingChainID === MAINCHAIN_ID', async () => { hasTerminatedStateAccountMock.mockResolvedValueOnce(false); await ccSidechainTerminatedCommand.execute(sampleExecuteContext); - expect(createTerminatedStateAccountMock).toBeCalledTimes(1); + expect(createTerminatedStateAccountMock).toHaveBeenCalledTimes(1); expect(createTerminatedStateAccountMock).toHaveBeenCalledWith( ccmSidechainTerminatedParams.chainID, ccmSidechainTerminatedParams.stateRoot, diff --git a/framework/test/unit/modules/interoperability/sidechain/store.spec.ts b/framework/test/unit/modules/interoperability/sidechain/store.spec.ts index 8f24126ae94..2098d2b46d7 100644 --- a/framework/test/unit/modules/interoperability/sidechain/store.spec.ts +++ b/framework/test/unit/modules/interoperability/sidechain/store.spec.ts @@ -220,7 +220,7 @@ describe('Sidechain interoperability store', () => { await expect(sidechainInteropStoreLocal.sendInternal(sendInternalContext)).resolves.toEqual( true, ); - expect(sidechainInteropStoreLocal.getChainAccount).toBeCalledWith( + expect(sidechainInteropStoreLocal.getChainAccount).toHaveBeenCalledWith( getIDAsKeyForStore(MAINCHAIN_ID), ); }); @@ -247,7 +247,7 @@ describe('Sidechain interoperability store', () => { await expect(sidechainInteropStoreLocal.sendInternal(sendInternalContext)).resolves.toEqual( true, ); - expect(sidechainInteropStoreLocal.getChainAccount).toBeCalledWith(ccm.receivingChainID); + expect(sidechainInteropStoreLocal.getChainAccount).toHaveBeenCalledWith(ccm.receivingChainID); }); it('should return false if the receiving chain is not live', async () => { diff --git a/framework/test/unit/modules/interoperability/store.spec.ts b/framework/test/unit/modules/interoperability/store.spec.ts index 21f96845c4b..a3315a01434 100644 --- a/framework/test/unit/modules/interoperability/store.spec.ts +++ b/framework/test/unit/modules/interoperability/store.spec.ts @@ -452,7 +452,7 @@ describe('Base interoperability store', () => { trsSender: beforeApplyCCMContext.trsSender, }; - beforeEach(async () => { + beforeEach(() => { mainchainStoreLocal = new MainchainInteroperabilityStore( MODULE_ID_INTEROPERABILITY_BUFFER, mockGetStore, @@ -468,7 +468,7 @@ describe('Base interoperability store', () => { await expect( mainchainStoreLocal.apply(ccmApplyContext, ccCommandsMap), ).resolves.toBeUndefined(); - expect(ccAPIMod1.beforeApplyCCM).toBeCalledTimes(0); + expect(ccAPIMod1.beforeApplyCCM).toHaveBeenCalledTimes(0); }); it('should call all the interoperable beforeApplyCCM hooks', async () => { @@ -489,7 +489,7 @@ describe('Base interoperability store', () => { await expect( mainchainStoreLocal.apply(ccmApplyContext, ccCommandsMap), ).resolves.toBeUndefined(); - expect(ccAPISampleMod.beforeApplyCCM).toBeCalledTimes(1); + expect(ccAPISampleMod.beforeApplyCCM).toHaveBeenCalledTimes(1); expect(ccAPISampleMod.beforeApplyCCM).toHaveBeenCalledWith( expect.toContainAllKeys(Object.keys(beforeApplyCCMContext)), ); @@ -515,11 +515,11 @@ describe('Base interoperability store', () => { await expect( mainchainStoreLocal.apply(ccmApplyContext, localCCCommandsMap), ).resolves.toBeUndefined(); - expect(ccAPIMod1.beforeApplyCCM).toBeCalledTimes(1); + expect(ccAPIMod1.beforeApplyCCM).toHaveBeenCalledTimes(1); expect(ccAPIMod1.beforeApplyCCM).toHaveBeenCalledWith( expect.toContainAllKeys(Object.keys(beforeApplyCCMContext)), ); - expect(mainchainStoreLocal.sendInternal).toBeCalledTimes(1); + expect(mainchainStoreLocal.sendInternal).toHaveBeenCalledTimes(1); expect(mainchainStoreLocal.sendInternal).toHaveBeenCalledWith( expect.objectContaining({ status: CCM_STATUS_MODULE_NOT_SUPPORTED }), ); @@ -549,11 +549,11 @@ describe('Base interoperability store', () => { await expect( mainchainStoreLocal.apply(ccmApplyContext, localCCCommandsMap), ).resolves.toBeUndefined(); - expect(ccAPISampleMod.beforeApplyCCM).toBeCalledTimes(1); + expect(ccAPISampleMod.beforeApplyCCM).toHaveBeenCalledTimes(1); expect(ccAPISampleMod.beforeApplyCCM).toHaveBeenCalledWith( expect.toContainAllKeys(Object.keys(beforeApplyCCMContext)), ); - expect(mainchainStoreLocal.sendInternal).toBeCalledTimes(1); + expect(mainchainStoreLocal.sendInternal).toHaveBeenCalledTimes(1); expect(mainchainStoreLocal.sendInternal).toHaveBeenCalledWith( expect.objectContaining({ status: CCM_STATUS_CROSS_CHAIN_COMMAND_NOT_SUPPORTED }), ); @@ -580,12 +580,12 @@ describe('Base interoperability store', () => { await expect( mainchainStoreLocal.apply(ccmApplyContext, ccCommandsMap), ).resolves.toBeUndefined(); - expect(ccAPISampleMod.beforeApplyCCM).toBeCalledTimes(1); + expect(ccAPISampleMod.beforeApplyCCM).toHaveBeenCalledTimes(1); expect(ccAPISampleMod.beforeApplyCCM).toHaveBeenCalledWith( expect.objectContaining({ ccu: beforeApplyCCMContext.ccu }), ); - expect(mainchainStoreLocal.sendInternal).toBeCalledTimes(0); - expect(ccCommands[0].execute).toBeCalledTimes(1); + expect(mainchainStoreLocal.sendInternal).toHaveBeenCalledTimes(0); + expect(ccCommands[0].execute).toHaveBeenCalledTimes(1); expect(ccCommands[0].execute).toHaveBeenCalledWith( expect.objectContaining({ ccm: executeCCMContext.ccm }), ); diff --git a/framework/test/unit/modules/interoperability/utils.spec.ts b/framework/test/unit/modules/interoperability/utils.spec.ts index 3ce13dec7fc..a23e222a981 100644 --- a/framework/test/unit/modules/interoperability/utils.spec.ts +++ b/framework/test/unit/modules/interoperability/utils.spec.ts @@ -689,7 +689,7 @@ describe('Utils', () => { let newInboxAppendPath: Buffer[] = []; let newInboxSize = 0; - beforeEach(async () => { + beforeEach(() => { for (const ccm of defaultCCMsEncoded) { const { appendPath, size, root } = merkleTree.regularMerkleTree.calculateMerkleRoot({ value: ccm, @@ -889,7 +889,7 @@ describe('Utils', () => { let context: any; let calculateRootFromRightWitness: any; - beforeEach(async () => { + beforeEach(() => { activeValidatorsUpdate = [ { blsKey: cryptography.utils.getRandomBytes(48), bftWeight: BigInt(1) }, { blsKey: cryptography.utils.getRandomBytes(48), bftWeight: BigInt(3) }, From c0a0973112e87449537db6ba72f4021cbd253533 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 20:50:03 +0300 Subject: [PATCH 16/39] fix test case --- elements/lisk-transactions/test/validate.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/elements/lisk-transactions/test/validate.spec.ts b/elements/lisk-transactions/test/validate.spec.ts index a9b47e65adf..f440258049d 100644 --- a/elements/lisk-transactions/test/validate.spec.ts +++ b/elements/lisk-transactions/test/validate.spec.ts @@ -14,7 +14,7 @@ */ import { utils } from '@liskhq/lisk-cryptography'; -import { validateTransaction } from '../src/validate'; +import { validateTransaction } from '../src'; describe('validateTransaction', () => { // Arrange @@ -68,7 +68,7 @@ describe('validateTransaction', () => { { ...validTransaction, senderPublicKey: 1 }, ]; return invalidTransactionObjects.forEach(transactionObject => - expect(validateTransaction(validParamsSchema, transactionObject)).toBeInstanceOf(Error), + expect(() => validateTransaction(validParamsSchema, transactionObject)).toThrow(), ); }); @@ -87,7 +87,7 @@ describe('validateTransaction', () => { }, ]; return invalidParams.forEach(transactionObject => - expect(validateTransaction(transactionObject, validParamsSchema)).toBeInstanceOf(Error), + expect(() => validateTransaction(transactionObject, validParamsSchema)).toThrow(), ); }); From 575e13dcd2814190e71586740fb4415dc30fccc9 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 21:26:03 +0300 Subject: [PATCH 17/39] fix - import can be shortened --- framework/test/unit/modules/dpos_v2/commands/vote.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts b/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts index 2721e6ae129..be0dc4d4b13 100644 --- a/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts +++ b/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts @@ -18,7 +18,7 @@ import { address, utils } from '@liskhq/lisk-cryptography'; import { InMemoryDatabase } from '@liskhq/lisk-db'; import { validator } from '@liskhq/lisk-validator'; import { when } from 'jest-when'; -import { VoteCommand } from '../../../../../src/modules/dpos_v2/commands/vote'; +import { VoteCommand, VerifyStatus } from '../../../../../src'; import { COMMAND_ID_VOTE, MAX_UNLOCKING, @@ -29,7 +29,7 @@ import { import { delegateStoreSchema, voterStoreSchema } from '../../../../../src/modules/dpos_v2/schemas'; import { DelegateAccount, VoteTransactionParams } from '../../../../../src/modules/dpos_v2/types'; import { getVoterOrDefault } from '../../../../../src/modules/dpos_v2/utils'; -import { VerifyStatus } from '../../../../../src/state_machine/types'; + import { createTransactionContext } from '../../../../../src/testing'; import { liskToBeddows } from '../../../../utils/assets'; import { DEFAULT_TOKEN_ID } from '../../../../utils/mocks/transaction'; From d30044b3a388687891c1286eb9d7cf262f5ddb5a Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 21:29:04 +0300 Subject: [PATCH 18/39] fix - broken tests --- framework/test/unit/modules/dpos_v2/commands/vote.spec.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts b/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts index be0dc4d4b13..69b99db1cc9 100644 --- a/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts +++ b/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts @@ -179,8 +179,7 @@ describe('VoteCommand', () => { it('should return errors', async () => { const verificationResult = await command.verify(context); - expect((verificationResult.error as any).value).toHaveLength(1); - expect((verificationResult.error as any).value[0].message).toInclude( + expect((verificationResult.error as any).value.message).toInclude( 'must NOT have fewer than 1 items', ); }); @@ -206,8 +205,7 @@ describe('VoteCommand', () => { it('should return errors', async () => { const verificationResult = await command.verify(context); - expect((verificationResult.error as any).value).toHaveLength(1); - expect((verificationResult.error as any).value[0].message).toInclude( + expect((verificationResult.error as any).value.message).toInclude( 'must NOT have more than 20 items', ); }); From 74e98becf6a44f11aa9609f0fbdc18f8478b6085 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Fri, 29 Jul 2022 11:25:23 +0300 Subject: [PATCH 19/39] apply requested changes --- elements/lisk-chain/src/block_header.ts | 4 +++- elements/lisk-chain/src/transaction.ts | 4 +++- framework/src/engine/generator/network_endpoint.ts | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/elements/lisk-chain/src/block_header.ts b/elements/lisk-chain/src/block_header.ts index 3da1ef51bce..61820913ee8 100644 --- a/elements/lisk-chain/src/block_header.ts +++ b/elements/lisk-chain/src/block_header.ts @@ -302,7 +302,9 @@ export class BlockHeader { } public getSigningBytes(): Buffer { - return codec.encode(signingBlockHeaderSchema, this._getSigningProps()); + const blockHeaderBytes = codec.encode(signingBlockHeaderSchema, this._getSigningProps()); + + return blockHeaderBytes; } public sign(networkIdentifier: Buffer, privateKey: Buffer): void { diff --git a/elements/lisk-chain/src/transaction.ts b/elements/lisk-chain/src/transaction.ts index 007b59300f9..609318e4554 100644 --- a/elements/lisk-chain/src/transaction.ts +++ b/elements/lisk-chain/src/transaction.ts @@ -134,10 +134,12 @@ export class Transaction { } public getSigningBytes(): Buffer { - return codec.encode(transactionSchema, ({ + const transactionBytes = codec.encode(transactionSchema, ({ ...this, signatures: [], } as unknown) as Record); + + return transactionBytes; } public sign(networkIdentifier: Buffer, privateKey: Buffer): void { diff --git a/framework/src/engine/generator/network_endpoint.ts b/framework/src/engine/generator/network_endpoint.ts index c9c2697618d..cc6c1284141 100644 --- a/framework/src/engine/generator/network_endpoint.ts +++ b/framework/src/engine/generator/network_endpoint.ts @@ -99,6 +99,8 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { peerId, penalty: 100, }); + + throw new Error('Received invalid getTransactions body'); } } From 56888bd7c9e7ead0154f44e4186116b10ab4cad2 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Tue, 26 Jul 2022 20:56:36 +0300 Subject: [PATCH 20/39] Update lisk-validators to return single error and compatible type check - Closes #7156 --- .../commands/genesis-block/create.ts | 8 +- .../commands/transaction/create.ts | 6 +- elements/lisk-api-client/src/transaction.ts | 8 +- elements/lisk-chain/src/block_assets.ts | 14 +- elements/lisk-chain/src/block_header.ts | 30 +- elements/lisk-chain/src/transaction.ts | 8 +- elements/lisk-codec/src/codec.ts | 9 +- elements/lisk-p2p/src/utils/validate.ts | 19 +- elements/lisk-transactions/src/validate.ts | 12 +- elements/lisk-validator/src/errors.ts | 5 +- elements/lisk-validator/src/lisk_validator.ts | 14 +- .../test/lisk_validator.spec.ts | 90 +--- .../test/lisk_validator_errors.spec.ts | 26 +- .../test/lisk_validator_formats.spec.ts | 95 ++-- .../test/lisk_validator_keywords.spec.ts | 461 +++++++++--------- .../src/plugin/endpoint.ts | 14 +- .../src/endpoint.ts | 8 +- framework/src/application.ts | 8 +- framework/src/controller/jsonrpc/utils.ts | 12 +- .../src/engine/consensus/network_endpoint.ts | 35 +- .../synchronizer/base_synchronizer.ts | 6 +- framework/src/engine/endpoint/chain.ts | 13 +- framework/src/engine/endpoint/txpool.ts | 14 +- framework/src/engine/generator/endpoint.ts | 8 +- framework/src/engine/generator/generator.ts | 7 +- .../src/engine/generator/network_endpoint.ts | 32 +- .../auth/commands/register_multisignature.ts | 10 +- framework/src/modules/auth/module.ts | 7 +- .../dpos_v2/commands/delegate_registration.ts | 12 +- framework/src/modules/dpos_v2/commands/pom.ts | 11 +- .../dpos_v2/commands/update_generator_key.ts | 12 +- .../src/modules/dpos_v2/commands/vote.ts | 10 +- framework/src/modules/dpos_v2/module.ts | 13 +- framework/src/modules/fee/module.ts | 8 +- .../mainchain/commands/cc_update.ts | 9 +- .../commands/sidechain_registration.ts | 11 +- .../mainchain/commands/state_recovery.ts | 11 +- .../sidechain/commands/cc_update.ts | 9 +- .../commands/mainchain_registration.ts | 9 +- .../src/modules/interoperability/utils.ts | 8 +- framework/src/modules/random/endpoint.ts | 8 +- framework/src/modules/random/module.ts | 14 +- framework/src/modules/reward/module.ts | 8 +- .../modules/token/cc_commands/cc_forward.ts | 8 +- .../modules/token/cc_commands/cc_transfer.ts | 8 +- .../src/modules/token/commands/cc_transfer.ts | 10 +- .../src/modules/token/commands/transfer.ts | 10 +- framework/src/modules/token/endpoint.ts | 14 +- framework/src/modules/token/module.ts | 13 +- framework/src/modules/validators/endpoint.ts | 7 +- framework/src/modules/validators/module.ts | 8 +- framework/src/plugins/base_plugin.ts | 13 +- .../modules/dpos_v2/commands/vote.spec.ts | 10 +- .../schema/application_config_schema.spec.ts | 47 +- 54 files changed, 538 insertions(+), 742 deletions(-) diff --git a/commander/src/bootstrapping/commands/genesis-block/create.ts b/commander/src/bootstrapping/commands/genesis-block/create.ts index 5580053d232..2b027070db8 100644 --- a/commander/src/bootstrapping/commands/genesis-block/create.ts +++ b/commander/src/bootstrapping/commands/genesis-block/create.ts @@ -22,7 +22,7 @@ import * as fs from 'fs-extra'; import { join, resolve } from 'path'; import * as inquirer from 'inquirer'; import * as ProgressBar from 'progress'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BlockJSON } from '@liskhq/lisk-chain'; import { createMnemonicPassphrase } from '../../../utils/mnemonic'; import { @@ -193,10 +193,8 @@ export abstract class BaseGenesisBlockCommand extends Command { // If assetsFile exist, create from assetsFile and default config/accounts are not needed if (assetsFile) { const assetsJSON = (await fs.readJSON(resolve(assetsFile))) as GenesisAssetsInput; - const assetSchemaError = validator.validate(genesisAssetsSchema, assetsJSON); - if (assetSchemaError.length) { - throw new LiskValidationError(assetSchemaError); - } + validator.validate(genesisAssetsSchema, assetsJSON); + const genesisBlock = await app.generateGenesisBlock({ assets: assetsJSON.assets.map(a => ({ moduleID: a.moduleID, diff --git a/commander/src/bootstrapping/commands/transaction/create.ts b/commander/src/bootstrapping/commands/transaction/create.ts index 06a61a300a2..e62d29f0e7c 100644 --- a/commander/src/bootstrapping/commands/transaction/create.ts +++ b/commander/src/bootstrapping/commands/transaction/create.ts @@ -122,11 +122,7 @@ const validateAndSignTransaction = ( ) as Schema; const txObject = codec.fromJSON(schema.transaction, { ...transactionWithoutParams, params: '' }); - const transactionErrors = validator.validator.validate(schema.transaction, txObject); - - if (transactionErrors.length) { - throw new validator.LiskValidationError([...transactionErrors]); - } + validator.validator.validate(schema.transaction, txObject); const paramsObject = paramsSchema ? codec.fromJSON(paramsSchema, params) : {}; diff --git a/elements/lisk-api-client/src/transaction.ts b/elements/lisk-api-client/src/transaction.ts index 353630e7224..160e9cd58aa 100644 --- a/elements/lisk-api-client/src/transaction.ts +++ b/elements/lisk-api-client/src/transaction.ts @@ -18,7 +18,7 @@ import { computeMinFee, } from '@liskhq/lisk-transactions'; import { address as cryptoAddress } from '@liskhq/lisk-cryptography'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { codec } from '@liskhq/lisk-codec'; import { decodeTransaction, @@ -337,13 +337,11 @@ export class Transaction { throw new Error('Transaction must be an object.'); } const { params, ...rest } = transaction as Record; - const errors = validator.validate(this._schema.transaction, { + validator.validate(this._schema.transaction, { ...rest, params: Buffer.alloc(0), }); - if (errors.length) { - throw new LiskValidationError(errors); - } + if (Buffer.isBuffer(params)) { throw new Error('Transaction parameter is not decoded.'); } diff --git a/elements/lisk-chain/src/block_assets.ts b/elements/lisk-chain/src/block_assets.ts index fd965908b13..c0fe3193a3f 100644 --- a/elements/lisk-chain/src/block_assets.ts +++ b/elements/lisk-chain/src/block_assets.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { codec } from '@liskhq/lisk-codec'; import { MerkleTree } from '@liskhq/lisk-tree'; import { blockAssetSchema } from './schema'; @@ -87,10 +87,8 @@ export class BlockAssets { let last = this._assets[0]; let i = 0; for (const asset of this._assets) { - const errors = validator.validate(blockAssetSchema, asset); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(blockAssetSchema, asset); + // Data size of each module should not be greater than max asset data size if (asset.data.byteLength > MAX_ASSET_DATA_SIZE_BYTES) { throw new Error( @@ -117,10 +115,8 @@ export class BlockAssets { let last = this._assets[0]; let i = 0; for (const asset of this._assets) { - const errors = validator.validate(blockAssetSchema, asset); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(blockAssetSchema, asset); + if (last.moduleID > asset.moduleID) { throw new Error('Assets are not sorted in the increasing values of moduleID.'); } diff --git a/elements/lisk-chain/src/block_header.ts b/elements/lisk-chain/src/block_header.ts index e0ad3cfd35d..392cc97765a 100644 --- a/elements/lisk-chain/src/block_header.ts +++ b/elements/lisk-chain/src/block_header.ts @@ -12,12 +12,15 @@ * Removal or modification of this copyright notice is prohibited. */ -import { ed, utils } from '@liskhq/lisk-cryptography'; -import { codec } from '@liskhq/lisk-codec'; -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; -import { EMPTY_BUFFER, EMPTY_HASH, SIGNATURE_LENGTH_BYTES, TAG_BLOCK_HEADER } from './constants'; -import { blockHeaderSchema, blockHeaderSchemaWithId, signingBlockHeaderSchema } from './schema'; -import { JSONObject } from './types'; +import {ed, utils} from '@liskhq/lisk-cryptography'; +import {codec} from '@liskhq/lisk-codec'; +import {LiskValidationError, validator} from '@liskhq/lisk-validator'; +import {LiskErrorObject} from "@liskhq/lisk-validator/dist-node/types"; +import {JSONObject} from './types'; +import {EMPTY_BUFFER, EMPTY_HASH, SIGNATURE_LENGTH_BYTES, TAG_BLOCK_HEADER} from './constants'; +import {blockHeaderSchema, blockHeaderSchemaWithId, signingBlockHeaderSchema} from './schema'; + + export interface BlockHeaderAttrs { readonly version: number; @@ -174,10 +177,8 @@ export class BlockHeader { } public validate(): void { - const errors = validator.validate(blockHeaderSchema, this._getBlockHeaderProps()); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(blockHeaderSchema, this._getBlockHeaderProps()); + if (this.previousBlockID.length === 0) { throw new Error('Previous block id must not be empty.'); } @@ -188,7 +189,10 @@ export class BlockHeader { public validateGenesis(): void { const header = this._getBlockHeaderProps(); - const errors = validator.validate(blockHeaderSchema, header); + + validator.validate(blockHeaderSchema, header); + + const errors: LiskErrorObject[] = [] if (header.previousBlockID.length !== 32) { errors.push({ @@ -301,9 +305,7 @@ export class BlockHeader { } public getSigningBytes(): Buffer { - const blockHeaderBytes = codec.encode(signingBlockHeaderSchema, this._getSigningProps()); - - return blockHeaderBytes; + return codec.encode(signingBlockHeaderSchema, this._getSigningProps()); } public sign(networkIdentifier: Buffer, privateKey: Buffer): void { diff --git a/elements/lisk-chain/src/transaction.ts b/elements/lisk-chain/src/transaction.ts index 6b573c9336e..c436a00a6a3 100644 --- a/elements/lisk-chain/src/transaction.ts +++ b/elements/lisk-chain/src/transaction.ts @@ -14,7 +14,7 @@ import { codec } from '@liskhq/lisk-codec'; import { utils, address, ed } from '@liskhq/lisk-cryptography'; -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { TAG_TRANSACTION } from './constants'; import { JSONObject } from './types'; @@ -155,10 +155,8 @@ export class Transaction { } public validate(): void { - const schemaErrors = validator.validate(transactionSchema, this); - if (schemaErrors.length > 0) { - throw new LiskValidationError(schemaErrors); - } + validator.validate(transactionSchema, this); + if (this.signatures.length === 0) { throw new Error('Signatures must not be empty'); } diff --git a/elements/lisk-codec/src/codec.ts b/elements/lisk-codec/src/codec.ts index 2034621ce2c..2044e8f8381 100644 --- a/elements/lisk-codec/src/codec.ts +++ b/elements/lisk-codec/src/codec.ts @@ -13,8 +13,6 @@ */ import { - ErrorObject, - LiskValidationError, validator, liskSchemaIdentifier, } from '@liskhq/lisk-validator'; @@ -60,12 +58,7 @@ export const validateSchema = (schema: { $schema: schema.$schema ?? liskSchemaIdentifier, }; - const errors: ReadonlyArray = validator.validateSchema(schemaToValidate); - - if (errors.length) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-call - throw new LiskValidationError([...errors]); - } + validator.validateSchema(schemaToValidate); try { // To validate keyword schema we have to compile it diff --git a/elements/lisk-p2p/src/utils/validate.ts b/elements/lisk-p2p/src/utils/validate.ts index 29ce557e710..6f097817534 100644 --- a/elements/lisk-p2p/src/utils/validate.ts +++ b/elements/lisk-p2p/src/utils/validate.ts @@ -146,25 +146,26 @@ export const validatePeerInfoList = ( }; export const validateRPCRequest = (request: unknown): void => { - const errors = validator.validate(rpcRequestSchema, request as Record); - - if (errors.length) { + try { + validator.validate(rpcRequestSchema, request as Record); + } catch { throw new Error('RPC request format is invalid.'); } }; export const validateProtocolMessage = (message: unknown): void => { - const errors = validator.validate(protocolMessageSchema, message as Record); - - if (errors.length) { + try { + validator.validate(protocolMessageSchema, message as Record); + } catch { throw new Error('Protocol message format is invalid.'); } + }; export const validatePacket = (packet: unknown): void => { - const errors = validator.validate(packetSchema, packet as P2PMessagePacket | P2PRequestPacket); - - if (errors.length) { + try { + validator.validate(packetSchema, packet as P2PMessagePacket | P2PRequestPacket); + } catch { throw new Error('Packet format is invalid.'); } }; diff --git a/elements/lisk-transactions/src/validate.ts b/elements/lisk-transactions/src/validate.ts index 83800db6727..00d3a3aff14 100644 --- a/elements/lisk-transactions/src/validate.ts +++ b/elements/lisk-transactions/src/validate.ts @@ -24,13 +24,11 @@ export const validateTransaction = ( ...transactionObject, params: Buffer.alloc(0), }; - const schemaErrors = validator.validate( + validator.validate( baseTransactionSchema, transactionObjectWithEmptyParameters, ); - if (schemaErrors.length) { - return new LiskValidationError([...schemaErrors]); - } + if (!paramsSchema) { return undefined; } @@ -38,9 +36,7 @@ export const validateTransaction = ( if (typeof transactionObject.params !== 'object' || transactionObject.params === null) { return new Error('Transaction object params must be of type object and not null'); } - const paramsSchemaErrors = validator.validate(paramsSchema, transactionObject.params); - if (paramsSchemaErrors.length) { - return new LiskValidationError([...paramsSchemaErrors]); - } + validator.validate(paramsSchema, transactionObject.params); + return undefined; }; diff --git a/elements/lisk-validator/src/errors.ts b/elements/lisk-validator/src/errors.ts index a8c65850c65..3237bb4a6b2 100644 --- a/elements/lisk-validator/src/errors.ts +++ b/elements/lisk-validator/src/errors.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { LiskErrorObject } from './types'; +import {LiskErrorObject} from './types'; // Ajv.ErrorObject makes `schemaPath` and `dataPath` required // While these are not if we want to infer default values from validation @@ -86,7 +86,6 @@ export class LiskValidationError extends Error { } private _compileErrors(): string[] { - const errorMsgs = this.errors.map(errorFormatter); - return errorMsgs; + return this.errors.map(errorFormatter); } } diff --git a/elements/lisk-validator/src/lisk_validator.ts b/elements/lisk-validator/src/lisk_validator.ts index bf786db7e4f..7574924f1d1 100644 --- a/elements/lisk-validator/src/lisk_validator.ts +++ b/elements/lisk-validator/src/lisk_validator.ts @@ -13,7 +13,7 @@ * */ -import Ajv, { AnySchema, ValidateFunction } from 'ajv'; +import Ajv, {SchemaObject, ValidateFunction} from 'ajv'; import addDefaultFormats from 'ajv-formats'; import * as formats from './formats'; import { convertErrorsToLegacyFormat, LiskValidationError } from './errors'; @@ -69,20 +69,16 @@ class LiskValidator { this._validator.addKeyword(dataTypeKeyword); } - public validate(schema: object, data: object): LiskErrorObject[] { + public validate>(schema: object, data: unknown): asserts data is T { if (!this._validator.validate(schema, data)) { - return convertErrorsToLegacyFormat(this._validator.errors as LiskErrorObject[]); + throw new LiskValidationError(convertErrorsToLegacyFormat(this._validator.errors as LiskErrorObject[])); } - - return []; } - public validateSchema(schema: AnySchema | boolean): ReadonlyArray { + public validateSchema(schema: object): asserts schema is SchemaObject { if (!this._validator.validateSchema(schema)) { - return convertErrorsToLegacyFormat(this._validator.errors as LiskErrorObject[]); + throw new LiskValidationError(convertErrorsToLegacyFormat(this._validator.errors as LiskErrorObject[])); } - - return []; } public compile(schema: object | boolean): ValidateFunction { diff --git a/elements/lisk-validator/test/lisk_validator.spec.ts b/elements/lisk-validator/test/lisk_validator.spec.ts index 3f89934bd61..aef5504b81c 100644 --- a/elements/lisk-validator/test/lisk_validator.spec.ts +++ b/elements/lisk-validator/test/lisk_validator.spec.ts @@ -38,7 +38,6 @@ describe('validator', () => { }); it('should return error on schema with type other than "object"', () => { - // Arrange const invalidSchema = { $id: '/myInvalidSchema', $schema: 'http://lisk.com/lisk-schema/schema#', @@ -46,61 +45,32 @@ describe('validator', () => { properties: {}, }; - // Act - const errors = validator.validateSchema(invalidSchema); - - // Assert - expect(errors).toContainEqual({ - dataPath: '.type', - keyword: 'const', - message: 'must be equal to constant', - schemaPath: '#/properties/type/const', - params: { allowedValue: 'object' }, - }); + const msg = "Lisk validator found 2 error[s]:\nmust be equal to constant\nmust NOT have fewer than 1 items" + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) }); + it('should return error when "type" is not defined', () => { - // Arrange const invalidSchema = { ...validSchema }; delete (invalidSchema as any).type; - // Act - const errors = validator.validateSchema(invalidSchema); - - // Assert - expect(errors).toContainEqual({ - dataPath: '', - keyword: 'required', - message: "must have required property 'type'", - schemaPath: '#/required', - params: { missingProperty: 'type' }, - }); + const msg = "Lisk validator found 1 error[s]:\nMissing property, must have required property 'type'" + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) }); + it('should return error when "$id" is not defined', () => { - // Arrange const invalidSchema = { ...validSchema }; delete (invalidSchema as any).$id; - // Act - const errors = validator.validateSchema(invalidSchema); - - // Assert - expect(errors).toContainEqual({ - dataPath: '', - keyword: 'required', - message: "must have required property '$id'", - schemaPath: '#/required', - params: { missingProperty: '$id' }, - }); + const msg = "Lisk validator found 1 error[s]:\nMissing property, must have required property '$id'" + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) }); // As the schema is always overridden it('should not return error when "$schema" is not defined', () => { - // Arrange const invalidSchema = cloneDeep(validSchema); delete invalidSchema.$schema; - // Assert - expect(validator.validateSchema(invalidSchema)).toEqual([]); + expect(() => validator.validateSchema(invalidSchema)).not.toThrow() }); it('should throw error when "$schema" value is defined other than lisk-schema uri', () => { @@ -115,21 +85,11 @@ describe('validator', () => { }); it('should return error when "properties" is not defined', () => { - // Arrange const invalidSchema = cloneDeep(validSchema); delete invalidSchema.properties; - // Act - const errors = validator.validateSchema(invalidSchema); - - // Assert - expect(errors).toContainEqual({ - dataPath: '', - keyword: 'required', - message: "must have required property 'properties'", - schemaPath: '#/required', - params: { missingProperty: 'properties' }, - }); + const msg = "Lisk validator found 1 error[s]:\nMissing property, must have required property 'properties'" + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) }); it('should return error when "properties" are not camelcase', () => { @@ -141,36 +101,16 @@ describe('validator', () => { }, }; - // Act - const errors = validator.validateSchema(invalidSchema); - - // Assert - expect(errors).toContainEqual({ - dataPath: '.properties', - keyword: 'format', - message: 'must match format "camelCase"', - schemaPath: '#/properties/properties/propertyNames/format', - params: { format: 'camelCase' }, - propertyName: 'my-custom-prop', - }); + const msg = "Lisk validator found 2 error[s]:\nProperty '.properties' must match format \"camelCase\""; + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) }); it('should return error when "properties" are empty object', () => { - // Arrange const invalidSchema = cloneDeep(validSchema); delete invalidSchema.properties.myProp; - // Act - const errors = validator.validateSchema(invalidSchema); - - // Assert - expect(errors).toContainEqual({ - dataPath: '.properties', - keyword: 'minProperties', - message: 'must NOT have fewer than 1 items', - schemaPath: '#/properties/properties/minProperties', - params: { limit: 1 }, - }); + const msg = "Lisk validator found 1 error[s]:\nmust NOT have fewer than 1 items"; + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) }); }); }); diff --git a/elements/lisk-validator/test/lisk_validator_errors.spec.ts b/elements/lisk-validator/test/lisk_validator_errors.spec.ts index b982cc51027..6855fd95f60 100644 --- a/elements/lisk-validator/test/lisk_validator_errors.spec.ts +++ b/elements/lisk-validator/test/lisk_validator_errors.spec.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. * */ -import { LiskValidationError, validator } from '../src'; +import { validator } from '../src'; // eslint-disable-next-line @typescript-eslint/no-var-requires const cloneDeep = require('lodash.clonedeep'); @@ -44,9 +44,7 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nProperty '.myProp' should be of type 'string'"; - expect(() => { - throw new LiskValidationError([...validator.validate(schema, obj)]); - }).toThrow(expectedError); + expect(() => validator.validate(schema, obj)).toThrow(expectedError) }); it('should format minLength errors', () => { @@ -58,9 +56,7 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have fewer than 2 characters"; - expect(() => { - throw new LiskValidationError([...validator.validate(schema, obj)]); - }).toThrow(expectedError); + expect(() => validator.validate(schema, obj)).toThrow(expectedError) }); it('should format maxLength errors', () => { @@ -72,9 +68,7 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have more than 5 characters"; - expect(() => { - throw new LiskValidationError([...validator.validate(schema, obj)]); - }).toThrow(expectedError); + expect(() => validator.validate(schema, obj)).toThrow(expectedError) }); it('should format custom format errors', () => { @@ -86,9 +80,7 @@ describe('LiskValidationError formatter', () => { const expectedError = 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' must match format "hex"'; - expect(() => { - throw new LiskValidationError([...validator.validate(schema, obj)]); - }).toThrow(expectedError); + expect(() => validator.validate(schema, obj)).toThrow(expectedError) }); it('should format missing required property errors', () => { @@ -97,9 +89,7 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nMissing property, must have required property 'myProp'"; - expect(() => { - throw new LiskValidationError([...validator.validate(schema, obj)]); - }).toThrow(expectedError); + expect(() => validator.validate(schema, obj)).toThrow(expectedError) }); it('should format additional property errors', () => { @@ -130,8 +120,6 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nProperty '.myProp' has extraneous property 'bar'"; - expect(() => { - throw new LiskValidationError([...validator.validate(schema, obj)]); - }).toThrow(expectedError); + expect(() => validator.validate(schema, obj)).toThrow(expectedError) }); }); diff --git a/elements/lisk-validator/test/lisk_validator_formats.spec.ts b/elements/lisk-validator/test/lisk_validator_formats.spec.ts index f9a327bd344..87a521d17d0 100644 --- a/elements/lisk-validator/test/lisk_validator_formats.spec.ts +++ b/elements/lisk-validator/test/lisk_validator_formats.spec.ts @@ -45,26 +45,16 @@ describe('validator formats', () => { it('should validate to true when valid hex string is provided', () => { expect( - validator.validate(schema, { target: '23b9ed818526a928bce91b96fb4508babb121ee2' }), - ).toEqual([]); + () => validator.validate(schema, { target: '23b9ed818526a928bce91b96fb4508babb121ee2' }) + ).not.toThrow() }); it('should validate to false when not hex is provided', () => { - const expectedError = [ - { - keyword: 'format', - dataPath: '.target', - schemaPath: '#/allOf/1/properties/target/format', - params: { format: 'hex' }, - message: 'must match format "hex"', - }, - ]; + const expectedError = "Lisk validator found 1 error[s]:\nProperty '.target' must match format \"hex\""; - expect( - validator.validate(schema, { - target: 'notValid?!hex-!!@', - }), - ).toEqual(expectedError); + expect(() => validator.validate(schema, { + target: 'notValid?!hex-!!@', + })).toThrow(expectedError) }); }); @@ -79,25 +69,15 @@ describe('validator formats', () => { }; it('should validate to false for invalid path', () => { - const expectedError = [ - { - keyword: 'format', - dataPath: '.rootPath', - schemaPath: '#/properties/rootPath/format', - params: { format: 'path' }, - message: 'must match format "path"', - }, - ]; - - expect(validator.validate(pathSchema, { rootPath: 'lisk' })).toEqual(expectedError); + expect(() => validator.validate(pathSchema, { rootPath: 'lisk' })).toThrow("Property '.rootPath' must match format \"path\"") }); it('should validate to true for valid path with tilde', () => { - expect(validator.validate(pathSchema, { rootPath: '~/.lisk' })).toBeEmpty(); + expect(() => validator.validate(pathSchema, { rootPath: '~/.lisk' })).not.toThrow(); }); it('should validate to true for valid path', () => { - expect(validator.validate(pathSchema, { rootPath: '/tmp/lisk/test/' })).toBeEmpty(); + expect(() => validator.validate(pathSchema, { rootPath: '/tmp/lisk/test/' })).not.toThrow(); }); }); @@ -112,15 +92,8 @@ describe('validator formats', () => { }; it('should validate to false for invalid path', () => { - const expectedError = [ - { - keyword: 'format', - dataPath: '.encryptedPassphrase', - schemaPath: '#/properties/encryptedPassphrase/format', - params: { format: 'encryptedPassphrase' }, - message: 'must match format "encryptedPassphrase"', - }, - ]; + const expectedError = + "Lisk validator found 1 error[s]:\nProperty '.encryptedPassphrase' must match format \"encryptedPassphrase\""; [ 'cipherText', @@ -128,20 +101,20 @@ describe('validator formats', () => { 'cipherText=abcd1234&iterations=10000&iv=ef012345cipherText=abcd1234&iterations=10000&iv=ef012345', ].forEach(text => { expect( - validator.validate(encryptedPassphraseSchema, { + () => validator.validate(encryptedPassphraseSchema, { encryptedPassphrase: text, }), - ).toEqual(expectedError); + ).toThrow(expectedError); }); }); it('should validate to true for valid encrypted passphrase', () => { ['cipherText=abcd1234', 'cipherText=abcd1234&iterations=10000&iv=ef012345'].forEach(text => { expect( - validator.validate(encryptedPassphraseSchema, { + () => validator.validate(encryptedPassphraseSchema, { encryptedPassphrase: text, }), - ).toBeEmpty(); + ).not.toThrow(); }); }); }); @@ -157,26 +130,20 @@ describe('validator formats', () => { }; it('should validate to false for invalid camel case text', () => { - const expectedError = [ - { - keyword: 'format', - dataPath: '.camelCaseRegex', - schemaPath: '#/properties/camelCaseRegex/format', - params: { format: 'camelCase' }, - message: 'must match format "camelCase"', - }, - ]; + const expectedError = "Lisk validator found 1 error[s]:\nProperty '.camelCaseRegex' must match format \"camelCase\""; ['NotCamelCase', '123Case', '_camelCase'].forEach(text => { - expect(validator.validate(camelCaseRegexSchema, { camelCaseRegex: text })).toEqual( - expectedError, - ); + expect( + () => validator.validate(camelCaseRegexSchema, { camelCaseRegex: text }) + ).toThrow(expectedError); }); }); it('should validate to true for valid camel case text', () => { ['camelCase'].forEach(text => { - expect(validator.validate(camelCaseRegexSchema, { camelCaseRegex: text })).toBeEmpty(); + expect( + () => validator.validate(camelCaseRegexSchema, { camelCaseRegex: text }) + ).not.toThrow(); }); }); }); @@ -192,24 +159,20 @@ describe('validator formats', () => { }; it('should validate to false for invalid semantic versions', () => { - const expectedError = [ - { - keyword: 'format', - dataPath: '.version', - schemaPath: '#/properties/version/format', - params: { format: 'version' }, - message: 'must match format "version"', - }, - ]; + const expectedError = "Lisk validator found 1 error[s]:\nProperty '.version' must match format \"version\""; ['9999999999999999.4.7.4', 'alpha one', '1.2.12.102', '4.6.3.9.2-alpha2'].forEach(text => { - expect(validator.validate(versionSchema, { version: text })).toEqual(expectedError); + expect( + () =>validator.validate(versionSchema, { version: text }) + ).toThrow(expectedError); }); }); it('should validate to true for valid semantic versions', () => { ['1.2.0', '1.0.0-alpha.0', 'v1.2.3', '1.0.0-beta+exp.sha.5114f85'].forEach(text => { - expect(validator.validate(versionSchema, { version: text })).toBeEmpty(); + expect( + () =>validator.validate(versionSchema, { version: text }) + ).not.toThrow() }); }); }); diff --git a/elements/lisk-validator/test/lisk_validator_keywords.spec.ts b/elements/lisk-validator/test/lisk_validator_keywords.spec.ts index dd60f6fb8a8..10e3d32d98e 100644 --- a/elements/lisk-validator/test/lisk_validator_keywords.spec.ts +++ b/elements/lisk-validator/test/lisk_validator_keywords.spec.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. * */ -import { LiskValidationError, validator } from '../src'; +import {LiskValidationError, validator} from '../src'; // eslint-disable-next-line @typescript-eslint/no-var-requires const cloneDeep = require('lodash.clonedeep'); @@ -84,326 +84,331 @@ describe('validator keywords', () => { describe('dataType value validation', () => { describe('string', () => { - it('should return empty error if valid', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'string', fieldNumber: 1 } }, - }, - { myProp: 'string' }, - ); - expect(result).toBeEmpty(); + it('should not throw error if valid', () => { + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'string', fieldNumber: 1}}, + }, + {myProp: 'string'}, + ) + ).not.toThrow(); }); it('should be invalid if minLength is not satisfied', () => { - const result = validator.validate( - { - ...validSchema, - properties: { - myProp: { dataType: 'string', fieldNumber: 1, minLength: 3 }, + expect( + () => validator.validate( + { + ...validSchema, + properties: { + myProp: {dataType: 'string', fieldNumber: 1, minLength: 3}, + }, }, - }, - { myProp: 'ch' }, - ); - expect(result).toHaveLength(1); + {myProp: 'ch'}, + )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have fewer than 3 characters"); }); it('should be invalid if maxLength is not satisfied', () => { - const result = validator.validate( - { - ...validSchema, - properties: { - myProp: { dataType: 'string', fieldNumber: 1, maxLength: 3 }, + expect( + () => validator.validate( + { + ...validSchema, + properties: { + myProp: {dataType: 'string', fieldNumber: 1, maxLength: 3}, + }, }, - }, - { myProp: 'change' }, - ); - expect(result).toHaveLength(1); + {myProp: 'change'}, + )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have more than 3 characters"); }); it('should be invalid if not string', () => { - const result = validator.validate( - { - ...validSchema, - properties: { - myProp: { dataType: 'string', fieldNumber: 1, maxLength: 3 }, + expect( + () => validator.validate( + { + ...validSchema, + properties: { + myProp: {dataType: 'string', fieldNumber: 1, maxLength: 3}, + }, }, - }, - { myProp: 32 }, - ); - expect(result).toHaveLength(1); + {myProp: 32}, + )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation") }); }); describe('bytes', () => { - it('should return empty error if valid', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'bytes', fieldNumber: 1 } }, - }, - { myProp: Buffer.from('value') }, - ); - expect(result).toBeEmpty(); + it('should not throw error if valid', () => { + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'bytes', fieldNumber: 1}}, + }, + {myProp: Buffer.from('value')}, + )).not.toThrow() }); it('should be invalid if minLength is not satisfied', () => { - const result = validator.validate( - { - ...validSchema, - properties: { - myProp: { dataType: 'bytes', fieldNumber: 1, minLength: 10 }, + expect( + () => validator.validate( + { + ...validSchema, + properties: { + myProp: {dataType: 'bytes', fieldNumber: 1, minLength: 10}, + }, }, - }, - { myProp: Buffer.alloc(9) }, - ); - expect(result).toHaveLength(1); - expect(result[0].message).toEqual('minLength not satisfied'); - expect(result[0].params).toEqual({ - dataType: 'bytes', - minLength: 10, - length: 9, - }); + {myProp: Buffer.alloc(9)}, + )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' minLength not satisfied") }); it('should be invalid if maxLength is not satisfied', () => { - const result = validator.validate( - { - ...validSchema, - properties: { - myProp: { dataType: 'bytes', fieldNumber: 1, maxLength: 10 }, + expect( + () => validator.validate( + { + ...validSchema, + properties: { + myProp: {dataType: 'bytes', fieldNumber: 1, maxLength: 10}, + }, }, - }, - { myProp: Buffer.alloc(11) }, - ); - expect(result).toHaveLength(1); - expect(result[0].message).toEqual('maxLength exceeded'); - expect(result[0].params).toEqual({ - dataType: 'bytes', - maxLength: 10, - length: 11, - }); + {myProp: Buffer.alloc(11)}, + )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' maxLength exceeded") }); it('should be invalid if not Buffer', () => { - const result = validator.validate( - { - ...validSchema, - properties: { - myProp: { dataType: 'bytes', fieldNumber: 1, maxLength: 10 }, + expect( + () => validator.validate( + { + ...validSchema, + properties: { + myProp: {dataType: 'bytes', fieldNumber: 1, maxLength: 10}, + }, }, - }, - { myProp: 'string' }, - ); - expect(result).toHaveLength(1); + {myProp: 'string'}, + )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation") }); }); describe('boolean', () => { - it('should return empty error if valid', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'boolean', fieldNumber: 1 } }, - }, - { myProp: true }, - ); - expect(result).toBeEmpty(); + it('should not throw error if valid', () => { + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'boolean', fieldNumber: 1}}, + }, + {myProp: true}, + )).not.toThrow() }); it('should be invalid if not boolean', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'boolean', fieldNumber: 1 } }, - }, - { myProp: 1 }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'boolean', fieldNumber: 1}}, + }, + {myProp: 1} + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation") }); }); describe('uint32', () => { - it('should return empty error if valid', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, - }, - { myProp: 0 }, - ); - expect(result).toBeEmpty(); + it('should not throw error if valid', () => { + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + }, + {myProp: 0}, + )).not.toThrow(); }); it('should be invalid if not number', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, - }, - { myProp: 'value' }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + }, + {myProp: 'value'}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); it('should be invalid if number has decimal', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, - }, - { myProp: 1.23 }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + }, + {myProp: 1.23}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); it('should be invalid if negative', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, - }, - { myProp: -1 }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + }, + {myProp: -1}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); it('should be invalid if above uint32 range', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, - }, - { myProp: 4294967296 }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + }, + {myProp: 4294967296}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); }); describe('uint64', () => { - it('should return empty error if valid', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint64', fieldNumber: 1 } }, - }, - { myProp: BigInt(32) }, - ); - expect(result).toBeEmpty(); + it('should not throw error if valid', () => { + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint64', fieldNumber: 1}}, + }, + {myProp: BigInt(32)}, + ) + ).not.toThrow(); }); it('should be invalid if not bigint', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint64', fieldNumber: 1 } }, - }, - { myProp: 32 }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint64', fieldNumber: 1}}, + }, + {myProp: 32}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); it('should be invalid if negative', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint64', fieldNumber: 1 } }, - }, - { myProp: BigInt(-32) }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint64', fieldNumber: 1}}, + }, + {myProp: BigInt(-32)}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); it('should be invalid if above uint64 range', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'uint64', fieldNumber: 1 } }, - }, - { myProp: BigInt('18446744073709551616') }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'uint64', fieldNumber: 1}}, + }, + {myProp: BigInt('18446744073709551616')}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); }); describe('sint32', () => { - it('should return empty error if valid', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'sint32', fieldNumber: 1 } }, - }, - { myProp: -32 }, - ); - expect(result).toBeEmpty(); + it('should not throw error if valid', () => { + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'sint32', fieldNumber: 1}}, + }, + {myProp: -32}, + ) + ).not.toThrow(); }); it('should be invalid if not number', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'sint32', fieldNumber: 1 } }, - }, - { myProp: 'value' }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'sint32', fieldNumber: 1}}, + }, + {myProp: 'value'}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); it('should be invalid if number has decimal', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'sint32', fieldNumber: 1 } }, - }, - { myProp: -1.23 }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'sint32', fieldNumber: 1}}, + }, + {myProp: -1.23}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); it('should be invalid if not sint32 range', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'sint32', fieldNumber: 1 } }, - }, - { myProp: -2147483649 }, - ); - expect(result).toHaveLength(1); + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'sint32', fieldNumber: 1}}, + }, + {myProp: -2147483649}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); }); describe('sint64', () => { - it('should return empty error if valid', () => { - const result = validator.validate( - { - ...validSchema, - properties: { myProp: { dataType: 'sint64', fieldNumber: 1 } }, - }, - { myProp: BigInt(-32) }, - ); - expect(result).toBeEmpty(); + it('should not throw error if valid', () => { + expect( + () => validator.validate( + { + ...validSchema, + properties: {myProp: {dataType: 'sint64', fieldNumber: 1}}, + }, + {myProp: BigInt(-32)}, + ) + ).not.toThrow() }); it('should be invalid if not bigint', () => { - const result = validator.validate( + expect( + () => validator.validate( { ...validSchema, - properties: { myProp: { dataType: 'sint64', fieldNumber: 1 } }, + properties: {myProp: {dataType: 'sint64', fieldNumber: 1}}, }, - { myProp: 32 }, - ); - expect(result).toHaveLength(1); + {myProp: 32}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); it('should be invalid if above sint64 range', () => { - const result = validator.validate( + expect( + () => validator.validate( { ...validSchema, - properties: { myProp: { dataType: 'sint64', fieldNumber: 1 } }, + properties: {myProp: {dataType: 'sint64', fieldNumber: 1}}, }, - { myProp: BigInt('-9223372036854775809') }, - ); - expect(result).toHaveLength(1); + {myProp: BigInt('-9223372036854775809')}, + ) + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); }); }); }); diff --git a/framework-plugins/lisk-framework-faucet-plugin/src/plugin/endpoint.ts b/framework-plugins/lisk-framework-faucet-plugin/src/plugin/endpoint.ts index 890658e5ddd..b4bd0b68770 100644 --- a/framework-plugins/lisk-framework-faucet-plugin/src/plugin/endpoint.ts +++ b/framework-plugins/lisk-framework-faucet-plugin/src/plugin/endpoint.ts @@ -24,7 +24,7 @@ import { import { authorizeParamsSchema, fundParamsSchema } from './schemas'; import { FaucetPluginConfig, State } from './types'; -const { validator, LiskValidationError } = liskValidator; +const { validator} = liskValidator; export class Endpoint extends BasePluginEndpoint { private _state: State = { publicKey: undefined, passphrase: undefined }; @@ -38,11 +38,7 @@ export class Endpoint extends BasePluginEndpoint { } // eslint-disable-next-line @typescript-eslint/require-await public async authorize(context: PluginEndpointContext): Promise<{ result: string }> { - const errors = validator.validate(authorizeParamsSchema, context.params); - - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(authorizeParamsSchema, context.params); const { enable, password } = context.params; @@ -72,13 +68,9 @@ export class Endpoint extends BasePluginEndpoint { } public async fundTokens(context: PluginEndpointContext): Promise<{ result: string }> { - const errors = validator.validate(fundParamsSchema, context.params); + validator.validate(fundParamsSchema, context.params); const { address, token } = context.params; - if (errors.length) { - throw new LiskValidationError(errors); - } - if (!this._state.publicKey || !this._state.passphrase) { throw new Error('Faucet is not enabled.'); } diff --git a/framework-plugins/lisk-framework-report-misbehavior-plugin/src/endpoint.ts b/framework-plugins/lisk-framework-report-misbehavior-plugin/src/endpoint.ts index 5c854151a00..df217e898b3 100644 --- a/framework-plugins/lisk-framework-report-misbehavior-plugin/src/endpoint.ts +++ b/framework-plugins/lisk-framework-report-misbehavior-plugin/src/endpoint.ts @@ -20,7 +20,7 @@ import { import { actionParamsSchema } from './schemas'; import { ReportMisbehaviorPluginConfig, State } from './types'; -const { validator, LiskValidationError } = liskValidator; +const { validator} = liskValidator; const { encrypt, address } = cryptography; export class Endpoint extends BasePluginEndpoint { @@ -34,11 +34,7 @@ export class Endpoint extends BasePluginEndpoint { // eslint-disable-next-line @typescript-eslint/require-await public async authorize(context: PluginEndpointContext): Promise<{ result: string }> { - const errors = validator.validate(actionParamsSchema, context.params); - - if (errors.length) { - throw new LiskValidationError([...errors]); - } + validator.validate(actionParamsSchema, context.params); const { enable, password } = context.params; diff --git a/framework/src/application.ts b/framework/src/application.ts index 4398be11eb9..f0d16077fe3 100644 --- a/framework/src/application.ts +++ b/framework/src/application.ts @@ -19,7 +19,7 @@ import * as assert from 'assert'; import * as childProcess from 'child_process'; import { Block } from '@liskhq/lisk-chain'; import { Database, StateDB } from '@liskhq/lisk-db'; -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { objects, jobHandlers } from '@liskhq/lisk-utils'; import { APP_EVENT_SHUTDOWN, APP_EVENT_READY } from './constants'; import { @@ -143,10 +143,8 @@ export class Application { config.label ?? `lisk-${config.genesis?.communityIdentifier}`; const mergedConfig = objects.mergeDeep({}, appConfig, config) as ApplicationConfig; - const applicationConfigErrors = validator.validate(applicationConfigSchema, mergedConfig); - if (applicationConfigErrors.length) { - throw new LiskValidationError(applicationConfigErrors); - } + validator.validate(applicationConfigSchema, mergedConfig); + this.config = mergedConfig; const { plugins, ...rootConfigs } = this.config; diff --git a/framework/src/controller/jsonrpc/utils.ts b/framework/src/controller/jsonrpc/utils.ts index 7779847281d..ab7d7fbd158 100644 --- a/framework/src/controller/jsonrpc/utils.ts +++ b/framework/src/controller/jsonrpc/utils.ts @@ -11,7 +11,7 @@ * * Removal or modification of this copyright notice is prohibited. */ -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { JSONRPCErrorObject, ID, @@ -69,17 +69,11 @@ export function validateJSONRPCRequest(data: unknown): asserts data is RequestOb if (typeof data !== 'object' || data === null) { throw new Error('Data must be type of object.'); } - const errors = validator.validate(requestSchema, data); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(requestSchema, data); } export const validateJSONRPCNotification = (data: Record): void => { - const errors = validator.validate(notificationSchema, data); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(notificationSchema, data); }; export const notificationRequest = ( diff --git a/framework/src/engine/consensus/network_endpoint.ts b/framework/src/engine/consensus/network_endpoint.ts index 8d3348d38e8..b1b72e7c2de 100644 --- a/framework/src/engine/consensus/network_endpoint.ts +++ b/framework/src/engine/consensus/network_endpoint.ts @@ -16,7 +16,7 @@ import { InMemoryDatabase, Database } from '@liskhq/lisk-db'; import { Chain, StateStore } from '@liskhq/lisk-chain'; import { codec } from '@liskhq/lisk-codec'; import { objects } from '@liskhq/lisk-utils'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { Logger } from '../../logger'; import { Network } from '../network'; import { @@ -97,10 +97,10 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { }); throw error; } - const errors = validator.validate(getBlocksFromIdRequestSchema, decodedData); - if (errors.length) { - const error = new LiskValidationError(errors); + try { + validator.validate(getBlocksFromIdRequestSchema, decodedData); + } catch (error) { this._logger.warn( { err: error, @@ -149,25 +149,29 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { getHighestCommonBlockRequestSchema, data as never, ); - const errors = validator.validate(getHighestCommonBlockRequestSchema, blockIds); - if (errors.length || !objects.bufferArrayUniqueItems(blockIds.ids)) { - const error = new LiskValidationError(errors); - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + const logDataAndApplyPenalty = (data? : unknown) => { this._logger.warn( - { - err: error, - req: data, - }, + data, 'getHighestCommonBlock request validation failed', ); this._network.applyPenaltyOnPeer({ peerId, penalty: 100, }); + } + + try { + validator.validate(getHighestCommonBlockRequestSchema, blockIds); + } catch (error) { + logDataAndApplyPenalty({ err: error, req: data}) throw error; } + if (!objects.bufferArrayUniqueItems(blockIds.ids)) { + logDataAndApplyPenalty({ req: data}); + } + const commonBlockHeaderID = await this._chain.dataAccess.getHighestCommonBlockID(blockIds.ids); return codec.encode(getHighestCommonBlockResponseSchema, { @@ -202,10 +206,9 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { throw error; } - const errors = validator.validate(singleCommitSchema, decodedData.singleCommit); - - if (errors.length) { - const error = new LiskValidationError(errors); + try { + validator.validate(singleCommitSchema, decodedData.singleCommit); + } catch (error) { this._logger.debug( { peerId, penalty: 100 }, 'Adding penalty on peer for invalid single commit', diff --git a/framework/src/engine/consensus/synchronizer/base_synchronizer.ts b/framework/src/engine/consensus/synchronizer/base_synchronizer.ts index 0f022b5b6e4..bb848f83566 100644 --- a/framework/src/engine/consensus/synchronizer/base_synchronizer.ts +++ b/framework/src/engine/consensus/synchronizer/base_synchronizer.ts @@ -78,8 +78,10 @@ export abstract class BaseSynchronizer { getHighestCommonBlockResponseSchema, data, ); - const errors = validator.validate(getHighestCommonBlockResponseSchema, decodedResp); - if (errors.length) { + + try { + validator.validate(getHighestCommonBlockResponseSchema, decodedResp); + } catch { throw new ApplyPenaltyAndAbortError(peerId, 'Invalid common block response format'); } return this._chain.dataAccess.getBlockHeaderByID(decodedResp.id); diff --git a/framework/src/engine/endpoint/chain.ts b/framework/src/engine/endpoint/chain.ts index f46a9abea84..b22a1946682 100644 --- a/framework/src/engine/endpoint/chain.ts +++ b/framework/src/engine/endpoint/chain.ts @@ -23,7 +23,7 @@ import { TransactionJSON, } from '@liskhq/lisk-chain'; import { InMemoryDatabase, Database, NotFoundError } from '@liskhq/lisk-db'; -import { isHexString, LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { isHexString, validator } from '@liskhq/lisk-validator'; import { SparseMerkleTree, SMTProof } from '@liskhq/lisk-tree'; import { JSONObject } from '../../types'; import { RequestContext } from '../rpc/rpc_server'; @@ -187,10 +187,8 @@ export class ChainEndpoint { } public async proveEvents(context: RequestContext): Promise> { - const errors = validator.validate(proveEventsRequestSchema, context.params); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(proveEventsRequestSchema, context.params); + const { height, queries } = context.params as { height: number; queries: string[] }; const queryBytes = queries.map(q => Buffer.from(q, 'hex')); const events = await this._chain.dataAccess.getEvents(height); @@ -232,10 +230,7 @@ export class ChainEndpoint { // eslint-disable-next-line @typescript-eslint/require-await public async areHeadersContradicting(context: RequestContext): Promise<{ valid: boolean }> { - const errors = validator.validate(areHeadersContradictingRequestSchema, context.params); - if (errors.length > 0) { - throw new LiskValidationError(errors); - } + validator.validate(areHeadersContradictingRequestSchema, context.params); const bftHeader1 = BlockHeader.fromBytes(Buffer.from(context.params.header1 as string, 'hex')); const bftHeader2 = BlockHeader.fromBytes(Buffer.from(context.params.header2 as string, 'hex')); diff --git a/framework/src/engine/endpoint/txpool.ts b/framework/src/engine/endpoint/txpool.ts index ebc78206672..2f841e046b4 100644 --- a/framework/src/engine/endpoint/txpool.ts +++ b/framework/src/engine/endpoint/txpool.ts @@ -15,7 +15,7 @@ import { Database } from '@liskhq/lisk-db'; import { Chain, Transaction, Event, StateStore } from '@liskhq/lisk-chain'; import { TransactionPool } from '@liskhq/lisk-transaction-pool'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { Broadcaster } from '../generator/broadcaster'; import { InvalidTransactionError } from '../generator/errors'; import { @@ -59,10 +59,8 @@ export class TxpoolEndpoint { } public async postTransaction(ctx: RequestContext): Promise { - const reqErrors = validator.validate(postTransactionRequestSchema, ctx.params); - if (reqErrors?.length) { - throw new LiskValidationError(reqErrors); - } + validator.validate(postTransactionRequestSchema, ctx.params); + const req = (ctx.params as unknown) as PostTransactionRequest; const transaction = Transaction.fromBytes(Buffer.from(req.transaction, 'hex')); @@ -110,10 +108,8 @@ export class TxpoolEndpoint { } public async dryRunTransaction(ctx: RequestContext): Promise { - const reqErrors = validator.validate(dryRunTransactionRequestSchema, ctx.params); - if (reqErrors?.length) { - throw new LiskValidationError(reqErrors); - } + validator.validate(dryRunTransactionRequestSchema, ctx.params); + const req = (ctx.params as unknown) as DryRunTransactionRequest; const transaction = Transaction.fromBytes(Buffer.from(req.transaction, 'hex')); diff --git a/framework/src/engine/generator/endpoint.ts b/framework/src/engine/generator/endpoint.ts index 2ec6e75523d..4cdbd7bc704 100644 --- a/framework/src/engine/generator/endpoint.ts +++ b/framework/src/engine/generator/endpoint.ts @@ -15,7 +15,7 @@ import { encrypt, ed, bls, address as cryptoAddress } from '@liskhq/lisk-cryptography'; import { Batch, Database } from '@liskhq/lisk-db'; import { dataStructures } from '@liskhq/lisk-utils'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { GeneratorStore } from './generator_store'; import { getLastGeneratedInfo, @@ -78,10 +78,8 @@ export class Endpoint { } public async updateStatus(ctx: RequestContext): Promise { - const reqErrors = validator.validate(updateStatusRequestSchema, ctx.params); - if (reqErrors?.length) { - throw new LiskValidationError(reqErrors); - } + validator.validate(updateStatusRequestSchema, ctx.params); + const req = (ctx.params as unknown) as UpdateStatusRequest; const address = Buffer.from(req.address, 'hex'); const encryptedGenerator = this._generators.find(item => item.address.equals(address)); diff --git a/framework/src/engine/generator/generator.ts b/framework/src/engine/generator/generator.ts index b0c0caa73de..96610e342a5 100644 --- a/framework/src/engine/generator/generator.ts +++ b/framework/src/engine/generator/generator.ts @@ -28,7 +28,7 @@ import { Database, Batch, SparseMerkleTree } from '@liskhq/lisk-db'; import { TransactionPool, events } from '@liskhq/lisk-transaction-pool'; import { MerkleTree } from '@liskhq/lisk-tree'; import { dataStructures, jobHandlers } from '@liskhq/lisk-utils'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { EVENT_NETWORK_READY } from '../events'; import { Logger } from '../../logger'; import { GenesisConfig } from '../../types'; @@ -378,10 +378,7 @@ export class Generator { }; const encodedData = codec.decode(getTransactionsResponseSchema, data); - const validatorErrors = validator.validate(getTransactionsResponseSchema, encodedData); - if (validatorErrors.length) { - throw new LiskValidationError(validatorErrors); - } + validator.validate(getTransactionsResponseSchema, encodedData); const transactions = encodedData.transactions.map(transaction => Transaction.fromBytes(transaction), diff --git a/framework/src/engine/generator/network_endpoint.ts b/framework/src/engine/generator/network_endpoint.ts index 7d7ca0f2748..0c171550ae9 100644 --- a/framework/src/engine/generator/network_endpoint.ts +++ b/framework/src/engine/generator/network_endpoint.ts @@ -13,7 +13,7 @@ */ import { codec } from '@liskhq/lisk-codec'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { objects as objectUtils } from '@liskhq/lisk-utils'; import { TransactionPool } from '@liskhq/lisk-transaction-pool'; import { Chain, Transaction } from '@liskhq/lisk-chain'; @@ -81,14 +81,27 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { if (Buffer.isBuffer(data)) { decodedData = codec.decode(getTransactionRequestSchema, data); - const errors = validator.validate(getTransactionRequestSchema, decodedData); - if (errors.length || !objectUtils.bufferArrayUniqueItems(decodedData.transactionIds)) { - this._logger.warn({ err: errors, peerId }, 'Received invalid getTransactions body'); + + const logDataAndApplyPenalty = (data? : unknown) => { + this._logger.warn( + data, + 'Received invalid getTransactions body', + ); this.network.applyPenaltyOnPeer({ peerId, penalty: 100, }); - throw new LiskValidationError(errors); + } + + try { + validator.validate(getTransactionRequestSchema, decodedData); + } catch (err) { + logDataAndApplyPenalty({ err: err, peerId }) + throw err; + } + + if (!objectUtils.bufferArrayUniqueItems(decodedData.transactionIds)) { + logDataAndApplyPenalty({ peerId }) } } @@ -180,15 +193,16 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { postTransactionsAnnouncementSchema, data, ); - const errors = validator.validate(postTransactionsAnnouncementSchema, decodedData); - if (errors.length) { - this._logger.warn({ err: errors, peerId }, 'Received invalid transactions body'); + try { + validator.validate(postTransactionsAnnouncementSchema, decodedData); + } catch (err) { + this._logger.warn({ err: err, peerId }, 'Received invalid transactions body'); this.network.applyPenaltyOnPeer({ peerId, penalty: 100, }); - throw new LiskValidationError(errors); + throw err; } this.event.emit(GENERATOR_EVENT_NEW_TRANSACTION_ANNOUNCEMENT, decodedData); diff --git a/framework/src/modules/auth/commands/register_multisignature.ts b/framework/src/modules/auth/commands/register_multisignature.ts index ad462b96817..258035bae8b 100644 --- a/framework/src/modules/auth/commands/register_multisignature.ts +++ b/framework/src/modules/auth/commands/register_multisignature.ts @@ -13,7 +13,7 @@ */ import { objects as objectUtils } from '@liskhq/lisk-utils'; -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { BaseCommand } from '../..'; import { CommandExecuteContext, @@ -43,12 +43,12 @@ export class RegisterMultisignatureCommand extends BaseCommand { const { transaction } = context; const { mandatoryKeys, optionalKeys, numberOfSignatures } = context.params; - const errors = validator.validate(registerMultisignatureParamsSchema, context.params); - - if (errors.length > 0) { + try { + validator.validate(registerMultisignatureParamsSchema, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } diff --git a/framework/src/modules/auth/module.ts b/framework/src/modules/auth/module.ts index 9cbf357fd61..2c8fa565c7a 100644 --- a/framework/src/modules/auth/module.ts +++ b/framework/src/modules/auth/module.ts @@ -15,7 +15,7 @@ import { NotFoundError, TAG_TRANSACTION } from '@liskhq/lisk-chain'; import { objects as objectUtils } from '@liskhq/lisk-utils'; import { codec } from '@liskhq/lisk-codec'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseModule, ModuleMetadata } from '../base_module'; import { GenesisBlockExecuteContext, @@ -89,11 +89,8 @@ export class AuthModule extends BaseModule { } keys.push(storeKey); - const errors = validator.validate(authAccountSchema, storeValue); + validator.validate(authAccountSchema, storeValue); - if (errors.length > 0) { - throw new LiskValidationError(errors); - } const { mandatoryKeys, optionalKeys, numberOfSignatures } = storeValue; if (mandatoryKeys.length > 0) { if (!objectUtils.bufferArrayOrderByLex(mandatoryKeys)) { diff --git a/framework/src/modules/dpos_v2/commands/delegate_registration.ts b/framework/src/modules/dpos_v2/commands/delegate_registration.ts index 1aec8aaa14a..c52a9aa6aa9 100644 --- a/framework/src/modules/dpos_v2/commands/delegate_registration.ts +++ b/framework/src/modules/dpos_v2/commands/delegate_registration.ts @@ -12,13 +12,13 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { CommandVerifyContext, VerificationResult, VerifyStatus, CommandExecuteContext, -} from '../../../state_machine/types'; +} from '../../../state_machine'; import { BaseCommand } from '../../base_command'; import { COMMAND_ID_DELEGATE_REGISTRATION, @@ -49,12 +49,12 @@ export class DelegateRegistrationCommand extends BaseCommand { ): Promise { const { transaction } = context; - const errors = validator.validate(delegateRegistrationCommandParamsSchema, context.params); - - if (errors.length > 0) { + try { + validator.validate(delegateRegistrationCommandParamsSchema, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } diff --git a/framework/src/modules/dpos_v2/commands/pom.ts b/framework/src/modules/dpos_v2/commands/pom.ts index f3929ea2bc0..b3072c94e60 100644 --- a/framework/src/modules/dpos_v2/commands/pom.ts +++ b/framework/src/modules/dpos_v2/commands/pom.ts @@ -12,14 +12,14 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { BlockHeader } from '@liskhq/lisk-chain'; import { CommandVerifyContext, VerificationResult, VerifyStatus, CommandExecuteContext, -} from '../../../state_machine/types'; +} from '../../../state_machine'; import { BaseCommand } from '../../base_command'; import { COMMAND_ID_POM, @@ -62,12 +62,13 @@ export class ReportDelegateMisbehaviorCommand extends BaseCommand { public async verify( context: CommandVerifyContext, ): Promise { - const errors = validator.validate(this.schema, context.params); - if (errors.length > 0) { + try { + validator.validate(this.schema, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } diff --git a/framework/src/modules/dpos_v2/commands/update_generator_key.ts b/framework/src/modules/dpos_v2/commands/update_generator_key.ts index 512facdaad9..7066c67d8ce 100644 --- a/framework/src/modules/dpos_v2/commands/update_generator_key.ts +++ b/framework/src/modules/dpos_v2/commands/update_generator_key.ts @@ -12,13 +12,13 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { CommandVerifyContext, VerificationResult, VerifyStatus, CommandExecuteContext, -} from '../../../state_machine/types'; +} from '../../../state_machine'; import { BaseCommand } from '../../base_command'; import { COMMAND_ID_UPDATE_GENERATOR_KEY, @@ -45,12 +45,12 @@ export class UpdateGeneratorKeyCommand extends BaseCommand { ): Promise { const { transaction } = context; - const errors = validator.validate(updateGeneratorKeyCommandParamsSchema, context.params); - - if (errors.length > 0) { + try { + validator.validate(updateGeneratorKeyCommandParamsSchema, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } diff --git a/framework/src/modules/dpos_v2/commands/vote.ts b/framework/src/modules/dpos_v2/commands/vote.ts index 4b85f018fcc..a467eb550df 100644 --- a/framework/src/modules/dpos_v2/commands/vote.ts +++ b/framework/src/modules/dpos_v2/commands/vote.ts @@ -20,7 +20,7 @@ import { VerificationResult, VerifyStatus, CommandExecuteContext, -} from '../../../state_machine/types'; +} from '../../../state_machine'; import { BaseCommand } from '../../base_command'; import { COMMAND_ID_VOTE, @@ -64,12 +64,12 @@ export class VoteCommand extends BaseCommand { params: { votes }, } = context; - const validationErrors = validator.validate(this.schema, context.params); - - if (validationErrors.length > 0) { + try { + validator.validate(this.schema, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new AggregateValidationError('Parameter is not valid.', validationErrors), + error: new AggregateValidationError('Parameter is not valid.', err.toString()), }; } diff --git a/framework/src/modules/dpos_v2/module.ts b/framework/src/modules/dpos_v2/module.ts index 44b436f3524..78fe0b46abf 100644 --- a/framework/src/modules/dpos_v2/module.ts +++ b/framework/src/modules/dpos_v2/module.ts @@ -14,7 +14,7 @@ import { utils } from '@liskhq/lisk-cryptography'; import { objects as objectUtils, dataStructures, objects } from '@liskhq/lisk-utils'; -import { isUInt64, LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { isUInt64, validator } from '@liskhq/lisk-validator'; import { codec } from '@liskhq/lisk-codec'; import { GenesisBlockExecuteContext, BlockAfterExecuteContext } from '../../state_machine'; import { BaseModule, ModuleInitArgs, ModuleMetadata } from '../base_module'; @@ -170,10 +170,7 @@ export class DPoSModule extends BaseModule { public async init(args: ModuleInitArgs) { const { moduleConfig } = args; const config = objects.mergeDeep({}, defaultConfig, moduleConfig) as ModuleConfigJSON; - const errors = validator.validate(configSchema, config); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(configSchema, config); this._moduleConfig = getModuleConfig(config); @@ -191,11 +188,7 @@ export class DPoSModule extends BaseModule { return; } const genesisStore = codec.decode(genesisStoreSchema, assetBytes); - const errors = validator.validate(genesisStoreSchema, genesisStore); - - if (errors.length > 0) { - throw new LiskValidationError(errors); - } + validator.validate(genesisStoreSchema, genesisStore); // validators property check const dposValidatorAddresses = []; diff --git a/framework/src/modules/fee/module.ts b/framework/src/modules/fee/module.ts index ba93299db39..8381e0ce1f1 100644 --- a/framework/src/modules/fee/module.ts +++ b/framework/src/modules/fee/module.ts @@ -14,7 +14,7 @@ import { address, utils } from '@liskhq/lisk-cryptography'; import { objects } from '@liskhq/lisk-utils'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseModule, ModuleInitArgs, ModuleMetadata } from '../base_module'; import { defaultConfig, MODULE_ID_FEE } from './constants'; import { BaseFee, TokenAPI } from './types'; @@ -56,10 +56,8 @@ export class FeeModule extends BaseModule { public async init(args: ModuleInitArgs): Promise { const { genesisConfig, moduleConfig } = args; const config = objects.mergeDeep({}, defaultConfig, moduleConfig); - const errors = validator.validate(configSchema, config); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(configSchema, config); + this._tokenID = Buffer.from(config.feeTokenID, 'hex'); this._minFeePerByte = genesisConfig.minFeePerByte; this._baseFees = genesisConfig.baseFees.map(fee => ({ ...fee, baseFee: BigInt(fee.baseFee) })); diff --git a/framework/src/modules/interoperability/mainchain/commands/cc_update.ts b/framework/src/modules/interoperability/mainchain/commands/cc_update.ts index f0747f3b370..d2e054e168c 100644 --- a/framework/src/modules/interoperability/mainchain/commands/cc_update.ts +++ b/framework/src/modules/interoperability/mainchain/commands/cc_update.ts @@ -13,7 +13,7 @@ */ import { codec } from '@liskhq/lisk-codec'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { certificateSchema } from '../../../../engine/consensus/certificate_generation/schema'; import { Certificate } from '../../../../engine/consensus/certificate_generation/types'; import { @@ -76,12 +76,13 @@ export class MainchainCCUpdateCommand extends BaseInteroperabilityCommand { context: CommandVerifyContext, ): Promise { const { params: txParams, transaction, getStore } = context; - const errors = validator.validate(crossChainUpdateTransactionParams, context.params); - if (errors.length > 0) { + try { + validator.validate(crossChainUpdateTransactionParams, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } diff --git a/framework/src/modules/interoperability/mainchain/commands/sidechain_registration.ts b/framework/src/modules/interoperability/mainchain/commands/sidechain_registration.ts index 922bdb0ad96..5c9fca838c2 100644 --- a/framework/src/modules/interoperability/mainchain/commands/sidechain_registration.ts +++ b/framework/src/modules/interoperability/mainchain/commands/sidechain_registration.ts @@ -14,7 +14,7 @@ import { codec } from '@liskhq/lisk-codec'; import { utils } from '@liskhq/lisk-cryptography'; -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { MainchainInteroperabilityStore } from '../store'; import { BaseInteroperabilityCommand } from '../../base_interoperability_command'; import { @@ -51,7 +51,7 @@ import { VerificationResult, VerifyStatus, CommandExecuteContext, -} from '../../../../state_machine/types'; +} from '../../../../state_machine'; export class SidechainRegistrationCommand extends BaseInteroperabilityCommand { public id = COMMAND_ID_SIDECHAIN_REG_BUFFER; @@ -65,12 +65,13 @@ export class SidechainRegistrationCommand extends BaseInteroperabilityCommand { transaction, params: { certificateThreshold, initValidators, genesisBlockID, name }, } = context; - const errors = validator.validate(sidechainRegParams, context.params); - if (errors.length > 0) { + try { + validator.validate(sidechainRegParams, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } diff --git a/framework/src/modules/interoperability/mainchain/commands/state_recovery.ts b/framework/src/modules/interoperability/mainchain/commands/state_recovery.ts index 5e2f0f3d203..1b1cc600556 100644 --- a/framework/src/modules/interoperability/mainchain/commands/state_recovery.ts +++ b/framework/src/modules/interoperability/mainchain/commands/state_recovery.ts @@ -14,7 +14,7 @@ import { sparseMerkleTree } from '@liskhq/lisk-tree'; import { utils } from '@liskhq/lisk-cryptography'; -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { MainchainInteroperabilityStore } from '../store'; import { BaseInteroperabilityCommand } from '../../base_interoperability_command'; import { @@ -30,7 +30,7 @@ import { CommandVerifyContext, VerificationResult, VerifyStatus, -} from '../../../../state_machine/types'; +} from '../../../../state_machine'; import { createRecoverCCMsgAPIContext } from '../../../../testing'; export class StateRecoveryCommand extends BaseInteroperabilityCommand { @@ -44,12 +44,13 @@ export class StateRecoveryCommand extends BaseInteroperabilityCommand { const { params: { chainID, storeEntries, siblingHashes }, } = context; - const errors = validator.validate(this.schema, context.params); - if (errors.length > 0) { + try { + validator.validate(this.schema, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } diff --git a/framework/src/modules/interoperability/sidechain/commands/cc_update.ts b/framework/src/modules/interoperability/sidechain/commands/cc_update.ts index 7756fa82e69..d3cc9ad4d7e 100644 --- a/framework/src/modules/interoperability/sidechain/commands/cc_update.ts +++ b/framework/src/modules/interoperability/sidechain/commands/cc_update.ts @@ -13,7 +13,7 @@ */ import { codec } from '@liskhq/lisk-codec'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { certificateSchema } from '../../../../engine/consensus/certificate_generation/schema'; import { Certificate } from '../../../../engine/consensus/certificate_generation/types'; import { @@ -74,12 +74,13 @@ export class SidechainCCUpdateCommand extends BaseInteroperabilityCommand { context: CommandVerifyContext, ): Promise { const { params: txParams, transaction, getStore } = context; - const errors = validator.validate(crossChainUpdateTransactionParams, context.params); - if (errors.length > 0) { + try { + validator.validate(crossChainUpdateTransactionParams, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } diff --git a/framework/src/modules/interoperability/sidechain/commands/mainchain_registration.ts b/framework/src/modules/interoperability/sidechain/commands/mainchain_registration.ts index a3de4458955..31bde8fcc6f 100644 --- a/framework/src/modules/interoperability/sidechain/commands/mainchain_registration.ts +++ b/framework/src/modules/interoperability/sidechain/commands/mainchain_registration.ts @@ -14,7 +14,7 @@ import { codec } from '@liskhq/lisk-codec'; import { utils, bls } from '@liskhq/lisk-cryptography'; -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { CCM_STATUS_OK, CHAIN_REGISTERED, @@ -74,11 +74,12 @@ export class MainchainRegistrationCommand extends BaseInteroperabilityCommand { }; } - const registrationParamsErrors = validator.validate(mainchainRegParams, context.params); - if (registrationParamsErrors.length > 0) { + try { + validator.validate(mainchainRegParams, context.params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(registrationParamsErrors), + error: err, }; } diff --git a/framework/src/modules/interoperability/utils.ts b/framework/src/modules/interoperability/utils.ts index 97bdd144428..53a10a5ba0e 100644 --- a/framework/src/modules/interoperability/utils.ts +++ b/framework/src/modules/interoperability/utils.ts @@ -15,7 +15,7 @@ import { regularMerkleTree, sparseMerkleTree } from '@liskhq/lisk-tree'; import { codec } from '@liskhq/lisk-codec'; import { utils, bls } from '@liskhq/lisk-cryptography'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { DB_KEY_STATE_STORE } from '@liskhq/lisk-chain'; import { dataStructures } from '@liskhq/lisk-utils'; import { @@ -92,12 +92,8 @@ interface CommonExecutionLogicArgs { export const getIDAsKeyForStore = (id: number) => utils.intToBuffer(id, 4); export const validateFormat = (ccm: CCMsg) => { - const errors = validator.validate(ccmSchema, ccm); - if (errors.length) { - const error = new LiskValidationError(errors); + validator.validate(ccmSchema, ccm); - throw error; - } const serializedCCM = codec.encode(ccmSchema, ccm); if (serializedCCM.byteLength > MAX_CCM_SIZE) { throw new Error(`Cross chain message is over the the max ccm size limit of ${MAX_CCM_SIZE}`); diff --git a/framework/src/modules/random/endpoint.ts b/framework/src/modules/random/endpoint.ts index 8b01b807f26..3b866e2993a 100644 --- a/framework/src/modules/random/endpoint.ts +++ b/framework/src/modules/random/endpoint.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { validator} from '@liskhq/lisk-validator'; import { ModuleEndpointContext } from '../../types'; import { BaseEndpoint } from '../base_endpoint'; import { STORE_PREFIX_RANDOM, EMPTY_KEY } from './constants'; @@ -22,10 +22,8 @@ import { getSeedRevealValidity } from './utils'; export class RandomEndpoint extends BaseEndpoint { public async isSeedRevealValid(context: ModuleEndpointContext): Promise<{ valid: boolean }> { - const errors = validator.validate(isSeedRevealValidRequestSchema, context.params); - if (errors.length > 0) { - throw new LiskValidationError([...errors]); - } + validator.validate(isSeedRevealValidRequestSchema, context.params); + const { generatorAddress, seedReveal } = context.params; const randomDataStore = context.getStore(this.moduleID, STORE_PREFIX_RANDOM); const { validatorReveals } = await randomDataStore.getWithSchema( diff --git a/framework/src/modules/random/module.ts b/framework/src/modules/random/module.ts index db7b3d70957..35f7898298a 100644 --- a/framework/src/modules/random/module.ts +++ b/framework/src/modules/random/module.ts @@ -15,7 +15,7 @@ import { utils } from '@liskhq/lisk-cryptography'; import { codec } from '@liskhq/lisk-codec'; import { dataStructures, objects } from '@liskhq/lisk-utils'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BlockAfterExecuteContext, BlockVerifyContext, @@ -88,15 +88,11 @@ export class RandomModule extends BaseModule { public async init(args: ModuleInitArgs): Promise { const { moduleConfig, generatorConfig } = args; const config = objects.mergeDeep({}, defaultConfig, moduleConfig); - const errors = validator.validate(randomModuleConfig, config); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(randomModuleConfig, config); + if (generatorConfig && Object.entries(generatorConfig).length > 0) { - const generatorErrors = validator.validate(randomModuleGeneratorConfig, generatorConfig); - if (generatorErrors.length) { - throw new LiskValidationError(generatorErrors); - } + validator.validate(randomModuleGeneratorConfig, generatorConfig); + this._generatorConfig = (generatorConfig.hashOnions as JSONObject[]).map(ho => ({ ...ho, address: Buffer.from(ho.address, 'hex'), diff --git a/framework/src/modules/reward/module.ts b/framework/src/modules/reward/module.ts index 35ada467a77..7e4be787c18 100644 --- a/framework/src/modules/reward/module.ts +++ b/framework/src/modules/reward/module.ts @@ -14,7 +14,7 @@ import { utils } from '@liskhq/lisk-cryptography'; import { objects } from '@liskhq/lisk-utils'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseModule, ModuleInitArgs, ModuleMetadata } from '../base_module'; import { defaultConfig, MODULE_ID_REWARD } from './constants'; import { ModuleConfig, RandomAPI, TokenAPI } from './types'; @@ -63,10 +63,8 @@ export class RewardModule extends BaseModule { public async init(args: ModuleInitArgs): Promise { const { moduleConfig } = args; const config = objects.mergeDeep({}, defaultConfig, moduleConfig); - const errors = validator.validate(configSchema, config); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(configSchema, config); + this._moduleConfig = (config as unknown) as ModuleConfig; this._tokenID = Buffer.from(this._moduleConfig.tokenID, 'hex'); diff --git a/framework/src/modules/token/cc_commands/cc_forward.ts b/framework/src/modules/token/cc_commands/cc_forward.ts index 4818f26d705..1b85be78f26 100644 --- a/framework/src/modules/token/cc_commands/cc_forward.ts +++ b/framework/src/modules/token/cc_commands/cc_forward.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ import { codec } from '@liskhq/lisk-codec'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseCCCommand } from '../../interoperability/base_cc_command'; import { CCCommandExecuteContext } from '../../interoperability/types'; import { TokenAPI } from '../api'; @@ -60,10 +60,8 @@ export class CCForwardCommand extends BaseCCCommand { let params: CCForwardMessageParams; try { params = codec.decode(crossChainForwardMessageParams, ccm.params); - const errors = validator.validate(crossChainTransferMessageParams, params); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(crossChainTransferMessageParams, params); + } catch (error) { ctx.logger.debug({ err: error as Error }, 'Error verifying the params.'); if (ccm.status === CCM_STATUS_OK) { diff --git a/framework/src/modules/token/cc_commands/cc_transfer.ts b/framework/src/modules/token/cc_commands/cc_transfer.ts index f57e1b5660f..5bfd0a193c4 100644 --- a/framework/src/modules/token/cc_commands/cc_transfer.ts +++ b/framework/src/modules/token/cc_commands/cc_transfer.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ import { codec } from '@liskhq/lisk-codec'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseCCCommand } from '../../interoperability/base_cc_command'; import { CCCommandExecuteContext } from '../../interoperability/types'; import { TokenAPI } from '../api'; @@ -73,10 +73,8 @@ export class CCTransferCommand extends BaseCCCommand { let tokenLocalID; try { params = codec.decode(crossChainTransferMessageParams, ccm.params); - const errors = validator.validate(crossChainTransferMessageParams, params); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(crossChainTransferMessageParams, params); + [tokenChainID, tokenLocalID] = splitTokenID(params.tokenID); if (tokenChainID.equals(ownChainID)) { const escrowedAmount = await this._tokenAPI.getEscrowedAmount( diff --git a/framework/src/modules/token/commands/cc_transfer.ts b/framework/src/modules/token/commands/cc_transfer.ts index 6c9b1037490..b4ebdab011c 100644 --- a/framework/src/modules/token/commands/cc_transfer.ts +++ b/framework/src/modules/token/commands/cc_transfer.ts @@ -11,7 +11,7 @@ * * Removal or modification of this copyright notice is prohibited. */ -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseCommand } from '../../base_command'; import { CommandExecuteContext, @@ -46,11 +46,13 @@ export class CCTransferCommand extends BaseCommand { // eslint-disable-next-line @typescript-eslint/require-await public async verify(context: CommandVerifyContext): Promise { const { params } = context; - const errors = validator.validate(this.schema, params); - if (errors.length) { + + try { + validator.validate(this.schema, params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } return { diff --git a/framework/src/modules/token/commands/transfer.ts b/framework/src/modules/token/commands/transfer.ts index 30d54e41894..5eeff4b768f 100644 --- a/framework/src/modules/token/commands/transfer.ts +++ b/framework/src/modules/token/commands/transfer.ts @@ -11,7 +11,7 @@ * * Removal or modification of this copyright notice is prohibited. */ -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseCommand } from '../../base_command'; import { CommandExecuteContext, @@ -44,11 +44,13 @@ export class TransferCommand extends BaseCommand { // eslint-disable-next-line @typescript-eslint/require-await public async verify(context: CommandVerifyContext): Promise { const { params } = context; - const errors = validator.validate(transferParamsSchema, params); - if (errors.length) { + + try { + validator.validate(transferParamsSchema, params); + } catch (err) { return { status: VerifyStatus.FAIL, - error: new LiskValidationError(errors), + error: err, }; } return { diff --git a/framework/src/modules/token/endpoint.ts b/framework/src/modules/token/endpoint.ts index 81f2634a42a..dba3140f100 100644 --- a/framework/src/modules/token/endpoint.ts +++ b/framework/src/modules/token/endpoint.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { NotFoundError } from '../../state_machine'; import { JSONObject, ModuleEndpointContext } from '../../types'; import { BaseEndpoint } from '../base_endpoint'; @@ -49,10 +49,8 @@ export class TokenEndpoint extends BaseEndpoint { public async getBalances( context: ModuleEndpointContext, ): Promise<{ balances: JSONObject[] }> { - const errors = validator.validate(getBalancesRequestSchema, context.params); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(getBalancesRequestSchema, context.params); + const address = Buffer.from(context.params.address as string, 'hex'); const userStore = context.getStore(this.moduleID, STORE_PREFIX_USER); const userData = await userStore.iterateWithSchema( @@ -76,10 +74,8 @@ export class TokenEndpoint extends BaseEndpoint { } public async getBalance(context: ModuleEndpointContext): Promise> { - const errors = validator.validate(getBalanceRequestSchema, context.params); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(getBalanceRequestSchema, context.params); + const address = Buffer.from(context.params.address as string, 'hex'); const tokenID = Buffer.from(context.params.tokenID as string, 'hex'); const canonicalTokenID = await this._tokenAPI.getCanonicalTokenID( diff --git a/framework/src/modules/token/module.ts b/framework/src/modules/token/module.ts index 6b84a640026..4def461937e 100644 --- a/framework/src/modules/token/module.ts +++ b/framework/src/modules/token/module.ts @@ -11,7 +11,7 @@ * * Removal or modification of this copyright notice is prohibited. */ -import { isUInt64, LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { isUInt64, validator } from '@liskhq/lisk-validator'; import { codec } from '@liskhq/lisk-codec'; import { objects, dataStructures } from '@liskhq/lisk-utils'; import { @@ -125,10 +125,8 @@ export class TokenModule extends BaseInteroperableModule { public async init(args: ModuleInitArgs) { const { moduleConfig } = args; const config = objects.mergeDeep({}, defaultConfig, moduleConfig) as ModuleConfig; - const errors = validator.validate(configSchema, config); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(configSchema, config); + this._minBalances = config.minBalances.map(mb => ({ tokenID: Buffer.from(mb.tokenID, 'hex'), amount: BigInt(mb.amount), @@ -147,10 +145,7 @@ export class TokenModule extends BaseInteroperableModule { return; } const genesisStore = codec.decode(genesisTokenStoreSchema, assetBytes); - const errors = validator.validate(genesisTokenStoreSchema, genesisStore); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(genesisTokenStoreSchema, genesisStore); const userStore = context.getStore(this.id, STORE_PREFIX_USER); const copiedUserStore = [...genesisStore.userSubstore]; diff --git a/framework/src/modules/validators/endpoint.ts b/framework/src/modules/validators/endpoint.ts index 280d4134581..fdff6853d6e 100644 --- a/framework/src/modules/validators/endpoint.ts +++ b/framework/src/modules/validators/endpoint.ts @@ -13,7 +13,7 @@ */ import { utils, bls } from '@liskhq/lisk-cryptography'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { NotFoundError } from '@liskhq/lisk-db'; import { ModuleEndpointContext } from '../../types'; import { BaseEndpoint } from '../base_endpoint'; @@ -22,10 +22,7 @@ import { MODULE_ID_VALIDATORS, STORE_PREFIX_BLS_KEYS } from './constants'; export class ValidatorsEndpoint extends BaseEndpoint { public async validateBLSKey(ctx: ModuleEndpointContext): Promise<{ valid: boolean }> { - const reqErrors = validator.validate(validateBLSKeyRequestSchema, ctx.params); - if (reqErrors?.length) { - throw new LiskValidationError(reqErrors); - } + validator.validate(validateBLSKeyRequestSchema, ctx.params); const req = (ctx.params as unknown) as ValidateBLSKeyRequest; const { proofOfPossession, blsKey } = req; diff --git a/framework/src/modules/validators/module.ts b/framework/src/modules/validators/module.ts index 2d589096675..f8ab7424041 100644 --- a/framework/src/modules/validators/module.ts +++ b/framework/src/modules/validators/module.ts @@ -14,7 +14,7 @@ import { utils } from '@liskhq/lisk-cryptography'; import { objects } from '@liskhq/lisk-utils'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseModule, ModuleInitArgs, ModuleMetadata } from '../base_module'; import { defaultConfig, @@ -59,10 +59,8 @@ export class ValidatorsModule extends BaseModule { public async init(args: ModuleInitArgs): Promise { const { moduleConfig } = args; const config = objects.mergeDeep({}, defaultConfig, moduleConfig); - const errors = validator.validate(configSchema, config); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(configSchema, config); + this._blockTime = config.blockTime as number; this.api.init({ diff --git a/framework/src/plugins/base_plugin.ts b/framework/src/plugins/base_plugin.ts index 8299a951436..4dfd9792119 100644 --- a/framework/src/plugins/base_plugin.ts +++ b/framework/src/plugins/base_plugin.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ import { join } from 'path'; -import { LiskValidationError, validator } from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { APIClient, createIPCClient } from '@liskhq/lisk-api-client'; import { objects } from '@liskhq/lisk-utils'; import { Logger } from '../logger'; @@ -71,10 +71,7 @@ export const validatePluginSpec = (pluginInstance: BasePlugin): void => { } if (pluginInstance.configSchema) { - const errors = validator.validateSchema(pluginInstance.configSchema); - if (errors.length) { - throw new LiskValidationError([...errors]); - } + validator.validateSchema(pluginInstance.configSchema); } }; @@ -120,11 +117,7 @@ export abstract class BasePlugin> { if (this.configSchema) { this._config = objects.mergeDeep({}, this.configSchema.default ?? {}, context.config) as T; - const errors = validator.validate(this.configSchema, this.config as Record); - - if (errors.length) { - throw new LiskValidationError([...errors]); - } + validator.validate(this.configSchema, this.config as Record); } else { this._config = {} as T; } diff --git a/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts b/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts index 0a0f16052e2..8dfb5d5fc6b 100644 --- a/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts +++ b/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts @@ -226,8 +226,9 @@ describe('VoteCommand', () => { }); it('should return errors', () => { - const errors = validator.validate(command.schema, transactionParamsDecoded); - expect(errors[0].message).toInclude('should pass "dataType" keyword validation'); + expect( + () => validator.validate(command.schema, transactionParamsDecoded) + ).toThrow('should pass "dataType" keyword validation') }); }); @@ -244,8 +245,9 @@ describe('VoteCommand', () => { }); it('should return errors', () => { - const errors = validator.validate(command.schema, transactionParamsDecoded); - expect(errors[0].message).toInclude('should pass "dataType" keyword validation'); + expect( + () => validator.validate(command.schema, transactionParamsDecoded) + ).toThrow('should pass "dataType" keyword validation') }); }); }); diff --git a/framework/test/unit/schema/application_config_schema.spec.ts b/framework/test/unit/schema/application_config_schema.spec.ts index d652ba22025..a415a4c24e9 100644 --- a/framework/test/unit/schema/application_config_schema.spec.ts +++ b/framework/test/unit/schema/application_config_schema.spec.ts @@ -14,7 +14,7 @@ import { validator } from '@liskhq/lisk-validator'; import { objects } from '@liskhq/lisk-utils'; -import { applicationConfigSchema } from '../../../src/schema/application_config_schema'; +import { applicationConfigSchema } from '../../../src/schema'; describe('schema/application_config_schema.js', () => { it('application config schema must match to the snapshot.', () => { @@ -22,56 +22,35 @@ describe('schema/application_config_schema.js', () => { }); it('should validate the defined schema', () => { - const errors = validator.validateSchema(applicationConfigSchema); - - expect(errors).toHaveLength(0); + expect( + () => validator.validateSchema(applicationConfigSchema) + ).not.toThrow() }); it('should validate if module properties are objects', () => { const config = objects.cloneDeep(applicationConfigSchema.default); config.genesis.modules = { myModule: { myProp: 1 } }; - const errors = validator.validate(applicationConfigSchema, config); - - expect(errors).toHaveLength(0); + expect( + () => validator.validate(applicationConfigSchema, config) + ).not.toThrow() }); it('should not validate if module properties are not objects', () => { const config = objects.cloneDeep(applicationConfigSchema.default); config.genesis.modules = { myModule: 10 }; - const errors = validator.validate(applicationConfigSchema, config); - - expect(errors).toHaveLength(1); - expect(errors[0]).toEqual( - expect.objectContaining({ - dataPath: '.genesis.modules.myModule', - keyword: 'type', - message: 'must be object', - }), - ); + expect( + () => validator.validate(applicationConfigSchema, config) + ).toThrow("Property '.genesis.modules.myModule' should be of type 'object'") }); it('should not validate if module properties are not valid format', () => { const config = objects.cloneDeep(applicationConfigSchema.default); config.genesis.modules = { 'my-custom-module': { myProp: 1 } }; - const errors = validator.validate(applicationConfigSchema, config); - - expect(errors).toHaveLength(2); - expect(errors[0]).toEqual( - expect.objectContaining({ - dataPath: '.genesis.modules', - keyword: 'pattern', - message: 'must match pattern "^[a-zA-Z][a-zA-Z0-9_]*$"', - }), - ); - expect(errors[1]).toEqual( - expect.objectContaining({ - dataPath: '.genesis.modules', - keyword: 'propertyNames', - message: 'property name must be valid', - }), - ); + expect( + () => validator.validate(applicationConfigSchema, config) + ).toThrow("must match pattern \"^[a-zA-Z][a-zA-Z0-9_]*$\"\nproperty name must be valid") }); }); From f1329c588cfa0e70b308ab59c85631af7077de09 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Wed, 27 Jul 2022 12:35:46 +0300 Subject: [PATCH 21/39] revert import(s) formatting --- elements/lisk-chain/src/block_header.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/elements/lisk-chain/src/block_header.ts b/elements/lisk-chain/src/block_header.ts index 392cc97765a..e91a555bbe4 100644 --- a/elements/lisk-chain/src/block_header.ts +++ b/elements/lisk-chain/src/block_header.ts @@ -12,15 +12,13 @@ * Removal or modification of this copyright notice is prohibited. */ -import {ed, utils} from '@liskhq/lisk-cryptography'; -import {codec} from '@liskhq/lisk-codec'; -import {LiskValidationError, validator} from '@liskhq/lisk-validator'; +import { ed, utils } from '@liskhq/lisk-cryptography'; +import { codec } from '@liskhq/lisk-codec'; +import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { EMPTY_BUFFER, EMPTY_HASH, SIGNATURE_LENGTH_BYTES, TAG_BLOCK_HEADER } from './constants'; +import { blockHeaderSchema, blockHeaderSchemaWithId, signingBlockHeaderSchema } from './schema'; +import { JSONObject } from './types'; import {LiskErrorObject} from "@liskhq/lisk-validator/dist-node/types"; -import {JSONObject} from './types'; -import {EMPTY_BUFFER, EMPTY_HASH, SIGNATURE_LENGTH_BYTES, TAG_BLOCK_HEADER} from './constants'; -import {blockHeaderSchema, blockHeaderSchemaWithId, signingBlockHeaderSchema} from './schema'; - - export interface BlockHeaderAttrs { readonly version: number; @@ -189,7 +187,6 @@ export class BlockHeader { public validateGenesis(): void { const header = this._getBlockHeaderProps(); - validator.validate(blockHeaderSchema, header); const errors: LiskErrorObject[] = [] From 03d83c203c3a104a22513c5bf80146274870a8b1 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Wed, 27 Jul 2022 12:49:50 +0300 Subject: [PATCH 22/39] fix broken test --- .../test/lisk_validator.spec.ts | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/elements/lisk-validator/test/lisk_validator.spec.ts b/elements/lisk-validator/test/lisk_validator.spec.ts index aef5504b81c..1dc8b946bf9 100644 --- a/elements/lisk-validator/test/lisk_validator.spec.ts +++ b/elements/lisk-validator/test/lisk_validator.spec.ts @@ -33,8 +33,7 @@ describe('validator', () => { }; it('should pass on for "object" type', () => { - // Assert - expect(validator.validateSchema(validSchema)).toEqual([]); + expect(() => validator.validateSchema(validSchema)).not.toThrow(); }); it('should return error on schema with type other than "object"', () => { @@ -45,24 +44,27 @@ describe('validator', () => { properties: {}, }; - const msg = "Lisk validator found 2 error[s]:\nmust be equal to constant\nmust NOT have fewer than 1 items" - expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) + const msg = + 'Lisk validator found 2 error[s]:\nmust be equal to constant\nmust NOT have fewer than 1 items'; + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg); }); it('should return error when "type" is not defined', () => { const invalidSchema = { ...validSchema }; delete (invalidSchema as any).type; - const msg = "Lisk validator found 1 error[s]:\nMissing property, must have required property 'type'" - expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) + const msg = + "Lisk validator found 1 error[s]:\nMissing property, must have required property 'type'"; + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg); }); it('should return error when "$id" is not defined', () => { const invalidSchema = { ...validSchema }; delete (invalidSchema as any).$id; - const msg = "Lisk validator found 1 error[s]:\nMissing property, must have required property '$id'" - expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) + const msg = + "Lisk validator found 1 error[s]:\nMissing property, must have required property '$id'"; + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg); }); // As the schema is always overridden @@ -70,7 +72,7 @@ describe('validator', () => { const invalidSchema = cloneDeep(validSchema); delete invalidSchema.$schema; - expect(() => validator.validateSchema(invalidSchema)).not.toThrow() + expect(() => validator.validateSchema(invalidSchema)).not.toThrow(); }); it('should throw error when "$schema" value is defined other than lisk-schema uri', () => { @@ -88,8 +90,9 @@ describe('validator', () => { const invalidSchema = cloneDeep(validSchema); delete invalidSchema.properties; - const msg = "Lisk validator found 1 error[s]:\nMissing property, must have required property 'properties'" - expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) + const msg = + "Lisk validator found 1 error[s]:\nMissing property, must have required property 'properties'"; + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg); }); it('should return error when "properties" are not camelcase', () => { @@ -101,16 +104,17 @@ describe('validator', () => { }, }; - const msg = "Lisk validator found 2 error[s]:\nProperty '.properties' must match format \"camelCase\""; - expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) + const msg = + 'Lisk validator found 2 error[s]:\nProperty \'.properties\' must match format "camelCase"'; + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg); }); it('should return error when "properties" are empty object', () => { const invalidSchema = cloneDeep(validSchema); delete invalidSchema.properties.myProp; - const msg = "Lisk validator found 1 error[s]:\nmust NOT have fewer than 1 items"; - expect(() => validator.validateSchema(invalidSchema)).toThrow(msg) + const msg = 'Lisk validator found 1 error[s]:\nmust NOT have fewer than 1 items'; + expect(() => validator.validateSchema(invalidSchema)).toThrow(msg); }); }); }); From 73f9f751cc043c93d3bb37dd5b908c8fc32b9af1 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Wed, 27 Jul 2022 14:13:21 +0300 Subject: [PATCH 23/39] refactor to use shorthand property name --- framework/src/engine/consensus/network_endpoint.ts | 6 +++--- framework/src/engine/generator/network_endpoint.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/framework/src/engine/consensus/network_endpoint.ts b/framework/src/engine/consensus/network_endpoint.ts index b1b72e7c2de..a0757179067 100644 --- a/framework/src/engine/consensus/network_endpoint.ts +++ b/framework/src/engine/consensus/network_endpoint.ts @@ -163,9 +163,9 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { try { validator.validate(getHighestCommonBlockRequestSchema, blockIds); - } catch (error) { - logDataAndApplyPenalty({ err: error, req: data}) - throw error; + } catch (err) { + logDataAndApplyPenalty({ err, req: data}) + throw err; } if (!objects.bufferArrayUniqueItems(blockIds.ids)) { diff --git a/framework/src/engine/generator/network_endpoint.ts b/framework/src/engine/generator/network_endpoint.ts index 0c171550ae9..b3b5cf1817b 100644 --- a/framework/src/engine/generator/network_endpoint.ts +++ b/framework/src/engine/generator/network_endpoint.ts @@ -96,7 +96,7 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { try { validator.validate(getTransactionRequestSchema, decodedData); } catch (err) { - logDataAndApplyPenalty({ err: err, peerId }) + logDataAndApplyPenalty({ err, peerId }) throw err; } From 79318e2b73d755e8add98b17a14bb02c6c295550 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Wed, 27 Jul 2022 14:19:55 +0300 Subject: [PATCH 24/39] use shorthand property name --- framework/src/engine/generator/network_endpoint.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/engine/generator/network_endpoint.ts b/framework/src/engine/generator/network_endpoint.ts index b3b5cf1817b..8bc78fb14dd 100644 --- a/framework/src/engine/generator/network_endpoint.ts +++ b/framework/src/engine/generator/network_endpoint.ts @@ -197,7 +197,7 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { try { validator.validate(postTransactionsAnnouncementSchema, decodedData); } catch (err) { - this._logger.warn({ err: err, peerId }, 'Received invalid transactions body'); + this._logger.warn({ err, peerId }, 'Received invalid transactions body'); this.network.applyPenaltyOnPeer({ peerId, penalty: 100, From 5923eff2a0d7663ca7aa620b7ea65082411e9ff8 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Wed, 27 Jul 2022 14:43:35 +0300 Subject: [PATCH 25/39] refactor to follow existing format --- .../src/engine/generator/network_endpoint.ts | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/framework/src/engine/generator/network_endpoint.ts b/framework/src/engine/generator/network_endpoint.ts index 8bc78fb14dd..1190c55d14c 100644 --- a/framework/src/engine/generator/network_endpoint.ts +++ b/framework/src/engine/generator/network_endpoint.ts @@ -82,26 +82,23 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { if (Buffer.isBuffer(data)) { decodedData = codec.decode(getTransactionRequestSchema, data); - const logDataAndApplyPenalty = (data? : unknown) => { - this._logger.warn( - data, - 'Received invalid getTransactions body', - ); + try { + validator.validate(getTransactionRequestSchema, decodedData); + } catch (err) { + this._logger.warn({ err, peerId }, 'Received invalid getTransactions body'); this.network.applyPenaltyOnPeer({ peerId, penalty: 100, }); - } - - try { - validator.validate(getTransactionRequestSchema, decodedData); - } catch (err) { - logDataAndApplyPenalty({ err, peerId }) throw err; } if (!objectUtils.bufferArrayUniqueItems(decodedData.transactionIds)) { - logDataAndApplyPenalty({ peerId }) + this._logger.warn({ peerId }, 'Received invalid getTransactions body'); + this.network.applyPenaltyOnPeer({ + peerId, + penalty: 100, + }); } } From 7dac2a3e8fa7cc5d0ccb86ddefb234c69aed5586 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Wed, 27 Jul 2022 20:27:00 +0300 Subject: [PATCH 26/39] replace manual conversion with type guards --- .../engine/consensus/synchronizer/base_synchronizer.ts | 4 ++-- framework/src/engine/endpoint/txpool.ts | 8 ++++---- framework/src/engine/generator/endpoint.ts | 4 ++-- framework/src/engine/generator/generator.ts | 6 +++--- .../src/modules/dpos_v2/commands/delegate_registration.ts | 8 ++++---- framework/src/modules/validators/endpoint.ts | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/framework/src/engine/consensus/synchronizer/base_synchronizer.ts b/framework/src/engine/consensus/synchronizer/base_synchronizer.ts index bb848f83566..137d42c1fda 100644 --- a/framework/src/engine/consensus/synchronizer/base_synchronizer.ts +++ b/framework/src/engine/consensus/synchronizer/base_synchronizer.ts @@ -100,8 +100,8 @@ export abstract class BaseSynchronizer { if (!data || !data.length) { throw new Error(`Peer ${peerId} did not respond with block`); } - const encodedData = codec.decode<{ blocks: Buffer[] }>(getBlocksFromIdResponseSchema, data); - return encodedData.blocks.map(block => Block.fromBytes(block)); + const decodedData = codec.decode<{ blocks: Buffer[] }>(getBlocksFromIdResponseSchema, data); + return decodedData.blocks.map(block => Block.fromBytes(block)); } public abstract run(receivedBlock: Block, peerId: string): Promise; diff --git a/framework/src/engine/endpoint/txpool.ts b/framework/src/engine/endpoint/txpool.ts index 2f841e046b4..0281f6f6e9b 100644 --- a/framework/src/engine/endpoint/txpool.ts +++ b/framework/src/engine/endpoint/txpool.ts @@ -59,9 +59,9 @@ export class TxpoolEndpoint { } public async postTransaction(ctx: RequestContext): Promise { - validator.validate(postTransactionRequestSchema, ctx.params); + validator.validate(postTransactionRequestSchema, ctx.params); - const req = (ctx.params as unknown) as PostTransactionRequest; + const req = ctx.params; const transaction = Transaction.fromBytes(Buffer.from(req.transaction, 'hex')); const { result } = await this._abi.verifyTransaction({ @@ -108,9 +108,9 @@ export class TxpoolEndpoint { } public async dryRunTransaction(ctx: RequestContext): Promise { - validator.validate(dryRunTransactionRequestSchema, ctx.params); + validator.validate(dryRunTransactionRequestSchema, ctx.params); - const req = (ctx.params as unknown) as DryRunTransactionRequest; + const req = ctx.params; const transaction = Transaction.fromBytes(Buffer.from(req.transaction, 'hex')); const { result } = await this._abi.verifyTransaction({ diff --git a/framework/src/engine/generator/endpoint.ts b/framework/src/engine/generator/endpoint.ts index 4cdbd7bc704..b8c2bf03037 100644 --- a/framework/src/engine/generator/endpoint.ts +++ b/framework/src/engine/generator/endpoint.ts @@ -78,9 +78,9 @@ export class Endpoint { } public async updateStatus(ctx: RequestContext): Promise { - validator.validate(updateStatusRequestSchema, ctx.params); + validator.validate(updateStatusRequestSchema, ctx.params); - const req = (ctx.params as unknown) as UpdateStatusRequest; + const req = ctx.params; const address = Buffer.from(req.address, 'hex'); const encryptedGenerator = this._generators.find(item => item.address.equals(address)); diff --git a/framework/src/engine/generator/generator.ts b/framework/src/engine/generator/generator.ts index 96610e342a5..bd3526c2b48 100644 --- a/framework/src/engine/generator/generator.ts +++ b/framework/src/engine/generator/generator.ts @@ -376,11 +376,11 @@ export class Generator { })) as unknown) as { data: Buffer; }; - const encodedData = codec.decode(getTransactionsResponseSchema, data); + const transactionResponse = codec.decode(getTransactionsResponseSchema, data); - validator.validate(getTransactionsResponseSchema, encodedData); + validator.validate(getTransactionsResponseSchema, transactionResponse); - const transactions = encodedData.transactions.map(transaction => + const transactions = transactionResponse.transactions.map(transaction => Transaction.fromBytes(transaction), ); diff --git a/framework/src/modules/dpos_v2/commands/delegate_registration.ts b/framework/src/modules/dpos_v2/commands/delegate_registration.ts index c52a9aa6aa9..5012c9d2241 100644 --- a/framework/src/modules/dpos_v2/commands/delegate_registration.ts +++ b/framework/src/modules/dpos_v2/commands/delegate_registration.ts @@ -47,7 +47,7 @@ export class DelegateRegistrationCommand extends BaseCommand { public async verify( context: CommandVerifyContext, ): Promise { - const { transaction } = context; + const { transaction, params } = context; try { validator.validate(delegateRegistrationCommandParamsSchema, context.params); @@ -58,15 +58,15 @@ export class DelegateRegistrationCommand extends BaseCommand { }; } - if (!isUsername(context.params.name)) { + if (!isUsername(params.name)) { return { status: VerifyStatus.FAIL, - error: new Error(`'name' is in an unsupported format: ${context.params.name}`), + error: new Error(`'name' is in an unsupported format: ${params.name}`), }; } const nameSubstore = context.getStore(MODULE_ID_DPOS_BUFFER, STORE_PREFIX_NAME); - const nameExists = await nameSubstore.has(Buffer.from(context.params.name, 'utf8')); + const nameExists = await nameSubstore.has(Buffer.from(params.name, 'utf8')); if (nameExists) { return { diff --git a/framework/src/modules/validators/endpoint.ts b/framework/src/modules/validators/endpoint.ts index fdff6853d6e..d32615732bf 100644 --- a/framework/src/modules/validators/endpoint.ts +++ b/framework/src/modules/validators/endpoint.ts @@ -22,9 +22,9 @@ import { MODULE_ID_VALIDATORS, STORE_PREFIX_BLS_KEYS } from './constants'; export class ValidatorsEndpoint extends BaseEndpoint { public async validateBLSKey(ctx: ModuleEndpointContext): Promise<{ valid: boolean }> { - validator.validate(validateBLSKeyRequestSchema, ctx.params); + validator.validate(validateBLSKeyRequestSchema, ctx.params); - const req = (ctx.params as unknown) as ValidateBLSKeyRequest; + const req = ctx.params; const { proofOfPossession, blsKey } = req; const blsKeysSubStore = ctx.getStore( From c0de9cb550e5ecc5618fbaf7f42afe203e8b137a Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 16:05:27 +0300 Subject: [PATCH 27/39] Fix ts error --- framework/src/modules/fee/module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/modules/fee/module.ts b/framework/src/modules/fee/module.ts index 8381e0ce1f1..b9707f091ba 100644 --- a/framework/src/modules/fee/module.ts +++ b/framework/src/modules/fee/module.ts @@ -58,7 +58,7 @@ export class FeeModule extends BaseModule { const config = objects.mergeDeep({}, defaultConfig, moduleConfig); validator.validate(configSchema, config); - this._tokenID = Buffer.from(config.feeTokenID, 'hex'); + this._tokenID = Buffer.from(config.feeTokenID as string, 'hex'); this._minFeePerByte = genesisConfig.minFeePerByte; this._baseFees = genesisConfig.baseFees.map(fee => ({ ...fee, baseFee: BigInt(fee.baseFee) })); } From 0756b34331a09a19a27de773db129503e0214386 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 17:06:12 +0300 Subject: [PATCH 28/39] refactor `as string` with generics --- framework/src/modules/fee/module.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/src/modules/fee/module.ts b/framework/src/modules/fee/module.ts index b9707f091ba..bcd2b5bd315 100644 --- a/framework/src/modules/fee/module.ts +++ b/framework/src/modules/fee/module.ts @@ -17,7 +17,7 @@ import { objects } from '@liskhq/lisk-utils'; import { validator } from '@liskhq/lisk-validator'; import { BaseModule, ModuleInitArgs, ModuleMetadata } from '../base_module'; import { defaultConfig, MODULE_ID_FEE } from './constants'; -import { BaseFee, TokenAPI } from './types'; +import { BaseFee, ModuleConfig, TokenAPI } from './types'; import { TransactionExecuteContext, TransactionVerifyContext, @@ -56,9 +56,9 @@ export class FeeModule extends BaseModule { public async init(args: ModuleInitArgs): Promise { const { genesisConfig, moduleConfig } = args; const config = objects.mergeDeep({}, defaultConfig, moduleConfig); - validator.validate(configSchema, config); + validator.validate(configSchema, config); - this._tokenID = Buffer.from(config.feeTokenID as string, 'hex'); + this._tokenID = Buffer.from(config.feeTokenID, 'hex'); this._minFeePerByte = genesisConfig.minFeePerByte; this._baseFees = genesisConfig.baseFees.map(fee => ({ ...fee, baseFee: BigInt(fee.baseFee) })); } From 9195c83e68b98f70b51af32185d527747d52b240 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 17:45:53 +0300 Subject: [PATCH 29/39] refactor to fix TypeScript errors --- .../src/bootstrapping/commands/transaction/create.ts | 4 ++-- elements/lisk-validator/src/index.ts | 4 ++-- elements/lisk-validator/src/lisk_validator.ts | 12 ++++++++---- .../src/plugin/endpoint.ts | 4 +++- .../src/endpoint.ts | 5 ++++- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/commander/src/bootstrapping/commands/transaction/create.ts b/commander/src/bootstrapping/commands/transaction/create.ts index e62d29f0e7c..d34fa7c2ec7 100644 --- a/commander/src/bootstrapping/commands/transaction/create.ts +++ b/commander/src/bootstrapping/commands/transaction/create.ts @@ -18,7 +18,7 @@ import { blockAssetSchema, eventSchema } from '@liskhq/lisk-chain'; import { codec, Schema } from '@liskhq/lisk-codec'; import * as cryptography from '@liskhq/lisk-cryptography'; import * as transactions from '@liskhq/lisk-transactions'; -import * as validator from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import Command, { flags as flagParser } from '@oclif/command'; import { Application, @@ -122,7 +122,7 @@ const validateAndSignTransaction = ( ) as Schema; const txObject = codec.fromJSON(schema.transaction, { ...transactionWithoutParams, params: '' }); - validator.validator.validate(schema.transaction, txObject); + validator.validate(schema.transaction, txObject); const paramsObject = paramsSchema ? codec.fromJSON(paramsSchema, params) : {}; diff --git a/elements/lisk-validator/src/index.ts b/elements/lisk-validator/src/index.ts index 93b15571909..58b55ed273a 100644 --- a/elements/lisk-validator/src/index.ts +++ b/elements/lisk-validator/src/index.ts @@ -12,11 +12,11 @@ * Removal or modification of this copyright notice is prohibited. * */ -import { validator, liskSchemaIdentifier } from './lisk_validator'; +import { validator, liskSchemaIdentifier, LiskValidator } from './lisk_validator'; // To keep backward compatibility import { LiskErrorObject as ErrorObject } from './types'; export * from './validation'; export * from './errors'; export * from './constants'; -export { validator, liskSchemaIdentifier, ErrorObject }; +export { validator, liskSchemaIdentifier, ErrorObject, LiskValidator }; diff --git a/elements/lisk-validator/src/lisk_validator.ts b/elements/lisk-validator/src/lisk_validator.ts index 7574924f1d1..11bfc5d4342 100644 --- a/elements/lisk-validator/src/lisk_validator.ts +++ b/elements/lisk-validator/src/lisk_validator.ts @@ -13,7 +13,7 @@ * */ -import Ajv, {SchemaObject, ValidateFunction} from 'ajv'; +import Ajv, { SchemaObject, ValidateFunction } from 'ajv'; import addDefaultFormats from 'ajv-formats'; import * as formats from './formats'; import { convertErrorsToLegacyFormat, LiskValidationError } from './errors'; @@ -24,7 +24,7 @@ import { LiskErrorObject } from './types'; export const liskSchemaIdentifier: string = liskMetaSchema.$id; -class LiskValidator { +export class LiskValidator { private readonly _validator: Ajv; public constructor() { @@ -71,13 +71,17 @@ class LiskValidator { public validate>(schema: object, data: unknown): asserts data is T { if (!this._validator.validate(schema, data)) { - throw new LiskValidationError(convertErrorsToLegacyFormat(this._validator.errors as LiskErrorObject[])); + throw new LiskValidationError( + convertErrorsToLegacyFormat(this._validator.errors as LiskErrorObject[]), + ); } } public validateSchema(schema: object): asserts schema is SchemaObject { if (!this._validator.validateSchema(schema)) { - throw new LiskValidationError(convertErrorsToLegacyFormat(this._validator.errors as LiskErrorObject[])); + throw new LiskValidationError( + convertErrorsToLegacyFormat(this._validator.errors as LiskErrorObject[]), + ); } } diff --git a/framework-plugins/lisk-framework-faucet-plugin/src/plugin/endpoint.ts b/framework-plugins/lisk-framework-faucet-plugin/src/plugin/endpoint.ts index b4bd0b68770..5aab8cca70d 100644 --- a/framework-plugins/lisk-framework-faucet-plugin/src/plugin/endpoint.ts +++ b/framework-plugins/lisk-framework-faucet-plugin/src/plugin/endpoint.ts @@ -24,7 +24,9 @@ import { import { authorizeParamsSchema, fundParamsSchema } from './schemas'; import { FaucetPluginConfig, State } from './types'; -const { validator} = liskValidator; +// disabled for type annotation +// eslint-disable-next-line prefer-destructuring +const validator: liskValidator.LiskValidator = liskValidator.validator; export class Endpoint extends BasePluginEndpoint { private _state: State = { publicKey: undefined, passphrase: undefined }; diff --git a/framework-plugins/lisk-framework-report-misbehavior-plugin/src/endpoint.ts b/framework-plugins/lisk-framework-report-misbehavior-plugin/src/endpoint.ts index df217e898b3..457afdf062e 100644 --- a/framework-plugins/lisk-framework-report-misbehavior-plugin/src/endpoint.ts +++ b/framework-plugins/lisk-framework-report-misbehavior-plugin/src/endpoint.ts @@ -20,7 +20,10 @@ import { import { actionParamsSchema } from './schemas'; import { ReportMisbehaviorPluginConfig, State } from './types'; -const { validator} = liskValidator; +// disabled for type annotation +// eslint-disable-next-line prefer-destructuring +const validator: liskValidator.LiskValidator = liskValidator.validator; + const { encrypt, address } = cryptography; export class Endpoint extends BasePluginEndpoint { From 28c44f508f23c9ec2069e12fb84a81313f59e2f0 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 18:07:03 +0300 Subject: [PATCH 30/39] fix - import should occur before import of `./constants` --- elements/lisk-chain/src/block_header.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elements/lisk-chain/src/block_header.ts b/elements/lisk-chain/src/block_header.ts index e91a555bbe4..3da1ef51bce 100644 --- a/elements/lisk-chain/src/block_header.ts +++ b/elements/lisk-chain/src/block_header.ts @@ -15,10 +15,10 @@ import { ed, utils } from '@liskhq/lisk-cryptography'; import { codec } from '@liskhq/lisk-codec'; import { validator, LiskValidationError } from '@liskhq/lisk-validator'; +import { LiskErrorObject } from '@liskhq/lisk-validator/dist-node/types'; import { EMPTY_BUFFER, EMPTY_HASH, SIGNATURE_LENGTH_BYTES, TAG_BLOCK_HEADER } from './constants'; import { blockHeaderSchema, blockHeaderSchemaWithId, signingBlockHeaderSchema } from './schema'; import { JSONObject } from './types'; -import {LiskErrorObject} from "@liskhq/lisk-validator/dist-node/types"; export interface BlockHeaderAttrs { readonly version: number; @@ -189,7 +189,7 @@ export class BlockHeader { const header = this._getBlockHeaderProps(); validator.validate(blockHeaderSchema, header); - const errors: LiskErrorObject[] = [] + const errors: LiskErrorObject[] = []; if (header.previousBlockID.length !== 32) { errors.push({ From b45a93761e8f81f21eec93ad42b9c4add42b848e Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 18:55:57 +0300 Subject: [PATCH 31/39] fix - `error Unsafe assignment of an any value @typescript-eslint/no-unsafe-assignment` --- .../src/engine/consensus/network_endpoint.ts | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/framework/src/engine/consensus/network_endpoint.ts b/framework/src/engine/consensus/network_endpoint.ts index a0757179067..4186fb77904 100644 --- a/framework/src/engine/consensus/network_endpoint.ts +++ b/framework/src/engine/consensus/network_endpoint.ts @@ -103,7 +103,7 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { } catch (error) { this._logger.warn( { - err: error, + err: error as Error, req: data, peerID: peerId, }, @@ -150,26 +150,23 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { data as never, ); - const logDataAndApplyPenalty = (data? : unknown) => { - this._logger.warn( - data, - 'getHighestCommonBlock request validation failed', - ); + const logDataAndApplyPenalty = (errData?: unknown) => { + this._logger.warn(errData, 'getHighestCommonBlock request validation failed'); this._network.applyPenaltyOnPeer({ peerId, penalty: 100, }); - } + }; try { - validator.validate(getHighestCommonBlockRequestSchema, blockIds); - } catch (err) { - logDataAndApplyPenalty({ err, req: data}) - throw err; + validator.validate(getHighestCommonBlockRequestSchema, blockIds); + } catch (error) { + logDataAndApplyPenalty({ err: error as Error, req: data }); + throw error; } if (!objects.bufferArrayUniqueItems(blockIds.ids)) { - logDataAndApplyPenalty({ req: data}); + logDataAndApplyPenalty({ req: data }); } const commonBlockHeaderID = await this._chain.dataAccess.getHighestCommonBlockID(blockIds.ids); From c6a79b3eb70740144cc63d10a957d27440c13693 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 19:20:28 +0300 Subject: [PATCH 32/39] fix - `error Unsafe assignment of an any value @typescript-eslint/no-unsafe-assignment` --- framework/src/engine/generator/network_endpoint.ts | 12 ++++++------ .../modules/auth/commands/register_multisignature.ts | 4 ++-- .../dpos_v2/commands/delegate_registration.ts | 4 ++-- framework/src/modules/dpos_v2/commands/pom.ts | 5 ++--- .../modules/dpos_v2/commands/update_generator_key.ts | 4 ++-- framework/src/modules/dpos_v2/commands/vote.ts | 2 +- .../interoperability/mainchain/commands/cc_update.ts | 2 +- .../mainchain/commands/sidechain_registration.ts | 4 ++-- .../mainchain/commands/state_recovery.ts | 4 ++-- .../interoperability/sidechain/commands/cc_update.ts | 2 +- .../sidechain/commands/mainchain_registration.ts | 4 ++-- framework/src/modules/token/commands/cc_transfer.ts | 2 +- framework/src/modules/token/commands/transfer.ts | 2 +- 13 files changed, 25 insertions(+), 26 deletions(-) diff --git a/framework/src/engine/generator/network_endpoint.ts b/framework/src/engine/generator/network_endpoint.ts index 1190c55d14c..c9c2697618d 100644 --- a/framework/src/engine/generator/network_endpoint.ts +++ b/framework/src/engine/generator/network_endpoint.ts @@ -84,13 +84,13 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { try { validator.validate(getTransactionRequestSchema, decodedData); - } catch (err) { - this._logger.warn({ err, peerId }, 'Received invalid getTransactions body'); + } catch (error) { + this._logger.warn({ err: error as Error, peerId }, 'Received invalid getTransactions body'); this.network.applyPenaltyOnPeer({ peerId, penalty: 100, }); - throw err; + throw error; } if (!objectUtils.bufferArrayUniqueItems(decodedData.transactionIds)) { @@ -193,13 +193,13 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { try { validator.validate(postTransactionsAnnouncementSchema, decodedData); - } catch (err) { - this._logger.warn({ err, peerId }, 'Received invalid transactions body'); + } catch (error) { + this._logger.warn({ err: error as Error, peerId }, 'Received invalid transactions body'); this.network.applyPenaltyOnPeer({ peerId, penalty: 100, }); - throw err; + throw error; } this.event.emit(GENERATOR_EVENT_NEW_TRANSACTION_ANNOUNCEMENT, decodedData); diff --git a/framework/src/modules/auth/commands/register_multisignature.ts b/framework/src/modules/auth/commands/register_multisignature.ts index 258035bae8b..5e3b7c2a5bf 100644 --- a/framework/src/modules/auth/commands/register_multisignature.ts +++ b/framework/src/modules/auth/commands/register_multisignature.ts @@ -13,7 +13,7 @@ */ import { objects as objectUtils } from '@liskhq/lisk-utils'; -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BaseCommand } from '../..'; import { CommandExecuteContext, @@ -48,7 +48,7 @@ export class RegisterMultisignatureCommand extends BaseCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/dpos_v2/commands/delegate_registration.ts b/framework/src/modules/dpos_v2/commands/delegate_registration.ts index 5012c9d2241..84a1afdcfd0 100644 --- a/framework/src/modules/dpos_v2/commands/delegate_registration.ts +++ b/framework/src/modules/dpos_v2/commands/delegate_registration.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { CommandVerifyContext, VerificationResult, @@ -54,7 +54,7 @@ export class DelegateRegistrationCommand extends BaseCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/dpos_v2/commands/pom.ts b/framework/src/modules/dpos_v2/commands/pom.ts index b3072c94e60..c6fa8da3ca1 100644 --- a/framework/src/modules/dpos_v2/commands/pom.ts +++ b/framework/src/modules/dpos_v2/commands/pom.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { BlockHeader } from '@liskhq/lisk-chain'; import { CommandVerifyContext, @@ -62,13 +62,12 @@ export class ReportDelegateMisbehaviorCommand extends BaseCommand { public async verify( context: CommandVerifyContext, ): Promise { - try { validator.validate(this.schema, context.params); } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/dpos_v2/commands/update_generator_key.ts b/framework/src/modules/dpos_v2/commands/update_generator_key.ts index 7066c67d8ce..20881826e35 100644 --- a/framework/src/modules/dpos_v2/commands/update_generator_key.ts +++ b/framework/src/modules/dpos_v2/commands/update_generator_key.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { CommandVerifyContext, VerificationResult, @@ -50,7 +50,7 @@ export class UpdateGeneratorKeyCommand extends BaseCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/dpos_v2/commands/vote.ts b/framework/src/modules/dpos_v2/commands/vote.ts index a467eb550df..435db34e745 100644 --- a/framework/src/modules/dpos_v2/commands/vote.ts +++ b/framework/src/modules/dpos_v2/commands/vote.ts @@ -69,7 +69,7 @@ export class VoteCommand extends BaseCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: new AggregateValidationError('Parameter is not valid.', err.toString()), + error: new AggregateValidationError('Parameter is not valid.', err), }; } diff --git a/framework/src/modules/interoperability/mainchain/commands/cc_update.ts b/framework/src/modules/interoperability/mainchain/commands/cc_update.ts index d2e054e168c..0ef146eb6d8 100644 --- a/framework/src/modules/interoperability/mainchain/commands/cc_update.ts +++ b/framework/src/modules/interoperability/mainchain/commands/cc_update.ts @@ -82,7 +82,7 @@ export class MainchainCCUpdateCommand extends BaseInteroperabilityCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/interoperability/mainchain/commands/sidechain_registration.ts b/framework/src/modules/interoperability/mainchain/commands/sidechain_registration.ts index 5c9fca838c2..0c7c49a5462 100644 --- a/framework/src/modules/interoperability/mainchain/commands/sidechain_registration.ts +++ b/framework/src/modules/interoperability/mainchain/commands/sidechain_registration.ts @@ -14,7 +14,7 @@ import { codec } from '@liskhq/lisk-codec'; import { utils } from '@liskhq/lisk-cryptography'; -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { MainchainInteroperabilityStore } from '../store'; import { BaseInteroperabilityCommand } from '../../base_interoperability_command'; import { @@ -71,7 +71,7 @@ export class SidechainRegistrationCommand extends BaseInteroperabilityCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/interoperability/mainchain/commands/state_recovery.ts b/framework/src/modules/interoperability/mainchain/commands/state_recovery.ts index 1b1cc600556..1be52cc0acb 100644 --- a/framework/src/modules/interoperability/mainchain/commands/state_recovery.ts +++ b/framework/src/modules/interoperability/mainchain/commands/state_recovery.ts @@ -14,7 +14,7 @@ import { sparseMerkleTree } from '@liskhq/lisk-tree'; import { utils } from '@liskhq/lisk-cryptography'; -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { MainchainInteroperabilityStore } from '../store'; import { BaseInteroperabilityCommand } from '../../base_interoperability_command'; import { @@ -50,7 +50,7 @@ export class StateRecoveryCommand extends BaseInteroperabilityCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/interoperability/sidechain/commands/cc_update.ts b/framework/src/modules/interoperability/sidechain/commands/cc_update.ts index d3cc9ad4d7e..d81288a1e6e 100644 --- a/framework/src/modules/interoperability/sidechain/commands/cc_update.ts +++ b/framework/src/modules/interoperability/sidechain/commands/cc_update.ts @@ -80,7 +80,7 @@ export class SidechainCCUpdateCommand extends BaseInteroperabilityCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/interoperability/sidechain/commands/mainchain_registration.ts b/framework/src/modules/interoperability/sidechain/commands/mainchain_registration.ts index 31bde8fcc6f..52c818a2da7 100644 --- a/framework/src/modules/interoperability/sidechain/commands/mainchain_registration.ts +++ b/framework/src/modules/interoperability/sidechain/commands/mainchain_registration.ts @@ -14,7 +14,7 @@ import { codec } from '@liskhq/lisk-codec'; import { utils, bls } from '@liskhq/lisk-cryptography'; -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { CCM_STATUS_OK, CHAIN_REGISTERED, @@ -79,7 +79,7 @@ export class MainchainRegistrationCommand extends BaseInteroperabilityCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } diff --git a/framework/src/modules/token/commands/cc_transfer.ts b/framework/src/modules/token/commands/cc_transfer.ts index b4ebdab011c..f95ad10454b 100644 --- a/framework/src/modules/token/commands/cc_transfer.ts +++ b/framework/src/modules/token/commands/cc_transfer.ts @@ -52,7 +52,7 @@ export class CCTransferCommand extends BaseCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } return { diff --git a/framework/src/modules/token/commands/transfer.ts b/framework/src/modules/token/commands/transfer.ts index 5eeff4b768f..3a190f25787 100644 --- a/framework/src/modules/token/commands/transfer.ts +++ b/framework/src/modules/token/commands/transfer.ts @@ -50,7 +50,7 @@ export class TransferCommand extends BaseCommand { } catch (err) { return { status: VerifyStatus.FAIL, - error: err, + error: err as Error, }; } return { From 323b64293659125e2f58274d4039882a1de6d9d1 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 19:42:21 +0300 Subject: [PATCH 33/39] yarn run format --- framework/src/application.ts | 2 +- framework/src/controller/jsonrpc/utils.ts | 2 +- framework/src/engine/generator/generator.ts | 5 ++++- framework/src/modules/random/endpoint.ts | 2 +- .../modules/token/cc_commands/cc_forward.ts | 1 - .../modules/dpos_v2/commands/vote.spec.ts | 12 +++++------ .../schema/application_config_schema.spec.ts | 20 ++++++++----------- 7 files changed, 21 insertions(+), 23 deletions(-) diff --git a/framework/src/application.ts b/framework/src/application.ts index f0d16077fe3..af8e332a999 100644 --- a/framework/src/application.ts +++ b/framework/src/application.ts @@ -19,7 +19,7 @@ import * as assert from 'assert'; import * as childProcess from 'child_process'; import { Block } from '@liskhq/lisk-chain'; import { Database, StateDB } from '@liskhq/lisk-db'; -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { objects, jobHandlers } from '@liskhq/lisk-utils'; import { APP_EVENT_SHUTDOWN, APP_EVENT_READY } from './constants'; import { diff --git a/framework/src/controller/jsonrpc/utils.ts b/framework/src/controller/jsonrpc/utils.ts index ab7d7fbd158..9b46275ce59 100644 --- a/framework/src/controller/jsonrpc/utils.ts +++ b/framework/src/controller/jsonrpc/utils.ts @@ -11,7 +11,7 @@ * * Removal or modification of this copyright notice is prohibited. */ -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { JSONRPCErrorObject, ID, diff --git a/framework/src/engine/generator/generator.ts b/framework/src/engine/generator/generator.ts index bd3526c2b48..fef37b77f2e 100644 --- a/framework/src/engine/generator/generator.ts +++ b/framework/src/engine/generator/generator.ts @@ -376,7 +376,10 @@ export class Generator { })) as unknown) as { data: Buffer; }; - const transactionResponse = codec.decode(getTransactionsResponseSchema, data); + const transactionResponse = codec.decode( + getTransactionsResponseSchema, + data, + ); validator.validate(getTransactionsResponseSchema, transactionResponse); diff --git a/framework/src/modules/random/endpoint.ts b/framework/src/modules/random/endpoint.ts index 3b866e2993a..a46b142b1be 100644 --- a/framework/src/modules/random/endpoint.ts +++ b/framework/src/modules/random/endpoint.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { ModuleEndpointContext } from '../../types'; import { BaseEndpoint } from '../base_endpoint'; import { STORE_PREFIX_RANDOM, EMPTY_KEY } from './constants'; diff --git a/framework/src/modules/token/cc_commands/cc_forward.ts b/framework/src/modules/token/cc_commands/cc_forward.ts index 1b85be78f26..bba59039611 100644 --- a/framework/src/modules/token/cc_commands/cc_forward.ts +++ b/framework/src/modules/token/cc_commands/cc_forward.ts @@ -61,7 +61,6 @@ export class CCForwardCommand extends BaseCCCommand { try { params = codec.decode(crossChainForwardMessageParams, ccm.params); validator.validate(crossChainTransferMessageParams, params); - } catch (error) { ctx.logger.debug({ err: error as Error }, 'Error verifying the params.'); if (ccm.status === CCM_STATUS_OK) { diff --git a/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts b/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts index 8dfb5d5fc6b..2721e6ae129 100644 --- a/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts +++ b/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts @@ -226,9 +226,9 @@ describe('VoteCommand', () => { }); it('should return errors', () => { - expect( - () => validator.validate(command.schema, transactionParamsDecoded) - ).toThrow('should pass "dataType" keyword validation') + expect(() => validator.validate(command.schema, transactionParamsDecoded)).toThrow( + 'should pass "dataType" keyword validation', + ); }); }); @@ -245,9 +245,9 @@ describe('VoteCommand', () => { }); it('should return errors', () => { - expect( - () => validator.validate(command.schema, transactionParamsDecoded) - ).toThrow('should pass "dataType" keyword validation') + expect(() => validator.validate(command.schema, transactionParamsDecoded)).toThrow( + 'should pass "dataType" keyword validation', + ); }); }); }); diff --git a/framework/test/unit/schema/application_config_schema.spec.ts b/framework/test/unit/schema/application_config_schema.spec.ts index a415a4c24e9..7f8c6d2afb4 100644 --- a/framework/test/unit/schema/application_config_schema.spec.ts +++ b/framework/test/unit/schema/application_config_schema.spec.ts @@ -22,35 +22,31 @@ describe('schema/application_config_schema.js', () => { }); it('should validate the defined schema', () => { - expect( - () => validator.validateSchema(applicationConfigSchema) - ).not.toThrow() + expect(() => validator.validateSchema(applicationConfigSchema)).not.toThrow(); }); it('should validate if module properties are objects', () => { const config = objects.cloneDeep(applicationConfigSchema.default); config.genesis.modules = { myModule: { myProp: 1 } }; - expect( - () => validator.validate(applicationConfigSchema, config) - ).not.toThrow() + expect(() => validator.validate(applicationConfigSchema, config)).not.toThrow(); }); it('should not validate if module properties are not objects', () => { const config = objects.cloneDeep(applicationConfigSchema.default); config.genesis.modules = { myModule: 10 }; - expect( - () => validator.validate(applicationConfigSchema, config) - ).toThrow("Property '.genesis.modules.myModule' should be of type 'object'") + expect(() => validator.validate(applicationConfigSchema, config)).toThrow( + "Property '.genesis.modules.myModule' should be of type 'object'", + ); }); it('should not validate if module properties are not valid format', () => { const config = objects.cloneDeep(applicationConfigSchema.default); config.genesis.modules = { 'my-custom-module': { myProp: 1 } }; - expect( - () => validator.validate(applicationConfigSchema, config) - ).toThrow("must match pattern \"^[a-zA-Z][a-zA-Z0-9_]*$\"\nproperty name must be valid") + expect(() => validator.validate(applicationConfigSchema, config)).toThrow( + 'must match pattern "^[a-zA-Z][a-zA-Z0-9_]*$"\nproperty name must be valid', + ); }); }); From c262f9bf2936945dc00a44a6d5dfaf8a802e664e Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 20:10:12 +0300 Subject: [PATCH 34/39] yarn run format & some eslint fixes --- elements/lisk-chain/src/block_assets.ts | 2 +- elements/lisk-chain/src/transaction.ts | 12 +- elements/lisk-codec/src/codec.ts | 5 +- elements/lisk-p2p/src/utils/validate.ts | 3 +- elements/lisk-transactions/src/validate.ts | 5 +- elements/lisk-validator/src/errors.ts | 2 +- .../test/lisk_validator_errors.spec.ts | 12 +- .../test/lisk_validator_formats.spec.ts | 55 +-- .../test/lisk_validator_keywords.spec.ts | 345 ++++++++++-------- .../cc_commands/registration.spec.ts | 20 +- .../cc_commands/sidechain_terminated.spec.ts | 10 +- .../mainchain/commands/cc_update.spec.ts | 7 +- .../cc_commands/registration.spec.ts | 16 +- .../cc_commands/sidechain_terminated.spec.ts | 10 +- .../interoperability/sidechain/store.spec.ts | 4 +- .../modules/interoperability/store.spec.ts | 20 +- .../modules/interoperability/utils.spec.ts | 4 +- 17 files changed, 284 insertions(+), 248 deletions(-) diff --git a/elements/lisk-chain/src/block_assets.ts b/elements/lisk-chain/src/block_assets.ts index c0fe3193a3f..83dfac9260c 100644 --- a/elements/lisk-chain/src/block_assets.ts +++ b/elements/lisk-chain/src/block_assets.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { validator} from '@liskhq/lisk-validator'; +import { validator } from '@liskhq/lisk-validator'; import { codec } from '@liskhq/lisk-codec'; import { MerkleTree } from '@liskhq/lisk-tree'; import { blockAssetSchema } from './schema'; diff --git a/elements/lisk-chain/src/transaction.ts b/elements/lisk-chain/src/transaction.ts index c436a00a6a3..007b59300f9 100644 --- a/elements/lisk-chain/src/transaction.ts +++ b/elements/lisk-chain/src/transaction.ts @@ -13,8 +13,8 @@ */ import { codec } from '@liskhq/lisk-codec'; -import { utils, address, ed } from '@liskhq/lisk-cryptography'; -import { validator} from '@liskhq/lisk-validator'; +import { address, ed, utils } from '@liskhq/lisk-cryptography'; +import { validator } from '@liskhq/lisk-validator'; import { TAG_TRANSACTION } from './constants'; import { JSONObject } from './types'; @@ -130,18 +130,14 @@ export class Transaction { } public getBytes(): Buffer { - const transactionBytes = codec.encode(transactionSchema, this as Record); - - return transactionBytes; + return codec.encode(transactionSchema, this as Record); } public getSigningBytes(): Buffer { - const transactionBytes = codec.encode(transactionSchema, ({ + return codec.encode(transactionSchema, ({ ...this, signatures: [], } as unknown) as Record); - - return transactionBytes; } public sign(networkIdentifier: Buffer, privateKey: Buffer): void { diff --git a/elements/lisk-codec/src/codec.ts b/elements/lisk-codec/src/codec.ts index 2044e8f8381..e8871ddca8a 100644 --- a/elements/lisk-codec/src/codec.ts +++ b/elements/lisk-codec/src/codec.ts @@ -12,10 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import { - validator, - liskSchemaIdentifier, -} from '@liskhq/lisk-validator'; +import { validator, liskSchemaIdentifier } from '@liskhq/lisk-validator'; import { objects as objectUtils } from '@liskhq/lisk-utils'; import { generateKey } from './utils'; import { readObject, writeObject } from './collection'; diff --git a/elements/lisk-p2p/src/utils/validate.ts b/elements/lisk-p2p/src/utils/validate.ts index 6f097817534..d5d6f31487b 100644 --- a/elements/lisk-p2p/src/utils/validate.ts +++ b/elements/lisk-p2p/src/utils/validate.ts @@ -148,7 +148,7 @@ export const validatePeerInfoList = ( export const validateRPCRequest = (request: unknown): void => { try { validator.validate(rpcRequestSchema, request as Record); - } catch { + } catch { throw new Error('RPC request format is invalid.'); } }; @@ -159,7 +159,6 @@ export const validateProtocolMessage = (message: unknown): void => { } catch { throw new Error('Protocol message format is invalid.'); } - }; export const validatePacket = (packet: unknown): void => { diff --git a/elements/lisk-transactions/src/validate.ts b/elements/lisk-transactions/src/validate.ts index 00d3a3aff14..694ab0671ae 100644 --- a/elements/lisk-transactions/src/validate.ts +++ b/elements/lisk-transactions/src/validate.ts @@ -24,10 +24,7 @@ export const validateTransaction = ( ...transactionObject, params: Buffer.alloc(0), }; - validator.validate( - baseTransactionSchema, - transactionObjectWithEmptyParameters, - ); + validator.validate(baseTransactionSchema, transactionObjectWithEmptyParameters); if (!paramsSchema) { return undefined; diff --git a/elements/lisk-validator/src/errors.ts b/elements/lisk-validator/src/errors.ts index 3237bb4a6b2..d7a26e97ddb 100644 --- a/elements/lisk-validator/src/errors.ts +++ b/elements/lisk-validator/src/errors.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. */ -import {LiskErrorObject} from './types'; +import { LiskErrorObject } from './types'; // Ajv.ErrorObject makes `schemaPath` and `dataPath` required // While these are not if we want to infer default values from validation diff --git a/elements/lisk-validator/test/lisk_validator_errors.spec.ts b/elements/lisk-validator/test/lisk_validator_errors.spec.ts index 6855fd95f60..07021bd7c74 100644 --- a/elements/lisk-validator/test/lisk_validator_errors.spec.ts +++ b/elements/lisk-validator/test/lisk_validator_errors.spec.ts @@ -44,7 +44,7 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nProperty '.myProp' should be of type 'string'"; - expect(() => validator.validate(schema, obj)).toThrow(expectedError) + expect(() => validator.validate(schema, obj)).toThrow(expectedError); }); it('should format minLength errors', () => { @@ -56,7 +56,7 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have fewer than 2 characters"; - expect(() => validator.validate(schema, obj)).toThrow(expectedError) + expect(() => validator.validate(schema, obj)).toThrow(expectedError); }); it('should format maxLength errors', () => { @@ -68,7 +68,7 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have more than 5 characters"; - expect(() => validator.validate(schema, obj)).toThrow(expectedError) + expect(() => validator.validate(schema, obj)).toThrow(expectedError); }); it('should format custom format errors', () => { @@ -80,7 +80,7 @@ describe('LiskValidationError formatter', () => { const expectedError = 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' must match format "hex"'; - expect(() => validator.validate(schema, obj)).toThrow(expectedError) + expect(() => validator.validate(schema, obj)).toThrow(expectedError); }); it('should format missing required property errors', () => { @@ -89,7 +89,7 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nMissing property, must have required property 'myProp'"; - expect(() => validator.validate(schema, obj)).toThrow(expectedError) + expect(() => validator.validate(schema, obj)).toThrow(expectedError); }); it('should format additional property errors', () => { @@ -120,6 +120,6 @@ describe('LiskValidationError formatter', () => { const expectedError = "Lisk validator found 1 error[s]:\nProperty '.myProp' has extraneous property 'bar'"; - expect(() => validator.validate(schema, obj)).toThrow(expectedError) + expect(() => validator.validate(schema, obj)).toThrow(expectedError); }); }); diff --git a/elements/lisk-validator/test/lisk_validator_formats.spec.ts b/elements/lisk-validator/test/lisk_validator_formats.spec.ts index 87a521d17d0..6ea12f032a4 100644 --- a/elements/lisk-validator/test/lisk_validator_formats.spec.ts +++ b/elements/lisk-validator/test/lisk_validator_formats.spec.ts @@ -44,17 +44,20 @@ describe('validator formats', () => { }); it('should validate to true when valid hex string is provided', () => { - expect( - () => validator.validate(schema, { target: '23b9ed818526a928bce91b96fb4508babb121ee2' }) - ).not.toThrow() + expect(() => + validator.validate(schema, { target: '23b9ed818526a928bce91b96fb4508babb121ee2' }), + ).not.toThrow(); }); it('should validate to false when not hex is provided', () => { - const expectedError = "Lisk validator found 1 error[s]:\nProperty '.target' must match format \"hex\""; + const expectedError = + 'Lisk validator found 1 error[s]:\nProperty \'.target\' must match format "hex"'; - expect(() => validator.validate(schema, { - target: 'notValid?!hex-!!@', - })).toThrow(expectedError) + expect(() => + validator.validate(schema, { + target: 'notValid?!hex-!!@', + }), + ).toThrow(expectedError); }); }); @@ -69,7 +72,9 @@ describe('validator formats', () => { }; it('should validate to false for invalid path', () => { - expect(() => validator.validate(pathSchema, { rootPath: 'lisk' })).toThrow("Property '.rootPath' must match format \"path\"") + expect(() => validator.validate(pathSchema, { rootPath: 'lisk' })).toThrow( + 'Property \'.rootPath\' must match format "path"', + ); }); it('should validate to true for valid path with tilde', () => { @@ -93,15 +98,15 @@ describe('validator formats', () => { it('should validate to false for invalid path', () => { const expectedError = - "Lisk validator found 1 error[s]:\nProperty '.encryptedPassphrase' must match format \"encryptedPassphrase\""; + 'Lisk validator found 1 error[s]:\nProperty \'.encryptedPassphrase\' must match format "encryptedPassphrase"'; [ 'cipherText', 'cipherText=', 'cipherText=abcd1234&iterations=10000&iv=ef012345cipherText=abcd1234&iterations=10000&iv=ef012345', ].forEach(text => { - expect( - () => validator.validate(encryptedPassphraseSchema, { + expect(() => + validator.validate(encryptedPassphraseSchema, { encryptedPassphrase: text, }), ).toThrow(expectedError); @@ -110,8 +115,8 @@ describe('validator formats', () => { it('should validate to true for valid encrypted passphrase', () => { ['cipherText=abcd1234', 'cipherText=abcd1234&iterations=10000&iv=ef012345'].forEach(text => { - expect( - () => validator.validate(encryptedPassphraseSchema, { + expect(() => + validator.validate(encryptedPassphraseSchema, { encryptedPassphrase: text, }), ).not.toThrow(); @@ -130,19 +135,20 @@ describe('validator formats', () => { }; it('should validate to false for invalid camel case text', () => { - const expectedError = "Lisk validator found 1 error[s]:\nProperty '.camelCaseRegex' must match format \"camelCase\""; + const expectedError = + 'Lisk validator found 1 error[s]:\nProperty \'.camelCaseRegex\' must match format "camelCase"'; ['NotCamelCase', '123Case', '_camelCase'].forEach(text => { - expect( - () => validator.validate(camelCaseRegexSchema, { camelCaseRegex: text }) - ).toThrow(expectedError); + expect(() => validator.validate(camelCaseRegexSchema, { camelCaseRegex: text })).toThrow( + expectedError, + ); }); }); it('should validate to true for valid camel case text', () => { ['camelCase'].forEach(text => { - expect( - () => validator.validate(camelCaseRegexSchema, { camelCaseRegex: text }) + expect(() => + validator.validate(camelCaseRegexSchema, { camelCaseRegex: text }), ).not.toThrow(); }); }); @@ -159,20 +165,17 @@ describe('validator formats', () => { }; it('should validate to false for invalid semantic versions', () => { - const expectedError = "Lisk validator found 1 error[s]:\nProperty '.version' must match format \"version\""; + const expectedError = + 'Lisk validator found 1 error[s]:\nProperty \'.version\' must match format "version"'; ['9999999999999999.4.7.4', 'alpha one', '1.2.12.102', '4.6.3.9.2-alpha2'].forEach(text => { - expect( - () =>validator.validate(versionSchema, { version: text }) - ).toThrow(expectedError); + expect(() => validator.validate(versionSchema, { version: text })).toThrow(expectedError); }); }); it('should validate to true for valid semantic versions', () => { ['1.2.0', '1.0.0-alpha.0', 'v1.2.3', '1.0.0-beta+exp.sha.5114f85'].forEach(text => { - expect( - () =>validator.validate(versionSchema, { version: text }) - ).not.toThrow() + expect(() => validator.validate(versionSchema, { version: text })).not.toThrow(); }); }); }); diff --git a/elements/lisk-validator/test/lisk_validator_keywords.spec.ts b/elements/lisk-validator/test/lisk_validator_keywords.spec.ts index 10e3d32d98e..775d8f17156 100644 --- a/elements/lisk-validator/test/lisk_validator_keywords.spec.ts +++ b/elements/lisk-validator/test/lisk_validator_keywords.spec.ts @@ -12,7 +12,7 @@ * Removal or modification of this copyright notice is prohibited. * */ -import {LiskValidationError, validator} from '../src'; +import { LiskValidationError, validator } from '../src'; // eslint-disable-next-line @typescript-eslint/no-var-requires const cloneDeep = require('lodash.clonedeep'); @@ -85,330 +85,373 @@ describe('validator keywords', () => { describe('dataType value validation', () => { describe('string', () => { it('should not throw error if valid', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'string', fieldNumber: 1}}, + properties: { myProp: { dataType: 'string', fieldNumber: 1 } }, }, - {myProp: 'string'}, - ) + { myProp: 'string' }, + ), ).not.toThrow(); }); it('should be invalid if minLength is not satisfied', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, properties: { - myProp: {dataType: 'string', fieldNumber: 1, minLength: 3}, + myProp: { dataType: 'string', fieldNumber: 1, minLength: 3 }, }, }, - {myProp: 'ch'}, - )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have fewer than 3 characters"); + { myProp: 'ch' }, + ), + ).toThrow( + "Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have fewer than 3 characters", + ); }); it('should be invalid if maxLength is not satisfied', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, properties: { - myProp: {dataType: 'string', fieldNumber: 1, maxLength: 3}, + myProp: { dataType: 'string', fieldNumber: 1, maxLength: 3 }, }, }, - {myProp: 'change'}, - )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have more than 3 characters"); + { myProp: 'change' }, + ), + ).toThrow( + "Lisk validator found 1 error[s]:\nProperty '.myProp' must NOT have more than 3 characters", + ); }); it('should be invalid if not string', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, properties: { - myProp: {dataType: 'string', fieldNumber: 1, maxLength: 3}, + myProp: { dataType: 'string', fieldNumber: 1, maxLength: 3 }, }, }, - {myProp: 32}, - )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation") + { myProp: 32 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); }); describe('bytes', () => { it('should not throw error if valid', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'bytes', fieldNumber: 1}}, + properties: { myProp: { dataType: 'bytes', fieldNumber: 1 } }, }, - {myProp: Buffer.from('value')}, - )).not.toThrow() + { myProp: Buffer.from('value') }, + ), + ).not.toThrow(); }); it('should be invalid if minLength is not satisfied', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, properties: { - myProp: {dataType: 'bytes', fieldNumber: 1, minLength: 10}, + myProp: { dataType: 'bytes', fieldNumber: 1, minLength: 10 }, }, }, - {myProp: Buffer.alloc(9)}, - )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' minLength not satisfied") + { myProp: Buffer.alloc(9) }, + ), + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' minLength not satisfied"); }); it('should be invalid if maxLength is not satisfied', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, properties: { - myProp: {dataType: 'bytes', fieldNumber: 1, maxLength: 10}, + myProp: { dataType: 'bytes', fieldNumber: 1, maxLength: 10 }, }, }, - {myProp: Buffer.alloc(11)}, - )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' maxLength exceeded") + { myProp: Buffer.alloc(11) }, + ), + ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' maxLength exceeded"); }); it('should be invalid if not Buffer', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, properties: { - myProp: {dataType: 'bytes', fieldNumber: 1, maxLength: 10}, + myProp: { dataType: 'bytes', fieldNumber: 1, maxLength: 10 }, }, }, - {myProp: 'string'}, - )).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation") + { myProp: 'string' }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); }); describe('boolean', () => { it('should not throw error if valid', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'boolean', fieldNumber: 1}}, + properties: { myProp: { dataType: 'boolean', fieldNumber: 1 } }, }, - {myProp: true}, - )).not.toThrow() + { myProp: true }, + ), + ).not.toThrow(); }); it('should be invalid if not boolean', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'boolean', fieldNumber: 1}}, + properties: { myProp: { dataType: 'boolean', fieldNumber: 1 } }, }, - {myProp: 1} - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation") + { myProp: 1 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); }); describe('uint32', () => { it('should not throw error if valid', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, }, - {myProp: 0}, - )).not.toThrow(); + { myProp: 0 }, + ), + ).not.toThrow(); }); it('should be invalid if not number', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, }, - {myProp: 'value'}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: 'value' }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); it('should be invalid if number has decimal', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, }, - {myProp: 1.23}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: 1.23 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); it('should be invalid if negative', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, }, - {myProp: -1}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: -1 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); it('should be invalid if above uint32 range', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint32', fieldNumber: 1 } }, }, - {myProp: 4294967296}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: 4294967296 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); }); describe('uint64', () => { it('should not throw error if valid', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint64', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint64', fieldNumber: 1 } }, }, - {myProp: BigInt(32)}, - ) + { myProp: BigInt(32) }, + ), ).not.toThrow(); }); it('should be invalid if not bigint', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint64', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint64', fieldNumber: 1 } }, }, - {myProp: 32}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: 32 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); it('should be invalid if negative', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint64', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint64', fieldNumber: 1 } }, }, - {myProp: BigInt(-32)}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: BigInt(-32) }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); it('should be invalid if above uint64 range', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'uint64', fieldNumber: 1}}, + properties: { myProp: { dataType: 'uint64', fieldNumber: 1 } }, }, - {myProp: BigInt('18446744073709551616')}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: BigInt('18446744073709551616') }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); }); describe('sint32', () => { it('should not throw error if valid', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'sint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'sint32', fieldNumber: 1 } }, }, - {myProp: -32}, - ) + { myProp: -32 }, + ), ).not.toThrow(); }); it('should be invalid if not number', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'sint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'sint32', fieldNumber: 1 } }, }, - {myProp: 'value'}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: 'value' }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); it('should be invalid if number has decimal', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'sint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'sint32', fieldNumber: 1 } }, }, - {myProp: -1.23}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: -1.23 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); it('should be invalid if not sint32 range', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'sint32', fieldNumber: 1}}, + properties: { myProp: { dataType: 'sint32', fieldNumber: 1 } }, }, - {myProp: -2147483649}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + { myProp: -2147483649 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); }); describe('sint64', () => { it('should not throw error if valid', () => { - expect( - () => validator.validate( + expect(() => + validator.validate( { ...validSchema, - properties: {myProp: {dataType: 'sint64', fieldNumber: 1}}, + properties: { myProp: { dataType: 'sint64', fieldNumber: 1 } }, }, - {myProp: BigInt(-32)}, - ) - ).not.toThrow() + { myProp: BigInt(-32) }, + ), + ).not.toThrow(); }); it('should be invalid if not bigint', () => { - expect( - () => validator.validate( - { - ...validSchema, - properties: {myProp: {dataType: 'sint64', fieldNumber: 1}}, - }, - {myProp: 32}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + expect(() => + validator.validate( + { + ...validSchema, + properties: { myProp: { dataType: 'sint64', fieldNumber: 1 } }, + }, + { myProp: 32 }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); it('should be invalid if above sint64 range', () => { - expect( - () => validator.validate( - { - ...validSchema, - properties: {myProp: {dataType: 'sint64', fieldNumber: 1}}, - }, - {myProp: BigInt('-9223372036854775809')}, - ) - ).toThrow("Lisk validator found 1 error[s]:\nProperty '.myProp' should pass \"dataType\" keyword validation"); + expect(() => + validator.validate( + { + ...validSchema, + properties: { myProp: { dataType: 'sint64', fieldNumber: 1 } }, + }, + { myProp: BigInt('-9223372036854775809') }, + ), + ).toThrow( + 'Lisk validator found 1 error[s]:\nProperty \'.myProp\' should pass "dataType" keyword validation', + ); }); }); }); diff --git a/framework/test/unit/modules/interoperability/mainchain/cc_commands/registration.spec.ts b/framework/test/unit/modules/interoperability/mainchain/cc_commands/registration.spec.ts index 218e7dda903..40412bfe7fa 100644 --- a/framework/test/unit/modules/interoperability/mainchain/cc_commands/registration.spec.ts +++ b/framework/test/unit/modules/interoperability/mainchain/cc_commands/registration.spec.ts @@ -14,7 +14,7 @@ import { codec } from '@liskhq/lisk-codec'; import { utils } from '@liskhq/lisk-cryptography'; -import { MainchainCCRegistrationCommand } from '../../../../../../src/modules/interoperability/mainchain/cc_commands/registration'; +import { MainchainCCRegistrationCommand } from '../../../../../../src/modules/interoperability/mainchain/cc_commands'; import { MainchainInteroperabilityStore } from '../../../../../../src/modules/interoperability/mainchain/store'; import { registrationCCMParamsSchema } from '../../../../../../src/modules/interoperability/schemas'; import { CCCommandExecuteContext } from '../../../../../../src/modules/interoperability/types'; @@ -138,7 +138,7 @@ describe('MainchainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -165,7 +165,7 @@ describe('MainchainCCRegistrationCommand', () => { await ccRegistrationCommand.execute({ ...sampleExecuteContext, ccm: invalidCCM }); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -183,7 +183,7 @@ describe('MainchainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -201,7 +201,7 @@ describe('MainchainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -236,7 +236,7 @@ describe('MainchainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -271,7 +271,7 @@ describe('MainchainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -293,7 +293,7 @@ describe('MainchainCCRegistrationCommand', () => { networkIdentifier: differentNetworkID, }); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -321,7 +321,7 @@ describe('MainchainCCRegistrationCommand', () => { await ccRegistrationCommand.execute({ ...sampleExecuteContext, ccm: invalidCCM }); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -339,6 +339,6 @@ describe('MainchainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(0); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(0); }); }); diff --git a/framework/test/unit/modules/interoperability/mainchain/cc_commands/sidechain_terminated.spec.ts b/framework/test/unit/modules/interoperability/mainchain/cc_commands/sidechain_terminated.spec.ts index 43a0e3b9ea3..94dcb28927c 100644 --- a/framework/test/unit/modules/interoperability/mainchain/cc_commands/sidechain_terminated.spec.ts +++ b/framework/test/unit/modules/interoperability/mainchain/cc_commands/sidechain_terminated.spec.ts @@ -15,7 +15,7 @@ import { codec } from '@liskhq/lisk-codec'; import { utils } from '@liskhq/lisk-cryptography'; import { MAINCHAIN_ID_BUFFER } from '../../../../../../src/modules/interoperability/constants'; -import { MainchainCCSidechainTerminatedCommand } from '../../../../../../src/modules/interoperability/mainchain/cc_commands/sidechain_terminated'; +import { MainchainCCSidechainTerminatedCommand } from '../../../../../../src/modules/interoperability/mainchain/cc_commands'; import { MainchainInteroperabilityStore } from '../../../../../../src/modules/interoperability/mainchain/store'; import { sidechainTerminatedCCMParamsSchema } from '../../../../../../src/modules/interoperability/schemas'; import { CCCommandExecuteContext } from '../../../../../../src/modules/interoperability/types'; @@ -100,7 +100,7 @@ describe('MainchainCCSidechainTerminatedCommand', () => { it('should call terminateChainInternal when sendingChainID !== MAINCHAIN_ID', async () => { await ccSidechainTerminatedCommand.execute(sampleExecuteContextNew); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccmNew.sendingChainID, expect.objectContaining({ @@ -114,15 +114,15 @@ describe('MainchainCCSidechainTerminatedCommand', () => { hasTerminatedStateAccountMock.mockResolvedValueOnce(true); await ccSidechainTerminatedCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(0); - expect(createTerminatedStateAccountMock).toBeCalledTimes(0); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(0); + expect(createTerminatedStateAccountMock).toHaveBeenCalledTimes(0); }); it('should create an entry for the chainID in the terminated account substore when an entry does not exist and sendingChainID === MAINCHAIN_ID', async () => { hasTerminatedStateAccountMock.mockResolvedValueOnce(false); await ccSidechainTerminatedCommand.execute(sampleExecuteContext); - expect(createTerminatedStateAccountMock).toBeCalledTimes(1); + expect(createTerminatedStateAccountMock).toHaveBeenCalledTimes(1); expect(createTerminatedStateAccountMock).toHaveBeenCalledWith( ccmSidechainTerminatedParams.chainID, ccmSidechainTerminatedParams.stateRoot, diff --git a/framework/test/unit/modules/interoperability/mainchain/commands/cc_update.spec.ts b/framework/test/unit/modules/interoperability/mainchain/commands/cc_update.spec.ts index 9eedc22bb96..3a743304d04 100644 --- a/framework/test/unit/modules/interoperability/mainchain/commands/cc_update.spec.ts +++ b/framework/test/unit/modules/interoperability/mainchain/commands/cc_update.spec.ts @@ -22,6 +22,7 @@ import { CommandVerifyContext, testing, VerifyStatus, + MainchainCCUpdateCommand, } from '../../../../../../src'; import { ActiveValidator, @@ -31,7 +32,7 @@ import { ChannelData, CrossChainUpdateTransactionParams, } from '../../../../../../src/modules/interoperability/types'; -import { MainchainCCUpdateCommand } from '../../../../../../src/modules/interoperability/mainchain/commands/cc_update'; + import { Certificate } from '../../../../../../src/engine/consensus/certificate_generation/types'; import { certificateSchema } from '../../../../../../src/engine/consensus/certificate_generation/schema'; import * as interopUtils from '../../../../../../src/modules/interoperability/utils'; @@ -149,7 +150,7 @@ describe('CrossChainUpdateCommand', () => { let activeValidatorsUpdate: ActiveValidator[]; let sortedActiveValidatorsUpdate: ActiveValidator[]; - beforeEach(async () => { + beforeEach(() => { activeValidatorsUpdate = [ { blsKey: cryptography.utils.getRandomBytes(48), bftWeight: BigInt(1) }, { blsKey: cryptography.utils.getRandomBytes(48), bftWeight: BigInt(3) }, @@ -390,7 +391,7 @@ describe('CrossChainUpdateCommand', () => { let partnerValidatorsDataVerify: ChainValidators; let activeValidatorsVerify: ActiveValidator[]; - beforeEach(async () => { + beforeEach(() => { activeValidatorsVerify = [...activeValidatorsUpdate]; blockHeader = { height: 25, diff --git a/framework/test/unit/modules/interoperability/sidechain/cc_commands/registration.spec.ts b/framework/test/unit/modules/interoperability/sidechain/cc_commands/registration.spec.ts index e89f71bf8cd..54e86bf683f 100644 --- a/framework/test/unit/modules/interoperability/sidechain/cc_commands/registration.spec.ts +++ b/framework/test/unit/modules/interoperability/sidechain/cc_commands/registration.spec.ts @@ -138,7 +138,7 @@ describe('SidechainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -165,7 +165,7 @@ describe('SidechainCCRegistrationCommand', () => { await ccRegistrationCommand.execute({ ...sampleExecuteContext, ccm: invalidCCM }); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -183,7 +183,7 @@ describe('SidechainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -201,7 +201,7 @@ describe('SidechainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -236,7 +236,7 @@ describe('SidechainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -271,7 +271,7 @@ describe('SidechainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -293,7 +293,7 @@ describe('SidechainCCRegistrationCommand', () => { networkIdentifier: differentNetworkID, }); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccm.sendingChainID, expect.objectContaining({ @@ -311,6 +311,6 @@ describe('SidechainCCRegistrationCommand', () => { await ccRegistrationCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(0); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(0); }); }); diff --git a/framework/test/unit/modules/interoperability/sidechain/cc_commands/sidechain_terminated.spec.ts b/framework/test/unit/modules/interoperability/sidechain/cc_commands/sidechain_terminated.spec.ts index 9ffdf366e18..c43cf3928ed 100644 --- a/framework/test/unit/modules/interoperability/sidechain/cc_commands/sidechain_terminated.spec.ts +++ b/framework/test/unit/modules/interoperability/sidechain/cc_commands/sidechain_terminated.spec.ts @@ -15,7 +15,7 @@ import { codec } from '@liskhq/lisk-codec'; import { utils } from '@liskhq/lisk-cryptography'; import { MAINCHAIN_ID_BUFFER } from '../../../../../../src/modules/interoperability/constants'; -import { SidechainCCSidechainTerminatedCommand } from '../../../../../../src/modules/interoperability/sidechain/cc_commands/sidechain_terminated'; +import { SidechainCCSidechainTerminatedCommand } from '../../../../../../src/modules/interoperability/sidechain/cc_commands'; import { SidechainInteroperabilityStore } from '../../../../../../src/modules/interoperability/sidechain/store'; import { sidechainTerminatedCCMParamsSchema } from '../../../../../../src/modules/interoperability/schemas'; import { CCCommandExecuteContext } from '../../../../../../src/modules/interoperability/types'; @@ -100,7 +100,7 @@ describe('SidechainCCSidechainTerminatedCommand', () => { it('should call terminateChainInternal when sendingChainID !== MAINCHAIN_ID', async () => { await ccSidechainTerminatedCommand.execute(sampleExecuteContextNew); - expect(terminateChainInternalMock).toBeCalledTimes(1); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(1); expect(terminateChainInternalMock).toHaveBeenCalledWith( ccmNew.sendingChainID, expect.objectContaining({ @@ -114,15 +114,15 @@ describe('SidechainCCSidechainTerminatedCommand', () => { hasTerminatedStateAccountMock.mockResolvedValueOnce(true); await ccSidechainTerminatedCommand.execute(sampleExecuteContext); - expect(terminateChainInternalMock).toBeCalledTimes(0); - expect(createTerminatedStateAccountMock).toBeCalledTimes(0); + expect(terminateChainInternalMock).toHaveBeenCalledTimes(0); + expect(createTerminatedStateAccountMock).toHaveBeenCalledTimes(0); }); it('should create an entry for the chainID in the terminated account substore when an entry does not exist and sendingChainID === MAINCHAIN_ID', async () => { hasTerminatedStateAccountMock.mockResolvedValueOnce(false); await ccSidechainTerminatedCommand.execute(sampleExecuteContext); - expect(createTerminatedStateAccountMock).toBeCalledTimes(1); + expect(createTerminatedStateAccountMock).toHaveBeenCalledTimes(1); expect(createTerminatedStateAccountMock).toHaveBeenCalledWith( ccmSidechainTerminatedParams.chainID, ccmSidechainTerminatedParams.stateRoot, diff --git a/framework/test/unit/modules/interoperability/sidechain/store.spec.ts b/framework/test/unit/modules/interoperability/sidechain/store.spec.ts index 8f24126ae94..2098d2b46d7 100644 --- a/framework/test/unit/modules/interoperability/sidechain/store.spec.ts +++ b/framework/test/unit/modules/interoperability/sidechain/store.spec.ts @@ -220,7 +220,7 @@ describe('Sidechain interoperability store', () => { await expect(sidechainInteropStoreLocal.sendInternal(sendInternalContext)).resolves.toEqual( true, ); - expect(sidechainInteropStoreLocal.getChainAccount).toBeCalledWith( + expect(sidechainInteropStoreLocal.getChainAccount).toHaveBeenCalledWith( getIDAsKeyForStore(MAINCHAIN_ID), ); }); @@ -247,7 +247,7 @@ describe('Sidechain interoperability store', () => { await expect(sidechainInteropStoreLocal.sendInternal(sendInternalContext)).resolves.toEqual( true, ); - expect(sidechainInteropStoreLocal.getChainAccount).toBeCalledWith(ccm.receivingChainID); + expect(sidechainInteropStoreLocal.getChainAccount).toHaveBeenCalledWith(ccm.receivingChainID); }); it('should return false if the receiving chain is not live', async () => { diff --git a/framework/test/unit/modules/interoperability/store.spec.ts b/framework/test/unit/modules/interoperability/store.spec.ts index 21f96845c4b..a3315a01434 100644 --- a/framework/test/unit/modules/interoperability/store.spec.ts +++ b/framework/test/unit/modules/interoperability/store.spec.ts @@ -452,7 +452,7 @@ describe('Base interoperability store', () => { trsSender: beforeApplyCCMContext.trsSender, }; - beforeEach(async () => { + beforeEach(() => { mainchainStoreLocal = new MainchainInteroperabilityStore( MODULE_ID_INTEROPERABILITY_BUFFER, mockGetStore, @@ -468,7 +468,7 @@ describe('Base interoperability store', () => { await expect( mainchainStoreLocal.apply(ccmApplyContext, ccCommandsMap), ).resolves.toBeUndefined(); - expect(ccAPIMod1.beforeApplyCCM).toBeCalledTimes(0); + expect(ccAPIMod1.beforeApplyCCM).toHaveBeenCalledTimes(0); }); it('should call all the interoperable beforeApplyCCM hooks', async () => { @@ -489,7 +489,7 @@ describe('Base interoperability store', () => { await expect( mainchainStoreLocal.apply(ccmApplyContext, ccCommandsMap), ).resolves.toBeUndefined(); - expect(ccAPISampleMod.beforeApplyCCM).toBeCalledTimes(1); + expect(ccAPISampleMod.beforeApplyCCM).toHaveBeenCalledTimes(1); expect(ccAPISampleMod.beforeApplyCCM).toHaveBeenCalledWith( expect.toContainAllKeys(Object.keys(beforeApplyCCMContext)), ); @@ -515,11 +515,11 @@ describe('Base interoperability store', () => { await expect( mainchainStoreLocal.apply(ccmApplyContext, localCCCommandsMap), ).resolves.toBeUndefined(); - expect(ccAPIMod1.beforeApplyCCM).toBeCalledTimes(1); + expect(ccAPIMod1.beforeApplyCCM).toHaveBeenCalledTimes(1); expect(ccAPIMod1.beforeApplyCCM).toHaveBeenCalledWith( expect.toContainAllKeys(Object.keys(beforeApplyCCMContext)), ); - expect(mainchainStoreLocal.sendInternal).toBeCalledTimes(1); + expect(mainchainStoreLocal.sendInternal).toHaveBeenCalledTimes(1); expect(mainchainStoreLocal.sendInternal).toHaveBeenCalledWith( expect.objectContaining({ status: CCM_STATUS_MODULE_NOT_SUPPORTED }), ); @@ -549,11 +549,11 @@ describe('Base interoperability store', () => { await expect( mainchainStoreLocal.apply(ccmApplyContext, localCCCommandsMap), ).resolves.toBeUndefined(); - expect(ccAPISampleMod.beforeApplyCCM).toBeCalledTimes(1); + expect(ccAPISampleMod.beforeApplyCCM).toHaveBeenCalledTimes(1); expect(ccAPISampleMod.beforeApplyCCM).toHaveBeenCalledWith( expect.toContainAllKeys(Object.keys(beforeApplyCCMContext)), ); - expect(mainchainStoreLocal.sendInternal).toBeCalledTimes(1); + expect(mainchainStoreLocal.sendInternal).toHaveBeenCalledTimes(1); expect(mainchainStoreLocal.sendInternal).toHaveBeenCalledWith( expect.objectContaining({ status: CCM_STATUS_CROSS_CHAIN_COMMAND_NOT_SUPPORTED }), ); @@ -580,12 +580,12 @@ describe('Base interoperability store', () => { await expect( mainchainStoreLocal.apply(ccmApplyContext, ccCommandsMap), ).resolves.toBeUndefined(); - expect(ccAPISampleMod.beforeApplyCCM).toBeCalledTimes(1); + expect(ccAPISampleMod.beforeApplyCCM).toHaveBeenCalledTimes(1); expect(ccAPISampleMod.beforeApplyCCM).toHaveBeenCalledWith( expect.objectContaining({ ccu: beforeApplyCCMContext.ccu }), ); - expect(mainchainStoreLocal.sendInternal).toBeCalledTimes(0); - expect(ccCommands[0].execute).toBeCalledTimes(1); + expect(mainchainStoreLocal.sendInternal).toHaveBeenCalledTimes(0); + expect(ccCommands[0].execute).toHaveBeenCalledTimes(1); expect(ccCommands[0].execute).toHaveBeenCalledWith( expect.objectContaining({ ccm: executeCCMContext.ccm }), ); diff --git a/framework/test/unit/modules/interoperability/utils.spec.ts b/framework/test/unit/modules/interoperability/utils.spec.ts index ac0c84989ff..e2449af9f3b 100644 --- a/framework/test/unit/modules/interoperability/utils.spec.ts +++ b/framework/test/unit/modules/interoperability/utils.spec.ts @@ -718,7 +718,7 @@ describe('Utils', () => { let newInboxAppendPath: Buffer[] = []; let newInboxSize = 0; - beforeEach(async () => { + beforeEach(() => { for (const ccm of defaultCCMsEncoded) { const { appendPath, size, root } = merkleTree.regularMerkleTree.calculateMerkleRoot({ value: ccm, @@ -942,7 +942,7 @@ describe('Utils', () => { let context: any; let calculateRootFromRightWitness: any; - beforeEach(async () => { + beforeEach(() => { activeValidatorsUpdate = [ { blsKey: cryptography.utils.getRandomBytes(48), bftWeight: BigInt(1) }, { blsKey: cryptography.utils.getRandomBytes(48), bftWeight: BigInt(3) }, From 3bd62b5464a50861bf07ee9fd22d210bb4780413 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 20:50:03 +0300 Subject: [PATCH 35/39] fix test case --- elements/lisk-transactions/test/validate.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/elements/lisk-transactions/test/validate.spec.ts b/elements/lisk-transactions/test/validate.spec.ts index a9b47e65adf..f440258049d 100644 --- a/elements/lisk-transactions/test/validate.spec.ts +++ b/elements/lisk-transactions/test/validate.spec.ts @@ -14,7 +14,7 @@ */ import { utils } from '@liskhq/lisk-cryptography'; -import { validateTransaction } from '../src/validate'; +import { validateTransaction } from '../src'; describe('validateTransaction', () => { // Arrange @@ -68,7 +68,7 @@ describe('validateTransaction', () => { { ...validTransaction, senderPublicKey: 1 }, ]; return invalidTransactionObjects.forEach(transactionObject => - expect(validateTransaction(validParamsSchema, transactionObject)).toBeInstanceOf(Error), + expect(() => validateTransaction(validParamsSchema, transactionObject)).toThrow(), ); }); @@ -87,7 +87,7 @@ describe('validateTransaction', () => { }, ]; return invalidParams.forEach(transactionObject => - expect(validateTransaction(transactionObject, validParamsSchema)).toBeInstanceOf(Error), + expect(() => validateTransaction(transactionObject, validParamsSchema)).toThrow(), ); }); From 25de40a161c904bbe1b9af32821dfc34e2f64496 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 21:26:03 +0300 Subject: [PATCH 36/39] fix - import can be shortened --- framework/test/unit/modules/dpos_v2/commands/vote.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts b/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts index 2721e6ae129..be0dc4d4b13 100644 --- a/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts +++ b/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts @@ -18,7 +18,7 @@ import { address, utils } from '@liskhq/lisk-cryptography'; import { InMemoryDatabase } from '@liskhq/lisk-db'; import { validator } from '@liskhq/lisk-validator'; import { when } from 'jest-when'; -import { VoteCommand } from '../../../../../src/modules/dpos_v2/commands/vote'; +import { VoteCommand, VerifyStatus } from '../../../../../src'; import { COMMAND_ID_VOTE, MAX_UNLOCKING, @@ -29,7 +29,7 @@ import { import { delegateStoreSchema, voterStoreSchema } from '../../../../../src/modules/dpos_v2/schemas'; import { DelegateAccount, VoteTransactionParams } from '../../../../../src/modules/dpos_v2/types'; import { getVoterOrDefault } from '../../../../../src/modules/dpos_v2/utils'; -import { VerifyStatus } from '../../../../../src/state_machine/types'; + import { createTransactionContext } from '../../../../../src/testing'; import { liskToBeddows } from '../../../../utils/assets'; import { DEFAULT_TOKEN_ID } from '../../../../utils/mocks/transaction'; From 200a5703b2b0137159658631e0d47decb2f8244e Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Thu, 28 Jul 2022 21:29:04 +0300 Subject: [PATCH 37/39] fix - broken tests --- framework/test/unit/modules/dpos_v2/commands/vote.spec.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts b/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts index be0dc4d4b13..69b99db1cc9 100644 --- a/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts +++ b/framework/test/unit/modules/dpos_v2/commands/vote.spec.ts @@ -179,8 +179,7 @@ describe('VoteCommand', () => { it('should return errors', async () => { const verificationResult = await command.verify(context); - expect((verificationResult.error as any).value).toHaveLength(1); - expect((verificationResult.error as any).value[0].message).toInclude( + expect((verificationResult.error as any).value.message).toInclude( 'must NOT have fewer than 1 items', ); }); @@ -206,8 +205,7 @@ describe('VoteCommand', () => { it('should return errors', async () => { const verificationResult = await command.verify(context); - expect((verificationResult.error as any).value).toHaveLength(1); - expect((verificationResult.error as any).value[0].message).toInclude( + expect((verificationResult.error as any).value.message).toInclude( 'must NOT have more than 20 items', ); }); From 0e80af9f696d626be3c637f4e464cbdb06cb3aa1 Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Fri, 29 Jul 2022 11:25:23 +0300 Subject: [PATCH 38/39] apply requested changes --- elements/lisk-chain/src/block_header.ts | 4 +++- elements/lisk-chain/src/transaction.ts | 4 +++- framework/src/engine/generator/network_endpoint.ts | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/elements/lisk-chain/src/block_header.ts b/elements/lisk-chain/src/block_header.ts index 3da1ef51bce..61820913ee8 100644 --- a/elements/lisk-chain/src/block_header.ts +++ b/elements/lisk-chain/src/block_header.ts @@ -302,7 +302,9 @@ export class BlockHeader { } public getSigningBytes(): Buffer { - return codec.encode(signingBlockHeaderSchema, this._getSigningProps()); + const blockHeaderBytes = codec.encode(signingBlockHeaderSchema, this._getSigningProps()); + + return blockHeaderBytes; } public sign(networkIdentifier: Buffer, privateKey: Buffer): void { diff --git a/elements/lisk-chain/src/transaction.ts b/elements/lisk-chain/src/transaction.ts index 007b59300f9..609318e4554 100644 --- a/elements/lisk-chain/src/transaction.ts +++ b/elements/lisk-chain/src/transaction.ts @@ -134,10 +134,12 @@ export class Transaction { } public getSigningBytes(): Buffer { - return codec.encode(transactionSchema, ({ + const transactionBytes = codec.encode(transactionSchema, ({ ...this, signatures: [], } as unknown) as Record); + + return transactionBytes; } public sign(networkIdentifier: Buffer, privateKey: Buffer): void { diff --git a/framework/src/engine/generator/network_endpoint.ts b/framework/src/engine/generator/network_endpoint.ts index c9c2697618d..cc6c1284141 100644 --- a/framework/src/engine/generator/network_endpoint.ts +++ b/framework/src/engine/generator/network_endpoint.ts @@ -99,6 +99,8 @@ export class NetworkEndpoint extends BaseNetworkEndpoint { peerId, penalty: 100, }); + + throw new Error('Received invalid getTransactions body'); } } From cddf7d211284df2f156156241177749646903a8b Mon Sep 17 00:00:00 2001 From: Khalid Hameed Date: Fri, 29 Jul 2022 20:45:14 +0300 Subject: [PATCH 39/39] fix errors after rebase/merge with `development` branch --- framework/src/modules/interoperability/utils.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/framework/src/modules/interoperability/utils.ts b/framework/src/modules/interoperability/utils.ts index 53a10a5ba0e..e987e399402 100644 --- a/framework/src/modules/interoperability/utils.ts +++ b/framework/src/modules/interoperability/utils.ts @@ -631,10 +631,7 @@ export const initGenesisStateUtil = async (id: Buffer, ctx: GenesisBlockExecuteC genesisInteroperabilityStoreSchema, assetBytes, ); - const errors = validator.validate(genesisInteroperabilityStoreSchema, genesisStore); - if (errors.length) { - throw new LiskValidationError(errors); - } + validator.validate(genesisInteroperabilityStoreSchema, genesisStore); const outboxRootStoreKeySet = new dataStructures.BufferSet(); const outboxRootStore = getStore(id, STORE_PREFIX_OUTBOX_ROOT);