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

Commit

Permalink
🌱 Add block asset validation
Browse files Browse the repository at this point in the history
- Expose registered module ids from state machine
- Check the size of data of an asset not exceeding the limit
- Check a module asset is not duplicated
- Check a module assets are sorted by id and are registered in state machine
  • Loading branch information
ishantiw committed Nov 3, 2021
1 parent 5f19cca commit 004e232
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 0 deletions.
22 changes: 22 additions & 0 deletions elements/lisk-chain/src/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import { codec } from '@liskhq/lisk-codec';
import { BlockAssets } from './block_assets';
import { BlockHeader } from './block_header';
import { MAX_ASSET_DATA_SIZE_BYTES } from './constants';
import { blockSchema } from './schema';
import { Transaction } from './transaction';

Expand Down Expand Up @@ -76,5 +77,26 @@ export class Block {
for (const tx of this.payload) {
tx.validate();
}

const assets = this.assets.getAllAssets();
let last = assets[0];
let i = 0;
for (const asset of assets) {
// 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(
`Module with ID ${asset.moduleID} has data size more than ${MAX_ASSET_DATA_SIZE_BYTES} bytes.`,
);
}
if (last.moduleID > asset.moduleID) {
throw new Error('Assets are not sorted in the increasing values of moduleID.');
}
// Check for duplicates
if (i > 0 && asset.moduleID === last.moduleID) {
throw new Error(`Module with ID ${assets[i].moduleID} has duplicate entries.`);
}
i += 1;
last = asset;
}
}
}
4 changes: 4 additions & 0 deletions elements/lisk-chain/src/block_assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ export class BlockAssets {
return this._assets.find(a => a.moduleID === moduleID)?.data;
}

public getAllAssets(): BlockAsset[] {
return [...this._assets];
}

public setAsset(moduleID: number, value: Buffer): void {
const asset = this.getAsset(moduleID);
if (asset) {
Expand Down
3 changes: 3 additions & 0 deletions elements/lisk-chain/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@ export const GENESIS_BLOCK_TRANSACTION_ROOT = EMPTY_HASH;

export const TAG_BLOCK_HEADER = createMessageTag('BH');
export const TAG_TRANSACTION = createMessageTag('TX');

// TODO: Actual size TBD
export const MAX_ASSET_DATA_SIZE_BYTES = 64;
9 changes: 9 additions & 0 deletions framework/src/node/consensus/consensus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -484,8 +484,17 @@ export class Consensus {

// verify Block signature
await this._verifyBlockSignature(apiContext, block);

// Verify validatorsHash
await this._verifyValidatorsHash(apiContext, block);

// Validate a block
block.validate();
for (const asset of block.assets.getAllAssets()) {
if (!this._stateMachine.getAllModuleIDs().includes(asset.moduleID)) {
throw new Error(`Module with ID: ${asset.moduleID} is not registered.`);
}
}
}

private async _verifyTimestamp(apiContext: APIContext, block: Block): Promise<void> {
Expand Down
9 changes: 9 additions & 0 deletions framework/src/node/state_machine/state_machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,24 @@ export interface StateMachineModule {
export class StateMachine {
private readonly _modules: StateMachineModule[] = [];
private readonly _systemModules: StateMachineModule[] = [];
private readonly _moduleIDs: number[] = [];

public registerModule(mod: StateMachineModule): void {
this._validateExistingModuleID(mod.id);
this._modules.push(mod);
this._moduleIDs.push(mod.id);
this._moduleIDs.sort((a, b) => a - b);
}

public registerSystemModule(mod: StateMachineModule): void {
this._validateExistingModuleID(mod.id);
this._systemModules.push(mod);
this._moduleIDs.push(mod.id);
this._moduleIDs.sort((a, b) => a - b);
}

public getAllModuleIDs() {
return this._moduleIDs;
}

public async executeGenesisBlock(ctx: GenesisBlockContext): Promise<void> {
Expand Down

0 comments on commit 004e232

Please sign in to comment.