From 81c561fa3cf73a8a8618b093da47c6a6ec82b07c Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Thu, 19 Nov 2020 19:41:02 +0000 Subject: [PATCH 1/2] Added new block type --- package-lock.json | 8 +- package.json | 2 +- src/infrastructure/BlockHttp.ts | 31 +++- src/model/blockchain/BlockInfo.ts | 152 +--------------- src/model/blockchain/BlockType.ts | 21 +++ src/model/blockchain/ImportanceBlockFooter.ts | 38 ++++ .../blockchain/NemesisImportanceBlockInfo.ts | 20 +++ src/model/blockchain/NomalBlockInfo.ts | 164 ++++++++++++++++++ src/model/blockchain/index.ts | 4 + test/infrastructure/BlockHttp.spec.ts | 67 ++++++- test/model/blockchain/BlockInfo.spec.ts | 8 +- .../blockchain/ImportanceBlockFooter.spec.ts | 42 +++++ test/service/BlockService.spec.ts | 5 +- 13 files changed, 399 insertions(+), 163 deletions(-) create mode 100644 src/model/blockchain/BlockType.ts create mode 100644 src/model/blockchain/ImportanceBlockFooter.ts create mode 100644 src/model/blockchain/NemesisImportanceBlockInfo.ts create mode 100644 src/model/blockchain/NomalBlockInfo.ts create mode 100644 test/model/blockchain/ImportanceBlockFooter.spec.ts diff --git a/package-lock.json b/package-lock.json index 42ae48c8df..23eaa95c46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6159,7 +6159,7 @@ }, "which-module": { "version": "2.0.0", - "resolved": false, + "resolved": "", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, @@ -7746,9 +7746,9 @@ } }, "symbol-openapi-typescript-fetch-client": { - "version": "0.10.1-SNAPSHOT.202011161425", - "resolved": "https://registry.npmjs.org/symbol-openapi-typescript-fetch-client/-/symbol-openapi-typescript-fetch-client-0.10.1-SNAPSHOT.202011161425.tgz", - "integrity": "sha512-YaOVd47rrLwJ+5NhqHCpfvI7omVzkt4bc1RiW3swYK/U+pp4yBBFa6fcT4Myglfmz7QPwqcIW0Sr5Yq5W3hJwA==" + "version": "0.10.1-SNAPSHOT.202011191848", + "resolved": "https://registry.npmjs.org/symbol-openapi-typescript-fetch-client/-/symbol-openapi-typescript-fetch-client-0.10.1-SNAPSHOT.202011191848.tgz", + "integrity": "sha512-5V7FBtdzz8nX3U06a6yqudLOMvk0/sw+cD5uIubYOmOrleIWFp2nb1IE7nrCSr1t4Qr/Rlg9UU6T/Xuyfp4YFA==" }, "symbol-sdk": { "version": "0.21.0", diff --git a/package.json b/package.json index 84a7b20b04..6fac2197c1 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,7 @@ "ripemd160": "^2.0.2", "rxjs": "^6.6.3", "rxjs-compat": "^6.6.3", - "symbol-openapi-typescript-fetch-client": "0.10.1-SNAPSHOT.202011161425", + "symbol-openapi-typescript-fetch-client": "0.10.1-SNAPSHOT.202011191848", "tweetnacl": "^1.0.3", "ws": "^7.3.1" }, diff --git a/src/infrastructure/BlockHttp.ts b/src/infrastructure/BlockHttp.ts index 16e323fedb..168b532abb 100644 --- a/src/infrastructure/BlockHttp.ts +++ b/src/infrastructure/BlockHttp.ts @@ -15,13 +15,17 @@ */ import { Observable } from 'rxjs'; -import { BlockInfoDTO, BlockRoutesApi } from 'symbol-openapi-typescript-fetch-client'; +import { BlockInfoDTO, BlockRoutesApi, ImportanceBlockDTO } from 'symbol-openapi-typescript-fetch-client'; import { DtoMapping } from '../core/utils/DtoMapping'; import { Address } from '../model/account/Address'; import { PublicAccount } from '../model/account/PublicAccount'; import { BlockInfo } from '../model/blockchain/BlockInfo'; +import { BlockType } from '../model/blockchain/BlockType'; +import { ImportanceBlockFooter } from '../model/blockchain/ImportanceBlockFooter'; import { MerklePathItem } from '../model/blockchain/MerklePathItem'; import { MerkleProofInfo } from '../model/blockchain/MerkleProofInfo'; +import { NemesisImportanceBlockInfo } from '../model/blockchain/NemesisImportanceBlockInfo'; +import { NormalBlockInfo } from '../model/blockchain/NomalBlockInfo'; import { UInt64 } from '../model/UInt64'; import { BlockRepository } from './BlockRepository'; import { Http } from './Http'; @@ -88,7 +92,8 @@ export class BlockHttp extends Http implements BlockRepository { */ private toBlockInfo(dto: BlockInfoDTO): BlockInfo { const networkType = dto.block.network.valueOf(); - return new BlockInfo( + const blockType = dto.block.type; + const normalBlock = new NormalBlockInfo( dto.id ?? '', dto.block.size, dto.meta.hash, @@ -116,6 +121,28 @@ export class BlockHttp extends Http implements BlockRepository { dto.meta.transactionsCount, dto.meta.statementsCount, ); + if (blockType === BlockType.NormalBlock.valueOf()) { + return normalBlock; + } else if ([BlockType.ImportanceBlock.valueOf(), BlockType.NemesisBlock.valueOf()].includes(blockType)) { + const importanceBlockInfoDto = dto.block as ImportanceBlockDTO; + const importanceBlockFooter = new ImportanceBlockFooter( + importanceBlockInfoDto.votingEligibleAccountsCount, + UInt64.fromNumericString(importanceBlockInfoDto.harvestingEligibleAccountsCount), + UInt64.fromNumericString(importanceBlockInfoDto.totalVotingBalance), + importanceBlockInfoDto.previousImportanceBlockHash, + ); + return Object.assign( + { + __proto__: Object.getPrototypeOf(normalBlock), + }, + normalBlock, + { + importanceBlockFooter, + }, + ) as NemesisImportanceBlockInfo; + } else { + throw new Error(`Block type: ${blockType} invalid.`); + } } /** diff --git a/src/model/blockchain/BlockInfo.ts b/src/model/blockchain/BlockInfo.ts index f767c0421d..20097735fc 100644 --- a/src/model/blockchain/BlockInfo.ts +++ b/src/model/blockchain/BlockInfo.ts @@ -1,7 +1,7 @@ /* - * Copyright 2018 NEM + * Copyright 2020 NEM * - * Licensed under the Apache License, Version 2.0 (the "License"); + * Licensed under the Apache License, Version 2.0 (the "License"), * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * @@ -14,149 +14,7 @@ * limitations under the License. */ -import { Address } from '../account/Address'; -import { PublicAccount } from '../account/PublicAccount'; -import { NetworkType } from '../network/NetworkType'; -import { UInt64 } from '../UInt64'; +import { NemesisImportanceBlockInfo } from './NemesisImportanceBlockInfo'; +import { NormalBlockInfo } from './NomalBlockInfo'; -/** - * The block info structure describes basic information of a block. - */ -export class BlockInfo { - /** - * @param recordId - * @param size - * @param hash - * @param generationHash - * @param totalFee - * @param stateHashSubCacheMerkleRoots - * @param numTransactions - * @param signature - * @param signer - * @param networkType - * @param version - * @param type - * @param height - * @param timestamp - * @param difficulty - * @param proofGamma - * @param proofScalar - * @param proofVerificationHash - * @param feeMultiplier - * @param previousBlockHash - * @param blockTransactionsHash - * @param blockReceiptsHash - * @param blockStateHash - * @param beneficiaryAddress - * @param numStatements - */ - constructor( - /** - * The database record id. - */ - public readonly recordId: string, - /** - * Entity size in bytes. - */ - public readonly size: number, - /** - * The block hash. - */ - public readonly hash: string, - /** - * The generation hash - */ - public readonly generationHash: string, - /** - * The sum of all transaction fees included in the block. - */ - public readonly totalFee: UInt64, - /** - * State hash sub cache merkle roots - */ - public readonly stateHashSubCacheMerkleRoots: string[], - /** - * The total number of transactions confirmed (including embedded transaction) included. - */ - public readonly totalTransactionsCount: number, - /** - * The block signature. - * The signature was generated by the signer and can be used to validate that the blockchain - * data was not modified by a node. - */ - public readonly signature: string, - /** - * The public account of block harvester. - */ - public readonly signer: PublicAccount, - /** - * The network type. - */ - public readonly networkType: NetworkType, - /** - * The transaction version. - */ - public readonly version: number, - /** - * The block type. - */ - public readonly type: number, - /** - * The height of which the block was confirmed. - * Each block has a unique height. Subsequent blocks differ in height by 1. - */ - public readonly height: UInt64, - /** - * The number of milliseconds elapsed since the creation of the nemesis blockchain. - */ - public readonly timestamp: UInt64, - /** - * The POI difficulty to harvest a block. - */ - public readonly difficulty: UInt64, - /** - * The feeMultiplier defined by the harvester. - */ - public readonly feeMultiplier: number, - /** - * The last block hash. - */ - public readonly previousBlockHash: string, - /** - * The block transaction hash. - */ - public readonly blockTransactionsHash: string, - /** - * The block receipt hash. - */ - public readonly blockReceiptsHash: string, - /** - * The state hash. - */ - public readonly stateHash: string, - /** - * The proof gamma. - */ - public readonly proofGamma: string, - /** - * The proof scalar. - */ - public readonly proofScalar: string, - /** - * The proof verification hash. - */ - public readonly proofVerificationHash: string, - /** - * The beneficiary address. - */ - public readonly beneficiaryAddress: Address, - /** - * The number of statements confiemd (excluding embedded transaction) included. - */ - public readonly transactionsCount: number, - /** - * The number of statements included. - */ - public readonly statementsCount: number, - ) {} -} +export type BlockInfo = NormalBlockInfo | NemesisImportanceBlockInfo; diff --git a/src/model/blockchain/BlockType.ts b/src/model/blockchain/BlockType.ts new file mode 100644 index 0000000000..5b4a351a1e --- /dev/null +++ b/src/model/blockchain/BlockType.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export enum BlockType { + NemesisBlock = 0x8043, + NormalBlock = 0x8143, + ImportanceBlock = 0x8243, +} diff --git a/src/model/blockchain/ImportanceBlockFooter.ts b/src/model/blockchain/ImportanceBlockFooter.ts new file mode 100644 index 0000000000..e4356ae1c4 --- /dev/null +++ b/src/model/blockchain/ImportanceBlockFooter.ts @@ -0,0 +1,38 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { UInt64 } from '../UInt64'; + +export class ImportanceBlockFooter { + constructor( + /** + * Number of voting eligible accounts. + */ + public readonly votingEligibleAccountsCount: number, + /** + * Number of harvesting eligible accounts. + */ + public readonly harvestingEligibleAccountsCount: UInt64, + /** + * Total balance eligible for voting. + */ + public readonly totalVotingBalance: UInt64, + /** + * Previous importance block hash. + */ + public readonly previousImportanceBlockHash: string, + ) {} +} diff --git a/src/model/blockchain/NemesisImportanceBlockInfo.ts b/src/model/blockchain/NemesisImportanceBlockInfo.ts new file mode 100644 index 0000000000..3dad5023ee --- /dev/null +++ b/src/model/blockchain/NemesisImportanceBlockInfo.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ImportanceBlockFooter } from './ImportanceBlockFooter'; +import { NormalBlockInfo } from './NomalBlockInfo'; + +export type NemesisImportanceBlockInfo = NormalBlockInfo & { importanceBlockFooter: ImportanceBlockFooter }; diff --git a/src/model/blockchain/NomalBlockInfo.ts b/src/model/blockchain/NomalBlockInfo.ts new file mode 100644 index 0000000000..013c156eeb --- /dev/null +++ b/src/model/blockchain/NomalBlockInfo.ts @@ -0,0 +1,164 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Address } from '../account/Address'; +import { PublicAccount } from '../account/PublicAccount'; +import { NetworkType } from '../network/NetworkType'; +import { UInt64 } from '../UInt64'; +import { BlockType } from './BlockType'; + +/** + * The normal block info structure describes basic information of a block. + */ +export class NormalBlockInfo { + /** + * @param recordId + * @param size + * @param hash + * @param generationHash + * @param totalFee + * @param stateHashSubCacheMerkleRoots + * @param totalTransactionsCount + * @param signature + * @param signer + * @param networkType + * @param version + * @param type + * @param height + * @param timestamp + * @param difficulty + * @param proofGamma + * @param proofScalar + * @param proofVerificationHash + * @param feeMultiplier + * @param previousBlockHash + * @param blockTransactionsHash + * @param blockReceiptsHash + * @param blockStateHash + * @param beneficiaryAddress + * @param transactionsCount + * @param statementsCount + */ + constructor( + /** + * The database record id. + */ + public readonly recordId: string, + /** + * Entity size in bytes. + */ + public readonly size: number, + /** + * The block hash. + */ + public readonly hash: string, + /** + * The generation hash + */ + public readonly generationHash: string, + /** + * The sum of all transaction fees included in the block. + */ + public readonly totalFee: UInt64, + /** + * State hash sub cache merkle roots + */ + public readonly stateHashSubCacheMerkleRoots: string[], + /** + * The total number of transactions confirmed (including embedded transaction) included. + */ + public readonly totalTransactionsCount: number, + /** + * The block signature. + * The signature was generated by the signer and can be used to validate that the blockchain + * data was not modified by a node. + */ + public readonly signature: string, + /** + * The public account of block harvester. + */ + public readonly signer: PublicAccount, + /** + * The network type. + */ + public readonly networkType: NetworkType, + /** + * The transaction version. + */ + public readonly version: number, + /** + * The block type. + */ + public readonly type: BlockType, + /** + * The height of which the block was confirmed. + * Each block has a unique height. Subsequent blocks differ in height by 1. + */ + public readonly height: UInt64, + /** + * The number of milliseconds elapsed since the creation of the nemesis blockchain. + */ + public readonly timestamp: UInt64, + /** + * The POI difficulty to harvest a block. + */ + public readonly difficulty: UInt64, + /** + * The feeMultiplier defined by the harvester. + */ + public readonly feeMultiplier: number, + /** + * The last block hash. + */ + public readonly previousBlockHash: string, + /** + * The block transaction hash. + */ + public readonly blockTransactionsHash: string, + /** + * The block receipt hash. + */ + public readonly blockReceiptsHash: string, + /** + * The state hash. + */ + public readonly stateHash: string, + /** + * The proof gamma. + */ + public readonly proofGamma: string, + /** + * The proof scalar. + */ + public readonly proofScalar: string, + /** + * The proof verification hash. + */ + public readonly proofVerificationHash: string, + /** + * The beneficiary address. + */ + public readonly beneficiaryAddress: Address, + /** + * The number of statements confiemd (excluding embedded transaction) included. + */ + public readonly transactionsCount: number, + /** + * The number of statements included. + */ + public readonly statementsCount: number, + ) {} +} diff --git a/src/model/blockchain/index.ts b/src/model/blockchain/index.ts index e008706643..bea75697c1 100644 --- a/src/model/blockchain/index.ts +++ b/src/model/blockchain/index.ts @@ -1,11 +1,15 @@ // created from 'create-ts-index' export * from './BlockInfo'; +export * from './BlockType'; export * from './ChainInfo'; export * from './FinalizedBlock'; +export * from './ImportanceBlockFooter'; export * from './MerklePathItem'; export * from './MerklePosition'; export * from './MerkleProofInfo'; export * from './MerkleStateInfo'; +export * from './NemesisImportanceBlockInfo'; export * from './NewBlock'; +export * from './NomalBlockInfo'; export * from './StorageInfo'; diff --git a/test/infrastructure/BlockHttp.spec.ts b/test/infrastructure/BlockHttp.spec.ts index 5284c5d159..eedb5169e6 100644 --- a/test/infrastructure/BlockHttp.spec.ts +++ b/test/infrastructure/BlockHttp.spec.ts @@ -21,6 +21,7 @@ import { BlockMetaDTO, BlockPage, BlockRoutesApi, + ImportanceBlockDTO, MerklePathItemDTO, MerkleProofInfoDTO, NetworkTypeEnum, @@ -28,11 +29,13 @@ import { PositionEnum, } from 'symbol-openapi-typescript-fetch-client'; import { deepEqual, instance, mock, reset, when } from 'ts-mockito'; +import { NemesisImportanceBlockInfo } from '../../src'; import { DtoMapping } from '../../src/core/utils/DtoMapping'; import { BlockHttp } from '../../src/infrastructure/BlockHttp'; import { BlockRepository } from '../../src/infrastructure/BlockRepository'; import { Address } from '../../src/model/account/Address'; import { BlockInfo } from '../../src/model/blockchain/BlockInfo'; +import { BlockType } from '../../src/model/blockchain/BlockType'; import { MerklePathItem } from '../../src/model/blockchain/MerklePathItem'; import { MerklePosition } from '../../src/model/blockchain/MerklePosition'; import { NetworkType } from '../../src/model/network/NetworkType'; @@ -46,7 +49,7 @@ describe('BlockHttp', () => { blockDTO.feeMultiplier = 3; blockDTO.height = '4'; blockDTO.previousBlockHash = '5'; - blockDTO.type = 6; + blockDTO.type = BlockType.NormalBlock; blockDTO.signerPublicKey = '81E5E7AE49998802DABC816EC10158D3A7879702FF29084C2C992CD1289877A7'; blockDTO.timestamp = '7'; blockDTO.beneficiaryAddress = Address.createFromPublicKey( @@ -54,6 +57,25 @@ describe('BlockHttp', () => { NetworkType.PRIVATE_TEST, ).encoded(); + const importanceBlockDTO = {} as ImportanceBlockDTO; + importanceBlockDTO.version = 1; + importanceBlockDTO.network = NetworkTypeEnum.NUMBER_152; + importanceBlockDTO.difficulty = '2'; + importanceBlockDTO.feeMultiplier = 3; + importanceBlockDTO.height = '4'; + importanceBlockDTO.previousBlockHash = '5'; + importanceBlockDTO.type = BlockType.NemesisBlock; + importanceBlockDTO.signerPublicKey = '81E5E7AE49998802DABC816EC10158D3A7879702FF29084C2C992CD1289877A7'; + importanceBlockDTO.timestamp = '7'; + importanceBlockDTO.beneficiaryAddress = Address.createFromPublicKey( + '81E5E7AE49998802DABC816EC10158D3A7879702FF29084C2C992CD1289877A8', + NetworkType.PRIVATE_TEST, + ).encoded(); + importanceBlockDTO.harvestingEligibleAccountsCount = '1'; + importanceBlockDTO.previousImportanceBlockHash = 'hash'; + importanceBlockDTO.votingEligibleAccountsCount = 1; + importanceBlockDTO.totalVotingBalance = '1'; + const blockMetaDTO = {} as BlockMetaDTO; blockMetaDTO.generationHash = 'abc'; blockMetaDTO.hash = 'aHash'; @@ -67,6 +89,10 @@ describe('BlockHttp', () => { blockInfoDto.block = blockDTO; blockInfoDto.meta = blockMetaDTO; + const importanceBlockInfoDto = {} as BlockInfoDTO; + importanceBlockInfoDto.block = importanceBlockDTO; + importanceBlockInfoDto.meta = blockMetaDTO; + const url = 'http://someHost'; const response: http.IncomingMessage = mock(); const blockRoutesApi: BlockRoutesApi = mock(); @@ -79,9 +105,9 @@ describe('BlockHttp', () => { reset(blockRoutesApi); }); - function assertBlockInfo(blockInfo: BlockInfo): void { + function assertBlockInfo(blockInfo: BlockInfo, isImportance = false): void { expect(blockInfo).to.be.not.null; - expect(blockInfo.type).to.be.equals(blockInfoDto.block.type); + expect(blockInfo.type).to.be.equals(isImportance ? importanceBlockInfoDto.block.type : blockInfoDto.block.type); expect(blockInfo.previousBlockHash).to.be.equals(blockInfoDto.block.previousBlockHash); expect(blockInfo.height.toString()).to.be.equals(blockInfoDto.block.height); expect(blockInfo.feeMultiplier).to.be.equals(blockInfoDto.block.feeMultiplier); @@ -99,6 +125,21 @@ describe('BlockHttp', () => { expect(blockInfo.transactionsCount).to.be.equals(blockInfoDto.meta.transactionsCount); expect(blockInfo.totalTransactionsCount).to.be.equals(blockInfoDto.meta.totalTransactionsCount); expect(blockInfo.totalFee.toString()).to.be.equals(blockInfoDto.meta.totalFee); + + if (isImportance) { + expect((blockInfo as NemesisImportanceBlockInfo).importanceBlockFooter.harvestingEligibleAccountsCount.toString()).to.be.equals( + (importanceBlockInfoDto.block as ImportanceBlockDTO).harvestingEligibleAccountsCount, + ); + expect((blockInfo as NemesisImportanceBlockInfo).importanceBlockFooter.previousImportanceBlockHash).to.be.equals( + (importanceBlockInfoDto.block as ImportanceBlockDTO).previousImportanceBlockHash, + ); + expect((blockInfo as NemesisImportanceBlockInfo).importanceBlockFooter.totalVotingBalance.toString()).to.be.equals( + (importanceBlockInfoDto.block as ImportanceBlockDTO).totalVotingBalance, + ); + expect((blockInfo as NemesisImportanceBlockInfo).importanceBlockFooter.votingEligibleAccountsCount).to.be.equals( + (importanceBlockInfoDto.block as ImportanceBlockDTO).votingEligibleAccountsCount, + ); + } } it('getBlockInfo', async () => { @@ -107,6 +148,12 @@ describe('BlockHttp', () => { assertBlockInfo(blockInfo); }); + it('getImportanceBlockInfo', async () => { + when(blockRoutesApi.getBlockByHeight('1')).thenReturn(Promise.resolve(importanceBlockInfoDto)); + const blockInfo = await blockRepository.getBlockByHeight(UInt64.fromUint(1)).toPromise(); + assertBlockInfo(blockInfo, true); + }); + it('searchBlocks', async () => { const pagination = {} as Pagination; pagination.pageNumber = 1; @@ -166,4 +213,18 @@ describe('BlockHttp', () => { .toPromise() .catch((error) => expect(error).not.to.be.undefined); }); + + it('wrong block type - Error', async () => { + const wrongBlock = Object.assign({}, blockInfoDto, { + block: { + ...blockDTO, + type: 123, + }, + }); + when(blockRoutesApi.getBlockByHeight('1')).thenReturn(Promise.resolve(wrongBlock)); + await blockRepository + .getBlockByHeight(UInt64.fromUint(1)) + .toPromise() + .catch((error) => expect(error).not.to.be.undefined); + }); }); diff --git a/test/model/blockchain/BlockInfo.spec.ts b/test/model/blockchain/BlockInfo.spec.ts index f8f0b260ae..ef3602973c 100644 --- a/test/model/blockchain/BlockInfo.spec.ts +++ b/test/model/blockchain/BlockInfo.spec.ts @@ -18,11 +18,11 @@ import { deepEqual } from 'assert'; import { expect } from 'chai'; import { Address } from '../../../src/model/account/Address'; import { PublicAccount } from '../../../src/model/account/PublicAccount'; -import { BlockInfo } from '../../../src/model/blockchain/BlockInfo'; +import { NormalBlockInfo } from '../../../src/model/blockchain/NomalBlockInfo'; import { UInt64 } from '../../../src/model/UInt64'; describe('BlockInfo', () => { - it('should createComplete an BlockInfo object', () => { + it('should createComplete an NormalBlockInfo object', () => { const blockDTO = { id: '12345', block: { @@ -43,7 +43,7 @@ describe('BlockInfo', () => { signerPublicKey: 'B4F12E7C9F6946091E2CB8B6D3A12B50D17CCBBF646386EA27CE2946A7423DCF', beneficiaryAddress: '7826D27E1D0A26CA4E316F901E23E55C8711DB20DF5C49B5', timestamp: new UInt64([0, 0]), - type: 32768, + type: 33091, version: 1, network: 144, }, @@ -58,7 +58,7 @@ describe('BlockInfo', () => { }, }; - const blockInfo = new BlockInfo( + const blockInfo = new NormalBlockInfo( blockDTO.id, blockDTO.block.size, blockDTO.meta.hash, diff --git a/test/model/blockchain/ImportanceBlockFooter.spec.ts b/test/model/blockchain/ImportanceBlockFooter.spec.ts new file mode 100644 index 0000000000..9d4e260584 --- /dev/null +++ b/test/model/blockchain/ImportanceBlockFooter.spec.ts @@ -0,0 +1,42 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect } from 'chai'; +import { ImportanceBlockFooter } from '../../../src/model/blockchain/ImportanceBlockFooter'; +import { UInt64 } from '../../../src/model/UInt64'; + +describe('BlockFooter', () => { + it('should createComplete an blockFooter object', () => { + const importanceBlockInfoDto = { + votingEligibleAccountsCount: 1, + harvestingEligibleAccountsCount: '1', + totalVotingBalance: '1', + previousImportanceBlockHash: 'hash', + }; + const info = new ImportanceBlockFooter( + importanceBlockInfoDto.votingEligibleAccountsCount, + UInt64.fromNumericString(importanceBlockInfoDto.harvestingEligibleAccountsCount), + UInt64.fromNumericString(importanceBlockInfoDto.totalVotingBalance), + importanceBlockInfoDto.previousImportanceBlockHash, + ); + + expect(info).to.be.not.null; + expect(info.votingEligibleAccountsCount).to.be.equals(1); + expect(info.harvestingEligibleAccountsCount.toString()).to.be.equals('1'); + expect(info.totalVotingBalance.toString()).to.be.equals('1'); + expect(info.previousImportanceBlockHash).to.be.equals('hash'); + }); +}); diff --git a/test/service/BlockService.spec.ts b/test/service/BlockService.spec.ts index 68edb5a204..94fdd47d38 100644 --- a/test/service/BlockService.spec.ts +++ b/test/service/BlockService.spec.ts @@ -29,6 +29,7 @@ import { BlockInfo } from '../../src/model/blockchain/BlockInfo'; import { MerklePathItem } from '../../src/model/blockchain/MerklePathItem'; import { MerklePosition } from '../../src/model/blockchain/MerklePosition'; import { MerkleProofInfo } from '../../src/model/blockchain/MerkleProofInfo'; +import { NormalBlockInfo } from '../../src/model/blockchain/NomalBlockInfo'; import { PlainMessage } from '../../src/model/message/PlainMessage'; import { NetworkType } from '../../src/model/network/NetworkType'; import { Transaction } from '../../src/model/transaction/Transaction'; @@ -45,7 +46,7 @@ describe('BlockService', () => { function mockBlockInfo(isFake = false): BlockInfo { if (isFake) { - return new BlockInfo( + return new NormalBlockInfo( 'id', 1, 'hash', @@ -74,7 +75,7 @@ describe('BlockService', () => { 0, ); } - return new BlockInfo( + return new NormalBlockInfo( 'id', 1, 'hash', From 9533a27df9910f1f4c931544bb1165fb54e64c91 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Fri, 20 Nov 2020 11:29:19 +0000 Subject: [PATCH 2/2] PR feedbacks --- src/infrastructure/BlockHttp.ts | 22 +++------- src/model/blockchain/ImportanceBlockFooter.ts | 38 ----------------- .../blockchain/NemesisImportanceBlockInfo.ts | 9 +++- src/model/blockchain/index.ts | 1 - test/infrastructure/BlockHttp.spec.ts | 8 ++-- test/model/blockchain/BlockInfo.spec.ts | 3 +- .../blockchain/ImportanceBlockFooter.spec.ts | 42 ------------------- 7 files changed, 19 insertions(+), 104 deletions(-) delete mode 100644 src/model/blockchain/ImportanceBlockFooter.ts delete mode 100644 test/model/blockchain/ImportanceBlockFooter.spec.ts diff --git a/src/infrastructure/BlockHttp.ts b/src/infrastructure/BlockHttp.ts index 168b532abb..3bbcfedcd2 100644 --- a/src/infrastructure/BlockHttp.ts +++ b/src/infrastructure/BlockHttp.ts @@ -21,7 +21,6 @@ import { Address } from '../model/account/Address'; import { PublicAccount } from '../model/account/PublicAccount'; import { BlockInfo } from '../model/blockchain/BlockInfo'; import { BlockType } from '../model/blockchain/BlockType'; -import { ImportanceBlockFooter } from '../model/blockchain/ImportanceBlockFooter'; import { MerklePathItem } from '../model/blockchain/MerklePathItem'; import { MerkleProofInfo } from '../model/blockchain/MerkleProofInfo'; import { NemesisImportanceBlockInfo } from '../model/blockchain/NemesisImportanceBlockInfo'; @@ -125,21 +124,12 @@ export class BlockHttp extends Http implements BlockRepository { return normalBlock; } else if ([BlockType.ImportanceBlock.valueOf(), BlockType.NemesisBlock.valueOf()].includes(blockType)) { const importanceBlockInfoDto = dto.block as ImportanceBlockDTO; - const importanceBlockFooter = new ImportanceBlockFooter( - importanceBlockInfoDto.votingEligibleAccountsCount, - UInt64.fromNumericString(importanceBlockInfoDto.harvestingEligibleAccountsCount), - UInt64.fromNumericString(importanceBlockInfoDto.totalVotingBalance), - importanceBlockInfoDto.previousImportanceBlockHash, - ); - return Object.assign( - { - __proto__: Object.getPrototypeOf(normalBlock), - }, - normalBlock, - { - importanceBlockFooter, - }, - ) as NemesisImportanceBlockInfo; + return DtoMapping.assign(normalBlock, { + votingEligibleAccountsCount: importanceBlockInfoDto.votingEligibleAccountsCount, + harvestingEligibleAccountsCount: UInt64.fromNumericString(importanceBlockInfoDto.harvestingEligibleAccountsCount), + totalVotingBalance: UInt64.fromNumericString(importanceBlockInfoDto.totalVotingBalance), + previousImportanceBlockHash: importanceBlockInfoDto.previousImportanceBlockHash, + }) as NemesisImportanceBlockInfo; } else { throw new Error(`Block type: ${blockType} invalid.`); } diff --git a/src/model/blockchain/ImportanceBlockFooter.ts b/src/model/blockchain/ImportanceBlockFooter.ts deleted file mode 100644 index e4356ae1c4..0000000000 --- a/src/model/blockchain/ImportanceBlockFooter.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2020 NEM - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { UInt64 } from '../UInt64'; - -export class ImportanceBlockFooter { - constructor( - /** - * Number of voting eligible accounts. - */ - public readonly votingEligibleAccountsCount: number, - /** - * Number of harvesting eligible accounts. - */ - public readonly harvestingEligibleAccountsCount: UInt64, - /** - * Total balance eligible for voting. - */ - public readonly totalVotingBalance: UInt64, - /** - * Previous importance block hash. - */ - public readonly previousImportanceBlockHash: string, - ) {} -} diff --git a/src/model/blockchain/NemesisImportanceBlockInfo.ts b/src/model/blockchain/NemesisImportanceBlockInfo.ts index 3dad5023ee..68dd638c5f 100644 --- a/src/model/blockchain/NemesisImportanceBlockInfo.ts +++ b/src/model/blockchain/NemesisImportanceBlockInfo.ts @@ -14,7 +14,12 @@ * limitations under the License. */ -import { ImportanceBlockFooter } from './ImportanceBlockFooter'; +import { UInt64 } from '../UInt64'; import { NormalBlockInfo } from './NomalBlockInfo'; -export type NemesisImportanceBlockInfo = NormalBlockInfo & { importanceBlockFooter: ImportanceBlockFooter }; +export type NemesisImportanceBlockInfo = NormalBlockInfo & { + votingEligibleAccountsCount: number; + harvestingEligibleAccountsCount: UInt64; + totalVotingBalance: UInt64; + previousImportanceBlockHash: string; +}; diff --git a/src/model/blockchain/index.ts b/src/model/blockchain/index.ts index bea75697c1..dcb4a7b61c 100644 --- a/src/model/blockchain/index.ts +++ b/src/model/blockchain/index.ts @@ -4,7 +4,6 @@ export * from './BlockInfo'; export * from './BlockType'; export * from './ChainInfo'; export * from './FinalizedBlock'; -export * from './ImportanceBlockFooter'; export * from './MerklePathItem'; export * from './MerklePosition'; export * from './MerkleProofInfo'; diff --git a/test/infrastructure/BlockHttp.spec.ts b/test/infrastructure/BlockHttp.spec.ts index eedb5169e6..602aba67fa 100644 --- a/test/infrastructure/BlockHttp.spec.ts +++ b/test/infrastructure/BlockHttp.spec.ts @@ -127,16 +127,16 @@ describe('BlockHttp', () => { expect(blockInfo.totalFee.toString()).to.be.equals(blockInfoDto.meta.totalFee); if (isImportance) { - expect((blockInfo as NemesisImportanceBlockInfo).importanceBlockFooter.harvestingEligibleAccountsCount.toString()).to.be.equals( + expect((blockInfo as NemesisImportanceBlockInfo).harvestingEligibleAccountsCount.toString()).to.be.equals( (importanceBlockInfoDto.block as ImportanceBlockDTO).harvestingEligibleAccountsCount, ); - expect((blockInfo as NemesisImportanceBlockInfo).importanceBlockFooter.previousImportanceBlockHash).to.be.equals( + expect((blockInfo as NemesisImportanceBlockInfo).previousImportanceBlockHash).to.be.equals( (importanceBlockInfoDto.block as ImportanceBlockDTO).previousImportanceBlockHash, ); - expect((blockInfo as NemesisImportanceBlockInfo).importanceBlockFooter.totalVotingBalance.toString()).to.be.equals( + expect((blockInfo as NemesisImportanceBlockInfo).totalVotingBalance.toString()).to.be.equals( (importanceBlockInfoDto.block as ImportanceBlockDTO).totalVotingBalance, ); - expect((blockInfo as NemesisImportanceBlockInfo).importanceBlockFooter.votingEligibleAccountsCount).to.be.equals( + expect((blockInfo as NemesisImportanceBlockInfo).votingEligibleAccountsCount).to.be.equals( (importanceBlockInfoDto.block as ImportanceBlockDTO).votingEligibleAccountsCount, ); } diff --git a/test/model/blockchain/BlockInfo.spec.ts b/test/model/blockchain/BlockInfo.spec.ts index ef3602973c..509a3e33b3 100644 --- a/test/model/blockchain/BlockInfo.spec.ts +++ b/test/model/blockchain/BlockInfo.spec.ts @@ -16,6 +16,7 @@ import { deepEqual } from 'assert'; import { expect } from 'chai'; +import { BlockType } from '../../../src'; import { Address } from '../../../src/model/account/Address'; import { PublicAccount } from '../../../src/model/account/PublicAccount'; import { NormalBlockInfo } from '../../../src/model/blockchain/NomalBlockInfo'; @@ -43,7 +44,7 @@ describe('BlockInfo', () => { signerPublicKey: 'B4F12E7C9F6946091E2CB8B6D3A12B50D17CCBBF646386EA27CE2946A7423DCF', beneficiaryAddress: '7826D27E1D0A26CA4E316F901E23E55C8711DB20DF5C49B5', timestamp: new UInt64([0, 0]), - type: 33091, + type: BlockType.NormalBlock, version: 1, network: 144, }, diff --git a/test/model/blockchain/ImportanceBlockFooter.spec.ts b/test/model/blockchain/ImportanceBlockFooter.spec.ts deleted file mode 100644 index 9d4e260584..0000000000 --- a/test/model/blockchain/ImportanceBlockFooter.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2020 NEM - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { expect } from 'chai'; -import { ImportanceBlockFooter } from '../../../src/model/blockchain/ImportanceBlockFooter'; -import { UInt64 } from '../../../src/model/UInt64'; - -describe('BlockFooter', () => { - it('should createComplete an blockFooter object', () => { - const importanceBlockInfoDto = { - votingEligibleAccountsCount: 1, - harvestingEligibleAccountsCount: '1', - totalVotingBalance: '1', - previousImportanceBlockHash: 'hash', - }; - const info = new ImportanceBlockFooter( - importanceBlockInfoDto.votingEligibleAccountsCount, - UInt64.fromNumericString(importanceBlockInfoDto.harvestingEligibleAccountsCount), - UInt64.fromNumericString(importanceBlockInfoDto.totalVotingBalance), - importanceBlockInfoDto.previousImportanceBlockHash, - ); - - expect(info).to.be.not.null; - expect(info.votingEligibleAccountsCount).to.be.equals(1); - expect(info.harvestingEligibleAccountsCount.toString()).to.be.equals('1'); - expect(info.totalVotingBalance.toString()).to.be.equals('1'); - expect(info.previousImportanceBlockHash).to.be.equals('hash'); - }); -});