-
Notifications
You must be signed in to change notification settings - Fork 380
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(llm,lld): improve Solana scan accounts performances #9512
base: develop
Are you sure you want to change the base?
fix(llm,lld): improve Solana scan accounts performances #9512
Conversation
The latest updates on your projects. Learn more about Vercel for Git βοΈ
3 Skipped Deployments
|
4bc6d0d
to
db18121
Compare
db18121
to
6fe69e6
Compare
6fe69e6
to
a6fa77f
Compare
a6fa77f
to
2b2b3ac
Compare
2b2b3ac
to
d34c102
Compare
d34c102
to
bed6385
Compare
bed6385
to
9cf2238
Compare
); | ||
}); | ||
|
||
return compact(stakes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could do this without lodash but I don't really mind using it here
return compact(stakes); | |
return stakes.filter(Boolean); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It won't work as is, since Boolean
is no predicate. Better keeping it to avoid extra boilerplate in my opinion.
const rawStakeAccounts = await api.getStakeAccountsByWithdrawAuth(mainAccountAddress); | ||
|
||
if (!rawStakeAccounts.length) return []; | ||
|
||
const sysvarStakeHistoryAccount = await api.getAccountInfo( | ||
SYSVAR_STAKE_HISTORY_PUBKEY.toBase58(), | ||
); | ||
if ( | ||
!sysvarStakeHistoryAccount || | ||
!("parsed" in sysvarStakeHistoryAccount.data) || | ||
!("info" in sysvarStakeHistoryAccount.data.parsed) | ||
) | ||
throw new Error("StakeHistory not found"); | ||
|
||
const sysvarStakeHistoryAccountInfo = sysvarStakeHistoryAccount.data.parsed.info; | ||
const stakeHistory = Array.isArray(sysvarStakeHistoryAccountInfo) | ||
? sysvarStakeHistoryAccountInfo.filter(isHistoryEntry).map(e => ({ | ||
epoch: BigNumber(e.epoch), | ||
effective: BigNumber(e.stakeHistory.effective), | ||
activating: BigNumber(e.stakeHistory.activating), | ||
deactivating: BigNumber(e.stakeHistory.deactivating), | ||
})) | ||
: []; | ||
|
||
const { epoch } = await api.getEpochInfo(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably keep the promise.all
on the 3 calls getStakeAccountsByWithdrawAuth
, getAccountInfo
and getEpochInfo
as it was done before, wdyt ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually didn't do it in order to save useless calls to the network (if getStakeAccountsByWithdrawAuth
does not return any stake account, no need to call neither getAccountInfo
nor getEpochInfo
).
const nextSubAccs: TokenAccount[] = await Promise.all( | ||
accountsWithTransactions.map(account => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, looks like you're already doing the parallel calls we talked about today for the sub accounts
The only drawback maybe here is that we don't limit the number of concurrent promises
const { | ||
value: balanceValue, | ||
context: { slot: blockHeight }, | ||
} = await api.getBalanceAndContext(address); | ||
const balance = new BigNumber(balanceValue); | ||
|
||
const tokenAccountsRaw = (await api.getParsedTokenAccountsByOwner(address)).value; | ||
const token2022AccountsRaw = coinConfig.getCoinConfig().token2022Enabled | ||
? (await api.getParsedToken2022AccountsByOwner(address)).value | ||
: []; | ||
const tokenAccounts = [...tokenAccountsRaw, ...token2022AccountsRaw].map(toTokenAccountWithInfo); | ||
|
||
const stakes = await getStakeAccounts(api, address); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also probably do those calls in parallel too
descriptors: Array<TransactionDescriptor>; | ||
}> | ||
> { | ||
// TODO: before merging, rebase this PR on https://github.com/LedgerHQ/ledger-live/pull/9480 once CI is green, and use `ky` instead of `fetch` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still want to wait for the other PR ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just merged the other PR π
.map(account => | ||
account && "parsed" in account.data ? tryParseAsMintAccount(account.data) : undefined, | ||
) | ||
.map(mintInfo => (mintInfo && !(mintInfo instanceof Error) ? mintInfo.extensions : undefined)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could probably do a single map instead of 2 here, wdyt ?
9cf2238
to
9284a65
Compare
9284a65
to
df94c72
Compare
df94c72
to
5ffb3a8
Compare
5ffb3a8
to
66fd28b
Compare
66fd28b
to
4f271fd
Compare
4f271fd
to
eb1c438
Compare
|
β Checklist
npx changeset
was attached.π Description
The scan account operation for Solana is particularly slow in Ledger Live. One reason is that quite a lot of HTTP requests are done sequentially to list token and staking accounts, as well as fetching all the transactions.
This PR focuses on re-writing this part, grouping RPC requests together or running them asynchronously when possible.
β Context
π§ Checklist for the PR Reviewers