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 40d13300a6..125b49e124 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 @@ -301,9 +301,6 @@ export default class LightConnector extends Connector { } async appendScript(scripts: AppendScript[]) { - if (!scripts.length) { - return - } this.initSyncProgress(scripts) } } 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 8d39e238ae..e08667a452 100644 --- a/packages/neuron-wallet/src/block-sync-renderer/sync/queue.ts +++ b/packages/neuron-wallet/src/block-sync-renderer/sync/queue.ts @@ -10,6 +10,7 @@ import AssetAccountInfo from 'models/asset-account-info' import { Address as AddressInterface } from "models/address" import AddressParser from 'models/address-parser' import Multisig from 'models/multisig' +import BlockHeader from 'models/chain/block-header' import TxAddressFinder from './tx-address-finder' import IndexerConnector from './indexer-connector' import IndexerCacheService from './indexer-cache-service' @@ -134,8 +135,11 @@ export default class Queue { blockHashes.map(v => ['getHeader', v]) ).exec() headers.forEach((blockHeader, idx) => { - txs[idx].timestamp = blockHeader!.timestamp - txs[idx].blockNumber = blockHeader!.number + if (blockHeader) { + const header = BlockHeader.fromSDK(blockHeader) + txs[idx].timestamp = header.timestamp + txs[idx].blockNumber = header.number + } }) return txs } diff --git a/packages/neuron-wallet/src/database/chain/index.ts b/packages/neuron-wallet/src/database/chain/index.ts index 5e29bfbffe..a0bde9834a 100644 --- a/packages/neuron-wallet/src/database/chain/index.ts +++ b/packages/neuron-wallet/src/database/chain/index.ts @@ -1,23 +1,24 @@ import { getConnection } from 'typeorm' import MultisigOutputChangedSubject from 'models/subjects/multisig-output-db-changed-subject' +import SyncProgressService from 'services/sync-progress' import InputEntity from './entities/input' import OutputEntity from './entities/output' import TransactionEntity from './entities/transaction' import SyncInfoEntity from './entities/sync-info' import IndexerTxHashCache from './entities/indexer-tx-hash-cache' import MultisigOutput from './entities/multisig-output' -import SyncProgress from './entities/sync-progress' /* * Clean local sqlite storage */ export const clean = async () => { await Promise.all([ - ...[InputEntity, OutputEntity, TransactionEntity, IndexerTxHashCache, MultisigOutput, SyncProgress].map(entity => { + ...[InputEntity, OutputEntity, TransactionEntity, IndexerTxHashCache, MultisigOutput].map(entity => { return getConnection() .getRepository(entity) .clear() - }) + }), + SyncProgressService.clearCurrentWalletProgress() ]) MultisigOutputChangedSubject.getSubject().next('reset') diff --git a/packages/neuron-wallet/src/services/indexer.ts b/packages/neuron-wallet/src/services/indexer.ts index 7d70189f63..4f2f01837e 100644 --- a/packages/neuron-wallet/src/services/indexer.ts +++ b/packages/neuron-wallet/src/services/indexer.ts @@ -30,7 +30,7 @@ export default class IndexerService { } if (!NodeService.getInstance().isCkbNodeExternal) { - await startMonitor('ckb') + await startMonitor('ckb', true) } } diff --git a/packages/neuron-wallet/src/services/multisig.ts b/packages/neuron-wallet/src/services/multisig.ts index 89012ff0ea..c45543df38 100644 --- a/packages/neuron-wallet/src/services/multisig.ts +++ b/packages/neuron-wallet/src/services/multisig.ts @@ -11,6 +11,7 @@ import NetworksService from './networks' import Multisig from 'models/multisig' import SyncProgress, { SyncAddressType } from 'database/chain/entities/sync-progress' import { NetworkType } from 'models/network' +import WalletService from './wallets' const max64Int = '0x' + 'f'.repeat(16) export default class MultisigService { @@ -334,9 +335,13 @@ export default class MultisigService { } static async getMultisigConfigForLight() { + const currentWallet = WalletService.getInstance().getCurrent() const multisigConfigs = await getConnection() .getRepository(MultisigConfig) .createQueryBuilder() + .where({ + walletId: currentWallet?.id + }) .getMany() return multisigConfigs.map(v => ({ walletId: v.walletId, diff --git a/packages/neuron-wallet/src/services/sync-progress.ts b/packages/neuron-wallet/src/services/sync-progress.ts index 98598d4c25..100a9458fe 100644 --- a/packages/neuron-wallet/src/services/sync-progress.ts +++ b/packages/neuron-wallet/src/services/sync-progress.ts @@ -108,4 +108,11 @@ export default class SyncProgressService { .where({ hash: In(hashes) }) .getMany() } + + static async clearCurrentWalletProgress() { + const currentWallet = WalletService.getInstance().getCurrent() + await getConnection() + .getRepository(SyncProgress) + .delete({ walletId: currentWallet?.id }) + } } diff --git a/packages/neuron-wallet/src/utils/ckb-rpc.ts b/packages/neuron-wallet/src/utils/ckb-rpc.ts index e0f6acc08f..5e460d9a4e 100644 --- a/packages/neuron-wallet/src/utils/ckb-rpc.ts +++ b/packages/neuron-wallet/src/utils/ckb-rpc.ts @@ -91,7 +91,7 @@ const lightRPCProperties: Record[0] paramsFormatters: [paramsFormatter.toHash], resultFormatters: (result: { status: 'fetched' | 'fetching' | 'added' | 'not_found', data?: RPC.TransactionWithStatus }) => { if (result.status === 'fetched' && result.data) {return resultFormatter.toTransactionWithStatus(result.data)} - return null + return result } } } @@ -117,7 +117,7 @@ export class LightRPC extends Base { ) => Promise<{ lastCursor: HexString, txs: { txHash: HexString, txIndex: HexString, blockNumber: CKBComponents.BlockNumber }[]}> getTransactionInLight: Base['getTransaction'] - fetchTransaction: (hash: string) => Promise + fetchTransaction: (hash: string) => Promise getGenesisBlock: () => Promise exceptionMethods = ['getCurrentEpoch', 'getEpochByNumber', 'getBlockHash', 'getLiveCell'] @@ -151,7 +151,9 @@ export class LightRPC extends Base { if (!tx?.transaction) { tx = await CommonUtils.retry(3, 100, async () => { const tmp = await this.fetchTransaction(hash) - if (tmp === null) {throw new Error('Not fetch the transaction current')} + if ('status' in tmp) { + throw new Error(`transaction ${hash} status: ${tmp.status}`) + } return tmp }) if (!tx) {throw new Error(`Fetch transaction tx failed, please try it later: ${hash}`)} diff --git a/packages/neuron-wallet/tests/block-sync-renderer/queue.test.ts b/packages/neuron-wallet/tests/block-sync-renderer/queue.test.ts index eb964cdee8..9ca3175cab 100644 --- a/packages/neuron-wallet/tests/block-sync-renderer/queue.test.ts +++ b/packages/neuron-wallet/tests/block-sync-renderer/queue.test.ts @@ -73,7 +73,8 @@ const generateFakeTx = (id: string, publicKeyHash: string = '0x') => { lock: Script.fromObject({ hashType: ScriptHashType.Type, codeHash: '0x' + id.repeat(64), args: publicKeyHash }) }) ] - fakeTx.blockNumber = '1' + fakeTx.blockNumber = '0x1' + fakeTx.timestamp = '0x1880a3fa5bc' const fakeTxWithStatus = { transaction: fakeTx, txStatus: new TxStatus('0x' + id.repeat(64), TxStatusType.Committed) @@ -81,6 +82,14 @@ const generateFakeTx = (id: string, publicKeyHash: string = '0x') => { return fakeTxWithStatus } +const fakeBlockHeader = { + version: '0x0', + epoch: '0x0', + hash: `0x${'0'.repeat(64)}`, + parentHash: `0x${'0'.repeat(64)}`, + timestamp: '0x0', + number: '0x0', +} describe('queue', () => { let queue: Queue const fakeNodeUrl = 'http://fakenode:8114' @@ -216,7 +225,7 @@ describe('queue', () => { stubbedGetTransactionFn.mockResolvedValue(fakeTxWithStatus1) stubbedRPCCreateBatchRequestExecFn .mockResolvedValueOnce(fakeTxs) - .mockResolvedValueOnce(fakeTxs.map(v => ({ timestamp: v.transaction.timestamp, number: v.transaction.blockNumber }))) + .mockResolvedValueOnce(fakeTxs.map(v => ({ ...fakeBlockHeader, timestamp: v.transaction.timestamp, number: v.transaction.blockNumber }))) stubbedTransactionsSubject.next({ txHashes: fakeTxs.map(v => v.transaction.hash), params: fakeTxs[0].transaction.blockNumber }) }) describe('when saving transactions is succeeded', () => { @@ -226,7 +235,8 @@ describe('queue', () => { const lockHashes = ['0x1f2615a8dde4e28ca736ff763c2078aff990043f4cbf09eb4b3a58a140a0862d'] const tx = Transaction.fromSDK(fakeTxWithStatus2.transaction.toSDK()) tx.blockHash = fakeTxWithStatus2.txStatus.blockHash! - tx.blockNumber = fakeTxWithStatus2.transaction.blockNumber + tx.blockNumber = BigInt(fakeTxWithStatus2.transaction.blockNumber!).toString() + tx.timestamp = BigInt(fakeTxWithStatus2.transaction.timestamp!).toString() expect(stubbedTxAddressFinderConstructor).toHaveBeenCalledWith( lockHashes, [new AssetAccountInfo().generateAnyoneCanPayScript(addressInfo.blake160).computeHash()], @@ -238,7 +248,8 @@ describe('queue', () => { for (const { transaction } of fakeTxs) { const tx = Transaction.fromSDK(transaction.toSDK()) tx.blockHash = fakeTxWithStatus2.txStatus.blockHash! - tx.blockNumber = fakeTxWithStatus2.transaction.blockNumber + tx.blockNumber = BigInt(fakeTxWithStatus2.transaction.blockNumber!).toString() + tx.timestamp = BigInt(fakeTxWithStatus2.transaction.timestamp!).toString() expect(stubbedSaveFetchFn).toHaveBeenCalledWith(tx) } }) @@ -260,7 +271,7 @@ describe('queue', () => { stubbedSaveFetchFn.mockRejectedValueOnce(err) stubbedRPCCreateBatchRequestExecFn .mockResolvedValueOnce(fakeTxs) - .mockResolvedValueOnce(fakeTxs.map(v => ({ timestamp: v.transaction.timestamp, number: v.transaction.blockNumber }))) + .mockResolvedValueOnce(fakeTxs.map(v => ({ ...fakeBlockHeader, timestamp: v.transaction.timestamp, number: v.transaction.blockNumber }))) stubbedTransactionsSubject.next({ txHashes: fakeTxs.map(v => v.transaction.hash), params: fakeTxs[0].transaction.blockNumber }) await flushPromises() }) diff --git a/packages/neuron-wallet/tests/controllers/multisig.test.ts b/packages/neuron-wallet/tests/controllers/multisig.test.ts index 6a135ee333..f83962734c 100644 --- a/packages/neuron-wallet/tests/controllers/multisig.test.ts +++ b/packages/neuron-wallet/tests/controllers/multisig.test.ts @@ -18,6 +18,15 @@ jest.mock('electron', () => ({ getFocusedWindow: jest.fn() } })) +jest.mock('services/wallets', () => ({ + getInstance() { + return { + getCurrent() { + return jest.fn() + } + } + } +})) jest.mock('../../src/services/multisig') const MultiSigServiceMock = MultisigService as jest.MockedClass diff --git a/packages/neuron-wallet/tests/controllers/sync-api.test.ts b/packages/neuron-wallet/tests/controllers/sync-api.test.ts index 53d10e68a8..fcb367eefa 100644 --- a/packages/neuron-wallet/tests/controllers/sync-api.test.ts +++ b/packages/neuron-wallet/tests/controllers/sync-api.test.ts @@ -47,6 +47,9 @@ jest.doMock('services/ckb-runner', () => ({ jest.mock('undici', () => ({ request: () => jest.fn()() })) +jest.mock('services/multisig', () => ({ + syncMultisigOutput: () => jest.fn() +})) describe('SyncApiController', () => { const emitter = new Emitter() diff --git a/packages/neuron-wallet/tests/services/light-runner.test.ts b/packages/neuron-wallet/tests/services/light-runner.test.ts index 9f8c886ae7..11b3d85557 100644 --- a/packages/neuron-wallet/tests/services/light-runner.test.ts +++ b/packages/neuron-wallet/tests/services/light-runner.test.ts @@ -19,6 +19,7 @@ const spawnMock = jest.fn() const loggerErrorMock = jest.fn() const loggerInfoMock = jest.fn() const transportsGetFileMock = jest.fn() +const cleanMock = jest.fn() function resetMock() { mockFn.mockReset() @@ -38,6 +39,7 @@ function resetMock() { loggerErrorMock.mockReset() loggerInfoMock.mockReset() transportsGetFileMock.mockReset() + cleanMock.mockReset() } jest.doMock('../../src/env', () => ({ @@ -67,6 +69,10 @@ jest.doMock('../../src/services/settings', () => ({ } })) +jest.doMock('../../src/database/chain', () => ({ + clean: cleanMock +})) + jest.doMock('process', () => ({ get platform() { return platformMock()