Skip to content

Commit

Permalink
feat(fix): Remove left pool from state (#2373)
Browse files Browse the repository at this point in the history
  • Loading branch information
rossbulat authored Dec 19, 2024
1 parent 04308d4 commit 4b823b9
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 149 deletions.
65 changes: 31 additions & 34 deletions packages/app/src/api/subscribe/activePoolAccount/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,15 @@ export class ActivePoolAccount implements Unsubscribable {
document.dispatchEvent(
new CustomEvent('new-active-pool', {
detail: {
pool: this.pool,
address: this.address,
pool: this.activePool,
activePool: this.activePool,
nominations: this.poolNominations,
},
})
)
}
})

this.#sub = sub
} catch (e) {
// Subscription failed.
Expand All @@ -97,38 +97,35 @@ export class ActivePoolAccount implements Unsubscribable {
const balance = account.data
const rewardAccountBalance = balance?.free.toString()

if (Apis.getClient(peopleApiId)) {
// Fetch identities for roles and expand `bondedPool` state to store them.
bondedPool.roleIdentities = await Identities.fetch(
peopleApiId,
this.getUniqueRoleAddresses(bondedPool.roles)
)
}

const bondedPoolFormatted = {
points: bondedPool.points.toString(),
memberCounter: bondedPool.member_counter.toString(),
roles: bondedPool.roles,
roleIdentities: bondedPool.roleIdentities,
state: bondedPool.state.type,
}

const rewardPoolFormatted = {
lastRecordedRewardCounter:
rewardPool.last_recorded_reward_counter.toString(),
lastRecordedTotalPayouts:
rewardPool.last_recorded_total_payouts.toString(),
totalCommissionClaimed: rewardPool.total_commission_claimed.toString(),
totalCommissionPending: rewardPool.total_commission_pending.toString(),
totalRewardsClaimed: rewardPool.total_rewards_claimed.toString(),
}

const pendingRewards =
(await new PoolPendingRewards(this.#network, this.address).fetch()) || 0n

// Only persist the active pool to class state (and therefore dispatch an event) if both the
// bonded pool and reward pool are returned.
// Only format the active pool if both bonded and reward pools are valid. Otherwise, assume
// there is no active pool.
if (bondedPool && rewardPool) {
if (Apis.getClient(peopleApiId)) {
// Fetch identities for roles and expand `bondedPool` state to store them.
bondedPool.roleIdentities = await Identities.fetch(
peopleApiId,
this.getUniqueRoleAddresses(bondedPool.roles)
)
}
const bondedPoolFormatted = {
points: bondedPool.points.toString(),
memberCounter: bondedPool.member_counter.toString(),
roles: bondedPool.roles,
roleIdentities: bondedPool.roleIdentities,
state: bondedPool.state.type,
}
const rewardPoolFormatted = {
lastRecordedRewardCounter:
rewardPool.last_recorded_reward_counter.toString(),
lastRecordedTotalPayouts:
rewardPool.last_recorded_total_payouts.toString(),
totalCommissionClaimed: rewardPool.total_commission_claimed.toString(),
totalCommissionPending: rewardPool.total_commission_pending.toString(),
totalRewardsClaimed: rewardPool.total_rewards_claimed.toString(),
}
const pendingRewards =
(await new PoolPendingRewards(this.#network, this.address).fetch()) ||
0n
const newPool = {
id: Number(this.pool.id),
addresses: this.pool.addresses,
Expand All @@ -140,7 +137,7 @@ export class ActivePoolAccount implements Unsubscribable {

this.activePool = newPool
} else {
// Invalid pools were returned. To signal pool was synced, set active pool to `null`.
// No pool was returned. To signal pool was synced, set active pool to `null`.
this.activePool = null
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/common-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ declare global {
stakingMetrics: APIStakingMetrics
}>
'new-active-pool': CustomEvent<DetailActivePool>
'removed-active-pool': CustomEvent<{ address: string; poolId: string }>
'new-pool-members-batch': CustomEvent<PoolMemberBatchEvent>
'new-fast-unstake-config': CustomEvent<FastUnstakeConfigResult>
'new-fast-unstake-deposit': CustomEvent<FastUnstakeQueueResult>
Expand Down
2 changes: 0 additions & 2 deletions packages/app/src/contexts/Pools/ActivePool/defaults.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright 2024 @polkadot-cloud/polkadot-staking-dashboard authors & contributors
// SPDX-License-Identifier: GPL-3.0-only
/* eslint-disable @typescript-eslint/no-unused-vars */

import type { ActivePoolContextState } from './types'

Expand Down Expand Up @@ -28,7 +27,6 @@ export const defaultActivePoolContext: ActivePoolContextState = {
isBouncer: () => false,
getPoolUnlocking: () => [],
getPoolRoles: () => defaultPoolRoles,
setActivePoolId: (p) => {},
activePool: null,
activePoolNominations: null,
}
85 changes: 19 additions & 66 deletions packages/app/src/contexts/Pools/ActivePool/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// SPDX-License-Identifier: GPL-3.0-only

import { useEffectIgnoreInitial } from '@w3ux/hooks'
import { setStateWithRef } from '@w3ux/utils'
import { useActiveAccounts } from 'contexts/ActiveAccounts'
import { useBalances } from 'contexts/Balances'
import { useNetwork } from 'contexts/Network'
Expand All @@ -11,7 +10,7 @@ import { Syncs } from 'controllers/Syncs'
import { useActivePools } from 'hooks/useActivePools'
import { useCreatePoolAccounts } from 'hooks/useCreatePoolAccounts'
import type { ReactNode } from 'react'
import { createContext, useContext, useRef, useState } from 'react'
import { createContext, useContext } from 'react'
import type { ActivePoolItem } from 'types'
import { useApi } from '../../Api'
import { defaultActivePoolContext, defaultPoolRoles } from './defaults'
Expand All @@ -31,21 +30,10 @@ export const ActivePoolProvider = ({ children }: { children: ReactNode }) => {
const createPoolAccounts = useCreatePoolAccounts()

const membership = getPoolMembership(activeAccount)

// Determine active pools to subscribe to. Dependencies of `activeAccount`, and `membership` mean
// that this object is only recalculated when these values change.
// Determine active pool to subscribe to based on the membership pool id
const accountPoolId = membership?.poolId ? String(membership.poolId) : null

// Store the currently selected active pool for the UI. Should default to the membership pool if
// present. Used in event callback, therefore needs an accompanying ref.
const [activePoolId, setActivePoolIdState] = useState<string | null>(null)
const activePoolIdRef = useRef(activePoolId)

const setActivePoolId = (id: string | null) => {
setStateWithRef(id, setActivePoolIdState, activePoolIdRef)
}

// Only listen to the active account's active pools, otherwise return an empty array.
// Only listen to the active account's active pool
const { getActivePool, getPoolNominations } = useActivePools({
who: activeAccount,
onCallback: async () => {
Expand All @@ -55,14 +43,13 @@ export const ActivePoolProvider = ({ children }: { children: ReactNode }) => {
},
})

const activePool = activePoolId ? getActivePool(activePoolId) : null

const activePoolNominations = activePoolId
? getPoolNominations(activePoolId)
const activePool = accountPoolId ? getActivePool(accountPoolId) : null
const activePoolNominations = accountPoolId
? getPoolNominations(accountPoolId)
: null

// Sync active pool subscriptions.
const syncActivePools = async () => {
// Sync active pool subscription
const syncActivePool = async () => {
if (isReady) {
let newActivePool: ActivePoolItem[] = []
if (accountPoolId) {
Expand All @@ -81,27 +68,10 @@ export const ActivePoolProvider = ({ children }: { children: ReactNode }) => {
}
}

// Attempt to assign the default `activePoolId` if one is not currently active.
const assignActivePoolId = () => {
const initialActivePoolId = membership?.poolId || null
if (initialActivePoolId && !activePool) {
setActivePoolId(String(initialActivePoolId))
}
if (activePool && !initialActivePoolId) {
setActivePoolId(null)
}
}

// Reset `activePoolId`.
const resetActivePoolId = () => {
setStateWithRef(null, setActivePoolIdState, activePoolIdRef)
}

// Returns whether the active pool is being bonded to (essentially if there is indeed an
// activePool).
// Returns whether the active pool is being bonded to
const isBonding = () => !!activePool

// Returns whether the active account is the nominator in the active pool.
// Returns whether the active account is the nominator in the active pool
const isNominator = () => {
const roles = activePool?.bondedPool?.roles
if (!activeAccount || !roles) {
Expand All @@ -110,7 +80,7 @@ export const ActivePoolProvider = ({ children }: { children: ReactNode }) => {
return activeAccount === roles?.nominator
}

// Returns whether the active account is the owner of the active pool.
// Returns whether the active account is the owner of the active pool
const isOwner = () => {
const roles = activePool?.bondedPool?.roles
if (!activeAccount || !roles) {
Expand All @@ -119,7 +89,7 @@ export const ActivePoolProvider = ({ children }: { children: ReactNode }) => {
return activeAccount === roles?.root
}

// Returns whether the active account is a member of the active pool.
// Returns whether the active account is a member of the active pool
const isMember = () => {
const p = activePool ? String(activePool.id) : '-1'
return String(membership?.poolId || '') === p
Expand All @@ -128,7 +98,7 @@ export const ActivePoolProvider = ({ children }: { children: ReactNode }) => {
// Returns whether the active account is in a pool.
const inPool = () => !!membership

// Returns whether the active account is the depositor of the active pool.
// Returns whether the active account is the depositor of the active pool
const isDepositor = () => {
const roles = activePool?.bondedPool?.roles
if (!activeAccount || !roles) {
Expand All @@ -137,7 +107,7 @@ export const ActivePoolProvider = ({ children }: { children: ReactNode }) => {
return activeAccount === roles?.depositor
}

// Returns whether the active account is the depositor of the active pool.
// Returns whether the active account is the depositor of the active pool
const isBouncer = () => {
const roles = activePool?.bondedPool?.roles
if (!activeAccount || !roles) {
Expand All @@ -146,35 +116,19 @@ export const ActivePoolProvider = ({ children }: { children: ReactNode }) => {
return activeAccount === roles?.bouncer
}

// Returns the active pool's roles or the default roles object.
// Returns the active pool's roles or the default roles object
const getPoolRoles = () => activePool?.bondedPool?.roles || defaultPoolRoles

// Returns the unlock chunks of the active pool if `activeAccount` is a member of the pool.
const getPoolUnlocking = () => {
// exit early if the active pool is not membership pool
if (activePoolId !== String(membership?.poolId || -1)) {
return []
}
return membership?.unlocking || []
}
// Returns the unlock chunks of the active pool
const getPoolUnlocking = () => membership?.unlocking || []

// Initialise subscriptions to all active pools of imported accounts.
// Initialise subscriptions to the active account's active pool
useEffectIgnoreInitial(() => {
if (isReady) {
syncActivePools()
assignActivePoolId()
syncActivePool()
}
}, [network, isReady, membership])

// Reset on network change and component unmount. NOTE: ActivePools also unsubscribes on
// network change; this is handled by the Api instance.
useEffectIgnoreInitial(() => {
resetActivePoolId()
return () => {
resetActivePoolId()
}
}, [activeAccount, network])

return (
<ActivePoolContext.Provider
value={{
Expand All @@ -187,7 +141,6 @@ export const ActivePoolProvider = ({ children }: { children: ReactNode }) => {
isBonding,
getPoolUnlocking,
getPoolRoles,
setActivePoolId,
activePool,
activePoolNominations,
}}
Expand Down
1 change: 0 additions & 1 deletion packages/app/src/contexts/Pools/ActivePool/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export interface ActivePoolContextState {
isBouncer: () => boolean
getPoolUnlocking: () => PoolUnlocking[]
getPoolRoles: () => PoolRoles
setActivePoolId: (p: string) => void
activePool: ActivePool | null
activePoolNominations: Nominations | null
}
Loading

0 comments on commit 4b823b9

Please sign in to comment.