Cleanup staking info (#1532)

* Cleanup staking info

* Cache calls

* V1, V2 (Aura & Babe) tested & working

* Hopefully pacify docs build

* Second time lucky?

* Third time lucky?

* Fouth time
This commit is contained in:
Jaco Greeff
2019-10-30 14:15:20 +01:00
committed by GitHub
parent 2676909cd0
commit 8379689eaa
17 changed files with 232 additions and 102 deletions
@@ -30,6 +30,9 @@ export type AccountIdAndIndex = [AccountId?, AccountIndex?];
* ```
*/
export function idAndIndex (api: ApiInterfaceRx): (address?: Address | AccountId | AccountIndex | string | null) => Observable<AccountIdAndIndex> {
const idToIndexCall = idToIndex(api);
const indexToIdCall = indexToId(api);
return (address?: Address | AccountId | AccountIndex | string | null): Observable<AccountIdAndIndex> => {
try {
// yes, this can fail, don't care too much, catch will catch it
@@ -40,7 +43,7 @@ export function idAndIndex (api: ApiInterfaceRx): (address?: Address | AccountId
if (decoded.length === 32) {
const accountId = createType('AccountId', decoded);
return idToIndex(api)(accountId).pipe(
return idToIndexCall(accountId).pipe(
startWith(undefined),
map((accountIndex): AccountIdAndIndex => [accountId, accountIndex] as AccountIdAndIndex),
drr()
@@ -49,7 +52,7 @@ export function idAndIndex (api: ApiInterfaceRx): (address?: Address | AccountId
const accountIndex = createType('AccountIndex', decoded);
return indexToId(api)(accountIndex).pipe(
return indexToIdCall(accountIndex).pipe(
startWith(undefined),
map((accountId): AccountIdAndIndex => [accountId, accountIndex] as AccountIdAndIndex),
drr()
@@ -26,8 +26,10 @@ import { drr } from '../util/drr';
* ```
*/
export function idToIndex (api: ApiInterfaceRx): (accountId: AccountId | string) => Observable<AccountIndex | undefined> {
const indexesCall = indexes(api);
return (accountId: AccountId | string): Observable<AccountIndex | undefined> =>
indexes(api)().pipe(
indexesCall().pipe(
startWith({}),
map((indexes: AccountIndexes): AccountIndex | undefined =>
(indexes || {})[accountId.toString()]
+5 -2
View File
@@ -83,13 +83,16 @@ function queryBalances (api: ApiInterfaceRx, accountId: AccountId): Observable<R
* ```
*/
export function all (api: ApiInterfaceRx): (address: AccountIndex | AccountId | Address | string) => Observable<DerivedBalances> {
const bestNumberCall = bestNumber(api);
const idAndIndexCall = idAndIndex(api);
return (address: AccountIndex | AccountId | Address | string): Observable<DerivedBalances> => {
return idAndIndex(api)(address).pipe(
return idAndIndexCall(address).pipe(
switchMap(([accountId]): Observable<Result> =>
(accountId
? combineLatest([
of(accountId),
bestNumber(api)(),
bestNumberCall(),
queryBalances(api, accountId),
// FIXME This is having issues with Kusama, only use accountNonce atm
// api.rpc.account && api.rpc.account.nextIndex
@@ -15,8 +15,10 @@ import { drr } from '../util/drr';
import { votingBalances } from './votingBalances';
export function votingBalancesNominatorsFor (api: ApiInterfaceRx): (address: AccountId | AccountIndex | Address | string) => Observable<DerivedBalances[]> {
const idAndIndexCall = idAndIndex(api);
return (address: AccountId | AccountIndex | Address | string): Observable<DerivedBalances[]> => {
return idAndIndex(api)(address).pipe(
return idAndIndexCall(address).pipe(
switchMap(([accountId]): Observable<AccountId[]> =>
accountId
? (api.query.staking.nominatorsFor<Vec<AccountId>>(accountId))
@@ -27,10 +27,13 @@ import { bestNumberFinalized } from './bestNumberFinalized';
* ```
*/
export function bestNumberLag (api: ApiInterfaceRx): () => Observable<BlockNumber> {
const bestNumberCall = bestNumber(api);
const bestNumberFinalizedCall = bestNumberFinalized(api);
return (): Observable<BlockNumber> =>
combineLatest([
bestNumber(api)(),
bestNumberFinalized(api)()
bestNumberCall(),
bestNumberFinalizedCall()
]).pipe(
map(([bestNumber, bestNumberFinalized]): BlockNumber =>
createType('BlockNumber', bestNumber.sub(bestNumberFinalized))
@@ -16,13 +16,16 @@ import { votes } from './votes';
import { votingBalances } from '../balances/votingBalances';
export function referendumVotesFor (api: ApiInterfaceRx): (referendumId: BN | number) => Observable<DerivedReferendumVote[]> {
const votesCall = votes(api);
const votingBalancesCall = votingBalances(api);
return (referendumId: BN | number): Observable<DerivedReferendumVote[]> =>
(api.query.democracy.votersFor<Vec<AccountId>>(referendumId)).pipe(
switchMap((votersFor): Observable<[Vec<AccountId>, Vote[], DerivedBalances[]]> =>
combineLatest([
of(votersFor),
votes(api)(referendumId as BN, votersFor),
votingBalances(api)(votersFor)
votesCall(referendumId as BN, votersFor),
votingBalancesCall(votersFor)
])
),
map(([votersFor, votes, balances]): DerivedReferendumVote[] =>
@@ -15,6 +15,8 @@ import { drr } from '../util/drr';
import { referendumInfos } from './referendumInfos';
export function referendums (api: ApiInterfaceRx): () => Observable<Option<ReferendumInfoExtended>[]> {
const referendumInfosCall = referendumInfos(api);
return (): Observable<Option<ReferendumInfoExtended>[]> =>
(api.queryMulti([
api.query.democracy.nextTally,
@@ -22,7 +24,7 @@ export function referendums (api: ApiInterfaceRx): () => Observable<Option<Refer
]) as Observable<[ReferendumIndex?, ReferendumIndex?]>).pipe(
switchMap(([nextTally, referendumCount]): Observable<Option<ReferendumInfoExtended>[]> =>
referendumCount && nextTally && referendumCount.gt(nextTally) && referendumCount.gtn(0)
? referendumInfos(api)(
? referendumInfosCall(
[...Array(referendumCount.sub(nextTally).toNumber())].map((_, i): BN =>
nextTally.addn(i)
)
+2 -1
View File
@@ -58,7 +58,8 @@ function derivePhragmen (candidates: Vec<AccountId>, members: Vec<[AccountId, Ba
}
function queryPhragmen (api: ApiInterfaceRx): Observable<DerivedElectionsInfo> {
// NOTE We have an issue where candidates can return `null` for an empty array
// NOTE We have an issue where candidates can return `null` for an empty array, hence
// we are not using multi queries here, so empty array is empty (instead of space-filled)
return combineLatest([
api.query.electionsPhragmen.candidates<Vec<AccountId>>(),
api.query.electionsPhragmen.members<Vec<[AccountId, Balance] & Codec>>()
+3 -1
View File
@@ -26,8 +26,10 @@ import { voterPositions } from './voterPositions';
* ```
*/
export function voters (api: ApiInterfaceRx): () => Observable<Vec<AccountId>> {
const voterPositionsCall = voterPositions(api);
return (): Observable<Vec<AccountId>> =>
voterPositions(api)().pipe(
voterPositionsCall().pipe(
map(
(voterPositions: DerivedVoterPositions): Vec<AccountId> =>
createType(
+8 -5
View File
@@ -2,7 +2,8 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import BN from 'bn.js';
import { BlockNumber } from '@polkadot/types/interfaces';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
@@ -10,10 +11,12 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
import { drr } from '../util/drr';
import { info } from './info';
export function eraLength (api: ApiInterfaceRx): () => Observable<BN> {
return (): Observable<BN> =>
info(api)().pipe(
map(({ eraLength }): BN => eraLength),
export function eraLength (api: ApiInterfaceRx): () => Observable<BlockNumber> {
const infoCall = info(api);
return (): Observable<BlockNumber> =>
infoCall().pipe(
map(({ eraLength }): BlockNumber => eraLength),
drr()
);
}
@@ -11,8 +11,10 @@ import { drr } from '../util/drr';
import { info } from './info';
export function eraProgress (api: ApiInterfaceRx): () => Observable<BN> {
const infoCall = info(api);
return (): Observable<BN> =>
info(api)().pipe(
infoCall().pipe(
map(({ eraProgress }): BN => eraProgress),
drr()
);
+13 -14
View File
@@ -13,8 +13,8 @@ import { Option, u64, createType } from '@polkadot/types';
import { drr } from '../util/drr';
import { bestNumber } from '../chain';
type Result94Session = [SessionIndex, Option<BlockNumber>, BlockNumber, BlockNumber, SessionIndex];
type Result94 = [BlockNumber, Result94Session];
type ResultV1Session = [SessionIndex, Option<BlockNumber>, BlockNumber, BlockNumber, SessionIndex];
type ResultV1 = [BlockNumber, ResultV1Session];
type ResultIndex = [SessionIndex, EraIndex];
type ResultSlots = [u64, u64, u64, SessionIndex, EraIndex, SessionIndex];
@@ -22,7 +22,7 @@ type ResultType = [boolean, u64, SessionIndex];
type Result = [ResultType, ResultSlots];
// internal helper to just split the logic - take all inputs, do the calculations and combine
function createDerived94 ([bestNumber, [currentIndex, _lastLengthChange, sessionLength, lastEraLengthChange, sessionsPerEra]]: Result94): DerivedSessionInfo {
function createDerivedV1 ([bestNumber, [currentIndex, _lastLengthChange, sessionLength, lastEraLengthChange, sessionsPerEra]]: ResultV1): DerivedSessionInfo {
const lastLengthChange = (_lastLengthChange && _lastLengthChange.unwrapOr(null)) || createType('BlockNumber');
const sessionProgress = bestNumber
.sub(lastLengthChange)
@@ -68,10 +68,10 @@ function createDerivedLatest ([[hasBabe, epochDuration, sessionsPerEra], [curren
};
}
function info94 (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
function infoV1 (api: ApiInterfaceRx, bestNumberCall: () => Observable<BlockNumber>): Observable<DerivedSessionInfo> {
return combineLatest([
bestNumber(api)(),
api.queryMulti<Result94Session>([
bestNumberCall(),
api.queryMulti<ResultV1Session>([
api.query.session.currentIndex,
api.query.session.lastLengthChange,
api.query.session.sessionLength,
@@ -79,7 +79,7 @@ function info94 (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
api.query.staking.sessionsPerEra
])
]).pipe(
map(createDerived94),
map(createDerivedV1),
drr()
);
}
@@ -122,14 +122,13 @@ function infoLatestBabe (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
* @description Retrieves all the session and era info and calculates specific values on it as the length of the session and eras
*/
export function info (api: ApiInterfaceRx): () => Observable<DerivedSessionInfo> {
const bestNumberCall = bestNumber(api);
return (): Observable<DerivedSessionInfo> => {
// With substrate `spec_version 94`, the era and session has been explicitly exposed as `parameter_types`.
// pre-94 we had more info and needed to calculate (handle old/Alex first)
// https://github.com/paritytech/substrate/commit/dbf322620948935d2bbae214504e6c668c3073ed#diff-c29f42d6b931fa93ba038dbbbfec3055
return api.query.session.lastLengthChange
? info94(api) // 1.x
: api.consts.babe
return api.consts.staking
? api.consts.babe
? infoLatestBabe(api) // 2.x with Babe
: infoLatestAura(api); // 2.x with Aura (not all info there)
: infoLatestAura(api) // 2.x with Aura (not all info there)
: infoV1(api, bestNumberCall); // 1.x
};
}
@@ -12,8 +12,10 @@ import { drr } from '../util/drr';
import { info } from './info';
export function sessionProgress (api: ApiInterfaceRx): () => Observable<BlockNumber> {
const infoCall = info(api);
return (): Observable<BlockNumber> =>
info(api)().pipe(
infoCall().pipe(
map(({ sessionProgress }): BlockNumber => sessionProgress),
drr()
);
+31
View File
@@ -0,0 +1,31 @@
// Copyright 2017-2019 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { DerivedStaking } from '../types';
import { Observable, combineLatest } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { drr } from '../util/drr';
import { controllers } from './controllers';
import { info } from './info';
/**
* @description Retrieve all the staking info available for the chain
*/
export function all (api: ApiInterfaceRx): () => Observable<DerivedStaking[]> {
const infoCall = info(api);
const controllersCall = controllers(api);
return (): Observable<DerivedStaking[]> =>
controllersCall().pipe(
switchMap(([accountIds]): Observable<DerivedStaking[]> =>
combineLatest(
accountIds.map((accountId): Observable<DerivedStaking> => infoCall(accountId))
)
),
drr()
);
}
+1
View File
@@ -2,6 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export * from './all';
export * from './controllers';
export * from './info';
export * from './recentlyOffline';
+121 -64
View File
@@ -8,7 +8,7 @@ import { Exposure, RewardDestination, StakingLedger, UnlockChunk, ValidatorPrefs
import { Codec } from '@polkadot/types/types';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DerivedStaking, DerivedUnlocking } from '../types';
import { DerivedRecentlyOffline, DerivedStaking, DerivedUnlocking } from '../types';
import BN from 'bn.js';
import { combineLatest, Observable, of } from 'rxjs';
@@ -22,7 +22,28 @@ import { eraLength } from '../session/eraLength';
import { recentlyOffline } from './recentlyOffline';
import { drr } from '../util/drr';
type MultiResult = [Option<AccountId> | Vec<[AccountId, Keys] & Codec>, Option<StakingLedger>, [AccountId[]], RewardDestination, Exposure, [ValidatorPrefs], Option<Keys>?];
interface Calls {
bestNumberCall (): Observable<BlockNumber>;
eraLengthCall (): Observable<BlockNumber>;
recentlyOfflineCall (): Observable<DerivedRecentlyOffline>;
}
interface ParseInput {
accountId: AccountId;
bestNumber: BlockNumber;
controllerId: AccountId;
eraLength: BlockNumber;
recentlyOffline?: DerivedRecentlyOffline;
nominators: AccountId[];
rewardDestination: RewardDestination;
queuedKeys?: [AccountId, Keys][];
stakers: Exposure;
stakingLedger: Option<StakingLedger>;
stashId: AccountId;
validatorPrefs: ValidatorPrefs;
nextKeys?: Option<Keys>;
nextKeyFor?: Option<AccountId>;
}
// groups the supplied chunks by era, i.e. { [era]: BN(total of values) }
function groupByEra (list: UnlockChunk[]): Record<string, BN> {
@@ -82,7 +103,7 @@ function redeemableSum (stakingLedger: StakingLedger | undefined, eraLength: BN,
}, new BN(0)));
}
function unwrapSessionIds (stashId: AccountId, queuedKeys: Option<AccountId> | Vec<[AccountId, Keys] & Codec>, nextKeys: Option<Keys>): { nextSessionIds: AccountId[]; nextSessionId?: AccountId; sessionIds: AccountId[]; sessionId?: AccountId } {
function unwrapSessionIds (stashId: AccountId, queuedKeys: Option<AccountId> | [AccountId, Keys][], nextKeys: Option<Keys>): { nextSessionIds: AccountId[]; nextSessionId?: AccountId; sessionIds: AccountId[]; sessionId?: AccountId } {
// for 2.x we have a Vec<(ValidatorId,Keys)> of the keys
if (Array.isArray(queuedKeys)) {
const sessionIds = (queuedKeys.find(([currentId]): boolean =>
@@ -111,80 +132,116 @@ function unwrapSessionIds (stashId: AccountId, queuedKeys: Option<AccountId> | V
};
}
function retrieveMulti (api: ApiInterfaceRx, stashId: AccountId, controllerId: AccountId): Observable<MultiResult> {
// A bit horrible, since we push below to forge everything into 1 query - we do this we we end up with one
// query to retrieve everything
const queries: Array<any> = [
api.query.session.queuedKeys
? [api.query.session.queuedKeys]
: [api.query.session.nextKeyFor, controllerId],
[api.query.staking.ledger, controllerId],
[api.query.staking.nominators, stashId],
[api.query.staking.payee, stashId],
[api.query.staking.stakers, stashId],
[api.query.staking.validators, stashId]
];
function parseResult ({ accountId, controllerId, stashId, eraLength, bestNumber, recentlyOffline = {}, nextKeyFor = createType('Option<AccountId>', null), queuedKeys, stakingLedger, nominators, rewardDestination, stakers, validatorPrefs, nextKeys = createType('Option<Keys>', null) }: ParseInput): DerivedStaking {
const _stakingLedger = stakingLedger.unwrapOr(undefined);
//
if (api.query.session.nextKeys) {
queries.push([api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]]);
}
return api.queryMulti(queries) as Observable<MultiResult>;
return {
accountId,
controllerId,
nominators,
offline: recentlyOffline[stashId.toString()],
redeemable: redeemableSum(_stakingLedger, eraLength, bestNumber),
rewardDestination,
stakers,
stakingLedger: _stakingLedger,
stashId,
unlocking: calculateUnlocking(_stakingLedger, eraLength, bestNumber),
validatorPrefs,
...unwrapSessionIds(stashId, queuedKeys || nextKeyFor, nextKeys)
};
}
function retrieveInfo (api: ApiInterfaceRx, accountId: AccountId, stashId: AccountId, controllerId: AccountId): Observable<DerivedStaking> {
return combineLatest([
eraLength(api)(),
bestNumber(api)(),
recentlyOffline(api)(),
retrieveMulti(api, stashId, controllerId)
]).pipe(
map(([eraLength, bestNumber, recentlyOffline, [queuedKeys, _stakingLedger, [nominators], rewardDestination, stakers, [validatorPrefs], nextKeys = createType('Option<Keys>', null)]]): DerivedStaking => {
const stakingLedger = _stakingLedger.unwrapOr(undefined);
type MultiResultV1 = [Option<AccountId>, Option<StakingLedger>, [Vec<AccountId>], RewardDestination, Exposure, [ValidatorPrefs] & Codec];
return {
accountId,
controllerId,
nominators,
offline: recentlyOffline[stashId.toString()],
redeemable: redeemableSum(stakingLedger, eraLength, bestNumber),
rewardDestination,
stakers,
stakingLedger,
stashId,
unlocking: calculateUnlocking(stakingLedger, eraLength, bestNumber),
validatorPrefs,
...unwrapSessionIds(stashId, queuedKeys, nextKeys)
};
function retrieveInfoV1 (api: ApiInterfaceRx, { bestNumberCall, eraLengthCall, recentlyOfflineCall }: Calls, accountId: AccountId, stashId: AccountId, controllerId: AccountId): Observable<DerivedStaking> {
return combineLatest([
bestNumberCall(),
eraLengthCall(),
recentlyOfflineCall(),
api.queryMulti([
[api.query.session.nextKeyFor, controllerId],
[api.query.staking.ledger, controllerId],
[api.query.staking.nominators, stashId],
[api.query.staking.payee, stashId],
[api.query.staking.stakers, stashId],
[api.query.staking.validators, stashId]
]) as Observable<MultiResultV1>
]).pipe(map(([
bestNumber, eraLength, recentlyOffline,
[nextKeyFor, stakingLedger, [nominators], rewardDestination, stakers, [validatorPrefs]]
]: [BlockNumber, BlockNumber, DerivedRecentlyOffline, MultiResultV1]): DerivedStaking =>
parseResult({
accountId, controllerId, stashId, eraLength, bestNumber, recentlyOffline, nextKeyFor, stakingLedger, nominators, rewardDestination, stakers, validatorPrefs
})
);
));
}
type MultiResultV2 = [Option<StakingLedger>, [Vec<AccountId>], RewardDestination, Exposure, [ValidatorPrefs], Option<Keys>];
function retrieveInfoV2 (api: ApiInterfaceRx, { bestNumberCall, eraLengthCall }: Calls, accountId: AccountId, stashId: AccountId, controllerId: AccountId): Observable<DerivedStaking> {
return combineLatest([
bestNumberCall(),
eraLengthCall(),
api.query.session.queuedKeys<Vec<[AccountId, Keys] & Codec>>(),
api.queryMulti([
[api.query.staking.ledger, controllerId],
[api.query.staking.nominators, stashId],
[api.query.staking.payee, stashId],
[api.query.staking.stakers, stashId],
[api.query.staking.validators, stashId],
[api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]]
]) as Observable<MultiResultV2>
]).pipe(map(([
bestNumber, eraLength, queuedKeys,
[stakingLedger, [nominators], rewardDestination, stakers, [validatorPrefs], nextKeys]
]: [BlockNumber, BlockNumber, [AccountId, Keys][], MultiResultV2]): DerivedStaking =>
parseResult({
accountId, controllerId, stashId, eraLength, bestNumber, queuedKeys, stakingLedger, nominators, rewardDestination, stakers, validatorPrefs, nextKeys
})
));
}
function retrieveV1 (api: ApiInterfaceRx, calls: Calls, controllerId: AccountId): Observable<DerivedStaking> {
return api.query.staking
.ledger<Option<StakingLedger>>(controllerId)
.pipe(
switchMap((stakingLedger): Observable<DerivedStaking> =>
stakingLedger.isSome
? retrieveInfoV1(api, calls, controllerId, stakingLedger.unwrap().stash, controllerId)
: of({ accountId: controllerId, nextSessionIds: [], sessionIds: [] })
),
drr()
);
}
function retrieveV2 (api: ApiInterfaceRx, calls: Calls, stashId: AccountId): Observable<DerivedStaking> {
return api.query.staking
.bonded<Option<AccountId>>(stashId)
.pipe(
switchMap((controllerId): Observable<DerivedStaking> =>
controllerId.isSome
? retrieveInfoV2(api, calls, stashId, stashId, controllerId.unwrap())
: of({ accountId: stashId, nextSessionIds: [], sessionIds: [] })
),
drr()
);
}
/**
* @description From a stash, retrieve the controllerId and fill in all the relevant staking details
*/
export function info (api: ApiInterfaceRx): (_accountId: Uint8Array | string) => Observable<DerivedStaking> {
const calls = {
eraLengthCall: eraLength(api),
bestNumberCall: bestNumber(api),
recentlyOfflineCall: recentlyOffline(api)
};
return (_accountId: Uint8Array | string): Observable<DerivedStaking> => {
const accountId = createType('AccountId', _accountId);
return (
// NOTE For 2.x-only support, only the first path is required, therefore we
// can replace this with `.bonded<Option<AccountId>>(accountId)` - in 2.x
// the session.validators return the stashes (as expected)
api.queryMulti<[Option<AccountId>, Option<StakingLedger>]>([
[api.query.staking.bonded, accountId], // try to map to controller
[api.query.staking.ledger, accountId] // try to map to stash (1.x only)
])
).pipe(
switchMap(([controllerId, stakingLedger]): Observable<DerivedStaking> =>
controllerId.isSome
? retrieveInfo(api, accountId, accountId, controllerId.unwrap())
: stakingLedger.isSome
? retrieveInfo(api, accountId, stakingLedger.unwrap().stash, accountId)
: of({ accountId, nextSessionIds: [], sessionIds: [] })
),
drr()
);
return api.consts.session
? retrieveV2(api, calls, accountId)
: retrieveV1(api, calls, accountId);
};
}
+18 -4
View File
@@ -17,13 +17,27 @@ function u8aHasValue (value: Uint8Array): boolean {
// With isPedantic, actually check that the encoding matches that supplied. This
// is much slower, but verifies that we have the correct types defined
function checkInstance<T extends Codec = Codec, K extends string = string> (value: Uint8Array, created: FromReg<T, K>): void {
// For option, we are not adding the initial byte (this is via storage)
const crHex = created.toHex(true);
// the underlying type created.toRawType()
const rawType = created.toRawType();
// ignore bytes completely - this is probably a FIXME, since these are somewhat
// breaking for at least online queries - not quite sure wtf is going wrong here
if (rawType === 'Bytes') {
return;
}
// the hex values for what we have
const inHex = u8aToHex(value);
const crHex = created.toHex();
// Check equality, based on some different approaches (as decoded)
const isEqual = inHex === crHex || // raw hex values, quick path
inHex === created.toHex(true) || // wrapped options
u8aToHex(value.reverse()) === crHex; // reverse (for numbers, which are BE)
// if the hex doesn't match and the value for both is non-empty, complain... bitterly
if (inHex !== crHex && (u8aHasValue(value) || u8aHasValue(created.toU8a(true)))) {
console.warn(`${created.toRawType()}:: Input doesn't match output, received ${inHex}, created ${crHex}`);
if (!isEqual && (u8aHasValue(value) || u8aHasValue(created.toU8a(true)))) {
console.warn(`${rawType}:: Input doesn't match output, received ${u8aToHex(value)}, created ${crHex}`);
}
}