From 576cfa3bfb10eba7d574442196fe81c9363df9fc Mon Sep 17 00:00:00 2001 From: Przemek Rzad Date: Tue, 16 Jul 2024 06:11:35 +0200 Subject: [PATCH] Try decoding a preimage as a transaction (#10755) * registry does not make sense in this result type * use api instead * refactor - return early to reduce nesting, try api.tx first * Add warning * refactor return * lint --- packages/react-hooks/src/types.ts | 3 +- packages/react-hooks/src/usePreimage.ts | 84 +++++++++++++------------ 2 files changed, 46 insertions(+), 41 deletions(-) diff --git a/packages/react-hooks/src/types.ts b/packages/react-hooks/src/types.ts index f2f435784d..227ee500de 100644 --- a/packages/react-hooks/src/types.ts +++ b/packages/react-hooks/src/types.ts @@ -9,7 +9,7 @@ import type { DisplayedJudgement } from '@polkadot/react-components/types'; import type { Option, u32, u128, Vec } from '@polkadot/types'; import type { AccountId, BlockNumber, Call, Hash, SessionIndex, ValidatorPrefs } from '@polkadot/types/interfaces'; import type { PalletPreimageRequestStatus, PalletStakingRewardDestination, PalletStakingStakingLedger, SpStakingExposurePage, SpStakingPagedExposureMetadata } from '@polkadot/types/lookup'; -import type { ICompact, IExtrinsic, INumber, Registry } from '@polkadot/types/types'; +import type { ICompact, IExtrinsic, INumber } from '@polkadot/types/types'; import type { KeyringJson$Meta } from '@polkadot/ui-keyring/types'; import type { BN } from '@polkadot/util'; import type { HexString } from '@polkadot/util/types'; @@ -192,7 +192,6 @@ export interface PreimageStatus { isHashParam: boolean; proposalHash: HexString; proposalLength?: BN; - registry: Registry; status: PalletPreimageRequestStatus | null; } diff --git a/packages/react-hooks/src/usePreimage.ts b/packages/react-hooks/src/usePreimage.ts index 6dbf63d411..d4e8d01e4d 100644 --- a/packages/react-hooks/src/usePreimage.ts +++ b/packages/react-hooks/src/usePreimage.ts @@ -3,7 +3,7 @@ import type { ApiPromise } from '@polkadot/api'; import type { Bytes, u32, u128 } from '@polkadot/types'; -import type { AccountId, Call, Hash } from '@polkadot/types/interfaces'; +import type { AccountId, Hash } from '@polkadot/types/interfaces'; import type { FrameSupportPreimagesBounded, PalletPreimageRequestStatus } from '@polkadot/types/lookup'; import type { ITuple } from '@polkadot/types/types'; import type { HexString } from '@polkadot/util/types'; @@ -98,54 +98,60 @@ export function getPreimageHash (api: ApiPromise, hashOrBounded: Hash | HexStrin isHashParam: getParamType(api) === 'hash', proposalHash, proposalLength: inlineData && new BN(inlineData.length), - registry: api.registry, status: null } }; } /** @internal Creates a final result */ -function createResult (interimResult: PreimageStatus, optBytes: Option | Uint8Array): Preimage { +function createResult (api: ApiPromise, interimResult: PreimageStatus, optBytes: Option | Uint8Array): Preimage { const callData = isU8a(optBytes) ? optBytes : optBytes.unwrapOr(null); - let proposal: Call | null = null; - let proposalError: string | null = null; - let proposalWarning: string | null = null; - let proposalLength: BN | undefined; - if (callData) { - try { - proposal = interimResult.registry.createType('Call', callData); + const result = (preimage: Pick) => objectSpread({}, interimResult, { + isCompleted: true, + ...preimage + }); - const callLength = proposal.encodedLength; - - if (interimResult.proposalLength) { - const storeLength = interimResult.proposalLength.toNumber(); - - if (callLength !== storeLength) { - proposalWarning = `Decoded call length does not match on-chain stored preimage length (${formatNumber(callLength)} bytes vs ${formatNumber(storeLength)} bytes)`; - } - } else { - // for the old style, we set the actual length - proposalLength = new BN(callLength); - } - } catch (error) { - console.error(error); - - proposalError = 'Unable to decode preimage bytes into a valid Call'; - } - } else { - proposalWarning = 'No preimage bytes found'; + if (!callData) { + return result({ proposalWarning: 'No preimage bytes found' }); } - return objectSpread({}, interimResult, { - isCompleted: true, - proposal, - proposalError, - proposalLength: proposalLength || interimResult.proposalLength, - proposalWarning - }); + try { + const tx = api.tx(callData.toString()); + + const proposal = api.createType('Call', tx.method); + + if (tx.toHex() === callData.toString()) { + return result({ proposal }); + } + } catch {} + + try { + const proposal = api.registry.createType('Call', callData); + + const callLength = proposal.encodedLength; + + if (interimResult.proposalLength) { + const storeLength = interimResult.proposalLength.toNumber(); + + return result({ + proposal, + proposalWarning: callLength !== storeLength ? `Decoded call length does not match on-chain stored preimage length (${formatNumber(callLength)} bytes vs ${formatNumber(storeLength)} bytes)` : null + }); + } else { + // for the old style, we set the actual length + return result({ + proposal, + proposalLength: new BN(callLength) + }); + } + } catch (error) { + console.error(error); + } + + return result({ proposalError: 'Unable to decode preimage bytes into a valid Call' }); } /** @internal Helper to unwrap a deposit tuple into a structure */ @@ -238,14 +244,14 @@ function usePreimageImpl (hashOrBounded?: Hash | HexString | FrameSupportPreimag return useMemo( () => resultPreimageFor ? optBytes - ? createResult(resultPreimageFor, optBytes) + ? createResult(api, resultPreimageFor, optBytes) : resultPreimageFor : resultPreimageHash ? inlineData - ? createResult(resultPreimageHash, inlineData) + ? createResult(api, resultPreimageHash, inlineData) : resultPreimageHash : undefined, - [inlineData, optBytes, resultPreimageHash, resultPreimageFor] + [api, inlineData, optBytes, resultPreimageHash, resultPreimageFor] ); }