diff --git a/packages/neuron-wallet/src/block-sync-renderer/sync/light-connector.ts b/packages/neuron-wallet/src/block-sync-renderer/sync/light-connector.ts index 272c510bf3..46a9ad4d59 100644 --- a/packages/neuron-wallet/src/block-sync-renderer/sync/light-connector.ts +++ b/packages/neuron-wallet/src/block-sync-renderer/sync/light-connector.ts @@ -1,7 +1,7 @@ import { BI } from '@ckb-lumos/bi' import { Subject } from 'rxjs' import { queue, QueueObject } from 'async' -import { HexString, QueryOptions } from '@ckb-lumos/base' +import type { HexString, QueryOptions, TransactionWithStatus } from '@ckb-lumos/base' import { Indexer as CkbIndexer, CellCollector } from '@ckb-lumos/ckb-indexer' import logger from '../../utils/logger' import { Address } from '../../models/address' @@ -18,6 +18,7 @@ import AssetAccountInfo from '../../models/asset-account-info' import { DepType } from '../../models/chain/cell-dep' import { molecule } from '@ckb-lumos/codec' import { blockchain } from '@ckb-lumos/base' +import type { Base } from '@ckb-lumos/rpc/lib/Base' interface SyncQueueParam { script: CKBComponents.Script @@ -232,7 +233,9 @@ export default class LightConnector extends Connector { }) return } - this.transactionsSubject.next({ txHashes: result.txs.map(v => v.txHash), params: syncProgress.hash }) + const txHashes = result.txs.map(v => v.txHash) + await this.fetchPreviousOutputs(txHashes) + this.transactionsSubject.next({ txHashes, params: syncProgress.hash }) this.syncInQueue.set(syncProgress.hash, { blockStartNumber: result.lastCursor === '0x' ? parseInt(blockRange[1]) : parseInt(blockRange[0]), blockEndNumber: parseInt(blockRange[1]), @@ -240,6 +243,23 @@ export default class LightConnector extends Connector { }) } + private async fetchPreviousOutputs(txHashes: string[]) { + const transactions = await this.lightRpc + .createBatchRequest<'getTransaction', string[], TransactionWithStatus[]>(txHashes.map(v => ['getTransaction', v])) + .exec() + const previousTxHashes = new Set() + transactions + .flatMap(tx => tx.transaction.inputs) + .forEach(input => { + const previousTxHash = input.previousOutput!.txHash + // exclude the cell base transaction in a block + if (previousTxHash !== `0x${'0'.repeat(64)}`) { + previousTxHashes.add(previousTxHash) + } + }) + await this.lightRpc.createBatchRequest([...previousTxHashes].map(v => ['fetchTransaction' as keyof Base, v])).exec() + } + private async collectLiveCellsByScript(query: LumosCellQuery) { const { lock, type, data } = query if (!lock && !type) { diff --git a/packages/neuron-wallet/src/block-sync-renderer/sync/queue.ts b/packages/neuron-wallet/src/block-sync-renderer/sync/queue.ts index 3d3bb0cea1..e53df531d4 100644 --- a/packages/neuron-wallet/src/block-sync-renderer/sync/queue.ts +++ b/packages/neuron-wallet/src/block-sync-renderer/sync/queue.ts @@ -90,6 +90,7 @@ export default class Queue { while (true) { try { await this.#checkAndSave(txHashes) + process.send?.({ channel: 'tx-db-changed' }) break } catch (error) { logger.error('retry saving transactions in 2 seconds due to error:', error) @@ -171,7 +172,10 @@ export default class Queue { }, 1) const drainFetchTxQueue = new Promise((resolve, reject) => { - fetchTxQueue.error(reject) + fetchTxQueue.error(err => { + fetchTxQueue.kill() + reject(err) + }) fetchTxQueue.drain(() => resolve(0)) })