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 #3018 from LiskHQ/2989-remove_storage_read_chain
Browse files Browse the repository at this point in the history
Remove storageRead call from http_api to chain - Closes #2989
  • Loading branch information
MaciejBaj authored Mar 7, 2019
2 parents ae067c5 + e0372f3 commit 5ebf507
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 13 deletions.
2 changes: 0 additions & 2 deletions framework/src/modules/chain/chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,6 @@ module.exports = class Chain {
action.params[0],
action.params[1]
),
storageRead: async action =>
this.scope.logic.block.storageRead(action.params[0]),
getLastConsensus: async () => this.scope.modules.peers.getLastConsensus(),
loaderLoaded: async () => this.scope.modules.loader.loaded(),
loaderSyncing: async () => this.scope.modules.loader.syncing(),
Expand Down
1 change: 0 additions & 1 deletion framework/src/modules/chain/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ module.exports = class ChainModule extends BaseModule {
getPeersCountByFilter: async action =>
this.chain.actions.getPeersCountByFilter(action),
postSignature: async action => this.chain.actions.postSignature(action),
storageRead: async action => this.chain.actions.storageRead(action),
getLastConsensus: async () => this.chain.actions.getLastConsensus(),
loaderLoaded: async () => this.chain.actions.loaderLoaded(),
loaderSyncing: async () => this.chain.actions.loaderSyncing(),
Expand Down
5 changes: 2 additions & 3 deletions framework/src/modules/chain/logic/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -517,11 +517,10 @@ Block.prototype.dbRead = function(raw) {
};

/**
* Creates block object based on raw data.
* Creates block object based on raw database block data.
*
* @param {Object} raw
* @param {Object} raw Raw database data block object
* @returns {null|block} Block object
* @todo Add description for the params
*/
Block.prototype.storageRead = function(raw) {
if (!raw.id) {
Expand Down
70 changes: 63 additions & 7 deletions framework/src/modules/http_api/controllers/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
'use strict';

const _ = require('lodash');
const crypto = require('crypto');
const apiCodes = require('../helpers/api_codes.js');
const ApiError = require('../helpers/api_error.js');
const Bignum = require('../helpers/bignum.js');

let library;
let sortFields;
Expand Down Expand Up @@ -108,6 +110,66 @@ BlocksController.getBlocks = function(context, next) {
});
};

/**
* Gets address by public.
*
* @private
* @param {publicKey} publicKey Public key
* @returns {address} address
* @todo Replace by Lisk Elements once integrated.
*/
function getAddressByPublicKey(publicKey) {
const publicKeyHash = crypto
.createHash('sha256')
.update(publicKey, 'hex')
.digest();
const temp = Buffer.alloc(8);

for (let i = 0; i < 8; i++) {
temp[i] = publicKeyHash[7 - i];
}

const address = `${Bignum.fromBuffer(temp).toString()}L`;
return address;
}

/**
* Parse raw block data from database into expected API response type for blocks
*
* @param {Object} raw Raw block data from database
* @return {block} Block formatted according to API specification
*/
function parseBlockFromDatabase(raw) {
if (!raw.id) {
return null;
}

const block = {
id: raw.id,
version: parseInt(raw.version),
timestamp: parseInt(raw.timestamp),
height: parseInt(raw.height),
previousBlock: raw.previousBlockId,
numberOfTransactions: parseInt(raw.numberOfTransactions),
totalAmount: new Bignum(raw.totalAmount).toString(),
totalFee: new Bignum(raw.totalFee).toString(),
reward: new Bignum(raw.reward).toString(),
payloadLength: parseInt(raw.payloadLength),
payloadHash: raw.payloadHash,
generatorPublicKey: raw.generatorPublicKey,
generatorId: getAddressByPublicKey(raw.generatorPublicKey),
blockSignature: raw.blockSignature,
confirmations: parseInt(raw.confirmations),
totalForged: new Bignum(raw.totalFee).plus(raw.reward).toString(),
};

if (raw.transactions) {
block.transactions = raw.transactions;
}

return block;
}

/**
* Get filtered list of blocks (without transactions - BasicBlock).
*
Expand Down Expand Up @@ -180,13 +242,7 @@ function _list(params, cb) {
library.storage.entities.Block.get(filters, options)
// FIXME: Can have poor performance because it performs SHA256 hash calculation for each block
.then(async rows =>
setImmediate(
cb,
null,
await Promise.all(
rows.map(row => library.channel.invoke('chain:storageRead', [row]))
)
)
setImmediate(cb, null, rows.map(parseBlockFromDatabase))
)
.catch(err => {
library.logger.error(err.stack);
Expand Down
52 changes: 52 additions & 0 deletions framework/test/mocha/unit/modules/http_api/controllers/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,34 @@ const BlocksController = rewire(

describe('blocks/api', () => {
let _list;
let parseBlockFromDatabase;
let library;
let loggerSpy;
let storageStub;
let channelStub;
let rawBlock;

beforeEach(done => {
rawBlock = {
id: '8999789716699660339',
payloadHash:
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
generatorPublicKey:
'68680ca0bcd4676489976837edeac305c34f652e970386013ef26e67589a2516',
blockSignature:
'51356c69d94762ef355a95a960002aabc80d331da136cc07082bf98856e57ea9d13d2c74dd923c412221b36f4c3e276b2d83d9019521ddf003d0b39698d4ae0a',
height: 1860,
totalFee: '0',
reward: '0',
payloadLength: 0,
previousBlockId: '14888522644597494628',
numberOfTransactions: 0,
totalAmount: '0',
timestamp: 87670360,
version: '1',
confirmations: 37,
};

storageStub = {
entities: {
Block: {
Expand All @@ -52,6 +74,7 @@ describe('blocks/api', () => {
});
library = BlocksController.__get__('library');
_list = BlocksController.__get__('_list');
parseBlockFromDatabase = BlocksController.__get__('parseBlockFromDatabase');

done();
});
Expand All @@ -69,6 +92,35 @@ describe('blocks/api', () => {
});
});

describe('parseBlockFromDatabase', () => {
let formattedBlock;

beforeEach(async () => {
formattedBlock = parseBlockFromDatabase(rawBlock);
});

it('should return a block properly formatted when transactions is undefined', async () => {
const rawBlockWithTransactions = _.cloneDeep(rawBlock);
formattedBlock = parseBlockFromDatabase(rawBlockWithTransactions);
expect(formattedBlock).deep.equal(formattedBlock);
expect(formattedBlock).to.not.have.property('transactions');
});

it('should return a block properly formatted when transactions is not undefined', async () => {
const rawBlockWithTransactions = _.cloneDeep(rawBlock);
rawBlockWithTransactions.transactions = [];
formattedBlock = parseBlockFromDatabase(rawBlockWithTransactions);
expect(formattedBlock).to.have.property('transactions');
});

it('should return null when no id is present for raw data', async () => {
const rawBlockWithoutID = _.cloneDeep(rawBlock);
delete rawBlockWithoutID.id;
formattedBlock = parseBlockFromDatabase(rawBlockWithoutID);
expect(formattedBlock).to.be.null;
});
});

describe('_list', () => {
describe('list', () => {
afterEach(done => {
Expand Down

0 comments on commit 5ebf507

Please sign in to comment.