Skip to content

Commit 25ed522

Browse files
committed
feat: not start from zero in indexer when create wallet
1 parent 3a40dcc commit 25ed522

9 files changed

Lines changed: 103 additions & 31 deletions

File tree

packages/neuron-wallet/src/controllers/wallets/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export default class WalletsController {
7272
name,
7373
password,
7474
mnemonic,
75+
isImport: true,
7576
})
7677

7778
WalletCreatedSubject.getSubject().next('import')
@@ -93,6 +94,7 @@ export default class WalletsController {
9394
name,
9495
password,
9596
mnemonic,
97+
isImport: false,
9698
})
9799

98100
WalletCreatedSubject.getSubject().next('create')
@@ -104,10 +106,12 @@ export default class WalletsController {
104106
name,
105107
password,
106108
mnemonic,
109+
isImport,
107110
}: {
108111
name: string
109112
password: string
110113
mnemonic: string
114+
isImport: boolean
111115
}): Promise<Controller.Response<Omit<WalletProperties, 'extendedKey'>>> {
112116
if (!validateMnemonic(mnemonic)) {
113117
throw new InvalidMnemonic()
@@ -138,7 +142,7 @@ export default class WalletsController {
138142
keystore,
139143
})
140144

141-
await walletsService.generateAddressesById(wallet.id)
145+
await walletsService.generateAddressesById(wallet.id, isImport)
142146

143147
return {
144148
status: ResponseCode.Success,
@@ -188,7 +192,7 @@ export default class WalletsController {
188192
keystore: keystoreObject,
189193
})
190194

191-
await walletsService.generateAddressesById(wallet.id)
195+
await walletsService.generateAddressesById(wallet.id, true)
192196
WalletCreatedSubject.getSubject().next('import')
193197

194198
return {

packages/neuron-wallet/src/listeners/address.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export const register = () => {
2828
walletIds.map(async id => {
2929
const wallet = WalletService.getInstance().get(id)
3030
const accountExtendedPublicKey: AccountExtendedPublicKey = wallet.accountExtendedPublicKey()
31-
await AddressService.checkAndGenerateSave(id, accountExtendedPublicKey, 20, 10)
31+
await AddressService.checkAndGenerateSave(id, accountExtendedPublicKey, true, 20, 10)
3232
})
3333
)
3434
})
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { ReplaySubject } from 'rxjs'
2+
import { AddressWithWay } from 'services/addresses'
3+
4+
export default class AddressCreatedSubject {
5+
static subject = new ReplaySubject<AddressWithWay[]>(100)
6+
7+
static getSubject() {
8+
return this.subject
9+
}
10+
}

packages/neuron-wallet/src/services/addresses.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@ import LockUtils from 'models/lock-utils'
55
import AddressDao, { Address as AddressInterface } from 'database/address/dao'
66
import env from 'env'
77
import AddressEntity, { AddressVersion } from 'database/address/entities/address'
8+
import AddressCreatedSubject from 'models/subjects/address-created-subject'
89

910
const MAX_ADDRESS_COUNT = 30
1011

12+
export interface AddressWithWay {
13+
address: AddressInterface
14+
isImport: boolean | undefined
15+
}
16+
1117
export interface AddressMetaInfo {
1218
walletId: string
1319
addressType: AddressType
@@ -24,6 +30,7 @@ export default class AddressService {
2430
public static generateAndSave = async (
2531
walletId: string,
2632
extendedKey: AccountExtendedPublicKey,
33+
isImport: boolean | undefined,
2734
receivingStartIndex: number,
2835
changeStartIndex: number,
2936
receivingAddressCount: number = 20,
@@ -37,18 +44,35 @@ export default class AddressService {
3744
receivingAddressCount,
3845
changeAddressCount
3946
)
40-
const allAddresses = [
47+
const allAddresses: AddressInterface[] = [
4148
...addresses.testnetReceiving,
4249
...addresses.mainnetReceiving,
4350
...addresses.testnetChange,
4451
...addresses.mainnetChange,
4552
]
4653
await AddressDao.create(allAddresses)
54+
55+
// TODO: notify address created and pass addressWay
56+
AddressService.notifyAddressCreated(allAddresses, isImport)
57+
}
58+
59+
private static notifyAddressCreated = (addresses: AddressInterface[], isImport: boolean | undefined) => {
60+
const version = AddressService.getAddressVersion()
61+
const addressesWithWay: AddressWithWay[] = addresses
62+
.filter(addr => addr.version === version)
63+
.map(addr => {
64+
return {
65+
address: addr,
66+
isImport,
67+
}
68+
})
69+
AddressCreatedSubject.getSubject().next(addressesWithWay)
4770
}
4871

4972
public static checkAndGenerateSave = async (
5073
walletId: string,
5174
extendedKey: AccountExtendedPublicKey,
75+
isImport: boolean | undefined,
5276
receivingAddressCount: number = 20,
5377
changeAddressCount: number = 10
5478
) => {
@@ -68,6 +92,7 @@ export default class AddressService {
6892
return AddressService.generateAndSave(
6993
walletId,
7094
extendedKey,
95+
isImport,
7196
nextReceivingIndex,
7297
nextChangeIndex,
7398
receivingAddressCount,

packages/neuron-wallet/src/services/indexer/indexer-rpc.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default class IndexerRPC {
1111
return this.core.rpc.deindexLockHash(lockHash)
1212
}
1313

14-
public indexLockHash = async (lockHash: string, indexFrom = '0') => {
14+
public indexLockHash = async (lockHash: string, indexFrom?: string | undefined) => {
1515
return this.core.rpc.indexLockHash(lockHash, indexFrom)
1616
}
1717

packages/neuron-wallet/src/services/indexer/queue.ts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,19 @@ import IndexerTransaction from 'services/tx/indexer-transaction'
1212

1313
import IndexerRPC from './indexer-rpc'
1414

15+
export interface LockHashInfo {
16+
lockHash: string
17+
isImport: boolean | undefined
18+
}
19+
1520
enum TxPointType {
1621
CreatedBy = 'createdBy',
1722
ConsumedBy = 'consumedBy',
1823
}
1924

2025
export default class IndexerQueue {
21-
private lockHashes: string[]
26+
// private lockHashes: string[]
27+
private lockHashInfos: LockHashInfo[]
2228
private indexerRPC: IndexerRPC
2329
private getBlocksService: GetBlocks
2430
private per = 50
@@ -34,8 +40,9 @@ export default class IndexerQueue {
3440

3541
private resetFlag = false
3642

37-
constructor(url: string, lockHashes: string[], tipNumberSubject: Subject<string | undefined>) {
38-
this.lockHashes = lockHashes
43+
constructor(url: string, lockHashInfos: LockHashInfo[], tipNumberSubject: Subject<string | undefined>) {
44+
// this.lockHashes = lockHashes
45+
this.lockHashInfos = lockHashInfos
3946
this.indexerRPC = new IndexerRPC(url)
4047
this.getBlocksService = new GetBlocks()
4148
this.blockNumberService = new BlockNumber()
@@ -46,8 +53,9 @@ export default class IndexerQueue {
4653
})
4754
}
4855

49-
public setLockHashes = (lockHashes: string[]): void => {
50-
this.lockHashes = lockHashes
56+
public setLockHashInfos = (lockHashInfos: LockHashInfo[]): void => {
57+
// this.lockHashes = lockHashes
58+
this.lockHashInfos = lockHashInfos
5159
this.indexed = false
5260
}
5361

@@ -65,13 +73,14 @@ export default class IndexerQueue {
6573
await this.blockNumberService.updateCurrent(BigInt(0))
6674
this.resetFlag = false
6775
}
68-
const { lockHashes } = this
76+
const { lockHashInfos } = this
6977
const currentBlockNumber: bigint = await this.blockNumberService.getCurrent()
7078
if (!this.indexed || currentBlockNumber !== this.tipBlockNumber) {
7179
if (!this.indexed) {
72-
await this.indexLockHashes(lockHashes)
80+
await this.indexLockHashes(lockHashInfos)
7381
this.indexed = true
7482
}
83+
const lockHashes: string[] = lockHashInfos.map(info => info.lockHash)
7584
const minBlockNumber = await this.getCurrentBlockNumber(lockHashes)
7685
for (const lockHash of lockHashes) {
7786
await this.pipeline(lockHash, TxPointType.CreatedBy, currentBlockNumber)
@@ -130,13 +139,14 @@ export default class IndexerQueue {
130139
return minBlockNumber
131140
}
132141

133-
public indexLockHashes = async (lockHashes: string[]) => {
142+
public indexLockHashes = async (lockHashInfos: LockHashInfo[]) => {
134143
const lockHashIndexStates = await this.indexerRPC.getLockHashIndexStates()
135144
const indexedLockHashes: string[] = lockHashIndexStates.map(state => state.lockHash)
136-
const nonIndexedLockHashes = lockHashes.filter(i => !indexedLockHashes.includes(i))
145+
const nonIndexedLockHashInfos = lockHashInfos.filter(i => !indexedLockHashes.includes(i.lockHash))
137146

138-
await Utils.mapSeries(nonIndexedLockHashes, async (lockHash: string) => {
139-
await this.indexerRPC.indexLockHash(lockHash)
147+
await Utils.mapSeries(nonIndexedLockHashInfos, async (info: LockHashInfo) => {
148+
const indexFrom: string | undefined = info.isImport ? '0' : undefined
149+
await this.indexerRPC.indexLockHash(info.lockHash, indexFrom)
140150
})
141151
}
142152

packages/neuron-wallet/src/services/wallets.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,23 +169,31 @@ export default class WalletService {
169169

170170
public generateAddressesById = async (
171171
id: string,
172+
isImport: boolean,
172173
receivingAddressCount: number = 20,
173174
changeAddressCount: number = 10
174175
) => {
175176
const wallet: Wallet = this.get(id)
176177
const accountExtendedPublicKey: AccountExtendedPublicKey = wallet.accountExtendedPublicKey()
177-
await AddressService.checkAndGenerateSave(id, accountExtendedPublicKey, receivingAddressCount, changeAddressCount)
178+
await AddressService.checkAndGenerateSave(
179+
id,
180+
accountExtendedPublicKey,
181+
isImport,
182+
receivingAddressCount,
183+
changeAddressCount
184+
)
178185
}
179186

180187
public generateCurrentWalletAddresses = async (
188+
isImport: boolean,
181189
receivingAddressCount: number = 20,
182190
changeAddressCount: number = 10
183191
) => {
184192
const wallet: Wallet | undefined = this.getCurrent()
185193
if (!wallet) {
186194
return undefined
187195
}
188-
return this.generateAddressesById(wallet.id, receivingAddressCount, changeAddressCount)
196+
return this.generateAddressesById(wallet.id, isImport, receivingAddressCount, changeAddressCount)
189197
}
190198

191199
public create = (props: WalletProperties) => {

packages/neuron-wallet/src/startup/sync-block-task/indexer.ts

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import { remote } from 'electron'
2-
import AddressService from 'services/addresses'
2+
import AddressService, { AddressWithWay } from 'services/addresses'
33
import LockUtils from 'models/lock-utils'
4-
import IndexerQueue from 'services/indexer/queue'
4+
import IndexerQueue, { LockHashInfo } from 'services/indexer/queue'
5+
// import { Address } from 'database/address/dao'
56

67
import { initDatabase } from './init-database'
78

8-
const { nodeService, addressDbChangedSubject, walletCreatedSubject } = remote.require(
9-
'./startup/sync-block-task/params'
10-
)
9+
const { nodeService, addressCreatedSubject, walletCreatedSubject } = remote.require('./startup/sync-block-task/params')
1110

1211
// maybe should call this every time when new address generated
1312
// load all addresses and convert to lockHashes
@@ -29,16 +28,30 @@ export const switchNetwork = async (nodeURL: string) => {
2928
await initDatabase()
3029
// load lockHashes
3130
const lockHashes: string[] = await loadAddressesAndConvert()
31+
const lockHashInfos: LockHashInfo[] = lockHashes.map(lockHash => {
32+
return {
33+
lockHash,
34+
isImport: true,
35+
}
36+
})
3237
// start sync blocks service
33-
indexerQueue = new IndexerQueue(nodeURL, lockHashes, nodeService.tipNumberSubject)
38+
indexerQueue = new IndexerQueue(nodeURL, lockHashInfos, nodeService.tipNumberSubject)
3439

35-
addressDbChangedSubject.subscribe(async (event: string) => {
36-
// ignore update and remove
37-
if (event === 'AfterInsert') {
38-
const hashes: string[] = await loadAddressesAndConvert()
39-
if (indexerQueue) {
40-
indexerQueue.setLockHashes(hashes)
41-
}
40+
// listen to address created
41+
addressCreatedSubject.subscribe(async (addressWithWay: AddressWithWay[]) => {
42+
if (indexerQueue) {
43+
const infos: LockHashInfo[] = (await Promise.all(
44+
addressWithWay.map(async aw => {
45+
const hashes: string[] = await LockUtils.addressToAllLockHashes(aw.address.address)
46+
return hashes.map(h => {
47+
return {
48+
lockHash: h,
49+
isImport: aw.isImport,
50+
}
51+
})
52+
})
53+
)).reduce((acc, val) => acc.concat(val), [])
54+
indexerQueue.setLockHashInfos(infos)
4255
}
4356
})
4457

packages/neuron-wallet/src/startup/sync-block-task/params.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import NodeService from 'services/node'
22
import { AddressesUsedSubject } from 'models/subjects/addresses-used-subject'
33
import AddressDbChangedSubject from 'models/subjects/address-db-changed-subject'
44
import WalletCreatedSubject from 'models/subjects/wallet-created-subject'
5+
import AddressCreatedSubject from 'models/subjects/address-created-subject'
56

67
export { networkSwitchSubject } from 'services/networks'
78

@@ -12,3 +13,4 @@ export const nodeService = NodeService.getInstance()
1213
export const addressesUsedSubject = AddressesUsedSubject.getSubject()
1314
export const addressDbChangedSubject = AddressDbChangedSubject.getSubject()
1415
export const walletCreatedSubject = WalletCreatedSubject.getSubject()
16+
export const addressCreatedSubject = AddressCreatedSubject.getSubject()

0 commit comments

Comments
 (0)