From 33627b550bc02b970d384e72e407725591e57079 Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Thu, 25 May 2023 15:37:56 +0800 Subject: [PATCH 1/2] fix: Fix multisig with light client 1. Any multisig script should sync from 0. 2. When adding multisig address after deletion, it should start sync again. 3. Every 10s to refresh multisig sync height, not when multisig address changes. --- .../src/components/MultisigAddress/hooks.ts | 16 ++++++--- .../sync/light-connector.ts | 34 ++++++++++++------- .../src/services/sync-progress.ts | 19 +++++++++-- .../light-connector.test.ts | 11 ++++-- 4 files changed, 57 insertions(+), 23 deletions(-) diff --git a/packages/neuron-ui/src/components/MultisigAddress/hooks.ts b/packages/neuron-ui/src/components/MultisigAddress/hooks.ts index 6acbb6c2e6..b448c0ee00 100644 --- a/packages/neuron-ui/src/components/MultisigAddress/hooks.ts +++ b/packages/neuron-ui/src/components/MultisigAddress/hooks.ts @@ -320,17 +320,23 @@ export const useSubscription = ({ useEffect(() => { const dataUpdateSubscription = MultisigOutputUpdate.subscribe(() => { getAndSaveMultisigBalances() - if (isLightClient) { - getAndSaveMultisigSyncProgress() - } }) getAndSaveMultisigBalances() + return () => { + dataUpdateSubscription.unsubscribe() + } + }, [walletId, getAndSaveMultisigBalances]) + useEffect(() => { + let interval: ReturnType | undefined if (isLightClient) { + interval = setInterval(() => { + getAndSaveMultisigSyncProgress() + }, 10000) getAndSaveMultisigSyncProgress() } return () => { - dataUpdateSubscription.unsubscribe() + clearInterval(interval) } - }, [walletId, getAndSaveMultisigBalances]) + }, [isLightClient, getAndSaveMultisigSyncProgress]) return { multisigBanlances, multisigSyncProgress } } 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 a55ce16778..67e86d2eed 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 @@ -156,8 +156,8 @@ export default class LightConnector extends Connector { }) } - private async initSyncProgress(appendScripts?: AppendScript[]) { - if (!this.addressMetas.length && !appendScripts?.length) { + private async initSyncProgress(appendScripts: AppendScript[] = []) { + if (!this.addressMetas.length && !appendScripts.length) { return } const syncScripts = await this.lightRpc.getScripts() @@ -181,27 +181,35 @@ export default class LightConnector extends Connector { })) }) .flat() - .concat(appendScripts ?? []) const walletMinBlockNumber = await SyncProgressService.getWalletMinBlockNumber() const wallets = await WalletService.getInstance().getAll() const walletStartBlockMap = wallets.reduce>( (pre, cur) => ({ ...pre, [cur.id]: cur.startBlockNumberInLight }), {} ) - const setScriptsParams = allScripts.map(v => ({ - ...v, - blockNumber: - existSyncscripts[scriptToHash(v.script)]?.blockNumber ?? - walletStartBlockMap[v.walletId] ?? - `0x${(walletMinBlockNumber?.[v.walletId] ?? 0).toString(16)}` - })) + const otherTypeSyncProgress = await SyncProgressService.getOtherTypeSyncProgress() + const setScriptsParams = [ + ...allScripts.map(v => ({ + ...v, + blockNumber: + existSyncscripts[scriptToHash(v.script)]?.blockNumber ?? + walletStartBlockMap[v.walletId] ?? + `0x${(walletMinBlockNumber?.[v.walletId] ?? 0).toString(16)}` + })), + ...appendScripts.map(v => ({ + ...v, + blockNumber: + existSyncscripts[scriptToHash(v.script)]?.blockNumber ?? + `0x${(otherTypeSyncProgress[scriptToHash(v.script)] ?? 0).toString(16)}` + })) + ] await this.lightRpc.setScripts(setScriptsParams) - await SyncProgressService.resetSyncProgress(allScripts) const walletIds = [...new Set(this.addressMetas.map(v => v.walletId))] - await SyncProgressService.removeWalletsByExists(walletIds) + await SyncProgressService.resetSyncProgress([...allScripts, ...appendScripts]) + await SyncProgressService.updateSyncProgressFlag(walletIds) await SyncProgressService.removeByHashesAndAddressType( SyncAddressType.Multisig, - appendScripts?.map(v => scriptToHash(v.script)) + appendScripts.map(v => scriptToHash(v.script)) ) } diff --git a/packages/neuron-wallet/src/services/sync-progress.ts b/packages/neuron-wallet/src/services/sync-progress.ts index 8530e90516..7a1d9d5a9b 100644 --- a/packages/neuron-wallet/src/services/sync-progress.ts +++ b/packages/neuron-wallet/src/services/sync-progress.ts @@ -22,13 +22,19 @@ export default class SyncProgressService { .execute() } - static async removeWalletsByExists(existWalletIds: string[]) { + static async updateSyncProgressFlag(existWalletIds: string[]) { await getConnection() .createQueryBuilder() .update(SyncProgress) .set({ delete: true }) .where({ walletId: Not(In(existWalletIds)) }) .execute() + await getConnection() + .createQueryBuilder() + .update(SyncProgress) + .set({ delete: false }) + .where({ walletId: In(existWalletIds) }) + .execute() } static async removeByHashesAndAddressType(addressType: SyncAddressType, existHashes?: string[]) { @@ -84,7 +90,7 @@ export default class SyncProgressService { const item = await getConnection() .getRepository(SyncProgress) .createQueryBuilder() - .where({ delete: false, ...(currentWallet ? { walletId: currentWallet.id } : {}) }) + .where({ delete: false, addressType: SyncAddressType.Default, ...(currentWallet ? { walletId: currentWallet.id } : {}) }) .orderBy('blockEndNumber', 'ASC') .getOne() return item?.blockEndNumber || 0 @@ -101,6 +107,15 @@ export default class SyncProgressService { return items.reduce>((pre, cur) => ({ ...pre, [cur.walletId]: cur.blockStartNumber }), {}) } + static async getOtherTypeSyncProgress() { + const items = await getConnection() + .getRepository(SyncProgress) + .find({ + addressType: SyncAddressType.Multisig, + }) + return items.reduce>((pre, cur) => ({ ...pre, [cur.hash]: cur.blockStartNumber }), {}) + } + static async getSyncProgressByHashes(hashes: string[]) { return await getConnection() .getRepository(SyncProgress) diff --git a/packages/neuron-wallet/tests/block-sync-renderer/light-connector.test.ts b/packages/neuron-wallet/tests/block-sync-renderer/light-connector.test.ts index 5ebffb5634..779a7f366e 100644 --- a/packages/neuron-wallet/tests/block-sync-renderer/light-connector.test.ts +++ b/packages/neuron-wallet/tests/block-sync-renderer/light-connector.test.ts @@ -9,9 +9,10 @@ const getCurrentWalletMinBlockNumberMock = jest.fn() const getAllSyncStatusToMapMock = jest.fn() const resetSyncProgressMock = jest.fn() const updateSyncStatusMock = jest.fn() -const removeWalletsByExistsMock = jest.fn() +const updateSyncProgressFlagMock = jest.fn() const getWalletMinBlockNumberMock = jest.fn() const removeByHashesAndAddressType = jest.fn() +const getOtherTypeSyncProgressMock = jest.fn() const setScriptsMock = jest.fn() const getScriptsMock = jest.fn() @@ -31,6 +32,7 @@ function mockReset() { resetSyncProgressMock.mockReset() updateSyncStatusMock.mockReset() getWalletMinBlockNumberMock.mockReset() + getOtherTypeSyncProgressMock.mockReset() setScriptsMock.mockReset() getScriptsMock.mockReset() @@ -52,9 +54,10 @@ jest.mock('../../src/services/sync-progress', () => { static getAllSyncStatusToMap: any = () => getAllSyncStatusToMapMock() static resetSyncProgress: any = (arg: any) => resetSyncProgressMock(arg) static updateSyncStatus: any = (hash: string, update: any) => updateSyncStatusMock(hash, update) - static removeWalletsByExists: any = (walletIds: string[]) => removeWalletsByExistsMock(walletIds) + static updateSyncProgressFlag: any = (walletIds: string[]) => updateSyncProgressFlagMock(walletIds) static getWalletMinBlockNumber: any = () => getWalletMinBlockNumberMock() static removeByHashesAndAddressType: any = (type: number, scripts: CKBComponents.Script[]) => removeByHashesAndAddressType(type, scripts) + static getOtherTypeSyncProgress: any = () => getOtherTypeSyncProgressMock() } }) @@ -101,6 +104,8 @@ describe('test light connector', () => { beforeEach(() => { walletGetAllMock.mockReturnValue([]) createBatchRequestMock.mockResolvedValue([]) + getMultisigConfigForLightMock.mockResolvedValue([]) + getOtherTypeSyncProgressMock.mockResolvedValue({}) }) afterEach(() => { mockReset() @@ -287,7 +292,7 @@ describe('test light connector', () => { { script: addressMeta.generateACPLockScript().toSDK(), scriptType: 'lock', walletId: 'walletId' }, { script: addressMeta.generateLegacyACPLockScript().toSDK(), scriptType: 'lock', walletId: 'walletId' }, ]) - expect(removeWalletsByExistsMock).toBeCalledWith(['walletId']) + expect(updateSyncProgressFlagMock).toBeCalledWith(['walletId']) }) it('set new script with the synced min block number', async () => { getScriptsMock.mockResolvedValue([]) From 68df6f8177e4e51127af8c5d501ac4c65de80d4d Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Thu, 25 May 2023 18:10:28 +0800 Subject: [PATCH 2/2] fix: Code style. --- .../src/block-sync-renderer/sync/light-connector.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 67e86d2eed..e50f5a99fb 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 @@ -205,7 +205,7 @@ export default class LightConnector extends Connector { ] await this.lightRpc.setScripts(setScriptsParams) const walletIds = [...new Set(this.addressMetas.map(v => v.walletId))] - await SyncProgressService.resetSyncProgress([...allScripts, ...appendScripts]) + await SyncProgressService.resetSyncProgress([allScripts, appendScripts].flat()) await SyncProgressService.updateSyncProgressFlag(walletIds) await SyncProgressService.removeByHashesAndAddressType( SyncAddressType.Multisig,