From 9fe535b159a5aba4a227d0338aaddf3421463791 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Fri, 30 Aug 2019 14:25:04 +0800 Subject: [PATCH 01/18] feat: add hasData and typeScript to output entity --- .../src/database/chain/entities/output.ts | 11 +++++++++ .../1567144517514-AddTypeAndHasData.ts | 24 +++++++++++++++++++ .../src/database/chain/ormconfig.ts | 3 ++- 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 packages/neuron-wallet/src/database/chain/migrations/1567144517514-AddTypeAndHasData.ts diff --git a/packages/neuron-wallet/src/database/chain/entities/output.ts b/packages/neuron-wallet/src/database/chain/entities/output.ts index 23e5606b53..8ec0559ebd 100644 --- a/packages/neuron-wallet/src/database/chain/entities/output.ts +++ b/packages/neuron-wallet/src/database/chain/entities/output.ts @@ -35,6 +35,17 @@ export default class Output extends BaseEntity { }) status!: string + @Column({ + type: 'simple-json', + nullable: true, + }) + typeScript: Script | null = null + + @Column({ + type: 'boolean', + }) + hasData!: boolean + public outPoint(): OutPoint { return { txHash: this.outPointTxHash, diff --git a/packages/neuron-wallet/src/database/chain/migrations/1567144517514-AddTypeAndHasData.ts b/packages/neuron-wallet/src/database/chain/migrations/1567144517514-AddTypeAndHasData.ts new file mode 100644 index 0000000000..62d32918cf --- /dev/null +++ b/packages/neuron-wallet/src/database/chain/migrations/1567144517514-AddTypeAndHasData.ts @@ -0,0 +1,24 @@ +import {MigrationInterface, QueryRunner, TableColumn} from "typeorm"; + +export class AddTypeAndHasData1567144517514 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.addColumn('output', new TableColumn({ + name: 'typeScript', + type: 'varchar', + isNullable: true, + })) + + await queryRunner.addColumn('output', new TableColumn({ + name: 'hasData', + type: 'boolean', + default: false, + })) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('output', 'hasData') + await queryRunner.dropColumn('output', 'typeScript') + } + +} diff --git a/packages/neuron-wallet/src/database/chain/ormconfig.ts b/packages/neuron-wallet/src/database/chain/ormconfig.ts index d7732905f5..e2e4953a37 100644 --- a/packages/neuron-wallet/src/database/chain/ormconfig.ts +++ b/packages/neuron-wallet/src/database/chain/ormconfig.ts @@ -10,6 +10,7 @@ import Input from './entities/input' import Output from './entities/output' import SyncInfo from './entities/sync-info' import { InitMigration1566959757554 } from './migrations/1566959757554-InitMigration' +import { AddTypeAndHasData1567144517514 } from './migrations/1567144517514-AddTypeAndHasData' export const CONNECTION_NOT_FOUND_NAME = 'ConnectionNotFoundError' @@ -29,7 +30,7 @@ const connectOptions = async (genesisBlockHash: string): Promise Date: Fri, 30 Aug 2019 15:02:40 +0800 Subject: [PATCH 02/18] feat: skip cells which has data or type --- packages/neuron-wallet/src/services/cells.ts | 3 +++ .../src/services/tx/transaction-persistor.ts | 10 ++++++++++ packages/neuron-wallet/src/types/type-convert.ts | 6 ++++++ 3 files changed, 19 insertions(+) diff --git a/packages/neuron-wallet/src/services/cells.ts b/packages/neuron-wallet/src/services/cells.ts index 666ea6d7a9..8af295d2eb 100644 --- a/packages/neuron-wallet/src/services/cells.ts +++ b/packages/neuron-wallet/src/services/cells.ts @@ -10,12 +10,15 @@ export const MIN_CELL_CAPACITY = '6100000000' /* eslint no-await-in-loop: "warn" */ /* eslint no-restricted-syntax: "warn" */ export default class CellsService { + // exclude hasData = true and typeScript != null public static getBalance = async (lockHashes: string[], status: OutputStatus): Promise => { const cells: OutputEntity[] = await getConnection() .getRepository(OutputEntity) .find({ where: { lockHash: In(lockHashes), + hasData: false, + typeScript: null, status, }, }) diff --git a/packages/neuron-wallet/src/services/tx/transaction-persistor.ts b/packages/neuron-wallet/src/services/tx/transaction-persistor.ts index 0508fe0b77..e0e5e8f4fa 100644 --- a/packages/neuron-wallet/src/services/tx/transaction-persistor.ts +++ b/packages/neuron-wallet/src/services/tx/transaction-persistor.ts @@ -133,6 +133,7 @@ export class TransactionPersistor { } } + const outputsData = transaction.outputsData! const outputs: OutputEntity[] = await Promise.all( transaction.outputs!.map(async (o, index) => { const output = new OutputEntity() @@ -143,6 +144,15 @@ export class TransactionPersistor { output.lockHash = o.lockHash! output.transaction = tx output.status = outputStatus + if (o.type) { + output.typeScript = o.type + } + const data = outputsData[index] + if (data && data !== '0x') { + output.hasData = true + } else { + output.hasData = false + } return output }) ) diff --git a/packages/neuron-wallet/src/types/type-convert.ts b/packages/neuron-wallet/src/types/type-convert.ts index 7512600cdb..35b382b07a 100644 --- a/packages/neuron-wallet/src/types/type-convert.ts +++ b/packages/neuron-wallet/src/types/type-convert.ts @@ -41,6 +41,7 @@ export default class TypeConvert { witnesses: transaction.witnesses, inputs: transaction.inputs.map(input => TypeConvert.toInput(input)), outputs: transaction.outputs.map(output => TypeConvert.toOutput(output)), + outputsData: transaction.outputsData, } if (blockHeader) { tx.timestamp = blockHeader.timestamp @@ -72,9 +73,14 @@ export default class TypeConvert { } static toOutput(output: CKBComponents.CellOutput): Cell { + let type: Script | undefined + if (output.type) { + type = TypeConvert.toScript(output.type) + } return { capacity: output.capacity.toString(), lock: TypeConvert.toScript(output.lock), + type, } } From abf8ae9164466923130f7b7f65ae271938b32109 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Fri, 30 Aug 2019 15:35:56 +0800 Subject: [PATCH 03/18] chore: only spent cells without data or type when gather inputs --- packages/neuron-wallet/src/services/cells.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/neuron-wallet/src/services/cells.ts b/packages/neuron-wallet/src/services/cells.ts index 8af295d2eb..1f90e2614f 100644 --- a/packages/neuron-wallet/src/services/cells.ts +++ b/packages/neuron-wallet/src/services/cells.ts @@ -70,13 +70,15 @@ export default class CellsService { throw new Error(`capacity can't be less than ${MIN_CELL_CAPACITY}`) } - // only live cells + // only live cells, skip which has data or type const cellEntities: OutputEntity[] = await getConnection() .getRepository(OutputEntity) .find({ where: { lockHash: In(lockHashes), status: 'live', + hasData: false, + typeScript: null, }, }) cellEntities.sort((a, b) => { From e334085d73f3c68e4c51c940b9972b58c1588974 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Fri, 30 Aug 2019 15:42:29 +0800 Subject: [PATCH 04/18] fix: change typeScript type to `text` from `varchar` --- .../chain/migrations/1567144517514-AddTypeAndHasData.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/neuron-wallet/src/database/chain/migrations/1567144517514-AddTypeAndHasData.ts b/packages/neuron-wallet/src/database/chain/migrations/1567144517514-AddTypeAndHasData.ts index 62d32918cf..f6c6c2da0f 100644 --- a/packages/neuron-wallet/src/database/chain/migrations/1567144517514-AddTypeAndHasData.ts +++ b/packages/neuron-wallet/src/database/chain/migrations/1567144517514-AddTypeAndHasData.ts @@ -5,7 +5,7 @@ export class AddTypeAndHasData1567144517514 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { await queryRunner.addColumn('output', new TableColumn({ name: 'typeScript', - type: 'varchar', + type: 'text', isNullable: true, })) From a9521523af79fa79f09662a2f3070d421f3579a6 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Tue, 3 Sep 2019 13:06:52 +0800 Subject: [PATCH 05/18] feat: add SkipDataAndType class --- .../src/services/skip-data-and-type.ts | 51 +++++++++++++++++ .../tests/services/skip-data-and-type.test.ts | 56 +++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 packages/neuron-wallet/src/services/skip-data-and-type.ts create mode 100644 packages/neuron-wallet/tests/services/skip-data-and-type.test.ts diff --git a/packages/neuron-wallet/src/services/skip-data-and-type.ts b/packages/neuron-wallet/src/services/skip-data-and-type.ts new file mode 100644 index 0000000000..65a80dbac2 --- /dev/null +++ b/packages/neuron-wallet/src/services/skip-data-and-type.ts @@ -0,0 +1,51 @@ +import FileService from './file' + +export default class SkipDataAndType { + private static moduleName = '' + private static fileName = 'skip-data-and-type.json' + + private open: boolean | undefined = undefined + + private static instance: SkipDataAndType + + static getInstance(): SkipDataAndType { + if (!SkipDataAndType.instance) { + SkipDataAndType.instance = new SkipDataAndType() + } + + return SkipDataAndType.instance + } + + // open means can use cells with data and type + public update(open: boolean) { + FileService.getInstance().writeFileSync( + SkipDataAndType.moduleName, + SkipDataAndType.fileName, + JSON.stringify({ + open, + }) + ) + // cache this variable + this.open = open + } + + public get(): boolean { + // if cached, don't to read file + if (this.open !== undefined) { + return this.open + } + const fileService = FileService.getInstance() + const { moduleName, fileName } = SkipDataAndType + + if (fileService.hasFile(moduleName, fileName)) { + const info = FileService.getInstance().readFileSync(moduleName, fileName) + const { open } = JSON.parse(info) + if (open === false) { + return false + } + } + + // default is true + return true + } +} diff --git a/packages/neuron-wallet/tests/services/skip-data-and-type.test.ts b/packages/neuron-wallet/tests/services/skip-data-and-type.test.ts new file mode 100644 index 0000000000..c4122a2399 --- /dev/null +++ b/packages/neuron-wallet/tests/services/skip-data-and-type.test.ts @@ -0,0 +1,56 @@ +import SkipDataAndType from '../../src/services/skip-data-and-type' +import FileService from '../../src/services/file' + +describe(`SkipDataAndType`, () => { + let skipDataAndType: SkipDataAndType | undefined + + beforeEach(() => { + const fileService = FileService.getInstance() + // @ts-ignore: Private method + const { moduleName, fileName } = SkipDataAndType + if (fileService.hasFile(moduleName, fileName)) { + fileService.deleteFileSync(moduleName, fileName) + } + + skipDataAndType = new SkipDataAndType() + }) + + it('getInstance', () => { + const skip = SkipDataAndType.getInstance() + expect(skip).toBeInstanceOf(SkipDataAndType) + }) + + it('update', () => { + expect(() => { + skipDataAndType!.update(true) + }).not.toThrowError() + }) + + describe('with instance cache', () => { + it('get true', () => { + skipDataAndType!.update(true) + const open = skipDataAndType!.get() + expect(open).toBe(true) + }) + + it('get false', () => { + skipDataAndType!.update(false) + const open = skipDataAndType!.get() + expect(open).toBe(false) + }) + }) + + describe('without cache', () => { + it('first time open', () => { + const open = skipDataAndType!.get() + expect(open).toBe(true) + }) + + it('new instance', () => { + skipDataAndType!.update(false) + const newInstance = new SkipDataAndType() + const open = newInstance.get() + expect(open).toBe(false) + }) + }) +}) From 5746438d1960095664fb373a4f540e285606cc09 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Tue, 3 Sep 2019 13:07:05 +0800 Subject: [PATCH 06/18] feat: add totalBalance to address entity --- .../src/database/address/entities/address.ts | 3 +++ .../migrations/1562126909151-extendBalance.ts | 4 ++-- .../migrations/1567485550388-AddTotalBalance.ts | 17 +++++++++++++++++ .../src/database/address/ormconfig.ts | 3 ++- 4 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 packages/neuron-wallet/src/database/address/migrations/1567485550388-AddTotalBalance.ts diff --git a/packages/neuron-wallet/src/database/address/entities/address.ts b/packages/neuron-wallet/src/database/address/entities/address.ts index 1cdd995d60..a6391d98ce 100644 --- a/packages/neuron-wallet/src/database/address/entities/address.ts +++ b/packages/neuron-wallet/src/database/address/entities/address.ts @@ -73,6 +73,9 @@ export default class Address extends BaseEntity { @Column() pendingBalance: string = '0' + @Column() + totalBalance: string = '0' + public balance = (): string => { return (BigInt(this.liveBalance) + BigInt(this.sentBalance)).toString() } diff --git a/packages/neuron-wallet/src/database/address/migrations/1562126909151-extendBalance.ts b/packages/neuron-wallet/src/database/address/migrations/1562126909151-extendBalance.ts index 6b6de96d16..516d5befbc 100644 --- a/packages/neuron-wallet/src/database/address/migrations/1562126909151-extendBalance.ts +++ b/packages/neuron-wallet/src/database/address/migrations/1562126909151-extendBalance.ts @@ -13,8 +13,8 @@ export class extendBalance1562126909151 implements MigrationInterface { } public async down(queryRunner: QueryRunner): Promise { - await queryRunner.dropColumn('transaction', 'sentBalance') - await queryRunner.dropColumn('transaction', 'pendingBalance') + await queryRunner.dropColumn('address', 'sentBalance') + await queryRunner.dropColumn('address', 'pendingBalance') await queryRunner.changeColumn('address', 'liveBalance', new TableColumn({ name: 'balance', type: 'varchar', diff --git a/packages/neuron-wallet/src/database/address/migrations/1567485550388-AddTotalBalance.ts b/packages/neuron-wallet/src/database/address/migrations/1567485550388-AddTotalBalance.ts new file mode 100644 index 0000000000..03b3e5df9b --- /dev/null +++ b/packages/neuron-wallet/src/database/address/migrations/1567485550388-AddTotalBalance.ts @@ -0,0 +1,17 @@ +import {MigrationInterface, QueryRunner, TableColumn} from "typeorm"; + +export class AddTotalBalance1567485550388 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.addColumn('address', new TableColumn({ + name: 'totalBalance', + type: 'varchar', + default: '0', + })) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('address', 'totalBalance') + } + +} diff --git a/packages/neuron-wallet/src/database/address/ormconfig.ts b/packages/neuron-wallet/src/database/address/ormconfig.ts index 7e4731830e..63a6ee6765 100644 --- a/packages/neuron-wallet/src/database/address/ormconfig.ts +++ b/packages/neuron-wallet/src/database/address/ormconfig.ts @@ -8,6 +8,7 @@ import Address from './entities/address' import { AddAddress1561461669542 } from './migrations/1561461669542-AddAddress' import { extendBalance1562126909151 } from './migrations/1562126909151-extendBalance' +import { AddTotalBalance1567485550388 } from './migrations/1567485550388-AddTotalBalance' const dbPath = path.join(env.fileBasePath, 'address.sqlite') @@ -20,7 +21,7 @@ const connectOptions = (): SqliteConnectionOptions => { type: 'sqlite', database, entities: [Address], - migrations: [AddAddress1561461669542, extendBalance1562126909151], + migrations: [AddAddress1561461669542, extendBalance1562126909151, AddTotalBalance1567485550388], synchronize: false, migrationsRun: true, logging: ['error'], From f455545d825c0c5b851fc27e4da46263550c1bf9 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Tue, 3 Sep 2019 14:16:27 +0800 Subject: [PATCH 07/18] feat: calculate totalBalance and check skip data and type in gather inputs --- .../neuron-wallet/src/database/address/dao.ts | 11 +++-- packages/neuron-wallet/src/services/cells.ts | 45 +++++++++++++------ 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/packages/neuron-wallet/src/database/address/dao.ts b/packages/neuron-wallet/src/database/address/dao.ts index 9428164b98..e47bbb5730 100644 --- a/packages/neuron-wallet/src/database/address/dao.ts +++ b/packages/neuron-wallet/src/database/address/dao.ts @@ -51,6 +51,8 @@ export default class AddressDao { // sentBalance means balance of OutputStatus.Sent cells (sent to me but not committed) // pendingBalance means balance of OutputStatus.Pending cells (sent from me, but not committed) // so the final balance is (liveBalance + sentBalance - pendingBalance) + // balance is the balance which skipped data and type + // totalBalance means balance with data and type public static updateTxCountAndBalance = async (address: string): Promise => { const addressEntities = await getConnection() .getRepository(AddressEntity) @@ -67,9 +69,12 @@ export default class AddressDao { const addressEntity = entity addressEntity.txCount = txCount const lockHashes: string[] = await LockUtils.addressToAllLockHashes(addressEntity.address) - addressEntity.liveBalance = await CellsService.getBalance(lockHashes, OutputStatus.Live) - addressEntity.sentBalance = await CellsService.getBalance(lockHashes, OutputStatus.Sent) - addressEntity.pendingBalance = await CellsService.getBalance(lockHashes, OutputStatus.Pending) + addressEntity.liveBalance = await CellsService.getBalance(lockHashes, OutputStatus.Live, true) + addressEntity.sentBalance = await CellsService.getBalance(lockHashes, OutputStatus.Sent, true) + addressEntity.pendingBalance = await CellsService.getBalance(lockHashes, OutputStatus.Pending, true) + const totalLiveBalance = await CellsService.getBalance(lockHashes, OutputStatus.Live, false) + const totalSentBalance = await CellsService.getBalance(lockHashes, OutputStatus.Sent, false) + addressEntity.totalBalance = (BigInt(totalLiveBalance) - BigInt(totalSentBalance)).toString() return addressEntity }) ) diff --git a/packages/neuron-wallet/src/services/cells.ts b/packages/neuron-wallet/src/services/cells.ts index 1f90e2614f..0f00d39348 100644 --- a/packages/neuron-wallet/src/services/cells.ts +++ b/packages/neuron-wallet/src/services/cells.ts @@ -3,6 +3,7 @@ import OutputEntity from 'database/chain/entities/output' import { Cell, OutPoint, Input } from 'types/cell-types' import { CapacityNotEnough } from 'exceptions' import { OutputStatus } from './tx/params' +import SkipDataAndType from './skip-data-and-type' export const MIN_CELL_CAPACITY = '6100000000' @@ -11,16 +12,27 @@ export const MIN_CELL_CAPACITY = '6100000000' /* eslint no-restricted-syntax: "warn" */ export default class CellsService { // exclude hasData = true and typeScript != null - public static getBalance = async (lockHashes: string[], status: OutputStatus): Promise => { + public static getBalance = async ( + lockHashes: string[], + status: OutputStatus, + skipDataAndType: boolean + ): Promise => { + const queryParams = { + lockHash: In(lockHashes), + status, + } + + if (skipDataAndType) { + Object.assign(queryParams, { + hasData: false, + typeScript: null, + }) + } + const cells: OutputEntity[] = await getConnection() .getRepository(OutputEntity) .find({ - where: { - lockHash: In(lockHashes), - hasData: false, - typeScript: null, - status, - }, + where: queryParams, }) const capacity: bigint = cells.map(c => BigInt(c.capacity)).reduce((result, c) => result + c, BigInt(0)) @@ -70,16 +82,23 @@ export default class CellsService { throw new Error(`capacity can't be less than ${MIN_CELL_CAPACITY}`) } + const queryParams = { + lockHashes: In(lockHashes), + status: OutputStatus.Live, + } + const skipDataAndType = SkipDataAndType.getInstance().get() + if (skipDataAndType) { + Object.assign(queryParams, { + hasData: false, + typeScript: null, + }) + } + // only live cells, skip which has data or type const cellEntities: OutputEntity[] = await getConnection() .getRepository(OutputEntity) .find({ - where: { - lockHash: In(lockHashes), - status: 'live', - hasData: false, - typeScript: null, - }, + where: queryParams, }) cellEntities.sort((a, b) => { const result = BigInt(a.capacity) - BigInt(b.capacity) From 834390f9c4a996641cc559771016fab581f37278 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Tue, 3 Sep 2019 14:23:27 +0800 Subject: [PATCH 08/18] feat: add controller for skip data and type --- .../src/controllers/skip-data-and-type.ts | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 packages/neuron-wallet/src/controllers/skip-data-and-type.ts diff --git a/packages/neuron-wallet/src/controllers/skip-data-and-type.ts b/packages/neuron-wallet/src/controllers/skip-data-and-type.ts new file mode 100644 index 0000000000..5508879c6c --- /dev/null +++ b/packages/neuron-wallet/src/controllers/skip-data-and-type.ts @@ -0,0 +1,25 @@ +import { CatchControllerError } from 'decorators/errors' +import { ResponseCode } from 'utils/const' +import SkipDataAndType from 'services/skip-data-and-type' + +export default class SkipDataAndTypeController { + @CatchControllerError + public static async update(open: boolean): Promise> { + SkipDataAndType.getInstance().update(open) + + return { + status: ResponseCode.Success, + result: open, + } + } + + @CatchControllerError + public static async get(): Promise> { + const open = SkipDataAndType.getInstance().get() + + return { + status: ResponseCode.Success, + result: open, + } + } +} From 7a29c03779ec96e8dff951d67662c8517af75f4c Mon Sep 17 00:00:00 2001 From: classicalliu Date: Tue, 3 Sep 2019 14:33:44 +0800 Subject: [PATCH 09/18] feat: add totalBalance to address interface --- packages/neuron-wallet/src/database/address/dao.ts | 1 + .../neuron-wallet/src/database/address/entities/address.ts | 1 + packages/neuron-wallet/src/services/addresses.ts | 5 +++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/neuron-wallet/src/database/address/dao.ts b/packages/neuron-wallet/src/database/address/dao.ts index e47bbb5730..06c8df4f4f 100644 --- a/packages/neuron-wallet/src/database/address/dao.ts +++ b/packages/neuron-wallet/src/database/address/dao.ts @@ -19,6 +19,7 @@ export interface Address { sentBalance: string pendingBalance: string balance: string + totalBalance: string blake160: string version: AddressVersion description?: string diff --git a/packages/neuron-wallet/src/database/address/entities/address.ts b/packages/neuron-wallet/src/database/address/entities/address.ts index a6391d98ce..6ae67eb128 100644 --- a/packages/neuron-wallet/src/database/address/entities/address.ts +++ b/packages/neuron-wallet/src/database/address/entities/address.ts @@ -94,6 +94,7 @@ export default class Address extends BaseEntity { sentBalance: this.sentBalance, pendingBalance: this.pendingBalance, balance: this.balance(), + totalBalance: this.totalBalance, description: this.description, } } diff --git a/packages/neuron-wallet/src/services/addresses.ts b/packages/neuron-wallet/src/services/addresses.ts index 028bc4f946..dfdd910364 100644 --- a/packages/neuron-wallet/src/services/addresses.ts +++ b/packages/neuron-wallet/src/services/addresses.ts @@ -151,7 +151,7 @@ export default class AddressService { } } - private static toAddress = (addressMetaInfo: AddressMetaInfo) => { + private static toAddress = (addressMetaInfo: AddressMetaInfo): AddressInterface[] => { const path: string = Address.pathFor(addressMetaInfo.addressType, addressMetaInfo.addressIndex) const testnetAddress: string = addressMetaInfo.accountExtendedPublicKey.address( addressMetaInfo.addressType, @@ -167,7 +167,7 @@ export default class AddressService { const blake160: string = LockUtils.addressToBlake160(testnetAddress) - const testnetAddressInfo = { + const testnetAddressInfo: AddressInterface = { walletId: addressMetaInfo.walletId, address: testnetAddress, path, @@ -178,6 +178,7 @@ export default class AddressService { sentBalance: '0', pendingBalance: '0', balance: '0', + totalBalance: '0', blake160, version: AddressVersion.Testnet, } From af4ebcd88089b94ba6f6c4e2ee0f27f2c25e041d Mon Sep 17 00:00:00 2001 From: classicalliu Date: Tue, 3 Sep 2019 15:42:54 +0800 Subject: [PATCH 10/18] test: test cells service --- .../src/database/chain/ormconfig.ts | 3 +- .../tests/services/cells.test.ts | 201 ++++++++++++++++++ 2 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 packages/neuron-wallet/tests/services/cells.test.ts diff --git a/packages/neuron-wallet/src/database/chain/ormconfig.ts b/packages/neuron-wallet/src/database/chain/ormconfig.ts index e2e4953a37..af68e415ed 100644 --- a/packages/neuron-wallet/src/database/chain/ormconfig.ts +++ b/packages/neuron-wallet/src/database/chain/ormconfig.ts @@ -21,6 +21,7 @@ const dbPath = (networkName: string): string => { const connectOptions = async (genesisBlockHash: string): Promise => { const connectionOptions = await getConnectionOptions() + const database = env.isTestMode ? ':memory:' : dbPath(genesisBlockHash) const logging: boolean | ('query' | 'schema' | 'error' | 'warn' | 'info' | 'log' | 'migration')[] = process.env.SHOW_CHAIN_DB_LOG && (env.isDevMode || env.isTestMode) ? true : ['warn', 'error'] @@ -28,7 +29,7 @@ const connectOptions = async (genesisBlockHash: string): Promise { + const str: string = Array.from({ length }) + .map(() => Math.floor(Math.random() * 16).toString(16)) + .join('') + + return `0x${str}` +} + +describe('CellsService', () => { + beforeAll(async () => { + await initConnection('0x1234') + }) + + afterAll(async () => { + await getConnection().close() + }) + + beforeEach(async () => { + const connection = getConnection() + await connection.synchronize(true) + }) + + const bob = { + lockScript: { + codeHash: '0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88', + args: ['0x36c329ed630d6ce750712a477543672adab57f4c'], + hashType: ScriptHashType.Type, + }, + lockHash: '0x024b0fd0c4912e98aab6808f6474cacb1969255d526b3cac5d3bdd15962a8818', + address: 'ckt1qyqrdsefa43s6m882pcj53m4gdnj4k440axqswmu83', + blake160: '0x36c329ed630d6ce750712a477543672adab57f4c', + } + + const generateCell = (capacity: string, status: OutputStatus, hasData: boolean, typeScript: Script | null) => { + const output = new OutputEntity() + output.outPointTxHash = randomHex() + output.outPointIndex = '0' + output.capacity = capacity + output.lock = bob.lockScript + output.lockHash = bob.lockHash + output.status = status + output.hasData = hasData + output.typeScript = typeScript + + return output + } + + const createCell = async (capacity: string, status: OutputStatus, hasData: boolean, typeScript: Script | null) => { + const cell = generateCell(capacity, status, hasData, typeScript) + await getConnection().manager.save(cell) + return cell + } + + const typeScript: Script = { + codeHash: randomHex(), + args: [], + hashType: ScriptHashType.Data, + } + + it('getLiveCell', async () => { + const capacity = '1000' + const entity = await createCell(capacity, OutputStatus.Live, false, null) + const outPoint = entity.outPoint() + const cell = await CellsService.getLiveCell(outPoint) + expect(cell!.capacity).toEqual(capacity) + }) + + it('getLiveCell in Sent', async () => { + const capacity = '1000' + const entity = await createCell(capacity, OutputStatus.Sent, false, null) + const outPoint = entity.outPoint() + const cell = await CellsService.getLiveCell(outPoint) + expect(cell).toBeUndefined() + }) + + it('allBlake160s', async () => { + await createCell('1000', OutputStatus.Sent, false, null) + await createCell('1000', OutputStatus.Sent, false, null) + const blake160s = await CellsService.allBlake160s() + expect(blake160s).toEqual([bob.blake160]) + }) + + + + const lockHashes = [bob.lockHash] + + describe('getBalance', () => { + const createCells = async () => { + const cells: OutputEntity[] = [ + generateCell('100', OutputStatus.Live, false, null), + generateCell('200', OutputStatus.Sent, false, null), + generateCell('300', OutputStatus.Pending, false, null), + generateCell('400', OutputStatus.Dead, false, null), + generateCell('1000', OutputStatus.Live, true, null), + generateCell('2000', OutputStatus.Sent, true, null), + generateCell('3000', OutputStatus.Pending, true, null), + generateCell('4000', OutputStatus.Dead, true, null), + generateCell('10000', OutputStatus.Live, false, typeScript), + generateCell('20000', OutputStatus.Sent, false, typeScript), + generateCell('30000', OutputStatus.Pending, false, typeScript), + generateCell('40000', OutputStatus.Dead, false, typeScript), + ] + await getConnection().manager.save(cells) + } + + it('getBalance, Live, skip', async () => { + await createCells() + + const balance: string = await CellsService.getBalance(lockHashes, OutputStatus.Live, true) + expect(balance).toEqual('100') + }) + + it('getBalance, Sent, skip', async () => { + await createCells() + + const balance: string = await CellsService.getBalance(lockHashes, OutputStatus.Sent, true) + expect(balance).toEqual('200') + }) + + it('getBalance, Live, not skip', async () => { + await createCells() + + const balance: string = await CellsService.getBalance(lockHashes, OutputStatus.Live, false) + expect(balance).toEqual('11100') + }) + + it('getBalance, Pending, not skip', async () => { + await createCells() + + const balance: string = await CellsService.getBalance(lockHashes, OutputStatus.Pending, false) + expect(balance).toEqual('33300') + }) + }) + + describe('gatherInputs', () => { + const toShannon = (ckb: string) => `${ckb}00000000` + const createCells = async () => { + const cells: OutputEntity[] = [ + generateCell(toShannon('1000'), OutputStatus.Live, false, null), + generateCell(toShannon('200'), OutputStatus.Sent, false, null), + generateCell(toShannon('2000'), OutputStatus.Live, true, null), + generateCell(toShannon('3000'), OutputStatus.Live, false, typeScript), + ] + await getConnection().manager.save(cells) + } + + it('1000, skip', async () => { + SkipDataAndType.getInstance().update(true) + await createCells() + + const result = await CellsService.gatherInputs(toShannon('1000'), lockHashes) + + expect(result.capacities).toEqual('100000000000') + }) + + it('1001, skip', async () => { + SkipDataAndType.getInstance().update(true) + await createCells() + + let error + try { + await CellsService.gatherInputs(toShannon('1001'), lockHashes) + } catch (e) { + error = e + } + expect(error).toBeInstanceOf(CapacityNotEnough) + }) + + it('6000, not skip', async () => { + SkipDataAndType.getInstance().update(false) + await createCells() + + const ckb = toShannon('6000') + const result = await CellsService.gatherInputs(ckb, lockHashes) + + expect(result.capacities).toEqual(ckb) + }) + + it('6001, not skip', async () => { + SkipDataAndType.getInstance().update(false) + await createCells() + + let error + try { + await CellsService.gatherInputs(toShannon('6001'), lockHashes) + } catch (e) { + error = e + } + expect(error).toBeInstanceOf(CapacityNotEnough) + }) + }) +}) From 90184aa61c731b2f75280e29864a27ccc7b852e8 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Tue, 3 Sep 2019 15:51:30 +0800 Subject: [PATCH 11/18] fix: add totalBalance to address test --- packages/neuron-wallet/tests/database/address/dao.test.ts | 3 +++ packages/neuron-wallet/tests/services/address.test.ts | 3 +++ 2 files changed, 6 insertions(+) diff --git a/packages/neuron-wallet/tests/database/address/dao.test.ts b/packages/neuron-wallet/tests/database/address/dao.test.ts index 2f05b462d5..adb931c074 100644 --- a/packages/neuron-wallet/tests/database/address/dao.test.ts +++ b/packages/neuron-wallet/tests/database/address/dao.test.ts @@ -15,6 +15,7 @@ describe('Address Dao tests', () => { sentBalance: '0', pendingBalance: '0', balance: '0', + totalBalance: '0', blake160: '0x36c329ed630d6ce750712a477543672adab57f4c', version: AddressVersion.Testnet, } @@ -30,6 +31,7 @@ describe('Address Dao tests', () => { sentBalance: '0', pendingBalance: '0', balance: '0', + totalBalance: '0', blake160: '0x36c329ed630d6ce750712a477543672adab57f4c', version: AddressVersion.Testnet, } @@ -45,6 +47,7 @@ describe('Address Dao tests', () => { sentBalance: '0', pendingBalance: '0', balance: '0', + totalBalance: '0', blake160: '0x36c329ed630d6ce750712a477543672adab57f4c', version: AddressVersion.Testnet, } diff --git a/packages/neuron-wallet/tests/services/address.test.ts b/packages/neuron-wallet/tests/services/address.test.ts index 2fae0cdda5..7450c0beee 100644 --- a/packages/neuron-wallet/tests/services/address.test.ts +++ b/packages/neuron-wallet/tests/services/address.test.ts @@ -54,6 +54,7 @@ describe('Key tests with db', () => { sentBalance: '0', pendingBalance: '0', balance: '0', + totalBalance: '0', blake160: '0x36c329ed630d6ce750712a477543672adab57f4c', version: AddressVersion.Testnet, } @@ -69,6 +70,7 @@ describe('Key tests with db', () => { sentBalance: '0', pendingBalance: '0', balance: '0', + totalBalance: '0', blake160: '0x36c329ed630d6ce750712a477543672adab57f4c', version: AddressVersion.Testnet, } @@ -84,6 +86,7 @@ describe('Key tests with db', () => { sentBalance: '0', pendingBalance: '0', balance: '0', + totalBalance: '0', blake160: '0x36c329ed630d6ce750712a477543672adab57f4c', version: AddressVersion.Testnet, } From 4157306eafdecef0369b9d93bd705c8bf1041fd0 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Tue, 3 Sep 2019 15:56:46 +0800 Subject: [PATCH 12/18] chore: rename open to skip --- .../src/services/skip-data-and-type.ts | 16 ++++++++-------- .../tests/services/skip-data-and-type.test.ts | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/neuron-wallet/src/services/skip-data-and-type.ts b/packages/neuron-wallet/src/services/skip-data-and-type.ts index 65a80dbac2..13b2b72ef9 100644 --- a/packages/neuron-wallet/src/services/skip-data-and-type.ts +++ b/packages/neuron-wallet/src/services/skip-data-and-type.ts @@ -4,7 +4,7 @@ export default class SkipDataAndType { private static moduleName = '' private static fileName = 'skip-data-and-type.json' - private open: boolean | undefined = undefined + private skip: boolean | undefined = undefined private static instance: SkipDataAndType @@ -17,30 +17,30 @@ export default class SkipDataAndType { } // open means can use cells with data and type - public update(open: boolean) { + public update(skip: boolean) { FileService.getInstance().writeFileSync( SkipDataAndType.moduleName, SkipDataAndType.fileName, JSON.stringify({ - open, + skip, }) ) // cache this variable - this.open = open + this.skip = skip } public get(): boolean { // if cached, don't to read file - if (this.open !== undefined) { - return this.open + if (this.skip !== undefined) { + return this.skip } const fileService = FileService.getInstance() const { moduleName, fileName } = SkipDataAndType if (fileService.hasFile(moduleName, fileName)) { const info = FileService.getInstance().readFileSync(moduleName, fileName) - const { open } = JSON.parse(info) - if (open === false) { + const { skip } = JSON.parse(info) + if (skip === false) { return false } } diff --git a/packages/neuron-wallet/tests/services/skip-data-and-type.test.ts b/packages/neuron-wallet/tests/services/skip-data-and-type.test.ts index c4122a2399..a49896bfb0 100644 --- a/packages/neuron-wallet/tests/services/skip-data-and-type.test.ts +++ b/packages/neuron-wallet/tests/services/skip-data-and-type.test.ts @@ -29,28 +29,28 @@ describe(`SkipDataAndType`, () => { describe('with instance cache', () => { it('get true', () => { skipDataAndType!.update(true) - const open = skipDataAndType!.get() - expect(open).toBe(true) + const skip = skipDataAndType!.get() + expect(skip).toBe(true) }) it('get false', () => { skipDataAndType!.update(false) - const open = skipDataAndType!.get() - expect(open).toBe(false) + const skip = skipDataAndType!.get() + expect(skip).toBe(false) }) }) describe('without cache', () => { it('first time open', () => { - const open = skipDataAndType!.get() - expect(open).toBe(true) + const skip = skipDataAndType!.get() + expect(skip).toBe(true) }) it('new instance', () => { skipDataAndType!.update(false) const newInstance = new SkipDataAndType() - const open = newInstance.get() - expect(open).toBe(false) + const skip = newInstance.get() + expect(skip).toBe(false) }) }) }) From 11dcac798080ad4e239e9b3a3d8aa637cc197450 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Tue, 3 Sep 2019 16:13:37 +0800 Subject: [PATCH 13/18] fix: fix balance tests --- .../tests/database/address/balance.test.ts | 33 +++++++------------ 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/packages/neuron-wallet/tests/database/address/balance.test.ts b/packages/neuron-wallet/tests/database/address/balance.test.ts index c4279a664d..ebbfba8df6 100644 --- a/packages/neuron-wallet/tests/database/address/balance.test.ts +++ b/packages/neuron-wallet/tests/database/address/balance.test.ts @@ -18,7 +18,11 @@ describe('balance', () => { await connection.synchronize() }) - const generateAddress = (liveBalance: string | bigint, sentBalance: string | bigint, pendingBalance: string | bigint) => { + const generateAddress = ( + liveBalance: string | bigint, + sentBalance: string | bigint, + pendingBalance: string | bigint + ) => { const addr = Math.round(Math.random() * 100000000).toString() const address: Address = { walletId: '1', @@ -31,6 +35,7 @@ describe('balance', () => { sentBalance: sentBalance.toString(), pendingBalance: pendingBalance.toString(), balance: '0', + totalBalance: '0', blake160: '0x36c329ed630d6ce750712a477543672adab57f4c', version: AddressVersion.Testnet, } @@ -53,15 +58,10 @@ describe('balance', () => { it('sent to others', async () => { // have 1000, sent to others 200, and refund 800 - const addresses = [ - generateAddress('0', '0', '1000'), - generateAddress('0', '800', '0'), - ] + const addresses = [generateAddress('0', '0', '1000'), generateAddress('0', '800', '0')] const addrs: AddressEntity[] = await AddressDao.create(addresses) - const balance: bigint = addrs - .map(addr => BigInt(addr.balance())) - .reduce((result, c) => result + c, BigInt(0)) + const balance: bigint = addrs.map(addr => BigInt(addr.balance())).reduce((result, c) => result + c, BigInt(0)) expect(balance).toEqual(BigInt(800)) }) @@ -74,24 +74,17 @@ describe('balance', () => { generateAddress('0', '800', '0'), ] const addrs: AddressEntity[] = await AddressDao.create(addresses) - const balance: bigint = addrs - .map(addr => BigInt(addr.balance())) - .reduce((result, c) => result + c, BigInt(0)) + const balance: bigint = addrs.map(addr => BigInt(addr.balance())).reduce((result, c) => result + c, BigInt(0)) expect(balance).toEqual(BigInt(1000)) }) it('sent to others with 10 shannon fee', async () => { // have 1000, sent to others 200, and refund 790, with 10 shannon fee - const addresses = [ - generateAddress('0', '0', '1000'), - generateAddress('0', '790', '0'), - ] + const addresses = [generateAddress('0', '0', '1000'), generateAddress('0', '790', '0')] const addrs: AddressEntity[] = await AddressDao.create(addresses) - const balance: bigint = addrs - .map(addr => BigInt(addr.balance())) - .reduce((result, c) => result + c, BigInt(0)) + const balance: bigint = addrs.map(addr => BigInt(addr.balance())).reduce((result, c) => result + c, BigInt(0)) expect(balance).toEqual(BigInt(790)) }) @@ -105,9 +98,7 @@ describe('balance', () => { ] const addrs: AddressEntity[] = await AddressDao.create(addresses) - const balance: bigint = addrs - .map(addr => BigInt(addr.balance())) - .reduce((result, c) => result + c, BigInt(0)) + const balance: bigint = addrs.map(addr => BigInt(addr.balance())).reduce((result, c) => result + c, BigInt(0)) expect(balance).toEqual(BigInt(990)) }) From f85244973ca218e0435bef31d6efbdd1ab63b3d7 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Tue, 3 Sep 2019 16:27:50 +0800 Subject: [PATCH 14/18] chore: rename open to skip in controller --- .../src/controllers/skip-data-and-type.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/neuron-wallet/src/controllers/skip-data-and-type.ts b/packages/neuron-wallet/src/controllers/skip-data-and-type.ts index 5508879c6c..392718a6b5 100644 --- a/packages/neuron-wallet/src/controllers/skip-data-and-type.ts +++ b/packages/neuron-wallet/src/controllers/skip-data-and-type.ts @@ -4,22 +4,22 @@ import SkipDataAndType from 'services/skip-data-and-type' export default class SkipDataAndTypeController { @CatchControllerError - public static async update(open: boolean): Promise> { - SkipDataAndType.getInstance().update(open) + public static async update(skip: boolean): Promise> { + SkipDataAndType.getInstance().update(skip) return { status: ResponseCode.Success, - result: open, + result: skip, } } @CatchControllerError public static async get(): Promise> { - const open = SkipDataAndType.getInstance().get() + const skip = SkipDataAndType.getInstance().get() return { status: ResponseCode.Success, - result: open, + result: skip, } } } From 06362a5e32da22ca5d707eb016dc13d3c2fcc5dd Mon Sep 17 00:00:00 2001 From: classicalliu Date: Tue, 3 Sep 2019 18:02:32 +0800 Subject: [PATCH 15/18] chore: update comment open => skip --- packages/neuron-wallet/src/services/skip-data-and-type.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/neuron-wallet/src/services/skip-data-and-type.ts b/packages/neuron-wallet/src/services/skip-data-and-type.ts index 13b2b72ef9..a51cd26d4f 100644 --- a/packages/neuron-wallet/src/services/skip-data-and-type.ts +++ b/packages/neuron-wallet/src/services/skip-data-and-type.ts @@ -16,7 +16,7 @@ export default class SkipDataAndType { return SkipDataAndType.instance } - // open means can use cells with data and type + // skip means can use cells with data and type public update(skip: boolean) { FileService.getInstance().writeFileSync( SkipDataAndType.moduleName, From 37d82fbf10c978b33a9d80a77b623bbfe718be8d Mon Sep 17 00:00:00 2001 From: classicalliu Date: Wed, 4 Sep 2019 12:04:09 +0800 Subject: [PATCH 16/18] feat: add base settings and move skip config to here --- .../src/controllers/skip-data-and-type.ts | 2 +- packages/neuron-wallet/src/services/cells.ts | 2 +- .../src/services/settings/base.ts | 48 ++++++++++ .../{ => settings}/skip-data-and-type.ts | 28 ++---- .../tests/services/cells.test.ts | 2 +- .../tests/services/settings/base.test.ts | 89 +++++++++++++++++++ .../{ => settings}/skip-data-and-type.test.ts | 7 +- 7 files changed, 152 insertions(+), 26 deletions(-) create mode 100644 packages/neuron-wallet/src/services/settings/base.ts rename packages/neuron-wallet/src/services/{ => settings}/skip-data-and-type.ts (50%) create mode 100644 packages/neuron-wallet/tests/services/settings/base.test.ts rename packages/neuron-wallet/tests/services/{ => settings}/skip-data-and-type.test.ts (83%) diff --git a/packages/neuron-wallet/src/controllers/skip-data-and-type.ts b/packages/neuron-wallet/src/controllers/skip-data-and-type.ts index 392718a6b5..5357dc450d 100644 --- a/packages/neuron-wallet/src/controllers/skip-data-and-type.ts +++ b/packages/neuron-wallet/src/controllers/skip-data-and-type.ts @@ -1,6 +1,6 @@ import { CatchControllerError } from 'decorators/errors' import { ResponseCode } from 'utils/const' -import SkipDataAndType from 'services/skip-data-and-type' +import SkipDataAndType from 'services/settings/skip-data-and-type' export default class SkipDataAndTypeController { @CatchControllerError diff --git a/packages/neuron-wallet/src/services/cells.ts b/packages/neuron-wallet/src/services/cells.ts index 0f00d39348..9e20de0160 100644 --- a/packages/neuron-wallet/src/services/cells.ts +++ b/packages/neuron-wallet/src/services/cells.ts @@ -3,7 +3,7 @@ import OutputEntity from 'database/chain/entities/output' import { Cell, OutPoint, Input } from 'types/cell-types' import { CapacityNotEnough } from 'exceptions' import { OutputStatus } from './tx/params' -import SkipDataAndType from './skip-data-and-type' +import SkipDataAndType from './settings/skip-data-and-type' export const MIN_CELL_CAPACITY = '6100000000' diff --git a/packages/neuron-wallet/src/services/settings/base.ts b/packages/neuron-wallet/src/services/settings/base.ts new file mode 100644 index 0000000000..10ebce5bcf --- /dev/null +++ b/packages/neuron-wallet/src/services/settings/base.ts @@ -0,0 +1,48 @@ +import FileService from '../file' + +export default class BaseSettings { + private static moduleName = '' + private static fileName = 'settings.json' + + private static instance: BaseSettings + + public static getInstance(): BaseSettings { + if (!BaseSettings.instance) { + BaseSettings.instance = new BaseSettings() + } + + return BaseSettings.instance + } + + public updateSetting = (key: string, value: any) => { + let settings = this.read() + if (settings === undefined) { + settings = {} + } + Object.assign(settings, { [key]: value }) + FileService.getInstance().writeFileSync(BaseSettings.moduleName, BaseSettings.fileName, JSON.stringify(settings)) + } + + public getSetting = (key: string) => { + const info = this.read() + + if (info) { + return info[key] + } + + return undefined + } + + public read = () => { + const fileService = FileService.getInstance() + const { moduleName, fileName } = BaseSettings + + if (fileService.hasFile(moduleName, fileName)) { + const info = FileService.getInstance().readFileSync(moduleName, fileName) + const value = JSON.parse(info) + return value + } + + return undefined + } +} diff --git a/packages/neuron-wallet/src/services/skip-data-and-type.ts b/packages/neuron-wallet/src/services/settings/skip-data-and-type.ts similarity index 50% rename from packages/neuron-wallet/src/services/skip-data-and-type.ts rename to packages/neuron-wallet/src/services/settings/skip-data-and-type.ts index a51cd26d4f..490e87ac1f 100644 --- a/packages/neuron-wallet/src/services/skip-data-and-type.ts +++ b/packages/neuron-wallet/src/services/settings/skip-data-and-type.ts @@ -1,10 +1,8 @@ -import FileService from './file' +import BaseSettings from './base' export default class SkipDataAndType { - private static moduleName = '' - private static fileName = 'skip-data-and-type.json' - private skip: boolean | undefined = undefined + private keyName = 'skip' private static instance: SkipDataAndType @@ -18,13 +16,7 @@ export default class SkipDataAndType { // skip means can use cells with data and type public update(skip: boolean) { - FileService.getInstance().writeFileSync( - SkipDataAndType.moduleName, - SkipDataAndType.fileName, - JSON.stringify({ - skip, - }) - ) + BaseSettings.getInstance().updateSetting(this.keyName, skip) // cache this variable this.skip = skip } @@ -34,15 +26,11 @@ export default class SkipDataAndType { if (this.skip !== undefined) { return this.skip } - const fileService = FileService.getInstance() - const { moduleName, fileName } = SkipDataAndType - - if (fileService.hasFile(moduleName, fileName)) { - const info = FileService.getInstance().readFileSync(moduleName, fileName) - const { skip } = JSON.parse(info) - if (skip === false) { - return false - } + + const skip = BaseSettings.getInstance().getSetting(this.keyName) + + if (skip === false) { + return false } // default is true diff --git a/packages/neuron-wallet/tests/services/cells.test.ts b/packages/neuron-wallet/tests/services/cells.test.ts index aa8181e5e1..442aef7c82 100644 --- a/packages/neuron-wallet/tests/services/cells.test.ts +++ b/packages/neuron-wallet/tests/services/cells.test.ts @@ -5,7 +5,7 @@ import { OutputStatus } from '../../src/services/tx/params' import { ScriptHashType, Script } from '../../src/types/cell-types' import CellsService from '../../src/services/cells' import { CapacityNotEnough } from '../../src/exceptions/wallet' -import SkipDataAndType from '../../src/services/skip-data-and-type' +import SkipDataAndType from '../../src/services/settings/skip-data-and-type' const randomHex = (length: number = 64): string => { const str: string = Array.from({ length }) diff --git a/packages/neuron-wallet/tests/services/settings/base.test.ts b/packages/neuron-wallet/tests/services/settings/base.test.ts new file mode 100644 index 0000000000..58d2b1a3c6 --- /dev/null +++ b/packages/neuron-wallet/tests/services/settings/base.test.ts @@ -0,0 +1,89 @@ +import BaseSettings from '../../../src/services/settings/base' +import FileService from '../../../src/services/file' + +describe('BaseSettings', () => { + let base: BaseSettings | undefined + + beforeEach(() => { + const fileService = FileService.getInstance() + // @ts-ignore: Private method + const { moduleName, fileName } = BaseSettings + if (fileService.hasFile(moduleName, fileName)) { + fileService.deleteFileSync(moduleName, fileName) + } + + base = new BaseSettings() + }) + + const key = 'testKey' + const value = 'testValue' + + const key2 = 'testKey2' + const value2 = 'testValue2' + + it('getInstance', () => { + const baseSettings = BaseSettings.getInstance() + expect(baseSettings).toBeInstanceOf(BaseSettings) + }) + + it('update', () => { + expect(() => { + base!.updateSetting(key, value) + }).not.toThrowError() + }) + + it('read empty', () => { + const settings = base!.read() + expect(settings).toBeUndefined() + }) + + it('update and read', () => { + base!.updateSetting(key, value) + const settings = base!.read() + expect(settings).toEqual({ [key]: value }) + }) + + it('update and get', () => { + base!.updateSetting(key, value) + const result = base!.getSetting(key) + expect(result).toEqual(value) + }) + + it('update multi', () => { + base!.updateSetting(key, value) + base!.updateSetting(key2, value2) + const result = base!.read() + expect(result).toEqual({ + [key]: value, + [key2]: value2, + }) + }) + + it('update multi and get', () => { + base!.updateSetting(key, value) + base!.updateSetting(key2, value2) + const result = base!.getSetting(key) + expect(result).toEqual(value) + }) + + it('update key multi times', () => { + base!.updateSetting(key, value) + base!.updateSetting(key, value2) + + const result = base!.getSetting(key) + expect(result).toEqual(value2) + }) + + it('new instance', () => { + base!.updateSetting(key, value) + const newInstance = new BaseSettings() + const result = newInstance.getSetting(key) + expect(result).toEqual(value) + }) + + it('getSetting empty', () => { + expect(base!.read()).toBeUndefined() + const result = base!.getSetting(key) + expect(result).toBeUndefined() + }) +}) diff --git a/packages/neuron-wallet/tests/services/skip-data-and-type.test.ts b/packages/neuron-wallet/tests/services/settings/skip-data-and-type.test.ts similarity index 83% rename from packages/neuron-wallet/tests/services/skip-data-and-type.test.ts rename to packages/neuron-wallet/tests/services/settings/skip-data-and-type.test.ts index a49896bfb0..99b7851e06 100644 --- a/packages/neuron-wallet/tests/services/skip-data-and-type.test.ts +++ b/packages/neuron-wallet/tests/services/settings/skip-data-and-type.test.ts @@ -1,5 +1,6 @@ -import SkipDataAndType from '../../src/services/skip-data-and-type' -import FileService from '../../src/services/file' +import SkipDataAndType from '../../../src/services/settings/skip-data-and-type' +import FileService from '../../../src/services/file' +import BaseSettings from '../../../src/services/settings/base' describe(`SkipDataAndType`, () => { let skipDataAndType: SkipDataAndType | undefined @@ -7,7 +8,7 @@ describe(`SkipDataAndType`, () => { beforeEach(() => { const fileService = FileService.getInstance() // @ts-ignore: Private method - const { moduleName, fileName } = SkipDataAndType + const { moduleName, fileName } = BaseSettings if (fileService.hasFile(moduleName, fileName)) { fileService.deleteFileSync(moduleName, fileName) } From 05683c6d7a5e514508e53dddf064cae71e1f41d8 Mon Sep 17 00:00:00 2001 From: CL Date: Wed, 4 Sep 2019 12:07:49 +0800 Subject: [PATCH 17/18] chore: update comment Co-Authored-By: Chen Yu --- packages/neuron-wallet/src/database/address/dao.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/neuron-wallet/src/database/address/dao.ts b/packages/neuron-wallet/src/database/address/dao.ts index 06c8df4f4f..a6605c2f9d 100644 --- a/packages/neuron-wallet/src/database/address/dao.ts +++ b/packages/neuron-wallet/src/database/address/dao.ts @@ -52,8 +52,8 @@ export default class AddressDao { // sentBalance means balance of OutputStatus.Sent cells (sent to me but not committed) // pendingBalance means balance of OutputStatus.Pending cells (sent from me, but not committed) // so the final balance is (liveBalance + sentBalance - pendingBalance) - // balance is the balance which skipped data and type - // totalBalance means balance with data and type + // balance is the balance of the cells those who don't hold data or type script + // totalBalance means balance of all cells, including those who hold data and type script public static updateTxCountAndBalance = async (address: string): Promise => { const addressEntities = await getConnection() .getRepository(AddressEntity) From 8a0bfff5076dcf331db431ece41e321539eeffcf Mon Sep 17 00:00:00 2001 From: classicalliu Date: Wed, 4 Sep 2019 12:10:45 +0800 Subject: [PATCH 18/18] chore: update comment --- .../neuron-wallet/src/services/settings/skip-data-and-type.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/neuron-wallet/src/services/settings/skip-data-and-type.ts b/packages/neuron-wallet/src/services/settings/skip-data-and-type.ts index 490e87ac1f..c4b0e40a50 100644 --- a/packages/neuron-wallet/src/services/settings/skip-data-and-type.ts +++ b/packages/neuron-wallet/src/services/settings/skip-data-and-type.ts @@ -22,7 +22,7 @@ export default class SkipDataAndType { } public get(): boolean { - // if cached, don't to read file + // if cached, don't read file if (this.skip !== undefined) { return this.skip }