Browse Source

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
master
Gaëtan Renaudeau 6 years ago
parent
commit
683942217b
No known key found for this signature in database GPG Key ID: 7B66B85F042E5451
  1. 8
      src/bridge/LibcoreBridge.js
  2. 6
      src/commands/libcoreGetFees.js
  3. 2
      src/commands/libcoreSignAndBroadcast.js
  4. 2
      src/commands/libcoreSyncAccount.js
  5. 37
      src/helpers/libcore.js
  6. 67
      src/internals/index.js

8
src/bridge/LibcoreBridge.js

@ -126,8 +126,8 @@ const LibcoreBridge: WalletBridge<Transaction> = {
currencyId: account.currency.id, currencyId: account.currency.id,
}) })
.pipe( .pipe(
map(rawSyncedAccount => { map(({ rawAccount, requiresCacheFlush }) => {
const syncedAccount = decodeAccount(rawSyncedAccount) const syncedAccount = decodeAccount(rawAccount)
return account => { return account => {
const accountOps = account.operations const accountOps = account.operations
const syncedOps = syncedAccount.operations const syncedOps = syncedAccount.operations
@ -141,11 +141,11 @@ const LibcoreBridge: WalletBridge<Transaction> = {
} }
const hasChanged = const hasChanged =
requiresCacheFlush ||
accountOps.length !== syncedOps.length || // size change, we do a full refresh for now... accountOps.length !== syncedOps.length || // size change, we do a full refresh for now...
(accountOps.length > 0 && (accountOps.length > 0 &&
syncedOps.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)) accountOps[0].blockHeight !== syncedOps[0].blockHeight))
if (hasChanged) { if (hasChanged) {

6
src/commands/libcoreGetFees.js

@ -54,7 +54,11 @@ const cmd: Command<Input, Result> = createCommand(
withLibcore(async core => { withLibcore(async core => {
const { walletName } = accountIdHelper.decode(accountId) 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 if (isCancelled()) return
const njsAccount = await njsWallet.getAccount(accountIndex) const njsAccount = await njsWallet.getAccount(accountIndex)
if (isCancelled()) return if (isCancelled()) return

2
src/commands/libcoreSignAndBroadcast.js

@ -195,7 +195,7 @@ export async function doSignAndBroadcast({
const isSegwit = isSegwitPath(freshAddressPath) const isSegwit = isSegwitPath(freshAddressPath)
const isUnsplit = isUnsplitPath(freshAddressPath, splittedCurrencies[currencyId]) 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 if (isCancelled()) return
const njsAccount = await njsWallet.getAccount(index) const njsAccount = await njsWallet.getAccount(index)
if (isCancelled()) return if (isCancelled()) return

2
src/commands/libcoreSyncAccount.js

@ -14,7 +14,7 @@ type Input = {
index: number, index: number,
} }
type Result = AccountRaw type Result = { rawAccount: AccountRaw, requiresCacheFlush: boolean }
const cmd: Command<Input, Result> = createCommand('libcoreSyncAccount', accountInfos => const cmd: Command<Input, Result> = createCommand('libcoreSyncAccount', accountInfos =>
fromPromise(withLibcore(core => syncAccount({ ...accountInfos, core }))), fromPromise(withLibcore(core => syncAccount({ ...accountInfos, core }))),

37
src/helpers/libcore.js

@ -20,15 +20,6 @@ import { deserializeError } from './errors'
import { getAccountPlaceholderName, getNewAccountPlaceholderName } from './accountName' import { getAccountPlaceholderName, getNewAccountPlaceholderName } from './accountName'
import { timeoutTagged } from './promise' 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 { export function isValidAddress(core: *, currency: *, address: string): boolean {
const addr = new core.NJSAddress(address, currency) const addr = new core.NJSAddress(address, currency)
return addr.isValid(address, currency) return addr.isValid(address, currency)
@ -147,7 +138,7 @@ async function scanAccountsOnDeviceBySegwit({
const walletName = encodeWalletName({ publicKey, currencyId, isSegwit, isUnsplit }) const walletName = encodeWalletName({ publicKey, currencyId, isSegwit, isUnsplit })
// retrieve or create the wallet // 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() const accountsCount = await wallet.getAccountCount()
// recursively scan all accounts on device on the given app // recursively scan all accounts on device on the given app
@ -324,15 +315,19 @@ const createWalletConfig = (core, configMap = {}) => {
export async function getOrCreateWallet( export async function getOrCreateWallet(
core: *, core: *,
walletName: string, walletName: string,
currencyId: string, {
isSegwit: boolean, currencyId,
isUnsplit: boolean, isSegwit,
isUnsplit,
}: {
currencyId: string,
isSegwit: boolean,
isUnsplit: boolean,
},
): NJSWallet { ): NJSWallet {
const migrationNonce = migrationNonceByCurrency[currencyId]
const walletId = walletName + (migrationNonce ? `_${migrationNonce}` : '')
const pool = core.getPoolInstance() const pool = core.getPoolInstance()
try { try {
const wallet = await timeoutTagged('getWallet', 5000, pool.getWallet(walletId)) const wallet = await timeoutTagged('getWallet', 5000, pool.getWallet(walletName))
return wallet return wallet
} catch (err) { } catch (err) {
const currency = await timeoutTagged('getCurrency', 5000, pool.getCurrency(currencyId)) const currency = await timeoutTagged('getCurrency', 5000, pool.getCurrency(currencyId))
@ -352,7 +347,7 @@ export async function getOrCreateWallet(
const wallet = await timeoutTagged( const wallet = await timeoutTagged(
'createWallet', 'createWallet',
10000, 10000,
core.getPoolInstance().createWallet(walletId, currency, njsWalletConfig), core.getPoolInstance().createWallet(walletName, currency, njsWalletConfig),
) )
return wallet return wallet
} }
@ -522,12 +517,14 @@ export async function syncAccount({
const { walletName } = decodedAccountId const { walletName } = decodedAccountId
const isSegwit = isSegwitPath(freshAddressPath) const isSegwit = isSegwitPath(freshAddressPath)
const isUnsplit = isUnsplitPath(freshAddressPath, splittedCurrencies[currencyId]) 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 njsAccount
let requiresCacheFlush = false
try { try {
njsAccount = await timeoutTagged('getAccount', 10000, njsWallet.getAccount(index)) njsAccount = await timeoutTagged('getAccount', 10000, njsWallet.getAccount(index))
} catch (e) { } catch (e) {
requiresCacheFlush = true
logger.warn(`Have to recreate the account... (${e.message})`) logger.warn(`Have to recreate the account... (${e.message})`)
const extendedInfos = await timeoutTagged( const extendedInfos = await timeoutTagged(
'getEKACI', 'getEKACI',
@ -565,7 +562,7 @@ export async function syncAccount({
logger.log(`Synced account [${syncedRawAccount.name}]: ${syncedRawAccount.balance}`) logger.log(`Synced account [${syncedRawAccount.name}]: ${syncedRawAccount.balance}`)
return syncedRawAccount return { rawAccount: syncedRawAccount, requiresCacheFlush }
} }
export function libcoreAmountToBigNumber(njsAmount: *): BigNumber { export function libcoreAmountToBigNumber(njsAmount: *): BigNumber {
@ -597,7 +594,7 @@ export async function scanAccountsFromXPUB({
isUnsplit, 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)) await wallet.eraseDataSince(new Date(0))

67
src/internals/index.js

@ -63,34 +63,45 @@ process.on('message', m => {
} }
const startTime = Date.now() const startTime = Date.now()
logger.onCmd('cmd.START', id, 0, data) logger.onCmd('cmd.START', id, 0, data)
subscriptions[requestId] = cmd.impl(data).subscribe({ try {
next: data => { subscriptions[requestId] = cmd.impl(data).subscribe({
logger.onCmd('cmd.NEXT', id, Date.now() - startTime, data) next: data => {
process.send({ logger.onCmd('cmd.NEXT', id, Date.now() - startTime, data)
type: 'cmd.NEXT', process.send({
requestId, type: 'cmd.NEXT',
data, requestId,
}) data,
}, })
complete: () => { },
delete subscriptions[requestId] complete: () => {
logger.onCmd('cmd.COMPLETE', id, Date.now() - startTime) delete subscriptions[requestId]
process.send({ logger.onCmd('cmd.COMPLETE', id, Date.now() - startTime)
type: 'cmd.COMPLETE', process.send({
requestId, type: 'cmd.COMPLETE',
}) requestId,
}, })
error: error => { },
logger.warn('Command error:', error) error: error => {
delete subscriptions[requestId] logger.warn('Command error:', error)
logger.onCmd('cmd.ERROR', id, Date.now() - startTime, error) delete subscriptions[requestId]
process.send({ logger.onCmd('cmd.ERROR', id, Date.now() - startTime, error)
type: 'cmd.ERROR', process.send({
requestId, type: 'cmd.ERROR',
data: serializeError(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') { } else if (m.type === 'command-unsubscribe') {
const { requestId } = m const { requestId } = m
const sub = subscriptions[requestId] const sub = subscriptions[requestId]

Loading…
Cancel
Save