diff --git a/packages/neuron-wallet/src/startup/sync-block-task/indexer.ts b/packages/neuron-wallet/src/startup/sync-block-task/indexer.ts new file mode 100644 index 0000000000..8aad4a3d61 --- /dev/null +++ b/packages/neuron-wallet/src/startup/sync-block-task/indexer.ts @@ -0,0 +1,44 @@ +import { remote } from 'electron' +import AddressService from 'services/addresses' +import LockUtils from 'models/lock-utils' +import IndexerQueue from 'services/indexer/queue' + +import { initDatabase } from './init-database' + +const { addressDbChangedSubject } = remote.require('./startup/sync-block-task/params') + +// maybe should call this every time when new address generated +// load all addresses and convert to lockHashes +export const loadAddressesAndConvert = async (): Promise => { + const addresses: string[] = (await AddressService.allAddresses()).map(addr => addr.address) + const lockHashes: string[] = await LockUtils.addressesToAllLockHashes(addresses) + return lockHashes +} + +// call this after network switched +let indexerQueue: IndexerQueue | undefined +export const switchNetwork = async () => { + // stop all blocks service + if (indexerQueue) { + await indexerQueue.stopAndWait() + } + + // disconnect old connection and connect to new database + await initDatabase() + // load lockHashes + const lockHashes: string[] = await loadAddressesAndConvert() + // start sync blocks service + indexerQueue = new IndexerQueue(lockHashes) + + addressDbChangedSubject.subscribe(async (event: string) => { + // ignore update and remove + if (event === 'AfterInsert') { + const hashes: string[] = await loadAddressesAndConvert() + if (indexerQueue) { + indexerQueue.setLockHashes(hashes) + } + } + }) + + indexerQueue.start() +} diff --git a/packages/neuron-wallet/src/startup/sync-block-task/sync.ts b/packages/neuron-wallet/src/startup/sync-block-task/sync.ts new file mode 100644 index 0000000000..bbf26d2bd0 --- /dev/null +++ b/packages/neuron-wallet/src/startup/sync-block-task/sync.ts @@ -0,0 +1,65 @@ +import { remote } from 'electron' +import AddressService from 'services/addresses' +import LockUtils from 'models/lock-utils' +import BlockListener from 'services/sync/block-listener' + +import { initDatabase } from './init-database' + +const { nodeService, addressDbChangedSubject, walletCreatedSubject } = remote.require( + './startup/sync-block-task/params' +) + +// pass to task a main process subject +// AddressesUsedSubject.setSubject(addressesUsedSubject) + +// maybe should call this every time when new address generated +// load all addresses and convert to lockHashes +export const loadAddressesAndConvert = async (): Promise => { + const addresses: string[] = (await AddressService.allAddresses()).map(addr => addr.address) + const lockHashes: string[] = await LockUtils.addressesToAllLockHashes(addresses) + return lockHashes +} + +// call this after network switched +let blockListener: BlockListener | undefined +export const switchNetwork = async () => { + // stop all blocks service + if (blockListener) { + await blockListener.stopAndWait() + } + + // disconnect old connection and connect to new database + await initDatabase() + // load lockHashes + const lockHashes: string[] = await loadAddressesAndConvert() + // start sync blocks service + blockListener = new BlockListener(lockHashes, nodeService.tipNumberSubject) + + addressDbChangedSubject.subscribe(async (event: string) => { + // ignore update and remove + if (event === 'AfterInsert') { + const hashes: string[] = await loadAddressesAndConvert() + if (blockListener) { + blockListener.setLockHashes(hashes) + } + } + }) + + const regenerateListener = async () => { + if (blockListener) { + await blockListener.stopAndWait() + } + // wait former queue to be drained + const hashes: string[] = await loadAddressesAndConvert() + blockListener = new BlockListener(hashes, nodeService.tipNumberSubject) + await blockListener.start(true) + } + + walletCreatedSubject.subscribe(async (type: string) => { + if (type === 'import') { + await regenerateListener() + } + }) + + blockListener.start() +} diff --git a/packages/neuron-wallet/src/startup/sync-block-task/task.ts b/packages/neuron-wallet/src/startup/sync-block-task/task.ts index 94559ef9a4..4d949289f1 100644 --- a/packages/neuron-wallet/src/startup/sync-block-task/task.ts +++ b/packages/neuron-wallet/src/startup/sync-block-task/task.ts @@ -1,86 +1,45 @@ import { remote } from 'electron' import { initConnection as initAddressConnection } from 'database/address/ormconfig' -import AddressService from 'services/addresses' -import LockUtils from 'models/lock-utils' import AddressesUsedSubject from 'models/subjects/addresses-used-subject' -import BlockListener from 'services/sync/block-listener' import { NetworkWithID } from 'services/networks' import { register as registerTxStatusListener } from 'listeners/tx-status' import { register as registerAddressListener } from 'listeners/address' +import IndexerRPC from 'services/indexer/indexer-rpc' +import Utils from 'services/sync/utils' -import { initDatabase } from './init-database' +import { switchNetwork as syncSwitchNetwork } from './sync' +import { switchNetwork as indexerSwitchNetwork } from './indexer' // register to listen address updates registerAddressListener() -const { - nodeService, - addressDbChangedSubject, - addressesUsedSubject, - databaseInitSubject, - walletCreatedSubject, -} = remote.require('./startup/sync-block-task/params') +const { addressesUsedSubject, databaseInitSubject } = remote.require('./startup/sync-block-task/params') // pass to task a main process subject AddressesUsedSubject.setSubject(addressesUsedSubject) -// maybe should call this every time when new address generated -// load all addresses and convert to lockHashes -export const loadAddressesAndConvert = async (): Promise => { - const addresses: string[] = (await AddressService.allAddresses()).map(addr => addr.address) - const lockHashes: string[] = await LockUtils.addressesToAllLockHashes(addresses) - return lockHashes -} - -// call this after network switched -let blockListener: BlockListener | undefined -export const switchNetwork = async () => { - // stop all blocks service - if (blockListener) { - await blockListener.stopAndWait() +export const testIndexer = async (): Promise => { + const indexerRPC = new IndexerRPC() + try { + await Utils.retry(3, 100, () => { + return indexerRPC.getLockHashIndexStates() + }) + return true + } catch { + return false } - - // disconnect old connection and connect to new database - await initDatabase() - // load lockHashes - const lockHashes: string[] = await loadAddressesAndConvert() - // start sync blocks service - blockListener = new BlockListener(lockHashes, nodeService.tipNumberSubject) - - addressDbChangedSubject.subscribe(async (event: string) => { - // ignore update and remove - if (event === 'AfterInsert') { - const hashes: string[] = await loadAddressesAndConvert() - if (blockListener) { - blockListener.setLockHashes(hashes) - } - } - }) - - const regenerateListener = async () => { - if (blockListener) { - await blockListener.stopAndWait() - } - // wait former queue to be drained - const hashes: string[] = await loadAddressesAndConvert() - blockListener = new BlockListener(hashes, nodeService.tipNumberSubject) - await blockListener.start(true) - } - - walletCreatedSubject.subscribe(async (type: string) => { - if (type === 'import') { - await regenerateListener() - } - }) - - blockListener.start() } export const run = async () => { await initAddressConnection() databaseInitSubject.subscribe(async (network: NetworkWithID | undefined) => { if (network) { - await switchNetwork() + const indexerEnable = await testIndexer() + if (indexerEnable) { + await indexerSwitchNetwork() + } else { + await syncSwitchNetwork() + } } }) registerTxStatusListener()