Skip to content

Commit

Permalink
feat: reduce ledger polling on heavy duty work like recover accounts (#…
Browse files Browse the repository at this point in the history
…7715)

* feat: reduce ledger polling on heavy duty work like recover accounts

* fix: remove global variable

* chore: improve code

* chore: update variables as requested in PR

* feat: reduce ledger polling during shimmer rewards discovery

* fix: setTimeout
  • Loading branch information
begonaalvarezd authored Nov 17, 2023
1 parent a56001b commit 25b9993
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { showAppNotification } from '@auxiliary/notification'
import { IAccount } from '@core/account'
import { localize } from '@core/i18n'
import { AccountRecoveryProfileConfiguration, UnableToFindProfileTypeError } from '@core/profile'
import { updateLedgerNanoStatus } from '@core/ledger'
import { AccountRecoveryProfileConfiguration, ProfileType, UnableToFindProfileTypeError } from '@core/profile'
import { RecoverAccountsPayload, recoverAccounts } from '@core/profile-manager'
import { zip } from '@core/utils'
import { formatTokenAmountBestMatch } from '@core/wallet/utils'
Expand Down Expand Up @@ -58,12 +59,26 @@ export function initialiseAccountRecoveryConfigurationForShimmerClaiming(): void
}

export async function findShimmerRewards(): Promise<void> {
await depthSearchAndRecoverAccounts()
const _isOnboardingLedgerProfile = get(onboardingProfile)?.type === ProfileType.Ledger
try {
if (_isOnboardingLedgerProfile) {
// Note: This is a way to know the ledger is doing heavy work
updateLedgerNanoStatus({ busy: true })
}
await depthSearchAndRecoverAccounts()

if (hasOnlyDoneDepthSearch()) {
await breadthSearchAndRecoverAccounts()
if (hasOnlyDoneDepthSearch()) {
await breadthSearchAndRecoverAccounts()
}
updateRewardsFinderParameters()
} catch (error) {
const message = error?.message ?? error?.error ?? ''
throw new Error(message)
} finally {
if (_isOnboardingLedgerProfile) {
updateLedgerNanoStatus({ busy: false })
}
}
updateRewardsFinderParameters()
}

async function depthSearchAndRecoverAccounts(): Promise<void> {
Expand Down
38 changes: 27 additions & 11 deletions packages/shared/lib/core/account/actions/findBalances.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { DEFAULT_SYNC_OPTIONS, SearchAlgorithmType } from '@core/account'
import { updateLedgerNanoStatus } from '@core/ledger'
import {
BALANCE_FINDER_ACCOUNT_RECOVERY_CONFIGURATION,
UnableToFindProfileTypeError,
activeProfile,
isActiveLedgerProfile,
} from '@core/profile'
import { RecoverAccountsPayload, recoverAccounts } from '@core/profile-manager'
import { get } from 'svelte/store'
Expand Down Expand Up @@ -40,17 +42,31 @@ export async function findBalances(
init?: boolean,
config?: RecoverAccountsPayload
): Promise<void> {
if (init) {
initialiseAccountRecoveryConfiguration(algortihmType, config)
}
if (algortihmType === SearchAlgorithmType.BFS || algortihmType === SearchAlgorithmType.IDS) {
await breadthSearchAndRecoverAccounts(config)
searchAccountStartIndex += _accountGapLimit
}
if (algortihmType === SearchAlgorithmType.DFS || algortihmType === SearchAlgorithmType.IDS) {
await depthSearchAndRecoverAccounts(config)
// TODO: Improve the address start index, checking which is the last address index found in a account and continuing searching from that index
searchAddressStartIndex += _addressGapLimit
const _isActiveLedgerProfile = get(isActiveLedgerProfile)
try {
if (init) {
initialiseAccountRecoveryConfiguration(algortihmType, config)
}
if (_isActiveLedgerProfile) {
// Note: This is a way to know the ledger is doing heavy work
updateLedgerNanoStatus({ busy: true })
}
if (algortihmType === SearchAlgorithmType.BFS || algortihmType === SearchAlgorithmType.IDS) {
await breadthSearchAndRecoverAccounts(config)
searchAccountStartIndex += _accountGapLimit
}
if (algortihmType === SearchAlgorithmType.DFS || algortihmType === SearchAlgorithmType.IDS) {
await depthSearchAndRecoverAccounts(config)
// TODO: Improve the address start index, checking which is the last address index found in a account and continuing searching from that index
searchAddressStartIndex += _addressGapLimit
}
} catch (error) {
const message = error?.message ?? error?.error ?? ''
throw new Error(message)
} finally {
if (_isActiveLedgerProfile) {
updateLedgerNanoStatus({ busy: false })
}
}
}

Expand Down
26 changes: 16 additions & 10 deletions packages/shared/lib/core/ledger/actions/pollLedgerNanoStatus.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,35 @@
import { get } from 'svelte/store'

import { DEFAULT_LEDGER_NANO_STATUS_POLL_INTERVAL } from '../constants'
import { deconstructLedgerNanoStatusPollingConfiguration } from '../helpers'
import { ILedgerNanoStatusPollingConfiguration } from '../interfaces'
import { isPollingLedgerDeviceStatus } from '../stores'

import { isPollingLedgerDeviceStatus, ledgerNanoStatus } from '../stores'
import { getAndUpdateLedgerNanoStatus } from './getAndUpdateLedgerNanoStatus'

let intervalTimer: ReturnType<typeof setInterval>
let timeoutTimer: ReturnType<typeof setTimeout> | undefined

export function pollLedgerNanoStatus(config?: ILedgerNanoStatusPollingConfiguration): void {
const { pollInterval, profileManager } = deconstructLedgerNanoStatusPollingConfiguration(config)

const defaultPollInterval = pollInterval || DEFAULT_LEDGER_NANO_STATUS_POLL_INTERVAL
const slowedPollInterval = 10 * defaultPollInterval

if (!get(isPollingLedgerDeviceStatus)) {
void getAndUpdateLedgerNanoStatus(profileManager)
intervalTimer = setInterval(() => {
void getAndUpdateLedgerNanoStatus(profileManager)
}, pollInterval)
isPollingLedgerDeviceStatus.set(true)
const pollingFunction = async (): Promise<void> => {
await getAndUpdateLedgerNanoStatus(profileManager)
const isLedgerBusy = get(ledgerNanoStatus)?.busy
const currentPollInterval = isLedgerBusy ? slowedPollInterval : defaultPollInterval
timeoutTimer = setTimeout(() => void pollingFunction(), currentPollInterval)
}

void pollingFunction()
}
}

export function stopPollingLedgerNanoStatus(): void {
if (get(isPollingLedgerDeviceStatus)) {
clearInterval(intervalTimer)
intervalTimer = null
clearInterval(timeoutTimer)
timeoutTimer = undefined
isPollingLedgerDeviceStatus.set(false)
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import { LedgerNanoStatus } from '@iota/sdk/out/types'
import { writable } from 'svelte/store'

const DEFAULT_LEDGER_STATUS: LedgerNanoStatus = {
interface ExtendedLedgerNanoStatus extends LedgerNanoStatus {
busy?: boolean
}

const DEFAULT_LEDGER_STATUS: ExtendedLedgerNanoStatus = {
app: undefined,
blindSigningEnabled: false,
bufferSize: undefined,
connected: false,
device: undefined,
locked: false,
busy: false,
}

export const ledgerNanoStatus = writable<LedgerNanoStatus>(DEFAULT_LEDGER_STATUS)
export const ledgerNanoStatus = writable<ExtendedLedgerNanoStatus>(DEFAULT_LEDGER_STATUS)

export function updateLedgerNanoStatus(payload: Partial<LedgerNanoStatus>): void {
export function updateLedgerNanoStatus(payload: Partial<ExtendedLedgerNanoStatus>): void {
return ledgerNanoStatus.update((state) => {
if (ledgerNanoStatus) {
return { ...state, ...payload }
Expand Down

0 comments on commit 25b9993

Please sign in to comment.