Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions packages/neuron-wallet/src/controllers/skip-data-and-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { CatchControllerError } from 'decorators/errors'
import { ResponseCode } from 'utils/const'
import SkipDataAndType from 'services/settings/skip-data-and-type'

export default class SkipDataAndTypeController {
@CatchControllerError
public static async update(skip: boolean): Promise<Controller.Response<boolean>> {
SkipDataAndType.getInstance().update(skip)

return {
status: ResponseCode.Success,
result: skip,
}
}

@CatchControllerError
public static async get(): Promise<Controller.Response<boolean>> {
const skip = SkipDataAndType.getInstance().get()

return {
status: ResponseCode.Success,
result: skip,
}
}
}
12 changes: 9 additions & 3 deletions packages/neuron-wallet/src/database/address/dao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface Address {
sentBalance: string
pendingBalance: string
balance: string
totalBalance: string
blake160: string
version: AddressVersion
description?: string
Expand Down Expand Up @@ -51,6 +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 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<AddressEntity[]> => {
const addressEntities = await getConnection()
.getRepository(AddressEntity)
Expand All @@ -67,9 +70,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)
Comment thread
classicalliu marked this conversation as resolved.
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
})
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand All @@ -91,6 +94,7 @@ export default class Address extends BaseEntity {
sentBalance: this.sentBalance,
pendingBalance: this.pendingBalance,
balance: this.balance(),
totalBalance: this.totalBalance,
description: this.description,
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export class extendBalance1562126909151 implements MigrationInterface {
}

public async down(queryRunner: QueryRunner): Promise<any> {
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',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {MigrationInterface, QueryRunner, TableColumn} from "typeorm";

export class AddTotalBalance1567485550388 implements MigrationInterface {

public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.addColumn('address', new TableColumn({
name: 'totalBalance',
type: 'varchar',
default: '0',
}))
}

public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.dropColumn('address', 'totalBalance')
}

}
3 changes: 2 additions & 1 deletion packages/neuron-wallet/src/database/address/ormconfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Expand All @@ -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'],
Expand Down
11 changes: 11 additions & 0 deletions packages/neuron-wallet/src/database/chain/entities/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {MigrationInterface, QueryRunner, TableColumn} from "typeorm";

export class AddTypeAndHasData1567144517514 implements MigrationInterface {

public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.addColumn('output', new TableColumn({
name: 'typeScript',
type: 'text',
isNullable: true,
}))

await queryRunner.addColumn('output', new TableColumn({
name: 'hasData',
type: 'boolean',
default: false,
}))
}

public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.dropColumn('output', 'hasData')
await queryRunner.dropColumn('output', 'typeScript')
}

}
6 changes: 4 additions & 2 deletions packages/neuron-wallet/src/database/chain/ormconfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand All @@ -20,16 +21,17 @@ const dbPath = (networkName: string): string => {

const connectOptions = async (genesisBlockHash: string): Promise<SqliteConnectionOptions> => {
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']

return {
...connectionOptions,
type: 'sqlite',
database: dbPath(genesisBlockHash),
database,
entities: [Transaction, Input, Output, SyncInfo],
migrations: [InitMigration1566959757554],
migrations: [InitMigration1566959757554, AddTypeAndHasData1567144517514],
logging,
}
}
Expand Down
5 changes: 3 additions & 2 deletions packages/neuron-wallet/src/services/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -178,6 +178,7 @@ export default class AddressService {
sentBalance: '0',
pendingBalance: '0',
balance: '0',
totalBalance: '0',
blake160,
version: AddressVersion.Testnet,
}
Expand Down
44 changes: 34 additions & 10 deletions packages/neuron-wallet/src/services/cells.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,36 @@ 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 './settings/skip-data-and-type'

export const MIN_CELL_CAPACITY = '6100000000'

/* eslint @typescript-eslint/no-unused-vars: "warn" */
/* eslint no-await-in-loop: "warn" */
/* eslint no-restricted-syntax: "warn" */
export default class CellsService {
public static getBalance = async (lockHashes: string[], status: OutputStatus): Promise<string> => {
// exclude hasData = true and typeScript != null
public static getBalance = async (
lockHashes: string[],
status: OutputStatus,
skipDataAndType: boolean
): Promise<string> => {
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),
status,
},
where: queryParams,
})

const capacity: bigint = cells.map(c => BigInt(c.capacity)).reduce((result, c) => result + c, BigInt(0))
Expand Down Expand Up @@ -67,14 +82,23 @@ export default class CellsService {
throw new Error(`capacity can't be less than ${MIN_CELL_CAPACITY}`)
}

// only live cells
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',
},
where: queryParams,
})
cellEntities.sort((a, b) => {
const result = BigInt(a.capacity) - BigInt(b.capacity)
Expand Down
48 changes: 48 additions & 0 deletions packages/neuron-wallet/src/services/settings/base.ts
Original file line number Diff line number Diff line change
@@ -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
}
}
39 changes: 39 additions & 0 deletions packages/neuron-wallet/src/services/settings/skip-data-and-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import BaseSettings from './base'

export default class SkipDataAndType {
private skip: boolean | undefined = undefined
private keyName = 'skip'

private static instance: SkipDataAndType

static getInstance(): SkipDataAndType {
if (!SkipDataAndType.instance) {
SkipDataAndType.instance = new SkipDataAndType()
}

return SkipDataAndType.instance
}

// skip means can use cells with data and type
public update(skip: boolean) {
BaseSettings.getInstance().updateSetting(this.keyName, skip)
// cache this variable
this.skip = skip
}

public get(): boolean {
// if cached, don't read file
if (this.skip !== undefined) {
return this.skip
}

const skip = BaseSettings.getInstance().getSetting(this.keyName)

if (skip === false) {
return false
}

// default is true
return true
}
}
Loading