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

Commit

Permalink
Transaction schema validation now throws error instead of returning e…
Browse files Browse the repository at this point in the history
…rror
  • Loading branch information
bobanm committed Oct 19, 2023
1 parent f8ceee6 commit 05358df
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 44 deletions.
32 changes: 13 additions & 19 deletions elements/lisk-transactions/src/sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*
*/

import { codec, Schema } from '@liskhq/lisk-codec';
import { codec, emptySchema, Schema } from '@liskhq/lisk-codec';
import { utils, ed } from '@liskhq/lisk-cryptography';
import { validateTransaction } from './validate';
import { baseTransactionSchema } from './schema';
Expand All @@ -27,11 +27,11 @@ export interface MultiSignatureKeys {
readonly optionalKeys: Array<Buffer>;
}

const encodeParams = (transaction: Record<string, unknown>, paramsSchema?: object): Buffer => {
const validationErrors = validateTransaction(transaction, paramsSchema);
if (validationErrors) {
throw validationErrors;
}
const encodeParams = (
transaction: Record<string, unknown>,
paramsSchema = emptySchema as object,
): Buffer => {
validateTransaction(transaction, paramsSchema);

const hasParams =
typeof transaction.params === 'object' && transaction.params !== null && paramsSchema;
Expand Down Expand Up @@ -101,7 +101,7 @@ export const getBytes = (transaction: Record<string, unknown>, paramsSchema?: ob
* const signedTransaction = signTransaction(unsignedTrx, chainID, privateKey, paramsSchema);
* ```
*
* @param transactionObject The unsigned transaction object.
* @param transaction The unsigned transaction object.
* @param chainID The chain ID of the chain to which the transaction belongs.
* @param privateKey The private key of the sender of the transaction.
* @param paramsSchema The schema for the `params` of the transaction.
Expand All @@ -113,7 +113,7 @@ export const getBytes = (transaction: Record<string, unknown>, paramsSchema?: ob
* @see [LIP 0062 - Use pre-hashing for signatures](https://github.com/LiskHQ/lips/blob/main/proposals/lip-0062.md)
*/
export const signTransaction = (
transactionObject: Record<string, unknown>,
transaction: Record<string, unknown>,
chainID: Buffer,
privateKey: Buffer,
paramsSchema?: object,
Expand All @@ -126,21 +126,18 @@ export const signTransaction = (
throw new Error('Private key must be 64 bytes');
}

const validationErrors = validateTransaction(transactionObject, paramsSchema);
if (validationErrors) {
throw validationErrors;
}
validateTransaction(transaction, paramsSchema);

const signature = ed.signDataWithPrivateKey(
TAG_TRANSACTION,
chainID,
getSigningBytes(transactionObject, paramsSchema),
getSigningBytes(transaction, paramsSchema),
privateKey,
);

// eslint-disable-next-line no-param-reassign
transactionObject.signatures = [signature];
return { ...transactionObject, id: utils.hash(getBytes(transactionObject, paramsSchema)) };
transaction.signatures = [signature];
return { ...transaction, id: utils.hash(getBytes(transaction, paramsSchema)) };
};

/**
Expand Down Expand Up @@ -185,10 +182,7 @@ export const signMultiSignatureTransaction = (
throw new Error('Signatures must be of type array');
}

const validationErrors = validateTransaction(transactionObject, paramsSchema);
if (validationErrors) {
throw validationErrors;
}
validateTransaction(transactionObject, paramsSchema);

keys.mandatoryKeys.sort((publicKeyA, publicKeyB) => publicKeyA.compare(publicKeyB));
keys.optionalKeys.sort((publicKeyA, publicKeyB) => publicKeyA.compare(publicKeyB));
Expand Down
30 changes: 13 additions & 17 deletions elements/lisk-transactions/src/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
*
*/

import { LiskValidationError, validator } from '@liskhq/lisk-validator';
import { validator } from '@liskhq/lisk-validator';
import { emptySchema } from '@liskhq/lisk-codec';
import { baseTransactionSchema } from './schema';

/**
Expand All @@ -25,7 +26,7 @@ import { baseTransactionSchema } from './schema';
* const validation = validateTransaction(transaction, paramsSchema);
* ```
*
* @param transactionObject The transaction to validate.
* @param transaction The transaction to validate.
* @param paramsSchema The parameters schema for the transaction.
*
* @returns `undefined`, if the transaction is valid and no errors are found.
Expand All @@ -34,24 +35,19 @@ import { baseTransactionSchema } from './schema';
* @see [LIP 0062 - Use pre-hashing for signatures](https://github.com/LiskHQ/lips/blob/main/proposals/lip-0062.md)
* @see {@link @liskhq/lisk-validator!LiskValidator.validate}
*/

export const validateTransaction = (
transactionObject: Record<string, unknown>,
paramsSchema?: object,
): LiskValidationError | Error | undefined => {
const transactionObjectWithEmptyParameters = {
...transactionObject,
transaction: Record<string, unknown>,
paramsSchema = emptySchema as object,
) => {
const transactionWithEmptyParams = {
...transaction,
params: Buffer.alloc(0),
};
validator.validate(baseTransactionSchema, transactionObjectWithEmptyParameters);

if (!paramsSchema) {
return undefined;
}
validator.validate(baseTransactionSchema, transactionWithEmptyParams);

if (typeof transactionObject.params !== 'object' || transactionObject.params === null) {
return new Error('Transaction object params must be of type object and not null');
if (typeof transaction.params !== 'object' || transaction.params === null) {
throw new Error('Transaction object params must be of type object and not null');
}
validator.validate(paramsSchema, transactionObject.params);

return undefined;
validator.validate(paramsSchema, transaction.params);
};
2 changes: 1 addition & 1 deletion elements/lisk-transactions/test/sign.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ describe('sign', () => {

it('should return a signed transaction for an undefined params schema', () => {
const signedTransaction = signTransaction(
{ ...validTransaction, params: undefined },
{ ...validTransaction },
chainID,
privateKey,
undefined,
Expand Down
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 @@ -70,10 +70,10 @@ describe('validateTransaction', () => {
);
});

it('should return error when params is null', () => {
return expect(
it('should throw when params is null', () => {
return expect(() =>
validateTransaction({ ...validTransaction, params: null }, validParamsSchema),
).toEqual(new Error('Transaction object params must be of type object and not null'));
).toThrow('Transaction object params must be of type object and not null');
});

it('should return error for invalid params property', () => {
Expand Down
5 changes: 1 addition & 4 deletions framework/src/testing/create_transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,7 @@ export const createTransaction = ({
};

if (commandInstance.schema) {
const validationErrors = validateTransaction(transaction, commandInstance.schema);
if (validationErrors) {
throw validationErrors;
}
validateTransaction(transaction, commandInstance.schema);
}
const result = new Transaction({ ...transaction, params: paramsBytes });

Expand Down

0 comments on commit 05358df

Please sign in to comment.