diff --git a/CHANGELOG.md b/CHANGELOG.md index dae6287e05..5e8d69cef9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Changes: - Support for `NominationPoolsApi` runtime interface - Support for `DebugRuntimeApi` runtime interface, Frontier-specific - Support for `NimbusApi` runtime interface (& older `AuthorFilterAPI`) +- Add additional historic `DispatchError` enum variant for asset chains - Add Kusama 9250 upgrade block diff --git a/packages/types-augment/src/registry/interfaces.ts b/packages/types-augment/src/registry/interfaces.ts index e0f6296858..909ea05408 100644 --- a/packages/types-augment/src/registry/interfaces.ts +++ b/packages/types-augment/src/registry/interfaces.ts @@ -60,7 +60,7 @@ import type { Bid, BidKind, SocietyJudgement, SocietyVote, StrikeCount, Vouching import type { ActiveEraInfo, CompactAssignments, CompactAssignmentsTo257, CompactAssignmentsTo265, CompactAssignmentsWith16, CompactAssignmentsWith24, CompactScore, CompactScoreCompact, ElectionCompute, ElectionPhase, ElectionResult, ElectionScore, ElectionSize, ElectionStatus, EraIndex, EraPoints, EraRewardPoints, EraRewards, Exposure, ExtendedBalance, Forcing, IndividualExposure, KeyType, MomentOf, Nominations, NominatorIndex, NominatorIndexCompact, OffchainAccuracy, OffchainAccuracyCompact, PhragmenScore, Points, RawSolution, RawSolutionTo265, RawSolutionWith16, RawSolutionWith24, ReadySolution, RewardDestination, RewardPoint, RoundSnapshot, SeatHolder, SignedSubmission, SignedSubmissionOf, SignedSubmissionTo276, SlashJournalEntry, SlashingSpans, SlashingSpansTo204, SolutionOrSnapshotSize, SolutionSupport, SolutionSupports, SpanIndex, SpanRecord, StakingLedger, StakingLedgerTo223, StakingLedgerTo240, SubmissionIndicesOf, Supports, UnappliedSlash, UnappliedSlashOther, UnlockChunk, ValidatorIndex, ValidatorIndexCompact, ValidatorPrefs, ValidatorPrefsTo145, ValidatorPrefsTo196, ValidatorPrefsWithBlocked, ValidatorPrefsWithCommission, VoteWeight, Voter } from '@polkadot/types/interfaces/staking'; import type { ApiId, BlockTrace, BlockTraceEvent, BlockTraceEventData, BlockTraceSpan, KeyValueOption, MigrationStatusResult, ReadProof, RuntimeVersion, RuntimeVersionApi, RuntimeVersionPartial, RuntimeVersionPre3, RuntimeVersionPre4, SpecVersion, StorageChangeSet, TraceBlockResponse, TraceError } from '@polkadot/types/interfaces/state'; import type { WeightToFeeCoefficient } from '@polkadot/types/interfaces/support'; -import type { AccountInfo, AccountInfoWithDualRefCount, AccountInfoWithProviders, AccountInfoWithRefCount, AccountInfoWithRefCountU8, AccountInfoWithTripleRefCount, ApplyExtrinsicResult, ApplyExtrinsicResultPre6, ArithmeticError, BlockLength, BlockWeights, ChainProperties, ChainType, ConsumedWeight, DigestOf, DispatchClass, DispatchError, DispatchErrorModule, DispatchErrorModulePre6, DispatchErrorModuleU8, DispatchErrorModuleU8a, DispatchErrorPre6, DispatchErrorTo198, DispatchInfo, DispatchInfoTo190, DispatchInfoTo244, DispatchOutcome, DispatchOutcomePre6, DispatchResult, DispatchResultOf, DispatchResultTo198, Event, EventId, EventIndex, EventRecord, Health, InvalidTransaction, Key, LastRuntimeUpgradeInfo, NetworkState, NetworkStatePeerset, NetworkStatePeersetInfo, NodeRole, NotConnectedPeer, Peer, PeerEndpoint, PeerEndpointAddr, PeerInfo, PeerPing, PerDispatchClassU32, PerDispatchClassWeight, PerDispatchClassWeightsPerClass, Phase, RawOrigin, RefCount, RefCountTo259, SyncState, SystemOrigin, TokenError, TransactionValidityError, TransactionalError, UnknownTransaction, WeightPerClass } from '@polkadot/types/interfaces/system'; +import type { AccountInfo, AccountInfoWithDualRefCount, AccountInfoWithProviders, AccountInfoWithRefCount, AccountInfoWithRefCountU8, AccountInfoWithTripleRefCount, ApplyExtrinsicResult, ApplyExtrinsicResultPre6, ArithmeticError, BlockLength, BlockWeights, ChainProperties, ChainType, ConsumedWeight, DigestOf, DispatchClass, DispatchError, DispatchErrorModule, DispatchErrorModulePre6, DispatchErrorModuleU8, DispatchErrorModuleU8a, DispatchErrorPre6, DispatchErrorPre6First, DispatchErrorTo198, DispatchInfo, DispatchInfoTo190, DispatchInfoTo244, DispatchOutcome, DispatchOutcomePre6, DispatchResult, DispatchResultOf, DispatchResultTo198, Event, EventId, EventIndex, EventRecord, Health, InvalidTransaction, Key, LastRuntimeUpgradeInfo, NetworkState, NetworkStatePeerset, NetworkStatePeersetInfo, NodeRole, NotConnectedPeer, Peer, PeerEndpoint, PeerEndpointAddr, PeerInfo, PeerPing, PerDispatchClassU32, PerDispatchClassWeight, PerDispatchClassWeightsPerClass, Phase, RawOrigin, RefCount, RefCountTo259, SyncState, SystemOrigin, TokenError, TransactionValidityError, TransactionalError, UnknownTransaction, WeightPerClass } from '@polkadot/types/interfaces/system'; import type { Bounty, BountyIndex, BountyStatus, BountyStatusActive, BountyStatusCuratorProposed, BountyStatusPendingPayout, OpenTip, OpenTipFinderTo225, OpenTipTip, OpenTipTo225, TreasuryProposal } from '@polkadot/types/interfaces/treasury'; import type { Multiplier } from '@polkadot/types/interfaces/txpayment'; import type { TransactionSource, TransactionValidity, ValidTransaction } from '@polkadot/types/interfaces/txqueue'; @@ -331,6 +331,7 @@ declare module '@polkadot/types/types/registry' { DispatchErrorModuleU8: DispatchErrorModuleU8; DispatchErrorModuleU8a: DispatchErrorModuleU8a; DispatchErrorPre6: DispatchErrorPre6; + DispatchErrorPre6First: DispatchErrorPre6First; DispatchErrorTo198: DispatchErrorTo198; DispatchFeePayment: DispatchFeePayment; DispatchInfo: DispatchInfo; diff --git a/packages/types-codec/src/abstract/Array.ts b/packages/types-codec/src/abstract/Array.ts index e6a6e2027a..fd85ab65c9 100644 --- a/packages/types-codec/src/abstract/Array.ts +++ b/packages/types-codec/src/abstract/Array.ts @@ -119,7 +119,7 @@ export abstract class AbstractArray extends Array implements const result = new Array(this.length); for (let i = 0; i < this.length; i++) { - result[i] = this[i].toHuman(isExtended); + result[i] = this[i] && this[i].toHuman(isExtended); } return result; @@ -132,7 +132,9 @@ export abstract class AbstractArray extends Array implements const result = new Array(this.length); for (let i = 0; i < this.length; i++) { - result[i] = this[i].toJSON(); + // We actually log inside the U8a decoding and use JSON.stringify(...), which + // means that the Vec may be partially populated (same applies to toHuman, same check) + result[i] = this[i] && this[i].toJSON(); } return result; diff --git a/packages/types-codec/src/native/Struct.ts b/packages/types-codec/src/native/Struct.ts index d09c20624f..b682cd42d4 100644 --- a/packages/types-codec/src/native/Struct.ts +++ b/packages/types-codec/src/native/Struct.ts @@ -285,6 +285,8 @@ export class Struct< for (const [k, v] of this.entries()) { const jsonKey = this.#jsonMap.get(k) || k; + // We actually log inside the U8a decoding and use JSON.stringify(...), which + // means that the Vec may be partially populated (same applies to toHuman, same check) json[jsonKey as string] = v && v.toJSON(); } diff --git a/packages/types-codec/src/utils/decodeU8a.ts b/packages/types-codec/src/utils/decodeU8a.ts index f6a10ae0fe..1b2c5aa93a 100644 --- a/packages/types-codec/src/utils/decodeU8a.ts +++ b/packages/types-codec/src/utils/decodeU8a.ts @@ -42,6 +42,8 @@ export function decodeU8a (registry: Registry, result: i++; } } catch (error) { + // console.error(JSON.stringify(result, null, 2)); + throw new Error(formatFailure(registry, error as Error, u8a.subarray(offset), i, count, Types[i], keys[i])); } @@ -68,6 +70,8 @@ export function decodeU8aStruct (registry: Registry, result: [string, Codec][], i++; } } catch (error) { + // console.error(JSON.stringify(result, null, 2)); + throw new Error(formatFailure(registry, error as Error, u8a.subarray(offset), i, count, Types[i], keys[i])); } @@ -94,6 +98,8 @@ export function decodeU8aVec (registry: Registry, resu i++; } } catch (error) { + console.error(JSON.stringify(result, null, 2)); + throw new Error(formatFailure(registry, error as Error, u8a.subarray(offset), i, count, Type)); } diff --git a/packages/types-known/src/spec/statemint.ts b/packages/types-known/src/spec/statemint.ts index ff5d4164c6..8417d2b28f 100644 --- a/packages/types-known/src/spec/statemint.ts +++ b/packages/types-known/src/spec/statemint.ts @@ -28,7 +28,11 @@ const sharedTypes = { const versioned: OverrideVersionedType[] = [ { minmax: [0, 3], - types: objectSpread({}, sharedTypes, mapXcmTypes('V0')) + types: objectSpread({ + // Enum was modified mid-flight - + // https://github.com/paritytech/substrate/pull/10382/files#diff-e4e016b33a82268b6208dc974eea841bad47597865a749fee2f937eb6fdf67b4R498 + DispatchError: 'DispatchErrorPre6First' + }, sharedTypes, mapXcmTypes('V0')) }, { minmax: [4, 5], diff --git a/packages/types/src/interfaces/system/definitions.ts b/packages/types/src/interfaces/system/definitions.ts index 6afce6fc8a..32bf66b125 100644 --- a/packages/types/src/interfaces/system/definitions.ts +++ b/packages/types/src/interfaces/system/definitions.ts @@ -101,6 +101,21 @@ export default { Transactional: 'TransactionalError' } }, + DispatchErrorPre6First: { + // The enum was modified mid-flight, affecting asset chains - + // https://github.com/paritytech/substrate/pull/10382/files#diff-e4e016b33a82268b6208dc974eea841bad47597865a749fee2f937eb6fdf67b4R498 + _enum: { + Other: 'Null', + CannotLookup: 'Null', + BadOrigin: 'Null', + Module: 'DispatchErrorModulePre6', + ConsumerRemaining: 'Null', + NoProviders: 'Null', + Token: 'TokenError', + Arithmetic: 'ArithmeticError', + Transactional: 'TransactionalError' + } + }, DispatchErrorModuleU8: { index: 'u8', error: 'u8' diff --git a/packages/types/src/interfaces/system/types.ts b/packages/types/src/interfaces/system/types.ts index 88c7447f42..d91cee997b 100644 --- a/packages/types/src/interfaces/system/types.ts +++ b/packages/types/src/interfaces/system/types.ts @@ -171,6 +171,24 @@ export interface DispatchErrorPre6 extends Enum { readonly type: 'Other' | 'CannotLookup' | 'BadOrigin' | 'Module' | 'ConsumerRemaining' | 'NoProviders' | 'TooManyConsumers' | 'Token' | 'Arithmetic' | 'Transactional'; } +/** @name DispatchErrorPre6First */ +export interface DispatchErrorPre6First extends Enum { + readonly isOther: boolean; + readonly isCannotLookup: boolean; + readonly isBadOrigin: boolean; + readonly isModule: boolean; + readonly asModule: DispatchErrorModulePre6; + readonly isConsumerRemaining: boolean; + readonly isNoProviders: boolean; + readonly isToken: boolean; + readonly asToken: TokenError; + readonly isArithmetic: boolean; + readonly asArithmetic: ArithmeticError; + readonly isTransactional: boolean; + readonly asTransactional: TransactionalError; + readonly type: 'Other' | 'CannotLookup' | 'BadOrigin' | 'Module' | 'ConsumerRemaining' | 'NoProviders' | 'Token' | 'Arithmetic' | 'Transactional'; +} + /** @name DispatchErrorTo198 */ export interface DispatchErrorTo198 extends Struct { readonly module: Option;