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

Commit

Permalink
Merge branch 'development' into 7542-fix_dpos_response
Browse files Browse the repository at this point in the history
  • Loading branch information
shuse2 authored Oct 5, 2022
2 parents 45e689d + 3303c8f commit 7142e3d
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 24 deletions.
13 changes: 10 additions & 3 deletions elements/lisk-chain/src/data_access/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,17 @@ export class Storage {
}

public async getEvents(height: number): Promise<Event[]> {
const eventsByte = await this._db.get(concatDBKeys(DB_KEY_BLOCK_EVENTS, uint32BE(height)));
const events = decodeByteArray(eventsByte);
try {
const eventsByte = await this._db.get(concatDBKeys(DB_KEY_BLOCK_EVENTS, uint32BE(height)));
const events = decodeByteArray(eventsByte);

return events.map(e => Event.fromBytes(e));
return events.map(e => Event.fromBytes(e));
} catch (error) {
if (!(error instanceof NotFoundError)) {
throw error;
}
return [];
}
}

public async getTempBlocks(): Promise<Buffer[]> {
Expand Down
7 changes: 6 additions & 1 deletion elements/lisk-chain/src/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export interface EventAttr {
type EventJSON = JSONObject<EventAttr>;

export class Event {
private readonly _index: number;
private _index: number;

private readonly _module: string;
private readonly _name: string;
private readonly _topics: Buffer[];
Expand All @@ -59,6 +60,10 @@ export class Event {
return utils.hash(codec.encode(eventSchema, this.toObject()));
}

public setIndex(index: number): void {
this._index = index;
}

public getBytes(): Buffer {
return codec.encode(eventSchema, this._getAllProps());
}
Expand Down
8 changes: 8 additions & 0 deletions elements/lisk-chain/test/unit/data_access/data_access.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,14 @@ describe('data_access', () => {
});

describe('#getEvents', () => {
it('should get empty array if the event does not exist', async () => {
db.get.mockRejectedValue(new NotFoundError());

const resp = await dataAccess.getEvents(30);
expect(db.get).toHaveBeenCalledWith(concatDBKeys(DB_KEY_BLOCK_EVENTS, uint32BE(30)));
expect(resp).toEqual([]);
});

it('should get the events related to heights', async () => {
const original = [
new Event({
Expand Down
18 changes: 14 additions & 4 deletions framework/src/engine/consensus/consensus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ export class Consensus {
// setting peerID to localhost with non existing port because this function is only called internally.
await this._execute(block, '127.0.0.1:0');
} catch (error) {
await this._abi.clear({});
this._logger.error({ err: error as Error }, 'Fail to execute block.');
}
}
Expand Down Expand Up @@ -961,7 +962,7 @@ export class Consensus {
assets: block.assets.getAll(),
consensus,
});
events.push(...beforeResult.events.map(e => new Event(e)));
events.push(...beforeResult.events);
for (const transaction of block.transactions) {
const { result: verifyResult } = await this._abi.verifyTransaction({
contextID,
Expand All @@ -983,14 +984,15 @@ export class Consensus {
this._logger.debug(`Failed to execute transaction ${transaction.id.toString('hex')}`);
throw new Error(`Failed to execute transaction ${transaction.id.toString('hex')}.`);
}
events.push(...txExecResult.events.map(e => new Event(e)));
events.push(...txExecResult.events);
}
const afterResult = await this._abi.afterTransactionsExecute({
contextID,
assets: block.assets.getAll(),
consensus,
transactions: block.transactions.map(tx => tx.toObject()),
});
events.push(...afterResult.events);

if (
!isEmptyConsensusUpdate(
Expand All @@ -1016,7 +1018,11 @@ export class Consensus {
});
}

return events;
return events.map((e, i) => {
const event = new Event(e);
event.setIndex(i);
return event;
});
} catch (err) {
await this._abi.clear({});
throw err;
Expand Down Expand Up @@ -1074,7 +1080,11 @@ export class Consensus {
stateRoot: utils.hash(Buffer.alloc(0)),
expectedStateRoot: genesisBlock.header.stateRoot,
});
return result.events.map(e => new Event(e));
return result.events.map((e, i) => {
const event = new Event(e);
event.setIndex(i);
return event;
});
} finally {
await this._abi.clear({});
}
Expand Down
5 changes: 4 additions & 1 deletion framework/src/engine/generator/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ export class Generator {
consensus,
transactions: transactions.map(tx => tx.toObject()),
});
blockEvents.push(...afterResult.events.map(e => new Event(e)));
if (
!isEmptyConsensusUpdate(
afterResult.preCommitThreshold,
Expand Down Expand Up @@ -593,7 +594,9 @@ export class Generator {

// Add event root calculation
const keypairs = [];
for (const e of blockEvents) {
for (let index = 0; index < blockEvents.length; index += 1) {
const e = blockEvents[index];
e.setIndex(index);
const pairs = e.keyPair();
for (const pair of pairs) {
keypairs.push(pair);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,8 @@ describe('Process block', () => {
expect(processedBlock.header.id).toEqual(newBlock.header.id);
});

it('should not save the events to the database', async () => {
await expect(dataAccess.getEvents(newBlock.header.height)).rejects.toThrow(
'does not exist',
);
it('should save the events to the database', async () => {
await expect(dataAccess.getEvents(newBlock.header.height)).resolves.not.toBeEmpty();
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ describe('Delete block', () => {
});

it('should delete the events from the database', async () => {
await expect(processEnv.getDataAccess().getEvents(newBlock.header.height)).rejects.toThrow(
'does not exist',
);
await expect(
processEnv.getDataAccess().getEvents(newBlock.header.height),
).resolves.toBeEmpty();
});

it('should match the sender account to the original state', async () => {
Expand Down
69 changes: 67 additions & 2 deletions framework/test/unit/engine/consensus/consensus.spec.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 { Block, BlockAssets, Chain, StateStore, Event } from '@liskhq/lisk-chain';
import { Block, BlockAssets, Chain, StateStore, Event, Transaction } from '@liskhq/lisk-chain';
import { codec } from '@liskhq/lisk-codec';
import { when } from 'jest-when';
import { Mnemonic } from '@liskhq/lisk-passphrase';
Expand All @@ -39,7 +39,7 @@ import * as forkchoice from '../../../../src/engine/consensus/fork_choice/fork_c
import { postBlockEventSchema } from '../../../../src/engine/consensus/schema';
import { fakeLogger } from '../../../utils/mocks';
import { BFTModule } from '../../../../src/engine/bft';
import { ABI } from '../../../../src/abi';
import { ABI, TransactionExecutionResult, TransactionVerifyResult } from '../../../../src/abi';
import {
CONSENSUS_EVENT_BLOCK_BROADCAST,
NETWORK_EVENT_POST_BLOCK,
Expand Down Expand Up @@ -618,6 +618,9 @@ describe('consensus', () => {
db: dbMock,
genesisBlock: genesis,
});
jest.spyOn(abi, 'verifyTransaction').mockResolvedValue({
result: TransactionVerifyResult.OK,
});
});

describe('when skipBroadcast option is not specified', () => {
Expand All @@ -628,6 +631,17 @@ describe('consensus', () => {
previousBlockID: chain.lastBlock.header.id,
timestamp: consensus['_chain'].lastBlock.header.timestamp + 10,
},
transactions: [
new Transaction({
command: 'exec',
module: 'sample',
fee: BigInt(200),
nonce: BigInt(2),
params: utils.getRandomBytes(100),
senderPublicKey: utils.getRandomBytes(32),
signatures: [utils.getRandomBytes(64)],
}),
],
});
stateStore = new StateStore(new InMemoryDatabase());
jest.spyOn(bft.method, 'getBFTParameters').mockResolvedValue({
Expand Down Expand Up @@ -657,6 +671,57 @@ describe('consensus', () => {
block: expect.any(Block),
});
});

it('should include events from hooks', async () => {
jest.spyOn(abi, 'beforeTransactionsExecute').mockResolvedValue({
events: [
{
module: 'sample',
name: 'init',
data: Buffer.from([0, 0, 2]),
topics: [Buffer.from([2])],
height: 2,
index: 0,
},
],
});
jest.spyOn(abi, 'afterTransactionsExecute').mockResolvedValue({
events: [
{
module: 'sample',
name: 'init',
data: Buffer.from([0, 0, 1]),
topics: [Buffer.from([3])],
height: 2,
index: 0,
},
],
nextValidators: [],
preCommitThreshold: BigInt(0),
certificateThreshold: BigInt(0),
});
jest.spyOn(abi, 'executeTransaction').mockResolvedValue({
result: TransactionExecutionResult.OK,
events: [
{
module: 'sample',
name: 'exec',
data: Buffer.from([0, 0, 2]),
topics: [utils.getRandomBytes(32)],
height: 2,
index: 0,
},
],
});

jest.spyOn(chain, 'saveBlock');

await consensus['_executeValidated'](block);

const savingEvents = (chain.saveBlock as jest.Mock).mock.calls[0][1];
expect(savingEvents).toHaveLength(3);
savingEvents.forEach((e: Event, i: number) => expect(e.toObject().index).toEqual(i));
});
});

describe('block verification', () => {
Expand Down
29 changes: 23 additions & 6 deletions framework/test/unit/engine/generator/generator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ describe('generator', () => {
}),
} as never;
abi = {
beforeTransactionsExecute: jest.fn().mockResolvedValue({ events: [] }),
beforeTransactionsExecute: jest.fn().mockResolvedValue({
events: [],
}),
afterTransactionsExecute: jest.fn().mockResolvedValue({
events: [],
nextValidators: [],
Expand Down Expand Up @@ -537,15 +539,30 @@ describe('generator', () => {
jest.spyOn(abi, 'beforeTransactionsExecute').mockResolvedValue({
events: [
{
data: utils.getRandomBytes(32),
module: 'sample',
name: 'init',
data: Buffer.from([0, 0, 2]),
topics: [Buffer.from([2])],
height: 2,
index: 0,
module: 'token',
topics: [Buffer.from([0])],
name: 'Transfer Name',
height: 12,
},
],
});
jest.spyOn(abi, 'afterTransactionsExecute').mockResolvedValue({
events: [
{
module: 'sample',
name: 'init',
data: Buffer.from([0, 0, 1]),
topics: [Buffer.from([3])],
height: 2,
index: 0,
},
],
nextValidators: [],
preCommitThreshold: BigInt(0),
certificateThreshold: BigInt(0),
});
const block = await generator.generateBlock({
generatorAddress,
timestamp: currentTime,
Expand Down

0 comments on commit 7142e3d

Please sign in to comment.