Perform per-loaded bag rebag calculations (#7288)
This commit is contained in:
parent
7502a148e4
commit
97b4217610
@ -4,7 +4,7 @@
|
||||
import type { AccountId32 } from '@polkadot/types/interfaces';
|
||||
import type { PalletBagsListListBag } from '@polkadot/types/lookup';
|
||||
import type { BN } from '@polkadot/util';
|
||||
import type { StashNode } from './types';
|
||||
import type { ListNode, StashNode } from './types';
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
@ -24,8 +24,21 @@ interface Props {
|
||||
upper: BN;
|
||||
}
|
||||
|
||||
function getRebags (bonded: ListNode[], stashNodes: StashNode[], lower: BN, upper: BN): string[] {
|
||||
return bonded
|
||||
.filter(({ bonded, stashId }) =>
|
||||
(
|
||||
bonded.gt(upper) ||
|
||||
bonded.lt(lower)
|
||||
) &&
|
||||
stashNodes.every((n) => n.stashId !== stashId)
|
||||
)
|
||||
.map(({ stashId }) => stashId);
|
||||
}
|
||||
|
||||
function Bag ({ info, lower, stashNodes, upper }: Props): React.ReactElement<Props> {
|
||||
const [[headId, trigger], setHeadId] = useState<[AccountId32 | null, number]>([null, 0]);
|
||||
const [, setRebags] = useState<string[]>([]);
|
||||
const [isLoading, setLoading] = useState(true);
|
||||
const [isCompleted, list] = useBagEntries(headId, trigger);
|
||||
const bonded = useBonded(list);
|
||||
@ -43,6 +56,16 @@ function Bag ({ info, lower, stashNodes, upper }: Props): React.ReactElement<Pro
|
||||
);
|
||||
}, [bonded, isCompleted, stashNodes]);
|
||||
|
||||
// TODO: Currently not used, but calculated. This is the list of stashes that
|
||||
// should be rebagged (need to provide a rebag modal to move all these at once)
|
||||
useEffect((): void => {
|
||||
// NOTE: There may be some issues if these are indeed rebagged - we need
|
||||
// the StashNode to see if this item is indeed still within this list
|
||||
!isLoading && bonded && stashNodes && setRebags(
|
||||
getRebags(bonded, stashNodes, lower, upper)
|
||||
);
|
||||
}, [bonded, isLoading, lower, stashNodes, upper]);
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td className='number' />
|
||||
|
||||
@ -70,12 +70,10 @@ function Bags ({ ownStashes }: Props): React.ReactElement<Props> {
|
||||
value={filterIndex}
|
||||
/>
|
||||
</Button.Group>
|
||||
{(
|
||||
<article className='warning centered'>
|
||||
<p>{t('The All bags list is composed of bags that each describe a range of active bonded funds of the nominators. In each bag is a list of nodes that correspond to a nominator and their staked funds.')}</p>
|
||||
<p>{t('Within the context of a single bag, nodes are not sorted by their stake, but instead placed in insertion order. In other words, the most recently inserted node will be the last node in the bag, regardless of stake. Events like staking rewards or slashes do not automatically put you in a different bag. The bags-list pallet comes with an important permissionless extrinsic: rebag. This allows anyone to specify another account that is in the wrong bag, and place it in the correct one.')}</p>
|
||||
</article>
|
||||
)}
|
||||
<article className='warning centered'>
|
||||
<p>{t('The All bags list is composed of bags that each describe a range of active bonded funds of the nominators. In each bag is a list of nodes that correspond to a nominator and their staked funds.')}</p>
|
||||
<p>{t('Within the context of a single bag, nodes are not sorted by their stake, but instead placed in insertion order. In other words, the most recently inserted node will be the last node in the bag, regardless of stake. Events like staking rewards or slashes do not automatically put you in a different bag. The bags-list pallet comes with an important permissionless extrinsic: rebag. This allows anyone to specify another account that is in the wrong bag, and place it in the correct one.')}</p>
|
||||
</article>
|
||||
<Table
|
||||
empty={filtered && t<string>('No available bags')}
|
||||
emptySpinner={t<string>('Retrieving all available bags, this will take some time')}
|
||||
|
||||
@ -6,7 +6,7 @@ import type { BN } from '@polkadot/util';
|
||||
|
||||
import { createNamedHook, useApi, useMapKeys } from '@polkadot/react-hooks';
|
||||
|
||||
const keyOptions = {
|
||||
const KEY_OPTS = {
|
||||
transform: (keys: StorageKey<[u64]>[]): BN[] =>
|
||||
keys.map(({ args: [id] }) => id)
|
||||
};
|
||||
@ -14,7 +14,7 @@ const keyOptions = {
|
||||
function useBagsIdsImpl (): BN[] | undefined {
|
||||
const { api } = useApi();
|
||||
|
||||
return useMapKeys(api.query.bagsList.listBags, keyOptions);
|
||||
return useMapKeys(api.query.bagsList.listBags, KEY_OPTS);
|
||||
}
|
||||
|
||||
export default createNamedHook('useBagsIds', useBagsIdsImpl);
|
||||
|
||||
@ -11,7 +11,7 @@ import { useEffect, useState } from 'react';
|
||||
import { createNamedHook, useApi, useCall } from '@polkadot/react-hooks';
|
||||
import { BN_ZERO } from '@polkadot/util';
|
||||
|
||||
const multiOptions = {
|
||||
const MULTI_OPTS = {
|
||||
transform: ([[ids], opts]: [[BN[]], Option<PalletBagsListListBag>[]]): BagInfo[] => {
|
||||
const sorted = ids
|
||||
.map((id, index): [BN, Option<PalletBagsListListBag>] => [id, opts[index]])
|
||||
@ -48,7 +48,7 @@ function merge (prev: BagInfo[] | undefined, curr: BagInfo[]): BagInfo[] {
|
||||
function useBagsListImpl (ids?: BN[]): BagInfo[] | undefined {
|
||||
const { api } = useApi();
|
||||
const [result, setResult] = useState<BagInfo[] | undefined>();
|
||||
const query = useCall(ids && ids.length !== 0 && api.query.bagsList.listBags.multi, [ids], multiOptions);
|
||||
const query = useCall(ids && ids.length !== 0 && api.query.bagsList.listBags.multi, [ids], MULTI_OPTS);
|
||||
|
||||
useEffect((): void => {
|
||||
query && setResult((prev) => merge(prev, query));
|
||||
|
||||
@ -9,7 +9,7 @@ import { useEffect, useState } from 'react';
|
||||
|
||||
import { createNamedHook, useApi, useCall } from '@polkadot/react-hooks';
|
||||
|
||||
const multiOptions = {
|
||||
const MULTI_OPTS = {
|
||||
transform: (opts: Option<PalletBagsListListNode>[]): BagMap =>
|
||||
opts
|
||||
.filter((o) => o.isSome)
|
||||
@ -42,7 +42,7 @@ function merge (prev: BagMap | undefined, curr: BagMap): BagMap {
|
||||
function useBagsNodesImpl (stashIds: string[]): BagMap | undefined {
|
||||
const { api } = useApi();
|
||||
const [result, setResult] = useState<BagMap | undefined>();
|
||||
const query = useCall(api.query.bagsList.listNodes.multi, [stashIds], multiOptions);
|
||||
const query = useCall(api.query.bagsList.listNodes.multi, [stashIds], MULTI_OPTS);
|
||||
|
||||
useEffect((): void => {
|
||||
query && setResult((prev) => merge(prev, query));
|
||||
|
||||
@ -7,7 +7,7 @@ import type { ListNode } from './types';
|
||||
|
||||
import { createNamedHook, useApi, useCall } from '@polkadot/react-hooks';
|
||||
|
||||
const deriveOpts = {
|
||||
const DERIVE_OPTS = {
|
||||
transform: (all: DeriveStakingAccount[]): ListNode[] => {
|
||||
const infos = all.map(({ stakingLedger, stashId }, index): ListNode => ({
|
||||
bonded: stakingLedger.active.unwrap(),
|
||||
@ -34,7 +34,7 @@ const deriveOpts = {
|
||||
function useBondedImpl (ids?: false | AccountId32[]): ListNode[] | undefined {
|
||||
const { api } = useApi();
|
||||
|
||||
return useCall(ids && ids.length !== 0 && api.derive.staking.accounts, [ids], deriveOpts);
|
||||
return useCall(ids && ids.length !== 0 && api.derive.staking.accounts, [ids], DERIVE_OPTS);
|
||||
}
|
||||
|
||||
export default createNamedHook('useBonded', useBondedImpl);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user