diff --git a/src/methods/storage_type_info.rs b/src/methods/storage_type_info.rs index 1cf8433..c4b7282 100644 --- a/src/methods/storage_type_info.rs +++ b/src/methods/storage_type_info.rs @@ -17,6 +17,7 @@ use super::Entry; use crate::utils::Either; use alloc::borrow::Cow; use alloc::borrow::ToOwned; +use alloc::format; use alloc::string::String; use alloc::vec::Vec; @@ -465,7 +466,7 @@ mod legacy { use scale_info_legacy::LookupName; macro_rules! impl_storage_type_info_for_v8_to_v12 { - ($path:path, $name:ident, $to_storage_hasher:ident) => { + ($path:path, $name:ident, $to_storage_hasher:ident, $is_linked_field:ident) => { const _: () = { use $path as path; impl StorageTypeInfo for path::$name { @@ -521,11 +522,24 @@ mod legacy { }) } path::StorageEntryType::Map { - hasher, key, value, .. + hasher, + key, + value, + $is_linked_field: is_linked, + .. } => { + // is_linked is some weird field that only appears on single-maps (not DoubleMap etc) + // and, if true, indicates that the value comes back with some trailing bytes pointing + // at the previous and next linked entry. Thus, we need to modify our output type ID + // to accomodate this. + let value_id = if *is_linked { + decode_is_linked_lookup_name_or_err(value, pallet_name)? + } else { + decode_lookup_name_or_err(value, pallet_name)? + }; + let key_id = decode_lookup_name_or_err(key, pallet_name)?; let hasher = $to_storage_hasher(hasher); - let value_id = decode_lookup_name_or_err(value, pallet_name)?; Ok(StorageInfo { keys: Cow::Owned(Vec::from_iter([StorageKeyInfo { hasher, @@ -621,27 +635,32 @@ mod legacy { impl_storage_type_info_for_v8_to_v12!( frame_metadata::v8, RuntimeMetadataV8, - to_storage_hasher_v8 + to_storage_hasher_v8, + is_linked ); impl_storage_type_info_for_v8_to_v12!( frame_metadata::v9, RuntimeMetadataV9, - to_storage_hasher_v9 + to_storage_hasher_v9, + is_linked ); impl_storage_type_info_for_v8_to_v12!( frame_metadata::v10, RuntimeMetadataV10, - to_storage_hasher_v10 + to_storage_hasher_v10, + is_linked ); impl_storage_type_info_for_v8_to_v12!( frame_metadata::v11, RuntimeMetadataV11, - to_storage_hasher_v11 + to_storage_hasher_v11, + unused ); impl_storage_type_info_for_v8_to_v12!( frame_metadata::v12, RuntimeMetadataV12, - to_storage_hasher_v12 + to_storage_hasher_v12, + unused ); impl StorageTypeInfo for frame_metadata::v13::RuntimeMetadataV13 { @@ -872,6 +891,17 @@ mod legacy { lookup_name_or_err(&ty, pallet_name) } + fn decode_is_linked_lookup_name_or_err>( + s: &DecodeDifferent<&str, S>, + pallet_name: &str, + ) -> Result> { + let ty = sanitize_type_name(as_decoded(s).as_ref()); + // Append a hardcoded::Linked type to the end, which we expect in the type definitions + // to be something like { previous: Option, next: Option }: + let ty = format!("({ty}, hardcoded::Linked)"); + lookup_name_or_err(&ty, pallet_name) + } + fn lookup_name_or_err( ty: &str, pallet_name: &str, diff --git a/types/kusama_relay_types.yaml b/types/kusama_relay_types.yaml index e42825a..2555332 100644 --- a/types/kusama_relay_types.yaml +++ b/types/kusama_relay_types.yaml @@ -1,4 +1,4 @@ -# This file provides all the type information necessary to decode historic blocks on the Kusama relay chain +# This file provides all the type information necessary to decode historic and storage blocks on the Kusama relay chain # for more information, or check out the documentation for this crate to see example usage. global: types: @@ -145,6 +145,7 @@ global: # Timestamp T::Moment: u64 + MomentOf: T::Moment # Indices T::AccountIndex: u32 @@ -163,6 +164,8 @@ global: LockIdentifier: '[u8; 8]' Reasons: _enum: ['Fee', 'Misc', 'All'] + # Early runtimes encoded lock withdraw reasons as bitflags; decode as scalar mask + WithdrawReasons: u8 Multiplier: u128 # Authorship @@ -357,8 +360,8 @@ global: reward: Balance # Session - T::Keys: (AccountId, AccountId, AccountId, AccountId, AccountId) - T::ValidatorId: AccountId + T::Keys: (T::AccountId, T::AccountId, T::AccountId, T::AccountId, T::AccountId) + T::ValidatorId: T::AccountId KeyTypeId: u32 # Grandpa @@ -450,6 +453,14 @@ global: - SuperMajorityApprove - SuperMajorityAgainst - SimpleMajority + ReferendumInfo: + _enum: + Ongoing: ReferendumStatus + Finished: ReferendumInfoFinished + ReferendumInfo: + _enum: + Ongoing: ReferendumStatus + Finished: ReferendumInfoFinished ReferendumInfoFinished: approved: bool end: BlockNumber @@ -711,7 +722,7 @@ global: OpenTip: reason: Hash who: AccountId - finder: AccountId + finder: Option deposit: Balance closes: Option tips: Vec<(AccountId, Balance)> @@ -764,6 +775,20 @@ global: WeakBoundedVec: Vec BoundedVec: Vec + Linkage: + previous: Option + next: Option + + # Society pallet bids + Bid: + who: AccountId + kind: BidKind + value: Balance + BidKind: + _enum: + Deposit: Balance + Vouch: (AccountId, Balance) + VouchDeposit: (AccountId, Balance) Balance: u128 BalanceOf: Balance @@ -947,9 +972,15 @@ global: hardcoded::ExtrinsicAddress: AccountId32 hardcoded::ExtrinsicSignature: Sr25519Signature hardcoded::ExtrinsicSignedExtensions: '(CheckVersion, CheckGenesis, CheckEra, CheckNonce, CheckWeight, ChargeAssetTxPayment, CheckBlockGasLimit)' - + # Legacy linked-map storage encodes linkage alongside the value; when + # frame-decode sees the historic `is_linked` flag it appends a + # `hardcoded::Linked` component to the storage value type. This models the + # `Linkage` shape used by those maps. + hardcoded::Linked: + previous: Option + next: Option # Hardcoded types for old metadatas that don't know about them. - + StrikeCount: u32 # signed exts ChargeAssetTxPayment: tip: Compact @@ -981,7 +1012,85 @@ global: DisallowSigned: [] Box: Call + VestingSchedule: + locked: T::Balance + per_block: T::Balance + starting_block: T::BlockNumber + VestingSchedule: + locked: Balance + per_block: Balance + starting_block: BlockNumber + BalanceLock: + id: LockIdentifier + amount: Balance + reasons: Reasons forSpec: + - range: [0, null] + types: + # Early Democracy used a struct for ReferendumInfo (no Tally, no enum) + ReferendumInfo: + end: BlockNumber + proposal_hash: Hash + threshold: VoteThreshold + delay: BlockNumber + ReferendumInfo: + end: BlockNumber + proposal_hash: Hash + threshold: VoteThreshold + delay: BlockNumber + - range: [1000, null] + types: + Weight: u32 + # Slots pallet aliases used in early Kusama events (e.g. NewLeasePeriod) + LeasePeriod: LeasePeriodOf + - range: [1000, null] + types: + # Democracy ReferendumInfo at these specs is a struct, not an enum + ReferendumInfo: + end: BlockNumber + proposal_hash: Hash + threshold: VoteThreshold + delay: BlockNumber + ReferendumInfo: + end: BlockNumber + proposal_hash: Hash + threshold: VoteThreshold + delay: BlockNumber + - range: [1020, null] + types: + EraPoints: + total: u32 + individual: Vec + - range: [1000, null] + types: + BalanceLock: + id: LockIdentifier + amount: T::Balance + until: BlockNumber + reasons: WithdrawReasons + # Early Kusama staking ledger did not include `claimed_rewards` + StakingLedger: + stash: AccountId + total: Compact + active: Compact + unlocking: Vec> + # Legacy linked-map storage for staking (Validators, Nominators) is + # modeled via an extra `hardcoded::Linked` component on the storage + # value type, so the value types themselves stay the same as in newer + # runtimes. + ValidatorPrefs: + commission: Compact + Nominations: + targets: Vec + submitted_in: EraIndex + suppressed: bool + - range: [1000, 1044] + types: + # Early Kusama Staking.SlashingSpans did not include last_nonzero_slash + slashing::SlashingSpans: + span_index: slashing::SpanIndex + last_start: EraIndex + prior: Vec - range: [1019, 1045] types: LookupSource: @@ -996,12 +1105,20 @@ forSpec: - range: [1032, 1042] types: # Spec 1032 specific overrides - Index: u64 + Index: u32 hardcoded::ExtrinsicAddress: LookupSource hardcoded::ExtrinsicSignature: MultiSignature hardcoded::ExtrinsicSignedExtensions: '(CheckVersion, CheckGenesis, CheckEra, CheckNonce, CheckWeight, ChargeTransactionPayment)' CheckVersion: [] CheckGenesis: [] + - range: [1042, 1050] + types: + OpenTip, T::BlockNumber, T::Hash>: + reason: T::Hash + who: T::AccountId + finder: Option<(T::AccountId, BalanceOf)> + closes: Option + tips: Vec<(T::AccountId, BalanceOf)> - range: [1028, 1028] types: # Spec 1028: legacy Address for dest and signer @@ -1084,7 +1201,7 @@ forSpec: types: # Society pallet's Judgement for this specific runtime version Judgement: u8 - - range: [2008, null] + - range: [2005, null] types: # Council.close uses Compact for proposal_weight_bound; by this spec Weight is u64. Weight: u64 @@ -1092,6 +1209,10 @@ forSpec: types: Address: AccountId32 LookupSource: AccountId32 + - range: [2025, null] + types: + # From this spec, `RefCount` was upgraded to `u32` (see `UpgradedToU32RefCount` flag in metadata). + RefCount: u32 - range: [9000, null] types: # ParasInherent (relay-chain) types needed to decode spec >= 9000 @@ -1229,6 +1350,23 @@ forSpec: ValidatorPrefs: commission: Compact blocked: bool + # AccountInfo upgraded to dual refcount (consumers + providers) at spec 2028 + AccountInfo: + nonce: Index + consumers: RefCount + providers: RefCount + data: AccountData + - range: [2030, null] + types: + # AccountInfo upgraded to triple refcount (consumers + providers + sufficients) + # By this spec, the runtime encodes an additional `sufficients: RefCount` + # field, which would otherwise appear as 4 leftover bytes when decoding. + AccountInfo: + nonce: Index + consumers: RefCount + providers: RefCount + sufficients: RefCount + data: AccountData - range: [9010, null] types: # Witness as defined in metadata (two Compact fields)