Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvement blocks listing page #1013

Merged
merged 11 commits into from Mar 22, 2022
15 changes: 15 additions & 0 deletions __tests__/TestHelper.js
Expand Up @@ -230,6 +230,21 @@ const TestHelper = {
new Mosaic(new MosaicId('7F2D26E89342D398'), UInt64.fromUint(5))
]
};
},
/**
* Mock inflation statement.
* @param {number} amount reward amount.
* @param {number} height block height.
* @returns {object} inflation statement.
*/
mockInflationStatement: (amount, height) => {
return {
amount: UInt64.fromUint(amount),
height: UInt64.fromUint(height),
mosaicId: new MosaicId('6BED913FA20223F8'),
type: 20803,
version: 1
};
}
};

Expand Down
20 changes: 19 additions & 1 deletion __tests__/infrastructure/BlockService.spec.js
@@ -1,5 +1,5 @@
import { BlockService, AccountService, NodeService } from '../../src/infrastructure';
import Helper from '../../src/helper';
import { BlockService, AccountService, NodeService, ReceiptService } from '../../src/infrastructure';
import TestHelper from '../TestHelper';
import { restore, stub } from 'sinon';

Expand Down Expand Up @@ -73,11 +73,13 @@ describe('Block Service', () => {
let getAccounts = {};
let searchBlocks = {};
let getStorageInfo = {};
let searchReceipts = {};

beforeAll(async () => {
getAccounts = stub(AccountService, 'getAccounts');
searchBlocks = stub(BlockService, 'searchBlocks');
getStorageInfo = stub(NodeService, 'getStorageInfo');
searchReceipts = stub(ReceiptService, 'searchReceipts');

getStorageInfo.returns(Promise.resolve({
numBlocks: 100
Expand All @@ -102,10 +104,24 @@ describe('Block Service', () => {
})
};

const mockBalanceTransferReceipt = {
data: {
inflationStatement: {
data: mockSearchBlocks.data.map(block => {
// mock reward amount
const amount = block.height * 1000000;
return TestHelper.mockInflationStatement(amount, block.height);
})
}
}
};

getAccounts.returns(Promise.resolve(mockAccounts));

searchBlocks.returns(Promise.resolve(mockSearchBlocks));

searchReceipts.returns(Promise.resolve(mockBalanceTransferReceipt));

// Act:
const blockList = await BlockService.getBlockList(pageInfo);

Expand All @@ -115,8 +131,10 @@ describe('Block Service', () => {
expect(blockList.pageSize).toEqual(pageInfo.pageSize);
expect(blockList.data[0].harvester.signer).toEqual(accounts[0].address.plain());
expect(blockList.data).toHaveLength(10);

blockList.data.forEach((block, index) => {
expect(block.age).toEqual(Helper.convertToUTCDate(epochAdjustment + index + 1));
expect(block.blockReward).toEqual(Helper.toNetworkCurrency(block.height * 1000000));
expect(block).toHaveProperty('harvester');
expect(block.harvester).toHaveProperty('signer');
expect(block.harvester).toHaveProperty('linkedAddress');
Expand Down
3 changes: 2 additions & 1 deletion src/config/i18n/en-us.json
Expand Up @@ -416,5 +416,6 @@
"recentNamespaces": "Recent Namespaces",
"lastEpoch": "Last Epoch",
"currentEpoch": "Current Epoch",
"value": "Value"
"value": "Value",
"blockReward": "Block Reward"
}
3 changes: 2 additions & 1 deletion src/config/i18n/es.json
Expand Up @@ -412,5 +412,6 @@
"recentNamespaces": "Recent Namespaces",
"lastEpoch": "Last Epoch",
"currentEpoch": "Current Epoch",
"value": "Value"
"value": "Value",
"blockReward": "Block Reward"
}
3 changes: 2 additions & 1 deletion src/config/i18n/ja.json
Expand Up @@ -416,5 +416,6 @@
"recentNamespaces": "直近ネームスペース",
"lastEpoch": "Last Epoch",
"currentEpoch": "Current Epoch",
"value": "値"
"value": "値",
"blockReward": "ブロック報酬"
}
3 changes: 2 additions & 1 deletion src/config/i18n/pt.json
Expand Up @@ -410,5 +410,6 @@
"recentNamespaces": "Recent Namespaces",
"lastEpoch": "Last Epoch",
"currentEpoch": "Current Epoch",
"value": "Value"
"value": "Value",
"blockReward": "Block Reward"
}
3 changes: 2 additions & 1 deletion src/config/i18n/ru.json
Expand Up @@ -416,5 +416,6 @@
"recentNamespaces": "Недавние Пространства имен",
"lastEpoch": "Last Epoch",
"currentEpoch": "Current Epoch",
"value": "Value"
"value": "Value",
"blockReward": "Награда за блок"
}
3 changes: 2 additions & 1 deletion src/config/i18n/ua.json
Expand Up @@ -412,5 +412,6 @@
"recentNamespaces": "Recent Namespaces",
"lastEpoch": "Last Epoch",
"currentEpoch": "Current Epoch",
"value": "Value"
"value": "Value",
"blockReward": "Block Reward"
}
3 changes: 2 additions & 1 deletion src/config/i18n/zh.json
Expand Up @@ -412,5 +412,6 @@
"recentNamespaces": "Recent Namespaces",
"lastEpoch": "Last Epoch",
"currentEpoch": "Current Epoch",
"value": "值"
"value": "值",
"blockReward": "Block Reward"
}
13 changes: 6 additions & 7 deletions src/config/pages/block-list.json
Expand Up @@ -14,24 +14,23 @@
"type": "CardTable",
"title": "blocksTitle",
"managerGetter": "block/timeline",
"infoTextGetter": "block/infoText",
"pagination": "server",
"hasFilter": false,
"hasInfoText": true,
"hasInfoText": false,
"fields": [
"height",
"blockType",
"age",
"harvester",
"totalTransactions",
"statements",
"totalFee",
"timestamp",
"harvester"
"blockReward",
"totalFee"
],
"mobileFields": [
"height",
"age",
"transactions",
"totalTransactions",
"blockReward",
"totalFee"
]
}
Expand Down
25 changes: 20 additions & 5 deletions src/infrastructure/BlockService.js
Expand Up @@ -16,14 +16,14 @@
*
*/

import NodeService from './NodeService';
import http from './http';
import { Constants } from '../config';
import helper from '../helper';
import { TransactionService, ReceiptService, AccountService } from '../infrastructure';
import { TransactionService, ReceiptService, AccountService, NodeService } from '../infrastructure';
import { sha3_256 as sha3256 } from 'js-sha3';
import { MerkleTree } from 'merkletreejs';
import { take, toArray } from 'rxjs/operators';
import { UInt64, TransactionGroup, Order, BlockOrderBy, BlockType } from 'symbol-sdk';
import { UInt64, TransactionGroup, Order, BlockOrderBy, BlockType, ReceiptType } from 'symbol-sdk';

class BlockService {
/**
Expand Down Expand Up @@ -131,19 +131,34 @@ class BlockService {

const signerAddress = blocks.data.map(block => block.signer);

const accountInfos = await AccountService.getAccounts(signerAddress);
// Get Inflation rate
const receiptSearchCriteria = {
pageSize: blocks.data.length,
order: Order.Desc,
fromHeight: UInt64.fromUint(blocks.data[blocks.data.length - 1].height),
toHeight: UInt64.fromUint(blocks.data[0].height),
receiptTypes: [ReceiptType.Inflation]
};

const { numBlocks } = await NodeService.getStorageInfo();
const [accountInfos, { numBlocks }, balanceTransferReceipt] = await Promise.all([
AccountService.getAccounts(signerAddress),
NodeService.getStorageInfo(),
ReceiptService.searchReceipts(receiptSearchCriteria)
]);

return {
...blocks,
totalRecords: numBlocks,
data: blocks.data.map(block => {
const { supplementalPublicKeys } = accountInfos.find(account => account.address === block.signer);
const inflationRate = balanceTransferReceipt.data.inflationStatement.data
.find(inflation => Number(inflation.height.toString()) === block.height);
const blockReward = Number(inflationRate?.amount.toString()) || 0;

return {
...block,
age: helper.convertToUTCDate(block.timestamp),
blockReward: helper.toNetworkCurrency(blockReward),
harvester: {
signer: block.signer,
linkedAddress: supplementalPublicKeys.linked === Constants.Message.UNAVAILABLE
Expand Down
25 changes: 19 additions & 6 deletions src/store/block.js
Expand Up @@ -30,8 +30,10 @@ import helper from '../helper';
import {
ListenerService,
BlockService,
AccountService
AccountService,
ReceiptService
} from '../infrastructure';
import { UInt64, ReceiptType } from 'symbol-sdk';
import Vue from 'vue';

const managers = [
Expand Down Expand Up @@ -91,10 +93,8 @@ export default {
merkleInfo: state => state.info?.data?.merkleInfo || {},

resolutionStatement: state => state.blockReceipts?.data?.resolutionStatements || [],
currentBlockHeight: state => state.currentBlockHeight,
infoText: (s, g, rs, rootGetters) =>
rootGetters['ui/getNameByKey']('chainHeight') + ': ' + (rootGetters['chain/getChainInfo']
&& rootGetters['chain/getChainInfo'].currentHeight ? rootGetters['chain/getChainInfo'].currentHeight : 0) },
currentBlockHeight: state => state.currentBlockHeight
},
mutations: {
...getMutationsFromManagers(managers),
setInitialized: (state, initialized) => {
Expand Down Expand Up @@ -134,13 +134,26 @@ export default {
if (null === getters.getSubscription) {
const subscription = await ListenerService.subscribeNewBlock(
async item => {
const latestBlock = await BlockService.getBlockByHeight(item.height.compact());
const blockHeight = Number(item.height.toString());

const [latestBlock, balanceTransferReceipt] = await Promise.all([
BlockService.getBlockByHeight(blockHeight),
ReceiptService.searchReceipts({
height: UInt64.fromUint(blockHeight),
receiptTypes: [ReceiptType.Inflation]
})
]);

const { supplementalPublicKeys } = await AccountService.getAccount(latestBlock.signer);

const inflationRate = balanceTransferReceipt.data.inflationStatement.data[0];

const blockReward = Number(inflationRate?.amount.toString()) || 0;

getters.timeline.addLatestItem({
...latestBlock,
age: helper.convertToUTCDate(latestBlock.timestamp),
blockReward: helper.toNetworkCurrency(blockReward),
harvester: {
signer: latestBlock.signer,
linkedAddress: supplementalPublicKeys.linked === Constants.Message.UNAVAILABLE
Expand Down