Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Commit

Permalink
Merge pull request #7347 from LiskHQ/7156-update-lisk-validators
Browse files Browse the repository at this point in the history
Update lisk-validators to return single error and compatible type check - Closes #7156
  • Loading branch information
ishantiw authored Aug 1, 2022
2 parents e4b4fbc + cddf7d2 commit d26d0f4
Show file tree
Hide file tree
Showing 64 changed files with 640 additions and 806 deletions.
8 changes: 3 additions & 5 deletions commander/src/bootstrapping/commands/genesis-block/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down
8 changes: 2 additions & 6 deletions commander/src/bootstrapping/commands/transaction/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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.validate(schema.transaction, txObject);

const paramsObject = paramsSchema ? codec.fromJSON(paramsSchema, params) : {};

Expand Down
8 changes: 3 additions & 5 deletions elements/lisk-api-client/src/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -337,13 +337,11 @@ export class Transaction {
throw new Error('Transaction must be an object.');
}
const { params, ...rest } = transaction as Record<string, unknown>;
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.');
}
Expand Down
14 changes: 5 additions & 9 deletions elements/lisk-chain/src/block_assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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(
Expand All @@ -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.');
}
Expand Down
11 changes: 6 additions & 5 deletions elements/lisk-chain/src/block_header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
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';
Expand Down Expand Up @@ -174,10 +175,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.');
}
Expand All @@ -188,7 +187,9 @@ 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({
Expand Down
14 changes: 5 additions & 9 deletions elements/lisk-chain/src/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
*/

import { codec } from '@liskhq/lisk-codec';
import { utils, address, ed } from '@liskhq/lisk-cryptography';
import { validator, LiskValidationError } 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';

Expand Down Expand Up @@ -130,9 +130,7 @@ export class Transaction {
}

public getBytes(): Buffer {
const transactionBytes = codec.encode(transactionSchema, this as Record<string, unknown>);

return transactionBytes;
return codec.encode(transactionSchema, this as Record<string, unknown>);
}

public getSigningBytes(): Buffer {
Expand All @@ -155,10 +153,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');
}
Expand Down
14 changes: 2 additions & 12 deletions elements/lisk-codec/src/codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,7 @@
* Removal or modification of this copyright notice is prohibited.
*/

import {
ErrorObject,
LiskValidationError,
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';
Expand Down Expand Up @@ -60,12 +55,7 @@ export const validateSchema = (schema: {
$schema: schema.$schema ?? liskSchemaIdentifier,
};

const errors: ReadonlyArray<ErrorObject> = 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
Expand Down
18 changes: 9 additions & 9 deletions elements/lisk-p2p/src/utils/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,25 +146,25 @@ export const validatePeerInfoList = (
};

export const validateRPCRequest = (request: unknown): void => {
const errors = validator.validate(rpcRequestSchema, request as Record<string, unknown>);

if (errors.length) {
try {
validator.validate(rpcRequestSchema, request as Record<string, unknown>);
} catch {
throw new Error('RPC request format is invalid.');
}
};

export const validateProtocolMessage = (message: unknown): void => {
const errors = validator.validate(protocolMessageSchema, message as Record<string, unknown>);

if (errors.length) {
try {
validator.validate(protocolMessageSchema, message as Record<string, unknown>);
} 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.');
}
};
Expand Down
15 changes: 4 additions & 11 deletions elements/lisk-transactions/src/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,16 @@ export const validateTransaction = (
...transactionObject,
params: Buffer.alloc(0),
};
const schemaErrors = validator.validate(
baseTransactionSchema,
transactionObjectWithEmptyParameters,
);
if (schemaErrors.length) {
return new LiskValidationError([...schemaErrors]);
}
validator.validate(baseTransactionSchema, transactionObjectWithEmptyParameters);

if (!paramsSchema) {
return undefined;
}

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;
};
6 changes: 3 additions & 3 deletions elements/lisk-transactions/test/validate.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*/

import { utils } from '@liskhq/lisk-cryptography';
import { validateTransaction } from '../src/validate';
import { validateTransaction } from '../src';

describe('validateTransaction', () => {
// Arrange
Expand Down Expand Up @@ -68,7 +68,7 @@ describe('validateTransaction', () => {
{ ...validTransaction, senderPublicKey: 1 },
];
return invalidTransactionObjects.forEach(transactionObject =>
expect(validateTransaction(validParamsSchema, transactionObject)).toBeInstanceOf(Error),
expect(() => validateTransaction(validParamsSchema, transactionObject)).toThrow(),
);
});

Expand All @@ -87,7 +87,7 @@ describe('validateTransaction', () => {
},
];
return invalidParams.forEach(transactionObject =>
expect(validateTransaction(transactionObject, validParamsSchema)).toBeInstanceOf(Error),
expect(() => validateTransaction(transactionObject, validParamsSchema)).toThrow(),
);
});

Expand Down
3 changes: 1 addition & 2 deletions elements/lisk-validator/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
4 changes: 2 additions & 2 deletions elements/lisk-validator/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
20 changes: 10 additions & 10 deletions elements/lisk-validator/src/lisk_validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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() {
Expand Down Expand Up @@ -69,20 +69,20 @@ class LiskValidator {
this._validator.addKeyword(dataTypeKeyword);
}

public validate(schema: object, data: object): LiskErrorObject[] {
public validate<T = Record<string, unknown>>(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<LiskErrorObject> {
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 {
Expand Down
Loading

0 comments on commit d26d0f4

Please sign in to comment.