Skip to content

Commit 25b9993

Browse files
feat: reduce ledger polling on heavy duty work like recover accounts (#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
1 parent a56001b commit 25b9993

File tree

4 files changed

+71
-29
lines changed

4 files changed

+71
-29
lines changed

packages/shared/lib/contexts/onboarding/actions/findShimmerRewards.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { showAppNotification } from '@auxiliary/notification'
22
import { IAccount } from '@core/account'
33
import { localize } from '@core/i18n'
4-
import { AccountRecoveryProfileConfiguration, UnableToFindProfileTypeError } from '@core/profile'
4+
import { updateLedgerNanoStatus } from '@core/ledger'
5+
import { AccountRecoveryProfileConfiguration, ProfileType, UnableToFindProfileTypeError } from '@core/profile'
56
import { RecoverAccountsPayload, recoverAccounts } from '@core/profile-manager'
67
import { zip } from '@core/utils'
78
import { formatTokenAmountBestMatch } from '@core/wallet/utils'
@@ -58,12 +59,26 @@ export function initialiseAccountRecoveryConfigurationForShimmerClaiming(): void
5859
}
5960

6061
export async function findShimmerRewards(): Promise<void> {
61-
await depthSearchAndRecoverAccounts()
62+
const _isOnboardingLedgerProfile = get(onboardingProfile)?.type === ProfileType.Ledger
63+
try {
64+
if (_isOnboardingLedgerProfile) {
65+
// Note: This is a way to know the ledger is doing heavy work
66+
updateLedgerNanoStatus({ busy: true })
67+
}
68+
await depthSearchAndRecoverAccounts()
6269

63-
if (hasOnlyDoneDepthSearch()) {
64-
await breadthSearchAndRecoverAccounts()
70+
if (hasOnlyDoneDepthSearch()) {
71+
await breadthSearchAndRecoverAccounts()
72+
}
73+
updateRewardsFinderParameters()
74+
} catch (error) {
75+
const message = error?.message ?? error?.error ?? ''
76+
throw new Error(message)
77+
} finally {
78+
if (_isOnboardingLedgerProfile) {
79+
updateLedgerNanoStatus({ busy: false })
80+
}
6581
}
66-
updateRewardsFinderParameters()
6782
}
6883

6984
async function depthSearchAndRecoverAccounts(): Promise<void> {

packages/shared/lib/core/account/actions/findBalances.ts

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { DEFAULT_SYNC_OPTIONS, SearchAlgorithmType } from '@core/account'
2+
import { updateLedgerNanoStatus } from '@core/ledger'
23
import {
34
BALANCE_FINDER_ACCOUNT_RECOVERY_CONFIGURATION,
45
UnableToFindProfileTypeError,
56
activeProfile,
7+
isActiveLedgerProfile,
68
} from '@core/profile'
79
import { RecoverAccountsPayload, recoverAccounts } from '@core/profile-manager'
810
import { get } from 'svelte/store'
@@ -40,17 +42,31 @@ export async function findBalances(
4042
init?: boolean,
4143
config?: RecoverAccountsPayload
4244
): Promise<void> {
43-
if (init) {
44-
initialiseAccountRecoveryConfiguration(algortihmType, config)
45-
}
46-
if (algortihmType === SearchAlgorithmType.BFS || algortihmType === SearchAlgorithmType.IDS) {
47-
await breadthSearchAndRecoverAccounts(config)
48-
searchAccountStartIndex += _accountGapLimit
49-
}
50-
if (algortihmType === SearchAlgorithmType.DFS || algortihmType === SearchAlgorithmType.IDS) {
51-
await depthSearchAndRecoverAccounts(config)
52-
// TODO: Improve the address start index, checking which is the last address index found in a account and continuing searching from that index
53-
searchAddressStartIndex += _addressGapLimit
45+
const _isActiveLedgerProfile = get(isActiveLedgerProfile)
46+
try {
47+
if (init) {
48+
initialiseAccountRecoveryConfiguration(algortihmType, config)
49+
}
50+
if (_isActiveLedgerProfile) {
51+
// Note: This is a way to know the ledger is doing heavy work
52+
updateLedgerNanoStatus({ busy: true })
53+
}
54+
if (algortihmType === SearchAlgorithmType.BFS || algortihmType === SearchAlgorithmType.IDS) {
55+
await breadthSearchAndRecoverAccounts(config)
56+
searchAccountStartIndex += _accountGapLimit
57+
}
58+
if (algortihmType === SearchAlgorithmType.DFS || algortihmType === SearchAlgorithmType.IDS) {
59+
await depthSearchAndRecoverAccounts(config)
60+
// TODO: Improve the address start index, checking which is the last address index found in a account and continuing searching from that index
61+
searchAddressStartIndex += _addressGapLimit
62+
}
63+
} catch (error) {
64+
const message = error?.message ?? error?.error ?? ''
65+
throw new Error(message)
66+
} finally {
67+
if (_isActiveLedgerProfile) {
68+
updateLedgerNanoStatus({ busy: false })
69+
}
5470
}
5571
}
5672

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,35 @@
11
import { get } from 'svelte/store'
2-
2+
import { DEFAULT_LEDGER_NANO_STATUS_POLL_INTERVAL } from '../constants'
33
import { deconstructLedgerNanoStatusPollingConfiguration } from '../helpers'
44
import { ILedgerNanoStatusPollingConfiguration } from '../interfaces'
5-
import { isPollingLedgerDeviceStatus } from '../stores'
6-
5+
import { isPollingLedgerDeviceStatus, ledgerNanoStatus } from '../stores'
76
import { getAndUpdateLedgerNanoStatus } from './getAndUpdateLedgerNanoStatus'
87

9-
let intervalTimer: ReturnType<typeof setInterval>
8+
let timeoutTimer: ReturnType<typeof setTimeout> | undefined
109

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

13+
const defaultPollInterval = pollInterval || DEFAULT_LEDGER_NANO_STATUS_POLL_INTERVAL
14+
const slowedPollInterval = 10 * defaultPollInterval
15+
1416
if (!get(isPollingLedgerDeviceStatus)) {
15-
void getAndUpdateLedgerNanoStatus(profileManager)
16-
intervalTimer = setInterval(() => {
17-
void getAndUpdateLedgerNanoStatus(profileManager)
18-
}, pollInterval)
1917
isPollingLedgerDeviceStatus.set(true)
18+
const pollingFunction = async (): Promise<void> => {
19+
await getAndUpdateLedgerNanoStatus(profileManager)
20+
const isLedgerBusy = get(ledgerNanoStatus)?.busy
21+
const currentPollInterval = isLedgerBusy ? slowedPollInterval : defaultPollInterval
22+
timeoutTimer = setTimeout(() => void pollingFunction(), currentPollInterval)
23+
}
24+
25+
void pollingFunction()
2026
}
2127
}
2228

2329
export function stopPollingLedgerNanoStatus(): void {
2430
if (get(isPollingLedgerDeviceStatus)) {
25-
clearInterval(intervalTimer)
26-
intervalTimer = null
31+
clearInterval(timeoutTimer)
32+
timeoutTimer = undefined
2733
isPollingLedgerDeviceStatus.set(false)
2834
}
2935
}

packages/shared/lib/core/ledger/stores/ledger-nano-status.store.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
import { LedgerNanoStatus } from '@iota/sdk/out/types'
22
import { writable } from 'svelte/store'
33

4-
const DEFAULT_LEDGER_STATUS: LedgerNanoStatus = {
4+
interface ExtendedLedgerNanoStatus extends LedgerNanoStatus {
5+
busy?: boolean
6+
}
7+
8+
const DEFAULT_LEDGER_STATUS: ExtendedLedgerNanoStatus = {
59
app: undefined,
610
blindSigningEnabled: false,
711
bufferSize: undefined,
812
connected: false,
913
device: undefined,
1014
locked: false,
15+
busy: false,
1116
}
1217

13-
export const ledgerNanoStatus = writable<LedgerNanoStatus>(DEFAULT_LEDGER_STATUS)
18+
export const ledgerNanoStatus = writable<ExtendedLedgerNanoStatus>(DEFAULT_LEDGER_STATUS)
1419

15-
export function updateLedgerNanoStatus(payload: Partial<LedgerNanoStatus>): void {
20+
export function updateLedgerNanoStatus(payload: Partial<ExtendedLedgerNanoStatus>): void {
1621
return ledgerNanoStatus.update((state) => {
1722
if (ledgerNanoStatus) {
1823
return { ...state, ...payload }

0 commit comments

Comments
 (0)