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

Commit

Permalink
Verify aggregate commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Incede committed Dec 20, 2021
1 parent b6f0843 commit 19f1f95
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,9 @@ import { createAggSig } from '@liskhq/lisk-cryptography';
import { EMPTY_BUFFER } from './constants';
import { BFTParameterNotFoundError } from '../../../modules/bft/errors';
import { APIContext } from '../../state_machine/types';
import { BFTAPI, PkSigPair, ValidatorAPI } from '../types';
import { BFTAPI, PkSigPair, ValidatorAPI, AggregateCommit } from '../types';
import { COMMIT_RANGE_STORED } from './constants';
import {
AggregateCommit,
Certificate,
CommitPoolConfig,
SingleCommit,
ValidatorInfo,
} from './types';
import { Certificate, CommitPoolConfig, SingleCommit, ValidatorInfo } from './types';
import {
computeCertificateFromBlockHeader,
verifyAggregateCertificateSignature,
Expand Down
6 changes: 0 additions & 6 deletions framework/src/node/consensus/certificate_generation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,3 @@ export interface ValidatorInfo {
readonly blsPublicKey: Buffer;
readonly blsSecretKey: Buffer;
}

export interface AggregateCommit {
readonly height: number;
readonly aggregationBits: Buffer;
readonly certificateSignature: Buffer;
}
24 changes: 24 additions & 0 deletions framework/src/node/consensus/consensus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import { ValidatorAPI, BFTAPI } from './types';
import { APIContext, createAPIContext } from '../state_machine';
import { forkChoice, ForkStatus } from './fork_choice/fork_choice_rule';
import { createNewAPIContext } from '../state_machine/api_context';
import { CommitPool } from './types';

interface ConsensusArgs {
stateMachine: StateMachine;
Expand All @@ -57,6 +58,7 @@ interface ConsensusArgs {
genesisConfig: GenesisConfig;
bftAPI: BFTAPI;
validatorAPI: ValidatorAPI;
commitPool: CommitPool;
}

interface InitArgs {
Expand Down Expand Up @@ -93,6 +95,7 @@ export class Consensus {
private readonly _validatorAPI: ValidatorAPI;
private readonly _bftAPI: BFTAPI;
private readonly _genesisConfig: GenesisConfig;
private readonly _commitPool: CommitPool;

// init parameters
private _logger!: Logger;
Expand All @@ -112,6 +115,7 @@ export class Consensus {
this._validatorAPI = args.validatorAPI;
this._bftAPI = args.bftAPI;
this._genesisConfig = args.genesisConfig;
this._commitPool = args.commitPool;
}

public async init(args: InitArgs): Promise<void> {
Expand Down Expand Up @@ -513,6 +517,9 @@ export class Consensus {
// verify Block signature
await this._verifyAssetsSignature(apiContext, block);

// verify aggregate commits
await this._verifyAggregateCommit(apiContext, block);

// Validate a block
block.validate();

Expand Down Expand Up @@ -638,6 +645,23 @@ export class Consensus {
}
}

private async _verifyAggregateCommit(apiContext: APIContext, block: Block): Promise<void> {
if (!block.header.aggregateCommit) {
throw new Error(
`Aggregate Commit is "undefined" for the block with id: ${block.header.id.toString('hex')}`,
);
}
const isVerified = await this._commitPool.verifyAggregateCommit(
apiContext,
block.header.aggregateCommit,
);
if (!isVerified) {
throw new Error(
`Invalid aggregateCommit for the block with id: ${block.header.id.toString('hex')}`,
);
}
}

private async _verifyValidatorsHash(apiContext: APIContext, block: Block): Promise<void> {
if (!block.header.validatorsHash) {
throw new Error(
Expand Down
15 changes: 14 additions & 1 deletion framework/src/node/consensus/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import { BFTParameters } from '../../modules/bft/schemas';
import { BFTHeights } from '../../modules/bft/types';
import { ValidatorKeys } from '../../modules/validators/types';
import { BlockHeader, ImmutableAPIContext } from '../state_machine';
import { BlockHeader, ImmutableAPIContext, APIContext } from '../state_machine';

export interface BFTHeader {
id: Buffer;
Expand Down Expand Up @@ -56,3 +56,16 @@ export interface PkSigPair {
publicKey: Buffer;
signature: Buffer;
}

export interface AggregateCommit {
readonly height: number;
readonly aggregationBits: Buffer;
readonly certificateSignature: Buffer;
}

export interface CommitPool {
verifyAggregateCommit: (
apiContext: APIContext,
aggregateCommit: AggregateCommit,
) => Promise<boolean>;
}
2 changes: 2 additions & 0 deletions framework/src/node/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
APP_EVENT_NETWORK_READY,
APP_EVENT_TRANSACTION_NEW,
} from './events';
import { CommitPool } from './consensus/types';

const MINIMUM_MODULE_ID = 2;

Expand Down Expand Up @@ -93,6 +94,7 @@ export class Node {
genesisConfig: this._options.genesis,
bftAPI: this._bftModule.api,
validatorAPI: this._validatorsModule.api,
commitPool: {} as CommitPool, // TODO Initialize commit pool
});
this._generator = new Generator({
chain: this._chain,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import {
} from '../../../../../src/node/consensus/certificate_generation/constants';
import { certificateSchema } from '../../../../../src/node/consensus/certificate_generation/schema';
import {
AggregateCommit,
Certificate,
SingleCommit,
} from '../../../../../src/node/consensus/certificate_generation/types';
Expand All @@ -42,6 +41,7 @@ import {
computeCertificateFromBlockHeader,
signCertificate,
} from '../../../../../src/node/consensus/certificate_generation/utils';
import { AggregateCommit } from '../../../../../src/node/consensus/types';

jest.mock('@liskhq/lisk-cryptography', () => ({
__esModule: true,
Expand Down
42 changes: 42 additions & 0 deletions framework/test/unit/node/consensus/consensus.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import * as forkchoice from '../../../../src/node/consensus/fork_choice/fork_cho
import { postBlockEventSchema } from '../../../../src/node/consensus/schema';
import { APIContext } from '../../../../src/node/state_machine';
import { createTransientAPIContext } from '../../../../src/testing';
import { CommitPool } from '../../../../src/node/consensus/types';

describe('consensus', () => {
const genesis = (genesisBlock() as unknown) as Block;
Expand All @@ -56,6 +57,7 @@ describe('consensus', () => {
let stateMachine: StateMachine;
let bftAPI: BFTAPI;
let validatorAPI: ValidatorAPI;
let commitPool: CommitPool;

let dbMock: any;

Expand Down Expand Up @@ -99,13 +101,17 @@ describe('consensus', () => {
getValidatorAccount: jest.fn(),
getSlotNumber: jest.fn(),
} as never;
commitPool = {
verifyAggregateCommit: jest.fn(),
};
consensus = new Consensus({
chain,
network,
stateMachine,
bftAPI,
validatorAPI,
genesisConfig: {} as any,
commitPool,
});
dbMock = {
get: jest.fn(),
Expand Down Expand Up @@ -852,6 +858,42 @@ describe('consensus', () => {
});
});

describe('aggregateCommit', () => {
it('should throw error when aggregateCommit is undefined', async () => {
Object.defineProperty(block.header, `aggregateCommit`, { value: undefined });

await expect(
consensus['_verifyAggregateCommit'](apiContext, block as any),
).rejects.toThrow(
`Aggregate Commit is "undefined" for the block with id: ${block.header.id.toString(
'hex',
)}`,
);
});

it('should throw error for invalid aggregateCommit', async () => {
when(consensus['_commitPool'].verifyAggregateCommit as never)
.calledWith(apiContext, block.header.aggregateCommit)
.mockResolvedValue(false as never);

await expect(
consensus['_verifyAggregateCommit'](apiContext, block as any),
).rejects.toThrow(
`Invalid aggregateCommit for the block with id: ${block.header.id.toString('hex')}`,
);
});

it('should be success for valid aggregateCommit', async () => {
when(consensus['_commitPool'].verifyAggregateCommit as never)
.calledWith(apiContext, block.header.aggregateCommit)
.mockResolvedValue(true as never);

await expect(
consensus['_verifyAggregateCommit'](apiContext, block as any),
).resolves.toBeUndefined();
});
});

describe('validateBlockAsset', () => {
it('should throw error if a module is not registered', async () => {
const assetList = [
Expand Down

0 comments on commit 19f1f95

Please sign in to comment.