Skip to content

Commit

Permalink
Fix slowness in delegate page (#180)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tbaut authored Oct 7, 2024
1 parent ad994c2 commit 0170c6e
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 84 deletions.
6 changes: 3 additions & 3 deletions src/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { ConnectionDialog } from 'dot-connect/react.js'
// MenubarTrigger,
// } from '@/components/ui/menubar'
import { useAccounts } from './contexts/AccountsContext'
import { useEffect, useState } from 'react'
import { Fragment, useEffect, useState } from 'react'
import { SupportedNetworkNames, useNetwork } from './contexts/NetworkContext'
import { useTheme } from './components/theme-provider'
import { Link, useLocation } from 'react-router-dom'
Expand Down Expand Up @@ -189,7 +189,7 @@ export const Header = () => {
</DropdownMenuTrigger>
<DropdownMenuContent className="max-h-[calc(100vh-5rem)] overflow-auto">
{accounts.map((account, index) => (
<>
<Fragment key={account.address}>
<DropdownMenuItem
className="cursor-pointer"
key={account.address}
Expand All @@ -206,7 +206,7 @@ export const Header = () => {
{index !== accounts.length - 1 && (
<DropdownMenuSeparator />
)}
</>
</Fragment>
))}
<DropdownMenuItem
className="cursor-pointer"
Expand Down
18 changes: 10 additions & 8 deletions src/hooks/useTestTx.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@ import {
} from '@polkadot-labs/hdkd-helpers'
import { getPolkadotSigner } from 'polkadot-api/signer'
import { useNetwork } from '@/contexts/NetworkContext'
import { useCallback } from 'react'
import { useCallback, useMemo } from 'react'

export const useTestTx = () => {
const { api } = useNetwork()
const derive = sr25519CreateDerive(
entropyToMiniSecret(mnemonicToEntropy(DEV_PHRASE)),
const derive = useMemo(
() =>
sr25519CreateDerive(entropyToMiniSecret(mnemonicToEntropy(DEV_PHRASE))),
[],
)
const aliceKeyPair = derive('//Alice')
const aliceSigner = getPolkadotSigner(
aliceKeyPair.publicKey,
'Sr25519',
aliceKeyPair.sign,
const aliceKeyPair = useMemo(() => derive('//Alice'), [derive])
const aliceSigner = useMemo(
() =>
getPolkadotSigner(aliceKeyPair.publicKey, 'Sr25519', aliceKeyPair.sign),
[aliceKeyPair.publicKey, aliceKeyPair.sign],
)

const isExhaustsResources = useCallback(
Expand Down
26 changes: 20 additions & 6 deletions src/pages/Delegate/MultiTransactionDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useAccounts } from '@/contexts/AccountsContext'
import { useNetwork } from '@/contexts/NetworkContext'
import { DelegateTxs } from '@/hooks/useGetDelegateTx'
import { useTestTx } from '@/hooks/useTestTx'
import { useState } from 'react'
import { useCallback, useState } from 'react'
import { TooLargeDialog } from './TooLargeDialog'
import { useGetSigningCallback } from '@/hooks/useGetSigningCallback'

Expand Down Expand Up @@ -42,7 +42,7 @@ export const MultiTransactionDialog = ({
step === 2 && onSignStep2()
}

const onSignStep1 = async () => {
const onSignStep1 = useCallback(async () => {
if (!api || !selectedAccount) return
setIsTxInitiated(true)

Expand Down Expand Up @@ -76,9 +76,16 @@ export const MultiTransactionDialog = ({
;(await step1Txs)
.signSubmitAndWatch(selectedAccount?.polkadotSigner, { at: 'best' })
.subscribe(subscriptionCallBack1)
}

const onSignStep2 = async () => {
}, [
api,
delegateTxs.removeDelegationsTxs,
delegateTxs.removeVotesTxs,
getSubscriptionCallBack,
isExhaustsResources,
selectedAccount,
])

const onSignStep2 = useCallback(async () => {
if (!api || !selectedAccount) return
setIsTxInitiated(true)

Expand Down Expand Up @@ -114,7 +121,14 @@ export const MultiTransactionDialog = ({
await step2Txs
.signSubmitAndWatch(selectedAccount?.polkadotSigner, { at: 'best' })
.subscribe(subscriptionCallBack2)
}
}, [
api,
delegateTxs.delegationTxs,
getSubscriptionCallBack,
isExhaustsResources,
onProcessFinished,
selectedAccount,
])

if (promptForHelpCallData)
return (
Expand Down
190 changes: 123 additions & 67 deletions src/pages/Delegate/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import {
} from '@/contexts/DelegatesContext'
import { useNetwork } from '@/contexts/NetworkContext'
import { VotingConviction } from '@polkadot-api/descriptors'
import { SetStateAction, useEffect, useMemo, useState } from 'react'
import {
SetStateAction,
useCallback,
useEffect,
useMemo,
useState,
} from 'react'
import { Button } from '@/components/ui/button'
import { useAccounts } from '@/contexts/AccountsContext'
import { Slider } from '@/components/ui/slider'
Expand All @@ -15,7 +21,7 @@ import { ArrowLeft, Loader2 } from 'lucide-react'
import { msgs } from '@/lib/constants'
import { evalUnits, planckToUnit } from '@polkadot-ui/utils'
import { useLocks } from '@/contexts/LocksContext'
import { DelegateTxs, useGetDelegateTx } from '@/hooks/useGetDelegateTx'
import { useGetDelegateTx } from '@/hooks/useGetDelegateTx'
import { AlertNote } from '@/components/Alert'
import { useTestTx } from '@/hooks/useTestTx'
import { MultiTransactionDialog } from './MultiTransactionDialog'
Expand Down Expand Up @@ -46,8 +52,50 @@ export const Delegate = () => {
const [isTxInitiated, setIsTxInitiated] = useState(false)
const { isExhaustsResources } = useTestTx()
const [isMultiTxDialogOpen, setIsMultiTxDialogOpen] = useState(false)
const [delegateTxs, setDelegateTxs] = useState<DelegateTxs>({} as DelegateTxs)
const [noDelegateFound, setNoDelegateFound] = useState(false)
const [allTracks, setAllTracks] = useState<number[]>([])
const [isExhaustsResourcesError, setIsExhaustsResourcesError] = useState<
boolean | null
>(false)
const {
delegationTxs = [],
removeDelegationsTxs = [],
removeVotesTxs = [],
} = useMemo(() => {
if (!delegate) return {}

return getDelegateTx({
delegateAddress: delegate.address,
conviction: conviction,
amount,
tracks: allTracks || [],
})
}, [allTracks, amount, conviction, delegate, getDelegateTx])

const allTxs = useMemo(() => {
if (!api) return

return api.tx.Utility.batch_all({
calls: [...removeVotesTxs, ...removeDelegationsTxs, ...delegationTxs].map(
(tx) => tx.decodedCall,
),
})
}, [api, delegationTxs, removeDelegationsTxs, removeVotesTxs])

useEffect(() => {
if (!allTxs) return

// check if we have an exhausted limit on the whole tx
isExhaustsResources(allTxs)
.then(setIsExhaustsResourcesError)
.catch(console.error)
}, [
allTxs,
delegationTxs,
isExhaustsResources,
removeDelegationsTxs,
removeVotesTxs,
])

useEffect(() => {
// the delegate list may still be loading
Expand All @@ -66,7 +114,12 @@ export const Delegate = () => {
}, [address, delegate, getDelegateByAddress, isLoadingDelegates])

const { display: convictionTimeDisplay, multiplier: convictionMultiplier } =
getConvictionLockTimeDisplay(convictionNo)
useMemo(
() =>
getConvictionLockTimeDisplay(convictionNo) ||
getConvictionLockTimeDisplay(convictionNo),
[convictionNo, getConvictionLockTimeDisplay],
)

const voteAmount = useMemo(() => {
if (!convictionMultiplier) return
Expand Down Expand Up @@ -101,77 +154,62 @@ export const Delegate = () => {
setAmountVisible('0')
}, [api])

const onChangeAmount = (
e: React.ChangeEvent<HTMLInputElement>,
decimals: number,
) => {
setIsAmountDirty(true)
setAmountError('')
const [bnResult, errorMessage] = evalUnits(e.target.value, decimals)
setAmount(bnResult || 0n)
if (errorMessage) setAmountError(errorMessage)
setAmountVisible(e.target.value)
}

const onChangeSplitTransactionDialog = (isOpen: boolean) => {
useEffect(() => {
if (!api) return

api.constants.Referenda.Tracks()
.then((tracks) => {
const trackIds = tracks.map(([track]) => track)
setAllTracks(trackIds)
})
.catch(console.error)
}, [api])

const onChangeAmount = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
setIsAmountDirty(true)
setAmountError('')
const [bnResult, errorMessage] = evalUnits(
e.target.value,
assetInfo.precision,
)
setAmount(bnResult || 0n)
if (errorMessage) setAmountError(errorMessage)
setAmountVisible(e.target.value)
},
[assetInfo.precision],
)

const onOpenChangeSplitTransactionDialog = useCallback((isOpen: boolean) => {
setIsMultiTxDialogOpen(isOpen)
setIsTxInitiated(false)
}
}, [])

const onProcessFinished = () => {
const onProcessFinished = useCallback(() => {
refreshLocks()
navigate(`/${search}`)
setIsTxInitiated(false)
onChangeSplitTransactionDialog(false)
}
onOpenChangeSplitTransactionDialog(false)
}, [navigate, onOpenChangeSplitTransactionDialog, refreshLocks, search])

const onSign = async () => {
const onSign = useCallback(async () => {
if (!delegate || !selectedAccount || !amount || !api) return

setIsTxInitiated(true)

const allTracks = await api.constants.Referenda.Tracks()
.then((tracks) => {
return tracks.map(([track]) => track)
})
.catch((e) => {
console.error(e)
setIsTxInitiated(false)
})

const {
delegationTxs = [],
removeDelegationsTxs = [],
removeVotesTxs = [],
} = getDelegateTx({
delegateAddress: delegate.address,
conviction: conviction,
amount,
tracks: allTracks || [],
})

setDelegateTxs({
removeVotesTxs,
removeDelegationsTxs,
delegationTxs,
})

const allTxs = api.tx.Utility.batch_all({
calls: [...removeVotesTxs, ...removeDelegationsTxs, ...delegationTxs].map(
(tx) => tx.decodedCall,
),
})
if (
!removeDelegationsTxs.length &&
!removeVotesTxs.length &&
!delegationTxs.length
) {
return
}

if (!allTxs) {
setIsTxInitiated(false)
return
}

// check if we have an exhausted limit on the whole tx
const isExhaustsRessouces = await isExhaustsResources(allTxs)

// this is too big of a batch we need to split it up
if (isExhaustsRessouces) {
if (isExhaustsResourcesError) {
setIsMultiTxDialogOpen(true)
return
}
Expand All @@ -184,7 +222,19 @@ export const Delegate = () => {
await allTxs
.signSubmitAndWatch(selectedAccount?.polkadotSigner, { at: 'best' })
.subscribe(subscriptionCallBack)
}
}, [
allTxs,
amount,
api,
delegate,
delegationTxs.length,
getSubscriptionCallBack,
isExhaustsResourcesError,
onProcessFinished,
removeDelegationsTxs.length,
removeVotesTxs.length,
selectedAccount,
])

if (noDelegateFound)
return (
Expand Down Expand Up @@ -230,7 +280,7 @@ export const Delegate = () => {
<div>
<Label>Amount</Label>
<Input
onChange={(value) => onChangeAmount(value, assetInfo.precision)}
onChange={onChangeAmount}
value={amountVisible}
error={amountErrorDisplay}
/>
Expand Down Expand Up @@ -272,12 +322,18 @@ export const Delegate = () => {
Delegate with {voteAmount} {assetInfo.symbol} votes
</Button>
</div>
<MultiTransactionDialog
isOpen={isMultiTxDialogOpen}
onOpenChange={onChangeSplitTransactionDialog}
delegateTxs={delegateTxs}
onProcessFinished={onProcessFinished}
/>
{isMultiTxDialogOpen && (
<MultiTransactionDialog
isOpen={isMultiTxDialogOpen}
onOpenChange={onOpenChangeSplitTransactionDialog}
delegateTxs={{
delegationTxs,
removeDelegationsTxs,
removeVotesTxs,
}}
onProcessFinished={onProcessFinished}
/>
)}
</main>
)
}

0 comments on commit 0170c6e

Please sign in to comment.