From 683942217bc46100326fcf4e5f71df854dd04f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Tue, 11 Sep 2018 15:03:05 +0200 Subject: [PATCH] remove the nonce mecanism because don't work for DGB also reinforce some failsafe: - try catch the command execution - mecanism to flush the cache in case an account was not found in libcore --- src/bridge/LibcoreBridge.js | 8 +-- src/commands/libcoreGetFees.js | 6 ++- src/commands/libcoreSignAndBroadcast.js | 2 +- src/commands/libcoreSyncAccount.js | 2 +- src/helpers/libcore.js | 37 +++++++------- src/internals/index.js | 67 ++++++++++++++----------- 6 files changed, 67 insertions(+), 55 deletions(-) diff --git a/src/bridge/LibcoreBridge.js b/src/bridge/LibcoreBridge.js index c9b9535d..abfa5eae 100644 --- a/src/bridge/LibcoreBridge.js +++ b/src/bridge/LibcoreBridge.js @@ -126,8 +126,8 @@ const LibcoreBridge: WalletBridge = { currencyId: account.currency.id, }) .pipe( - map(rawSyncedAccount => { - const syncedAccount = decodeAccount(rawSyncedAccount) + map(({ rawAccount, requiresCacheFlush }) => { + const syncedAccount = decodeAccount(rawAccount) return account => { const accountOps = account.operations const syncedOps = syncedAccount.operations @@ -141,11 +141,11 @@ const LibcoreBridge: WalletBridge = { } const hasChanged = + requiresCacheFlush || accountOps.length !== syncedOps.length || // size change, we do a full refresh for now... (accountOps.length > 0 && syncedOps.length > 0 && - (accountOps[0].accountId !== syncedOps[0].accountId || - accountOps[0].id !== syncedOps[0].id || // if same size, only check if the last item has changed. + (accountOps[0].id !== syncedOps[0].id || // if same size, only check if the last item has changed. accountOps[0].blockHeight !== syncedOps[0].blockHeight)) if (hasChanged) { diff --git a/src/commands/libcoreGetFees.js b/src/commands/libcoreGetFees.js index 58e8512c..4b3c8d5b 100644 --- a/src/commands/libcoreGetFees.js +++ b/src/commands/libcoreGetFees.js @@ -54,7 +54,11 @@ const cmd: Command = createCommand( withLibcore(async core => { const { walletName } = accountIdHelper.decode(accountId) - const njsWallet = await getOrCreateWallet(core, walletName, currencyId, isSegwit, isUnsplit) + const njsWallet = await getOrCreateWallet(core, walletName, { + currencyId, + isSegwit, + isUnsplit, + }) if (isCancelled()) return const njsAccount = await njsWallet.getAccount(accountIndex) if (isCancelled()) return diff --git a/src/commands/libcoreSignAndBroadcast.js b/src/commands/libcoreSignAndBroadcast.js index d1fbd814..ad81d05c 100644 --- a/src/commands/libcoreSignAndBroadcast.js +++ b/src/commands/libcoreSignAndBroadcast.js @@ -195,7 +195,7 @@ export async function doSignAndBroadcast({ const isSegwit = isSegwitPath(freshAddressPath) const isUnsplit = isUnsplitPath(freshAddressPath, splittedCurrencies[currencyId]) - const njsWallet = await getOrCreateWallet(core, walletName, currencyId, isSegwit, isUnsplit) + const njsWallet = await getOrCreateWallet(core, walletName, { currencyId, isSegwit, isUnsplit }) if (isCancelled()) return const njsAccount = await njsWallet.getAccount(index) if (isCancelled()) return diff --git a/src/commands/libcoreSyncAccount.js b/src/commands/libcoreSyncAccount.js index bbc94644..21104d20 100644 --- a/src/commands/libcoreSyncAccount.js +++ b/src/commands/libcoreSyncAccount.js @@ -14,7 +14,7 @@ type Input = { index: number, } -type Result = AccountRaw +type Result = { rawAccount: AccountRaw, requiresCacheFlush: boolean } const cmd: Command = createCommand('libcoreSyncAccount', accountInfos => fromPromise(withLibcore(core => syncAccount({ ...accountInfos, core }))), diff --git a/src/helpers/libcore.js b/src/helpers/libcore.js index cd4c1756..a81f2353 100644 --- a/src/helpers/libcore.js +++ b/src/helpers/libcore.js @@ -20,15 +20,6 @@ import { deserializeError } from './errors' import { getAccountPlaceholderName, getNewAccountPlaceholderName } from './accountName' import { timeoutTagged } from './promise' -// each time there is a breaking change that needs use to clear cache on both libcore and js side, -// we should bump a nonce in this map -// tech notes: -// - this is used to generate walletName for libcore to completely re-sync to a new wallet. -// - by changing walletName we also make the JS db refresh because we handle the accountId changes (walletName is in accountId). -const migrationNonceByCurrency = { - digibyte: 1, -} - export function isValidAddress(core: *, currency: *, address: string): boolean { const addr = new core.NJSAddress(address, currency) return addr.isValid(address, currency) @@ -147,7 +138,7 @@ async function scanAccountsOnDeviceBySegwit({ const walletName = encodeWalletName({ publicKey, currencyId, isSegwit, isUnsplit }) // retrieve or create the wallet - const wallet = await getOrCreateWallet(core, walletName, currencyId, isSegwit, isUnsplit) + const wallet = await getOrCreateWallet(core, walletName, { currencyId, isSegwit, isUnsplit }) const accountsCount = await wallet.getAccountCount() // recursively scan all accounts on device on the given app @@ -324,15 +315,19 @@ const createWalletConfig = (core, configMap = {}) => { export async function getOrCreateWallet( core: *, walletName: string, - currencyId: string, - isSegwit: boolean, - isUnsplit: boolean, + { + currencyId, + isSegwit, + isUnsplit, + }: { + currencyId: string, + isSegwit: boolean, + isUnsplit: boolean, + }, ): NJSWallet { - const migrationNonce = migrationNonceByCurrency[currencyId] - const walletId = walletName + (migrationNonce ? `_${migrationNonce}` : '') const pool = core.getPoolInstance() try { - const wallet = await timeoutTagged('getWallet', 5000, pool.getWallet(walletId)) + const wallet = await timeoutTagged('getWallet', 5000, pool.getWallet(walletName)) return wallet } catch (err) { const currency = await timeoutTagged('getCurrency', 5000, pool.getCurrency(currencyId)) @@ -352,7 +347,7 @@ export async function getOrCreateWallet( const wallet = await timeoutTagged( 'createWallet', 10000, - core.getPoolInstance().createWallet(walletId, currency, njsWalletConfig), + core.getPoolInstance().createWallet(walletName, currency, njsWalletConfig), ) return wallet } @@ -522,12 +517,14 @@ export async function syncAccount({ const { walletName } = decodedAccountId const isSegwit = isSegwitPath(freshAddressPath) const isUnsplit = isUnsplitPath(freshAddressPath, splittedCurrencies[currencyId]) - const njsWallet = await getOrCreateWallet(core, walletName, currencyId, isSegwit, isUnsplit) + const njsWallet = await getOrCreateWallet(core, walletName, { currencyId, isSegwit, isUnsplit }) let njsAccount + let requiresCacheFlush = false try { njsAccount = await timeoutTagged('getAccount', 10000, njsWallet.getAccount(index)) } catch (e) { + requiresCacheFlush = true logger.warn(`Have to recreate the account... (${e.message})`) const extendedInfos = await timeoutTagged( 'getEKACI', @@ -565,7 +562,7 @@ export async function syncAccount({ logger.log(`Synced account [${syncedRawAccount.name}]: ${syncedRawAccount.balance}`) - return syncedRawAccount + return { rawAccount: syncedRawAccount, requiresCacheFlush } } export function libcoreAmountToBigNumber(njsAmount: *): BigNumber { @@ -597,7 +594,7 @@ export async function scanAccountsFromXPUB({ isUnsplit, }) - const wallet = await getOrCreateWallet(core, walletName, currencyId, isSegwit, isUnsplit) + const wallet = await getOrCreateWallet(core, walletName, { currencyId, isSegwit, isUnsplit }) await wallet.eraseDataSince(new Date(0)) diff --git a/src/internals/index.js b/src/internals/index.js index e6b17f04..baf58aa6 100644 --- a/src/internals/index.js +++ b/src/internals/index.js @@ -63,34 +63,45 @@ process.on('message', m => { } const startTime = Date.now() logger.onCmd('cmd.START', id, 0, data) - subscriptions[requestId] = cmd.impl(data).subscribe({ - next: data => { - logger.onCmd('cmd.NEXT', id, Date.now() - startTime, data) - process.send({ - type: 'cmd.NEXT', - requestId, - data, - }) - }, - complete: () => { - delete subscriptions[requestId] - logger.onCmd('cmd.COMPLETE', id, Date.now() - startTime) - process.send({ - type: 'cmd.COMPLETE', - requestId, - }) - }, - error: error => { - logger.warn('Command error:', error) - delete subscriptions[requestId] - logger.onCmd('cmd.ERROR', id, Date.now() - startTime, error) - process.send({ - type: 'cmd.ERROR', - requestId, - data: serializeError(error), - }) - }, - }) + try { + subscriptions[requestId] = cmd.impl(data).subscribe({ + next: data => { + logger.onCmd('cmd.NEXT', id, Date.now() - startTime, data) + process.send({ + type: 'cmd.NEXT', + requestId, + data, + }) + }, + complete: () => { + delete subscriptions[requestId] + logger.onCmd('cmd.COMPLETE', id, Date.now() - startTime) + process.send({ + type: 'cmd.COMPLETE', + requestId, + }) + }, + error: error => { + logger.warn('Command error:', error) + delete subscriptions[requestId] + logger.onCmd('cmd.ERROR', id, Date.now() - startTime, error) + process.send({ + type: 'cmd.ERROR', + requestId, + data: serializeError(error), + }) + }, + }) + } catch (error) { + logger.warn('Command error:', error) + delete subscriptions[requestId] + logger.onCmd('cmd.ERROR', id, Date.now() - startTime, error) + process.send({ + type: 'cmd.ERROR', + requestId, + data: serializeError(error), + }) + } } else if (m.type === 'command-unsubscribe') { const { requestId } = m const sub = subscriptions[requestId]